分类: LINUX
2015-02-03 10:52:52
原文地址:Makefile基础知识 作者:SodaGreen_wyj
1.规则、目标、条件、命令之间的关系
目标:条件
命令
以上就构成了一条规则;
命令以tab键开头;
目标依赖于条件;
2.特殊变量
$@:规则中的目标;
$<:规则中的第一个条件(条件可以分为多条来写,但是命令只可以有一个);
$?:表示规则中所有比目标新的条件,组成一个列表,以空格分隔。
$^:表示规则中的所有条件,组成一个列表,以空格分隔。
3.变量的赋值
a、foo = ${bar} //不会立即展开$bar,好处在于可以将变量的值赋值推迟到后面
b、foo := ${bar} //立即展开$bar
一个变量的定义从=后面的第一个非空白字符开始(此例中即从${bar}的$开始),包括后面的所有字符,直到注释或换行之前结束碰到未赋值的变量,则为空;
例如:
foo := ${bar} hello
bar = hello
当makefile读到foo那行时,将foo展开为 hello(注意hello之前有个空格);
c、foo ?= ${bar}
?=作用在于如果foo之前没有定义过,那么此时即相当于=,且并不立即展开;若foo之前已经赋值过了,那么什么也不做;
d、+=:给变量追加赋值
objects = main.o
objetc += ${foo}
foo = a.o b.o
执行完后objects = main.o a.o b.o
+=保持=的特性
objects := main.o
objetc += ${foo}
foo = a.o b.o
执行完后objects = main.o #注意main.o后面是带有空格的
+=保持:=的特性
4.空格的定义
nullstring :=
space := ${nullstring} #这里加注释是为了突出显示${nullstring}后面的空格
5.自动生成目标文件和源文件的依赖关系
gcc中加入-M选项即可
例如:
gcc -M main.c
即可,但是-M会将系统头文件也输出,若不想输出系统头文件,则可使用-MM选项
6.常用的make命令选项
-n:只打印要执行的命令,而不会真的执行命令(--just-print也可以)
-c:可以切换到另一个目录执行那个目录下的Makefile
-s(--silent):全面禁止命令的显示
在make命令行也可以用=或:=定义变量,如果这次编译我想加调试选项-g,但我不想每次编译都加-g选项,可以在命令行定义CFLAGS变量,而不必修改Makefile编译完了再改回来:
$ make CFLAGS=-g
如果在Makefile中也定义了CFLAGS变量,则命令行的值覆盖Makefile中的值。
GCC中的“-M”选项可自动寻找源文件中的包含的头文件,并生成一个依赖关系;
"-MM"不会讲系统头文件列出,“-M”则会;
7.命令的执行
若要上条命令执行的结果应用于下条命令,则要用;来分隔这两条命令。
exec:
cd /home/;pwd
exec:
cd /home/
pwd
这两个执行的结果是不一样的。
第一个执行结果是:首先进入/home/目录,接着执行pwd命令,输出结果为/home/
第二个执行结果是:cd命令不起作用,pwd打印的是makefile所在的目录
8.使用shell命令
pwd = $(shell pwd)
9.变量的替换
a.变量值的替换
foo := a.o b.o c.o
bar := $(foo : .o=.c)
在此例中将foo中所有以.o结尾的字符串替换为以.c结尾的字符串
b.静态替换模式
foo := a.o b.o c.o
bar := $(foo : %.o=%.c)
这依赖于被替换字符中有相同的模式
c.将变量的值再当做变量
x = y
y = z
w = $($(x))
替换过程
首先:w = $(y)
最后:w = z
10.多行变量的定义
Makefile:
define print
@echo $(PWD)
@echo hello
endef
.PHONY: printhello
printhello:
${print}
执行此Makefile的结果是:
首先打印当前路径
然后打印字符串“hello”
11.目标变量
通常我们在Makefile中定义的变量,我们在整个文件中都是有效的;
然而我们可以为某个规则以及其连带规则定义一个局部变量,语法格式:
objects := main.o print.o
main : CFLAGS = -g
main : ${objects}
${CC} ${CFLAGS} -o main ${objects}
main.o : main.c
${CC} ${CFLAGS} -o main.o main.c
print.o : print.c
${CC} ${CFLAGS} -o print.o print.c
在此例中,CFLAGS = -g只在这三条规则中有效