author:李超
date:2012/05/06
纵然makefile的规则还是相当多的,编写一个大规模的软件,良好的makefile架构是方便维护程序编译的关键。学习makefile的时间周期还是比较长的,为了写出规范的代码,需要在很短的时间内编写一个makefile,这里给给出一个makefile示例。在组织程序的时候可以按照这个示例给出的结构进行,同时还能提高程序的可读性和合理的目录结构。
先贴出makefile的代码:
- CC = gcc
- CXX = g++
- CLINKER = gcc
- CXXLINKER = g++
- DEFINES +=
- CFLAGS +=
- CXXFLAGS +=
- LINKFLAGS +=
- LINK = $(CXXLINKER)
- INCPATH +=
- LIBS +=
- OBJECTS = main.o
- TARGETS = producer_consumer
- DEL = rm -rf
- first:all
- .SUFFIXES: .o .c .cpp .cxx .cc .C
- .c.o:
- $(CC) -c $(INCPATH) $(CXXFLAGS) -o "$@" "$<"
- .cpp.o:
- $(CXX) -c $(INCPATH) $(CXXFLAGS) -o "$@" "$<"
- .cxx.o:
- $(CXX) -c $(INCPATH) $(CXXFLAGS) -o "$@" "$<"
- .cc.o:
- $(CXX) -c $(INCPATH) $(CXXFLAGS) -o "$@" "$<"
- .C.o:
- $(CXX) -c $(INCPATH) $(CXXFLAGS) -o "$@" "$<"
- all:$(TARGETS)
- $(TARGETS):$(OBJECTS)
- $(LINK) $(LINKFLAGS) -o $(TARGETS) $(OBJECTS) $(LIBS)
- clean:
- $(DEL) $(OBJECTS)
首先,要说明的是这个makefile对应的是C和C++的源程序。对于一个makefile,我们需要定义的关键信息有:
l C编译器
l C++编译器
l C链接器
l C++链接器
l C编译标志
l C++编译标志
l C链接器的标志
l C++链接器的标志
l 编译时指定的宏
l 程序中用到的头文件所在的目录
l 程序中引用的库函数所在的目录,以及所用到的库
l 生成的可执行文件的名称
l 生成的可执行文件所需要的目标文件
OK,大致就是这些内容。有了这些信息之后,我们就利用隐形规则编写生成目标文件的命令了。在上面的makefile文件中:
u 变量CC表示C编译器
u 变量CXX表示表示C++编译器
u 变量CLINKER表示C链接器
u 变量CXXLINKER表示C++链接器
u 变量DEFINES表示定义的宏
u 变量CFLAGS表示编译C程序时需要的标志
u 变量CXXFLAGS表示编译C++程序时需要的标志
u 变量LINKFLAGS表示链接时用到的标志
u 变量LINK用来指定最终链接时用到的编译器
u 变量INCPATH用来指定头文件所在的路径(-I)
u 变量LIBS用来指定用到的库文件所在的目录以及要链接的库(-L -l)
u 变量OBJECTS用来指定生成可执行文件所需要的目标文件
u 变量TARGET用来指定可执行文件的最终名称
接下来就要编写makefile的第一个规则---入口规则,在makefile中使用 first:all,就是告诉make首先去all这个label处执行命令。
然后再看all这个label,all依赖于$(TARGET),所以make程序回去生成 $(TARGET),所以就顺理成章的执行了all下面这条命令:
$(LINK) $(LINKFLAGS) -o $(TARGET) $(OBJECTS) $(LIBS)
由于开始的时候,还没有生成所需要的目标文件(OBJECTS指定的),所以回去执行那些隐式规则以生成目标文件。这些隐式规则是由 .SUFFIX这行以及后续的几行指定的。
.SUFFIX说明了项目中用到的文件的后缀。然后再接下来几行中,对每个源文件的后缀和目标文件后缀的映射关系安排相应的命令,使之能够生成相应的目标文件,最终生成可执行文件。
至于clean就不多说了。
本文出自 “相信并热爱着” 博客,请务必保留此出处http://hipercomer.blog.51cto.com/4415661/854816