gcc -o test.o test.c 直接生成可执行文件, -o选项 进行连接指定生成可执行文件
gcc -c test.c 或
gcc -c test.c -o test.o 生成.o 为目标文件
第一层
递归
伪目标 .PHONY
第二层
=(替换) 在右值在遍历整个Makefile,完全展开后再赋值给左边的变量,可以先使用,后定义
foo=$(bar)
bar=$(ugh)
ugh=Hug?
all:
echo $(foo) Hug?
+=(追加)
:=(常量) 将右值当前的值赋值给左值,不会遍历Makefile获取右值的最终值,先定义再使用
x:=foo
y:=$(x)bar
x:=later
all:
echo $(y) foobar
y:=$(x)bar
x:=foo
all:
echo $(y) bar x为空
?=如果没定义过,则赋值
objects += another.o 等价于 objects := $(objects) another.o
第三层
隐含规则 %.c 任意.c *.c 所有的.c
第四层
通配符 $^ 所有的依赖文件 $@所有的目标文件(当前target下) $<所有依赖文件的第一个
$(TAR):$(OBJ)
gcc $^ -o $@
*.o:*.c
gcc -c $^ -o $@
第五层
-include filename
如果有文件没有找到的话,make会生成一条警告信息,但不会马上出现致命错误。它会继续载入其它的文件,一旦完成makefile的读取,make会再重试这些没有找到,或是不能读取的文件,如果还是不行,make才会出现一条致命信息。如果你想让make不理那些无法读取的文件,而继续执行,你可以在include前加一个减号“-”。和其它版本make兼容的相关命令是sinclude,其作用和这一个是一样的
A = -D EXT_MODE 相当于 在头文件中增加宏定义 #define EXT_MODE
$(info VAR=$(VAR)) 打印调试信息
DIR:=$(shell echo ~/GT565) 利用shell命令echo输出路径,赋给DIR
define ...... endef定义命令包
arm-oe-linux-gnueabi-gcc (交叉编译器) 需对此编译器配环境变量PATH
--sysroot=dir 编译器会去此目录的dir/usr/include 和 dir/usr/lib下寻找头文件与库
-g 将源码与编译的程序连接,便于调试
gcc -I(大写i) 首先在目录下寻址头文件
gcc -L 首先在目录下寻址库文件
-Wall,会显示警告
-rdynamic 却是一个 连接选项 ,它将指示连接器把所有符号(而不仅仅只是程序已使用到的外部符号)都添加到动态符号表(即.dynsym表)里,以便那些通过 dlopen() 或 backtrace() (这一系列函数使用.dynsym表内符号)这样的函数使用。
$(foreach <var>,<list>,<text> )
这个函数的意思是,把参数<list>中的单词逐一取出放到参数<var>所指定的变量中,然后再执行<text>所包含的表达式。每一次<text>会返回一个字符串,循环过程中,<text>的所返回的每个字符串会以空格分隔,最后当整个循环结束时,<text>所返回的每个字符串所组成的整个字符串(以空格分隔)将会是foreach函数的返回值。
所以,<var>最好是一个变量名,<list>可以是一个表达式,而<text>中一般会使用<var>
这个参数来依次枚举<list>中的单词。举个例子:
names := a b c d
files := $(foreach n,$(names),$(n).o)
上面的例子中,$(name)中的单词会被挨个取出,并存到变量“n”中,“$(n).o”每次根据“$(n)”计算出一个值,这些值以空格分隔,最后作为foreach函数的返回,所以,$(f
iles)的值是“a.o b.o c.o d.o”。
函数原型 $(eval text)
它的意思是 text 的内容将作为makefile的一部分而被make解析和执行。
替换
foo := a.o b.o c.o
bar := $(foo:%.o=%.c)
bar := $(foo:.o=.c)
call函数其实只是宏替换,并未执行因此需要加上eval才会对展开进行执行
$(addsuffix SUFFIX,NAMES…) addprefix前缀
函数名称:加后缀函数—addsuffix。
函数功能:为“NAMES…”中的每一个文件名添加后缀“SUFFIX”。参数“NAMES…”
在$(patsubst %.c,%.o,$(dir) )中,patsubst把$(dir)中的变量符合后缀是.c的全部替换成.o
%.c不可换为*.c
subst:一个字符串中替换
patsubst:以空格,tab,回车为单位分割成单词替换
$(patsubst %.c, %.o, "aaa.c bbb.c ddd.c.c.c eee.co")
out: aaa.o bbb.o ddd.c.c.o eee.co
$(subst %.c, %.o, "aaa.c bbb.c ddd.c.c.c eee.co")
out: aaa.o bbb.o ddd.o.o.o eee.oo
$(dir src/foo.c hacks)返回值是“src/, ./”
想要编译生成多个可执行文件,使用all,如果想删除过程文件,clean,但clean却不会执行,因为clean没有任何依赖,多以make 会忽略它,使用.PHONY申明clean即可,告诉make该目标是假的,磁盘上没有clean,从而make会为了生成这个目标而执行其规则
all:main1 main2 clean:
main1: main1.c
@gcc main1.c -o main1
main2: main2.c
@gcc main2.c -o main2
.PHONY:clean
clean:
@rm -f main2.o
$(filter PATTERN…,TEXT)
函数名称:过滤函数—filter。
函数功能:过滤掉字串“TEXT”中所有不符合模式“PATTERN”的单词,将不是.c .s 的内容过滤掉
sources := foo.c bar.c baz.s ugh.h
foo: $(sources)
cc $(filter %.c %.s,$(sources)) -o foo
objects = foo.o bar.o 静态模式 all: $(objects) $(objects): %.o: %.c $(CC) -c $(CFLAGS) $< -o $@