导读:

3.1.Makefile的编写

       Linux下一般都是使用make工具来管理和编译一个大的开发工程的所有源文件,make命令执行时,需要一个 Makefile 文件,以告诉make命令需要怎么样的去编译和链接程序,makefile关系到了整个工程的编译规则。一个工程中的源文件不计其数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作,因为makefile就像一个Shell脚本一样,其中也可以执行操作系统的命令。在Windows的一些IDE如VC中将自动帮你生成相应的makefile,所有这些都是透明的,但在Linux下你就不能不自己写makefile了,会不会写makefile,从一个侧面说明了一个人是否具备完成大型工程的能力。

     make工具采用增量编译的方式,每次只编译被改动过确实需要编译的源文件,每次编译时make工具将自动判断那些源文件需要重新编译,当一个工程很大而又只改动了很少的几个源文件,这将节省很多时间。

具体makefile文件的编写规则可以查看make的man 和info文档(在Linux命令行方式下输入:man make 或info make)。makefile文件的编写规则很多,重要的是怎样使用最简单的方式写出我们自己需要的makefile文件。

    网上也有很多介绍资料,网上有一篇很好的介绍makefile文件编写的文章:

下文将着重介绍使用pwlib开发库的工程的makefile的编写,但对于其它工程只需将common.mak文件中对pwlib库进行编译的脚本去掉也可适用。

3.1.1使用pwlib开发库的工程的makefile的编写

PWLib是Portable Windows Library的缩写,翻译为轻便的Windows类库.PWLib采用C++编写,设计初衷是为了能让Openh323在Windows和Unix的X-Windows下运行, 不过随着一步步的完善PWLib已经被跨平台的程序所广泛采用。

查看Pwlib的主目录下/samples/hello_world/目录下例子程序的makefile文件可以发现该Makefile文件内容如下:

# Simple makefile for the hello world program
PROG    = hello
SOURCES = hello.cxx
ifndef PWLIBDIR
PWLIBDIR=$(HOME)/pwlib
endif
include $(PWLIBDIR)/make/ptlib.mak
# End of Makefile

实际上就是使用了Pwlib库的ptlib.mak文件,编译时需要的头文件,相应的编译选项都在ptlib.mak文件中设置好了。

我们只需在该makefile文件所在目录下,命令行输入make all命令即可编译出程序的Release版本和Debug版本,它们分别放在当前目录的obj_linux_x86_r和obj_linux_x86_d子目录下。

下面对该makefile中的内容进行解释:

lPROG变量为编译出来的程序名称。

lSOURCES变量存储的为本工程要进行编译和链接的源文件,当有多个源文件时可以用空格隔开,虽然文件名可以带上路径,但路径在SOURCES变量中不起作用,实际编译时对于每个文件它将截掉最后一个”/”字符前面的所有内容只保留文件名。

lPWLIBDIR为pwlib的安装目录,需要设置该环境变量(若要系统每次重启都自动设置好该环境变量则将该环境变量的设置放入/etc/profile文件中),若没设置好则自动以”用户主目录/pwlib”作为pwlib的安装目录。

3.1.2深入分析ptlib.mak文件
分析ptlib.mak文件,它的内容如下;
ifndef PWLIBDIR
PWLIBDIR=$(HOME)/pwlib
endif

include $(PWLIBDIR)/make/unix.mak
include $(PWLIBDIR)/make/common.mak

也就是ptlib.mak包含了另两个文件unix.mak和common.mak文件,其中unix.mak为定义编译选项变量的文件,编译规则放在common.mak文件中。

通过对这两个文件的分析,归纳出一些我们写makefile文件要用到的一些变量,列出如下:

lSTDCCFLAGS:所有头文件的include目录编译选项、预编译宏定义选项、警告选项、优化选项都放在该变量中,各编译选项之间用空格分开。

lLDFLAGS:共享库、静态库搜索目录设置放入该变量中。

lLDLIBS:链接时要用的库的设置放入该变量中。

lVPATH_CXX:*.cxx源文件的搜索路径放入该变量中,多个目录以空格分开,编译时将首先在makefile所在目录查找相应源文件,没找到则按照VPATH_CXX中的路径设置进行查找。

lVPATH_C:*.c源文件的搜索路径放入该变量中,多个目录以空格分开,文件查找顺序和VPATH_CXX变量的类似。

3.1.3加入新的编译规则

common.mak文件中只对*.c和*.cxx的源文件定义了编译规则,而一般windows下程序大多都使用了.cpp来作为C++源文件的后缀。

怎样加入对于.cpp后缀的源文件的编译规则呢,这需要修改pwlib的common.mak文件,具体步骤如下:

       1.加入对于.cpp文件的搜索目录设置

在vpath %.cxx $(VPATH_CXX)语句后面加入如下语句:

              vpath %.cpp $(VPATH_CXX)

       2.加入对于.cpp文件的编译规则

 

在$(OBJDIR)/%.o : %.cxx语句的前面加入如下语句:
$(OBJDIR)/%.o : %.cpp 
       @if [ ! -d $(OBJDIR) ] ; then mkdir -p $(OBJDIR) ; fi
       $(CPLUS) $(STDCCFLAGS) $(OPTCCFLAGS) $(CFLAGS) $(STDCXXFLAGS) -x c++ -c $< -o $@
       3.加入对于.cpp文件的.o文件(目标代码文件)的命名规则
       在SRC_OBJS := $(SRC_OBJS:.cxx=.o)语句后面加入如下语句
SRC_OBJS := $(SRC_OBJS:.cpp=.o)
       4.加入对于.cpp文件的.dep文件(依赖文件)的命名规则
       在SRC_DEPS := $(SRC_DEPS:.cxx=.dep)语句后面加入如下语句
SRC_DEPS := $(SRC_DEPS:.cpp=.dep)
       5.加入对于.cpp文件生成.dep文件的生成规则,加入如下语句:
       在$(DEPDIR)/%.dep : %.cxx语句前面加入如下语句
$(DEPDIR)/%.dep : %.cpp 
       @if [ ! -d $(DEPDIR) ] ; then mkdir -p $(DEPDIR) ; fi
       @printf %s $(OBJDIR) > $@
       $(CPLUS) $(STDCCFLAGS:-g=) -M $< >> $@