Make
make命令需要一个名为makefile的文件来告诉它如何构建一个应用程序,makefile文件由一组依赖关系和规则构成
make命令常用的三个参数:
-k: 让make命令在发生错误时仍然继续执行
-n: 让make命令输出要执行的操作步骤,而不真正的执行这些操作
-f: 指定哪个文件作为makefile文件
makefile依赖关系:定义了最终应用程序里的每个文件与源文件之间的关系
例如:
#myapp就是最终所要生成的目标
#利用all: myapp myapp.1 则可以指定两个最终目标
makefile规则:它定义了目标的创建方式,此外makefile中规则所在行要以TAB作为起始,空格开始或者结尾都会发生错误myapp: main.o 2.o 3.o
main.o: main.c a.h
2.o: 2.c a.h b.h
3.o: 3.c b.h c.h
makefile文件中的宏:定义宏 MACRONAME=value 引用宏 $(MACRONAME)或者${MACRONAME},若value为空则为空值
makefile多个目标:几个常用的内置特殊宏
$? 当前目标所依赖的文件列表中比当前目标文件还要新的文件
$@ 当前目标的名字
$< 当前依赖文件的名字
$* 不包括后缀名的当前依赖文件的名字
两个特殊字符
-: 告诉make命令忽略所有错误
@: 告诉make在执行某一条命令前不要将该命令显示在标准输出上
在makefile中若没有指定all参数,则默认第一个目标为最终的目标,根据这个最终目标推导依赖先后顺序,执行规则
若指定了all参数则,最终目标为all参数中的目标。在makefile中有一类目标是需要在执行make命令时,指定其执行的比如常用的clean目标,在makefile中可以使用shell脚本命令,但是在每一个规则行都会使用一个新的shell,用'\ '可以使命令处于同一个逻辑行上。
makefile内置规则:
make命令中内置了很多规则,通过make -p可以查看
内置规则通过匹配与其符合的目标文件和依赖文件的后缀,调用其相应的内置规则。可以通过修改宏的值,改变内置规则的默认行为,比如CC=g++可以修改默认的编译器。利用默认规则后,可以只写出依赖关系,而省略其规则。
后缀规则:例 由.cpp生成.o
.SUFFIXES: .cpp
.o.cpp:
$(CC) -xc++ $(CFLAGS) -I$(INCLUDE) -c $<
模式规则:例,实现与上相同的功能。%相当与shell中的*通配符
%.cpp: %o
$(CC) -xc++ $(CFLAGS) -I$(INCLUDE) -c $<
用make管理函数库:
在依赖关系中使用语法 lib(file.o) 来表示file.o在函数库lib中。make命令使用一个内置规则来管理函数库
.c.a:
$(CC) -c $(CFLAGS) $<
$(AR) $(ARFLAGS) $@ $*.o
添加函数库
$(MYLIB): $(MYLIB)(2.o) $(MYLIB)(3.o)
makefile文件和子目录
如果一个项目有子目录,有两种方法可以使用make
1.在子目录中编写一个makefile,它的作用是编译该子目录下的源文件并将其保存到一个函数库中。然后将其复制到主目录,在主目录中包含一条用于制作函数库的规则
mylib.a:
(cd mylibdirectory;$(MAKE))
2.在原先的makefile文件中添加一些宏,字母D表示目录,F表示文件
然后用代替内置规则.c.o
.c.c:
$(CC) $(CFLAGS) -c $(@D)/$(<F) -o $(@D)/$(@F)
再编写如下依赖和规则
mylib.a: mydir/2.o mydir/3.o
ar -rv mylib.a $?
GNU make 和 gcc两个选项
make -jN 例如 make -j3 同时条用3条规则,加快编译
gcc -MM 1.c 2.c 3.c 4.c会输出几个文件之间的依赖关系,与makefile中的格式相同
$(LIB_DEPS):%.d:%.c//将LIB_DEPS中.d替换为.c