内容发布更新时间 : 2024/11/19 7:26:26星期一 下面是文章的全部内容请认真阅读。
Makefile基础实例讲解
一、makefile简介
定义:makefile定义了软件开发过程中,项目工程编译链、接接的方法和规则。 产生:由IDE自动生成或者开发者手动书写。
作用:Unix(MAC OS、Solars)和Linux(Red Hat、Ubuntu)系统下由make命令调用当前目录下的makefile文件执行,可实现项目工程的自动化编译。
二、语法规则
target:prerequisites
command
其中,target为需要生成的目标,prerequisites为依赖项,command为make需要执行的命令(任意的Shell命令)。
注意:其中command前必须以tab键开始。 三、makefile内容
Makefile里主要包含了五个东西:显式规则、隐晦规则、变量定义、文件指示和注释。
1.显式规则。显式规则说明了,如何生成一个或多的的目标文件。这是由Makefile的书写者明显指出,要生成的文件,文件的依赖文件,生成的命令。
2.隐晦规则。由于我们的make有自动推导的功能,所以隐晦的规则可以让我们比较粗糙地简略地书写Makefile,这是由make所支持的。
3.变量的定义。在Makefile中我们要定义一系列的变量,变量一般都是字符串,这个有点你C语言中的宏,当Makefile被执行时,其中的变量都会被扩展到相应的引用位置上。
4.文件指示。其包括了三个部分,一个是在一个Makefile中引用另一个Makefile,就像C语言中的include一样;另一个是指根据某些情况指定Makefile中的有效部分,就像C语言中的预编译#if一样;还有就是定义一个多行的命令。有关这一部分的内容,请参考文末的参考资料。
5.注释。Makefile中只有行注释,和UNIX的Shell脚本一样,其注释是用“#”字符,这个就像C/C++中的“//”一样。如果你要在你的Makefile中使用“#”字符,可以用反斜框进行转义,如:“\\#”。
四、make的工作流程
在默认的方式下,也就是我们只输入make命令,则相当于make first_objname_in_makefile。意思是生成出现在makefile中第一个目标文件。或者指明生成的目标名称,如make [objname]。
按默认方式,输入make命令,其工作方式是:
1. make会在当前目录下找名字叫“Makefile”或“makefile”的文件。 2.如果找到,它会找文件中的第一个目标文件(target),在上面的例子中,并把这个文件作为最终的目标文件。
3.如果target不存在,则根据target后的依赖项和command生成target。如果target已存在,则make检测target依赖项是否有修改,若修改,则跟新target。
四、实例讲解
鄙人将以实际工作项目的makefile为例为大家讲解makefile的创建过程。Makefile内容如下:
1
CCFILES += $(wildcard src/*.cpp)
SRCDIR := ./src/
VPATH = src:./include:./src/xmlparser:./lib
# Compilers
#CC := /opt/intel/composer_xe_2013.0.079/bin/intel64/icpc CC := icpc
# Compilers para
FLAGS := -openmp -openmp-report -vec-report -O2
OBJECT :=file_interface.o tinyxml2.o mic_decomposer.o Charset.o network.o buffer.o \\ task_queue.o common.o main.o mic_function.o hashtree.o nodeconfig.o md5_mic.o ntlm_mic.o
ALG.out : $(OBJECT) $(CC) $(FLAGS) -o ALG.out $(OBJECT) ./lib/libxmlextern.a
file_interface.o :global.h tinyxml2.h file_interface.h $(SRCDIR)file_interface.cpp $(CC) $(FLAGS) -c $(SRCDIR)file_interface.cpp tinyxml2.o :tinyxml2.h $(SRCDIR)tinyxml2.cpp $(CC) $(FLAGS) -c $(SRCDIR)tinyxml2.cpp
mic_decomposer.o :$(SRCDIR)mic_decomposer.cpp mic_decomposer.h mic_define.h cnre.h \\ common.h hashtree.h $(CC) $(FLAGS) -c $(SRCDIR)mic_decomposer.cpp Charset.o :Charset.h cnre.h $(SRCDIR)Charset.cpp $(CC) $(FLAGS) -c $(SRCDIR)Charset.cpp
network.o :network.h task_queue.h network_packet.h nodeconfig.h $(SRCDIR)network.cpp $(CC) $(FLAGS) -c $(SRCDIR)network.cpp
buffer.o :network.h task_queue.h network_packet.h nodeconfig.h buffer.h $(SRCDIR)buffer.cpp $(CC) $(FLAGS) -c $(SRCDIR)buffer.cpp
task_queue.o :task_queue.h $(SRCDIR)task_queue.cpp $(CC) $(FLAGS) -c $(SRCDIR)task_queue.cpp
common.o :common.h mic_define.h mic_function.h $(SRCDIR)common.cpp $(CC) $(FLAGS) -c $(SRCDIR)common.cpp
main.o :task_queue.h global.h network.h network_packet.h common.h nodeconfig.h \\ mic_define.h mic_function.h file_interface.h $(SRCDIR)main.cpp $(CC) $(FLAGS) -c $(SRCDIR)main.cpp
mic_function.o :mic_function.h $(SRCDIR)mic_function.cpp $(CC) $(FLAGS) -c $(SRCDIR)mic_function.cpp hashtree.o :hashtree.h $(SRCDIR)hashtree.cpp $(CC) $(FLAGS) -c $(SRCDIR)hashtree.cpp
2
nodeconfig.o :nodeconfig.h ./src/xmlparser/tinyxml.h $(SRCDIR)nodeconfig.cpp $(CC) $(FLAGS) -c $(SRCDIR)nodeconfig.cpp
md5_mic.o :simd.h mic_define.h common.h share_macro.h md5_macro.h md5_mic.h \\ file_interface.h $(SRCDIR)md5_mic.cpp $(CC) $(FLAGS) -c $(SRCDIR)md5_mic.cpp
ntlm_mic.o :simd.h mic_define.h common.h share_macro.h ntlm_macro.h ntlm_mic.h $(CC) $(FLAGS) -c $(SRCDIR)sha256_mic.cpp
.PHONY clean: rm -f *.o *.out
具体讲解:
1. CCFILES += $(wildcard src/*.cpp)
利用wildcard函数获取src目录下所有.cpp文件,并赋值给自定义变量CCFILES。
2. SRCDIR:= ./src/
用于指明.cpp源文件所在目录。SRCDIR变量在command中出现时,以类似于宏替换的方式将其载入command中。
3. VPATH= src:./include:./src/xmlparser:./lib
指明makefile寻找依赖项时,若当前目录不存在,则去VPATH指明的目录去寻找。各目录以“:”号隔开。
4. CC := icpc,自定义变量CC指明为icpc,表示使用Intel c++ Compiler编译项目。
5. FLAGS := -openmp -openmp-report -vec-report -O2,指明编译选项。
6. OBJECT :=file_interface.o tinyxml2.o mic_decomposer.o Charset.o network.o buffer.o \\
task_queue.o common.o main.o mic_function.o hashtree.o nodeconfig.o md5_mic.o ntlm_mic.o
指明目标文件;其中反斜杠\\表示一行还未结束。
7. ALG.out : $(OBJECT)
$(CC) $(FLAGS) -o ALG.out $(OBJECT) ./lib/libxmlextern.a
此处表示makefile需要生成的第一个目标文件,也是不指明目标文件的make命令默认生成的目标文件。加入icpc的编译选项,并指明目标ALG.out依赖的目标文件和静态链接库项./lib/libxmlextern.a后,进行链接生成可执行文件ALG.out。
8. file_interface.o :global.h tinyxml2.h file_interface.h $(SRCDIR)file_interface.cpp
$(CC) $(FLAGS) -c $(SRCDIR)file_interface.cpp
指明file_interface.o的依赖项并编译成二进制文件file_interface.o。后面的每个目标文件皆是如此做法。
9. .PHONY clean:
rm -f *.o *.out
3