Introduction
Pmake is a program designed to simplify the maintenance of other programs. Its input is a list of specifications as to the files upon which programs and other files depend. mkdep, a program to construct Makefile dependency lists, is also included.
This doc is not to introduce how to use pmake in detail. The goal of this doc is to introduce how to use the pmake templates which under /usr/share/mk . For more detail, refer to /usr/share/mk/bsd.README.
Mk Template Files
The following mk templates are very useful when you create your project. In this doc, we will deep into them.
bsd.subdir.mk - targets for building subdirectories
bsd.lib.mk - support for building libraries
bsd.prog.mk - building programs from source files
Server Common Targets for three mks:
all:
build the program and its manual page
clean:
remove the program, any object files and the files a.out,
Errs, errs, mklog, and ${PROG}.core.
cleandir:
remove all of the files removed by the target clean, as
well as .depend, tags, and any manual pages.
depend:
make the dependencies for the source files, and store
them in the file .depend.
install:
install the program and its manual pages; if the Makefile
does not itself define the target install, the targets
beforeinstall and afterinstall may also be used to cause
actions immediately before and after the install target
is executed.
lint:
run lint on the source files
tags:
create a tags file for the source files.
1. Target: all, clean. depend and install are often used in our project.
2. Using “.include ” to include any files into your makefile, such as “.include <bsd.subdir.mk>”, “../Makefile.env” and so on.
3. <bsd.lib.mk> and <bsd.prog.mk> include the file named "../Makefile.inc " if it exists, as well as the include file <bsd.man.mk>.
4. It's fairly difficult to make the BSD .mk files work when you're building multiple programs in a single directory. It's a lot easier split up the programs than to deal with the problem. In this doc we introduce two way to build multiple programs in a single directory..
5. The variable DESTDIR works when you want to install. It's not set anywhere but will change the tree where the file gets installed. Like: pmake DESTDIR=/home/yourdir/install [-f Makefile] install
Make Command
Make command format:
all: one two # file one and two will be made first!
Gcc **** # multi shell commands can follow one target.
Make –f Makefile.a #The command will be execute in order.
Chmod 777 path
Other command…..
Note:
1. Any target can depend on some other files, such as *.c, *.cpp, *.o, lib and binary. These depended files will be made first before making the target.
2. One target can follow multi shell commands. These command swill be executed in order.
bsd.subdir.mk
Usage: Define which subdirs you want to make in variable SUBDIR.
For all of the directories listed in the variable SUBDIR, the specified directory will be visited and the target made. The default targets are Server Common Targets.
Example
===================================
MYDIR= toolbox app # internal variable
SUBDIR= TestLib TestLib/demo ${MYDOR}
.include <bsd.subdir.mk>
# DO NOT DELETE
====================================
bsd.lib.mk
<bsd.lib.mk> has support for building libraries, such as *.a, *.so, *.po. Note: profiled libraries(*.po) are built by default.
Common Variable
LIB à define the lib your want to build
SRCS à lib’s source files
CFLAGS à define the include dir, which are used to search include files
[ LDFLAGS à define the libs dir, which are used to search libs]
[ LDADD à define the libs you want to link/ Additional loader objects]
NOMAN à not to build manual page
INTERNALLIB à internal lib(??)
NO_PROFILE à not to build *.po lib
Example
====================================
LIB = test
SRCS = test.cc
NOMAN=
NO_PROFILE=
INTERNALLIB=
.include "../Makefile.env"
CFLAGS+= -I../myutil
.include <bsd.lib.mk>
# DO NOT DELETE
====================================
bsd.prog.mk
The include file <bsd.prog.mk> handles building programs from one or more source files, along with their manual pages.
Common Variable
PROG à name of the program to build; If not supplied, nothing is built.
PROG_CXX à using C++ lib; PROG_CXX overrides the value of PROG if PROG is also set.
SRCS à lib’s source files
PROGNAME à installation program name
CFLAGS à define the include dir, which are used to search include files
LDFLAGS à define the libs dir, which are used to search libs
LDADD à define the libs you want to link/ Additional loader objects
DPADD à define additional dependencies for the program. Note: can’t build lib automatically!
SUBDIR à A list of subdirectories that should be built as well. Like <bsd.subdir.mk>.
Example
Make one program:
====================================
PROG= unit-doe
SRCS= doeclient.cc TaskProtocol.pb.cc
NOMAN= # not need to make manual page.
NEED_GBUFFER= # include CFLAGS, LDFALGS and LDADD from “../Makfile.inc”
NEED_SACP=
CFLAGS= -Wall
.include <bsd.prog.mk>
====================================
Make multi programs way 1:
====================================
PROG= doeserver
SRCS= doeserver.cc ServerMixedApp.cc DoeTaskProcess.cc TasksOperation.cc TaskProtocol.pb.cc
BINDIR= /app/bin
BINDIRTOP= /bin
DOECLIENT=unit-doe
DOESERVER=doeserver
DOEPROXY=doeproxy
NOMAN= # not need to make manual page.
NEED_IPOPT= # include CFLAGS, LDFALGS and LDADD “../Makfile.inc”
NEED_LITHO=
NEED_RESIST=
NEED_DOE=
NEED_SERVER_FRAME=
all: updatelibs # make updatelis before make default “doeserver”, then exec follow command
($(MAKE) -f Makefile.client ${.TARGET})
($(MAKE) -f Makefile.proxy ${.TARGET})
updatelibs: # make depend libs
(cd http://www.cnblogs.com/util && $(MAKE) libutility.a)
(cd http://www.cnblogs.com/SACP && $(MAKE) libSACP.a)
(cd http://www.cnblogs.com/doe/helper && $(MAKE))
(cd ../lens && $(MAKE) liblens.a)
install: # installation
install -d -m 755 ${DESTDIR}$(BINDIR)
install -m555 ${DOECLIENT} $(DESTDIR)$(BINDIR)
install -m555 ${DOESERVER} $(DESTDIR)$(BINDIR)
install -d -m 755 ${DESTDIR}$(BINDIRTOP)
install -m555 ${DOEPROXY} $(DESTDIR)$(BINDIRTOP)
.include <bsd.prog.mk> # put before clean target, or the deoserver can’t be clean!
clean: cleanall
cleanall:
($(MAKE) -f Makefile.client clean)
($(MAKE) -f Makefile.proxy clean)
====================================
Make multi programs way 2:
====================================
PROG= DoeUnitTest
SRCS= DoeUnitTest.cc
NOMAN = # not need to make manual page.
NEED_BRIONTEST = # include CFLAGS, LDFALGS and LDADD “../Makfile.inc”
TGT_LIST = DoeUnitTest sample1_unittest sample2_unittest # DoeUnitTest will be made by default, even if it don’t list here.
all: updatelibs $(TGT_LIST) # define all target we want to make.
clean:
rm -f *.o $(TGT_LIST)
updatelibs: # make depend libs
(cd ../ && $(MAKE))
sample1_unittest : sample1.o sample1_unittest.o # *.o will be made by default.
${CXX} ${CFLAGS} $(LDFLAGS) -o ${.TARGET} sample1.o sample1_unittest.o ${LDADD}
sample2_unittest : sample2_unittest.o
${CXX} ${CFLAGS} $(LDFLAGS) -o ${.TARGET} sample2_unittest.o ${LDADD}
.include <http://www.cnblogs.com/Makefile.env>
.include <bsd.prog.mk>
====================================
Make lib and programs:
====================================
LIB= retrieval # default make target
SRCS= PupilRetrieval.cpp PupilRetrievalFrameStacks.cpp
NOMAN = # not need to make manual page.
INTERNALLIB =
NEED_RENDER= # include CFLAGS, LDFALGS and LDADD “../Makfile.inc”
NEED_UTIL=
NEED_RESIST=
TGT_LIST = asmlpupiltool # define targets will be made
all: libretrieval.a asmlpupiltool
clean:
rm -f *.o $(TGT_LIST) libretrieval.a
install:
@(install -m 555 asmlpupiltool ${DESTDIR}/app/bin/)
.include <bsd.lib.mk>
LDADD := -lfftw3f ${LDADD} -lodbc -lfetch -lgsl -llapack -lblas -lgslcblas -lexpat -lg2c -lstdc++ -lm
asmlpupiltool: asmlpupiltool.o
${CXX} ${LDFLAGS} -o ${.TARGET} asmlpupiltool.o ${LDADD}
====================================
Makefile Env File
In a large project, we have to deal with muitl-platform, all kinds of third party lib and internal libs. Thus we can define some common make env variables in a file, other makefile only need to include the env file to load all env variables.
Example
OS Env
====================================
OSTYPE!= uname –s # get OS, such as Linux, Sun, FreeBSD and so on.
.if ${OSTYPE} == "Linux" # condition compile
SUBDIR+= tacloader tacmanager tacshlib tacutil leafutilsampler tacutilsampler
SUBDIR+= vspgen smo flaremapgen sim doeserver
.endif
=======================================
Third Party Env
=======================================
.ifdef NEED_SERVER_FRAME # define compiler macro
NEED_SACP= # enable compiler macro control variable, the macro must be defined after
NEED_GBUFFER=
CFLAGS+= -I${APP}/comm. # add additional include path
LDFLAGS+= -L${APP}/comm
LDADD+= -lcomm
.endif
.ifdef NEED_SACP #these code must define before “LDADD+= -lutility…”. See Note 4).
CFLAGS+= -I${TOPDIR}/SACP
LDFLAGS+= -L${TOPDIR}/SACP
LDADD+= -lSACP
.endif
#============= NOTE: define NEED_XXXX above this line ============
# Because our lib will depend on some third party lib and utility lib!
CFLAGS+= -I${UTIL}
LDFLAGS+= -L${UTIL} -L${THIRD_PARTY}/opt
LDADD+= -lutility -Wl,-Bstatic -larpack -Wl,-Bdynamic -lcrypto -ltiff -ljpeg -lexpat -lpam -lopt
.ifdef NEED_GBUFFER # third party lib should be put after our libs.
CFLAGS+= -I${PROTOBUF_DIR}/include
LDFLAGS+= -L${PROTOBUF_DIR}/lib
LDADD+= -Wl,-Bstatic -lprotobuf -Wl,-Bdynamic
.endif
Note:
1) General speaking, the env file will be included by other makefile automatically or manually.
2) Make tool interpret all kinds of variables in order. It means that you should define variable before you use it. Thus, you should define macro control variable before the macro body.
3) CFLAGS, LDFLAGS and LDADD will be used in many places. Note: add first display first!
4) Gcc/g++ depend on the order of libs. Only the former libs can depend on latter libs. Thus, when you define the env file, you must pay attention on the order of libs.
5) If some libs are circular reference, they must be put between -Wl,--start-group and -Wl,--end-group.
6) –lutility will link libutility.a or libutility.so, *.so first. If you want to enforce to link lib statically, please use -Wl,-Bstatic to do that. Put these lib you want to link statically after -Wl,-Bstatic and don’t forget to put -Wl,-Bdynamic to recover to link dynamically.
本文转自 zhenjing 博客园博客,原文链接:http://www.cnblogs.com/zhenjing/archive/2011/04/20/2021779.html ,如需转载请自行联系原作者