您的位置:首页 > 其它

Makefile笔记整理

2016-01-04 19:08 232 查看

GCC常用选项

-DMACRO选项

-DOS_LINUX将宏定义OS_LINUX

-Idir

添加头文件搜索目录dir

-Ldir

添加链接库搜索目录dir。gcc优先使用共享程序库

-static

仅选用静态程序库进行链接,如果一个目录中静态库和动态库都存在,则仅选用静态库

-g

包括调试信息

-On

优化程序,n代表优化级别,n常为2

-Wall

打开警告信息

Makefile规则基本格式

[code]TARGET...: DEPENDEDS...
    COMMAND
    ...
    ...


TARGET:规则定义的目标

DEPENDEDS:执行规则锁必须依赖的条件(DEPENDEDS也可以是某个TARGET,形成嵌套)

COMMAND:规则所执行的命令

Makefile中常用变量及含义

变量名含义默认值
AR生成静态库文件的程序名称ar
AS汇编编译器的名称as
CCC语言编译器的名称cc
CPPC语言预编译器的名称$(CC) -E
CXXC++语言编译器的名称g++
FCFORTRAN语言编译器的名称f77
RM删除文件程序的名称rm -f
ARFLAGS生成静态库库文件程序的选项\
ASFLAGS汇编语言编译器的编译选项\
CFLAGSC语言编译器的编译选项\
CPPFLAGSC语言预编译的编译选项\
CXXFLAGSC++语言编译器的编译选项\
FFLAGSFORTRAN语言编译器的编译选项\

Makefile中的自动变量

变量含义
$*表示目标文件的名称,不包含目标文件的扩展名(GUN make特有,其他make不一定支持)
$+所有依赖项的集合,不会去除重复的依赖项
$<表示依赖项中第一个依赖文件的名称
$?依赖项中,所有目标文件时间戳晚的依赖文件,以来稳健之间以空格分开
$@目标项中目标文件的名称
$<依赖项中,所有不重复的依赖文件,这些文件之间以空格分开

Makefile中的VPATH变量

使用方法:

[code]VPATH=add:sub(加入add和sub搜索路径)


VPATH 只控制.c/.cpp的查找路径(将.c/.cpp文件所在文件夹添加到VPATH后只用写文件名gcc即可查找到文件),对于.h文件,需要使用-I./header。

Makefile中的= := ?= +=赋值运算符

= 是最基本的赋值

:= 是覆盖之前的值

?= 是如果没有被赋值过就赋予等号后面的值

+= 是添加等号后面的值

1“=”

make会将整个makefile展开后,再决定变量的值。也就是说,变量的值将会是整个makefile中最后被指定的值。看例子:

x = foo

y = $(x) bar

x = xyz

在上例中,y的值将会是 xyz bar ,而不是 foo bar 。

2“:=”

“:=”表示变量的值决定于它在makefile中的位置,而不是整个makefile展开后的最终值。

x := foo

y := $(x) bar

x := xyz

在上例中,y的值将会是 foo bar ,而不是 xyz bar 了。

Makefile中的.PHONY

[code].PHONY:romfs   # .PHONY修饰romfs只有规则,没有依赖
romfs


[code]all:main1 main2 clean
main1: main1.c
    @gcc main1.c -o main1
main2: main2.o
    @gcc main2.o -o main2
main2.o: main2.c
    @gcc -c main2.c 
clean:
    @rm -f main2.o


但是当我们make之后main2.o仍然存在,怎么回事呢makefile中的all和.PHONY的作用

原来这里的目标clean没有任何依赖,make执行时认为这已经到“根上”了(就是认为磁盘上有clean,就像main2.c),将其忽略(尽管它有规则)。

关键字.PHONY可以解决这问题,告诉make该目标是“假的”(磁盘上其实没有clean),这时make为生成这个目标就会将其规则执行一次。.PHONY修饰的目标就是只有规则没有依赖。

加上一句.PHONY:clean即可:

[code]all:main1 main2 clean
main1: main1.c
    @gcc main1.c -o main1
main2: main2.o
    @gcc main2.o -o main2
main2.o: main2.c
    @gcc -c main2.c 
.PHONY:clean
clean:
    @rm -f main2.o


Makefile中的@

makefile中@是不打印命令本身的意思 ,以下Makefile执行make clean时终端不会打印rm -f main2.o的信息。

[code]clean:
    @rm -f main2.o


递归make

递归调用的方式

make可以递归调用每个子目录中的Makefile。我们可以用如下方式编译add中的文件:

[code]add:
    cd add && $(MAKE)


等价于:

[code]add:
    $(MAKE) -C add


上面两个例子都是先进入子目录下add中,然后执行make命令。

总控Makefile

调用“$(MAKE) -C”的Makefile叫做总控Makefile。如果总控Makefile中的一些变量需要传递给下层的Makefile,可以使用export命令,如:

[code]export OBJSDIR=./objs


Makefile中的函数

获取匹配模式的文件名wildcard

这个函数功能是查找当前目录下所有符合迷失PATTERN的文件名,其返回值是以空格分割的、当前目录下的所有符合模式PATTERN的文件名列表。原型如下:

[code]$(wildcard PATTERN)


例如,如下模式返回当前目录下所有扩展名为.c的文件列表

[code]$(wildcard *.c)


模式替换函数patsubst

这个函数的功能是查找字符串text中按照空格分开的单词,将符合模式pattern的字符串替换成replacement。pattern中的模式可以使用通配符,%代表0到n个字符,当pattern和replacement中都有%时,符合条件的字符将被replacement中的替换。函数的返回值是替换后的新字符串。原型如下:

[code]$(patsubst pattern,replacement,text)


返回值:例如需要将.c文件替换成.o文件可以使用如下模式

[code]$(patsubst %.c,%.o,$(wildcard *.c))


输出的字符串将当前扩展名为.c的文件替换成扩展名为.o的文件列表

循环函数foreach

函数原型:

[code]$(foreach VAR,LIST,TEXT)


foreach将LIST字符串中的一个人空格分隔符的单词,先传给临时变量VAR,然后执行TEXT表达式,TEXT表达式处理结束后输出。其返回值是空格分割表达式TEXT的计算结果。

例如,对于存在add和sub的两个目录,设置DIRS为“add sub ./”包含目录add、sub和当前目录。表达式
$(wildcard$(dir)/*.c)
,可以去除目录add和sub及当前目录中的所有扩展名为.c的文件。

[code]DIRS = sub add ./

#查找所有目录下的扩展名为.c的文件,复制给变量FILES
FILES = $(foreach dir, $(DIRS), $(wildcard $(dir)/*.c))
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: