代码改变世界

Usage of pmake

2011-04-20 09:31  zhenjing  阅读(970)  评论(0编辑  收藏  举报

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.