Makefile部分学习理解

来源:互联网 发布:去衣软件下载 编辑:程序博客网 时间:2024/05/16 05:20

1.通配符等

变量定义中通配符 *.c类似只是表示字符串,在依赖规则以及shell命令的时候可以这样使用。需要变量定义使用wildcard函数。

2.wildcard patsubst

可以使用$(patsubst %.c,%.o,$(wildcard *.c),首先使用“wildcard”
函数获取工作目录下的.c 文件列表;之后将列表中所有文件名的后缀.c 替换为.o。这样
我们就可以得到在当前目录可生成的.o 文件列表。
PROGS := $(var1:%=$(var2)%) 这样写也是调用patsubst方法,%后面没有跟字符代表匹配所有,
所以这个相当于$(var2)$(var1)字符串拼接

3.VPATH

VPATH”变量所指定的是 Makefile 中所有文件的搜索路径,包括了规则的
依赖文件和目标文件。
例如:VPATH = src:../headers
这样我们就为所有规则的依赖指定了两个搜索目录,“src”和“../headers”

4.vpath

另一个设置文件搜索路径的方法是使用 make 的“vpath”关键字(全小写的)。它
不是一个变量,而是一个 make 的关键字,它所实现的功能和上一小节提到的“VPATH”
变量很类似,但是它更为灵活。它可以为不同类型的文件(由文件名区分)指定不同的目录。
vpath %.c foo : bar
vpath % blish
对于所有的.c 文件 make 将依次查找目录:“foo”、“bar”、“blish”

5.GPATH

如下代码:

LIBS = libtest.aVPATH = srclibtest.a : sum.o memcp.o$(AR) $(ARFLAGS) $@ $^

首先,如果在两个目录(“prom”和“src”)都不存在目标“libtest.a”,执行 make
时将会在当前目录下创建目标文件“libtest.a”。另外;如果“src”目录下已经存在
“libtest.a”,以下两种不同的执行结果:
1) 当它的两个依赖文件“sum.c”和“memcp.c”没有被更新的情况下我们执行
make,首先 make 程序会搜索到目录“src”下的已经存在的目标“libtest.a”。
由于目标“libtest.a”的依赖文件没有发生变化,所以不会重建目标。并且目标
所在的目录不会发生变化。
2) 当我们修改了文件“sum.c”或者“memcp.c”以后执行 make。“libtest.a”和
“sum.o”或者“memcp.o”文件将会被在当前目录下创建(目标完整路径名
被废弃),而不是在“src”目录下更新这些已经存在的文件。此时在两个目录下
(“prom”和“src”)同时存在文件“libtest.a”。但只有“prom/libtest.a”是最
新的库文件

看看怎么使用“GPATH”,改变后的 Makefile 内容如下:

LIBS = libtest.aGPATH = srcVPATH = srcLDFLAGS += -L ./. –ltest

同样;当两个目录都不存在目标文件“libtest.a”时,目标将会在当前目录(“prom”
目录)下创建。如果“src”目录下已经存在目标文件“libtest.a”。当其依赖文件任何
一个被改变以后执行 make,目标“libtest.a”将会被在“src”目录下被更新(目标完
整路径名不会被废弃)。

6.特殊符号隐含命令

$@目标文件,$^所有的依赖文件,$<第一个依赖文件。
$%当规则的目标文件是一个静态库文件时,代表静态库的一个成员名。
$?所有比目标文件更新的依赖文件列表,空格分割。
$+类似“$^”,但是它保留了依赖文件中重复出现的文件。
$*代表“茎”。例如:文件“dir/a.foo.b”,当目标的模式为“a.%.b”时,
“$*”的值为“dir/a.foo”。

部分隐含命令

变量名 含义 RM rm -f AR ar CC cc CXX g++

例如直接用$(AR)来使用

7.库文件的搜索

例如:

foo : foo.c -lcurses
cc $^ -o $@

则会去搜索
libcurses.so libcurses.a

搜索规则:
1. make 在执行规则时会在当前目录下搜索一个名字为“libNAME.so”的文件;
2. 如果当前工作目录下不存在这样一个文件,则make 会继续搜索使用“VPATH”或者“vpath”指定的搜索目录。
3. 还是不存在,make将搜索系统库文件存在的默认目录,顺序是:“/lib”、“/usr/lib”和“PREFIX/lib”(在Linux 系统中为“/usr/local/lib”,其他的系统可能不同)