- 先标注一个很好的makefile教程
- 这里归纳了如下符号的含义,请对号入座如下 $@, $^, $<, $?和=, +=, :=, ?=和;\ 和 $, $$和%
- section1:(自动化变量,更多自动化变量可参照)
- $@ 表示目标文件(标的)
$^ 表示所有的依赖文件(标的)
$< 表示第一个依赖文件(标的)
$? 表示比目标还要新的依赖文件列表 - 例子分析:(如有hello.c hi.c main.c 源文件,按照 Makefile 规则写)
那么用上面符号进行书写则为:main: main.o hello.o hi.o gcc -o main main.o hello.o hi.o main.o: main.c cc -c main.c hello.o: hello.c cc -c hello.c hi.o: hi.c cc -c hi.c clean: rm *.o rm main
main: main.o hello.o hi.o gcc -o $@ $^ main.o: main.c cc -c $< hello.o: hello.c cc -c $< hi.o: hi.c cc -c $< clean: rm *.o rm main
- $@ 表示目标文件(标的)
- section2:
- = 直接对变量赋值
- += 追加赋值
- := 该符号右侧是否有变量,如有变量且变量的定义在后边,则忽略该右侧变量,其他情况同=号
- ?= 如果符号左侧的变量已经定义过则跳过该句。
- section2的具体例子可参照
- section3:(分号和反斜线)
- 分号是分隔符,反斜线是换行符。像if语句块或for语句要写在一行时,必须使用分号进行分隔,在此期间如需进行换行则使用反斜线\进行换行即可。此外,注意if语句后的左中括号[前后都有有空格,双等号“==”表示相等符号,单等号“=”既可以表示相等也可表示赋值,其区别为:当比较时,比较符号左右都有空格;赋值时,等号左右没空格。
- section4:( $和$$)
- 单美元符号$表示引用makefile定义变量的值,双美元符号$$表示引用shell命令中定义的变量的值。一些使用事项可参照
- section5:%(makefile中通配符,附与系统通配符的区别)
- 区别1:Makefile中的%标记和系统通配符*的区别在于,*是应用在系统中的,%是应用在这个Makefile文件中的。
- 区别2:Makefile的通配符%是在**带着目的(如“寻找test1.o”)**的时候才会把他要寻找的目标套用通配符%中。而系统通配符*是我不知道目标的名字,系统该目录下中所有后缀为.c的文件都是我要找的。
- 重要例子:
如果你想编译一个文件夹下的所有.c文件,你可能会这样写:
但是如果整个文件只有这两行的话,就会出现这样的错误:%.o:%.c gcc -o $@ $<
Make: *** target not found. stop.
要知道原因,我们先来看看另一个makefile的运行过程,例如有Makefile如下:
如果没有指定输出项目的时候Make会自动找到makefile中第一个目标中没有通配符的目标进行构造,所以步骤是:test1.o:test1.c gcc -o test1.o test1.c test2.o:test2.c gcc -o test2.o test2.c all:test1.o test2.o
1、构造all,发现需要test1.o和test2.o
2、这个时候他就会在Makefile文件中找到目标能匹配test1.o和test2.o的规则。
3、找到test1.o的规则并且知道test1.c存在,运行下面的命令。
4、同步骤三构造出test2.o
5、现在构造all的源文件已经齐全,构建all
其中最重要的是第2步。
Makefile的通配符是在带着目的(如“寻找test1.o”)的时候才会把他要寻找的目标套用通配符%中。
而系统通配符*的意思是:
1、我不知道目标的名字,系统该目录下中所有后缀为.c的文件都是我要找的。
2、然后遍历目录的文件,看是否匹配。找出所有匹配的项目。
makefile中一些符号的含义
最新推荐文章于 2025-03-05 20:41:07 发布