工程中编写自己的Makefile---1 一些基本概念

来源:互联网 发布:淘宝9.9元特价专区在哪 编辑:程序博客网 时间:2024/05/22 03:51

本文是基于网上的一系列文章,加上自己的一些看法,提炼精简而构成的;

参考文章有如下:

http://www.cnblogs.com/OpenShiFt/p/4313351.html

http://blog.csdn.net/cjsycyl/article/details/47946039

http://blog.csdn.net/wangzhen209/article/details/47153239

还有大神陈浩的文章

http://blog.csdn.net/haoel/article/details/2886

1        一些基本的知识

1.1             常用的交叉编译工具选项

-ofile :指定输出的文件为file,但只能指定一个输出文件

-c     :编译或汇编源文件,但不做连接,编译器输出对应于源文件的目标文件(.o文件)

-I(大写i)dir    :在头文件的搜索路径列表中添加dir目录

-L(大写l)dir    :常接”-L”指定的库文件搜索路径

-l(小写l)libname:指定期望连接的库的名字,注意!!!文件的顺序就是链接的顺序

 

例如:

gcc -o hello.o -c hello.c -I/opt/hello/include -L/opt/hello/lib-lworld

-ohello.o  :指定输出文件为hello.o

-c          :编译或汇编源文件,但不做连接

-I/opt/hello/include:源文件hello.c中用到的头文件的搜索路径

-L/opt/hello/lib    :源文件hello.c中用到的库文件的搜索路径

-lworld             :表示在上面的lib的路径中寻找libworld.so动态库文件,注意!!!去掉了字符“lib”, 如果编译选项中加入了“-static”表示寻找libworld.a静态库文件;

1.2             Makefile书写规则

1,命令必须以[Tab键]开头

2,在 include 前面可以有一些空字符,但是绝不能是[Tab]键开始

3,定义变量的语句,等号两端可有空格,最后不要空格(特别是目录);建议[MYNAME := wzt]

4,如果想要让上一条命令的结果应用在下一条命令时,这两条命令写同一行并用分号分隔

1.3             Makeflie中一些常用字符含义

1,-    :命令前面加了一个小减号,标记为不管命令出不出错都认为是成功的

2,@       :用“@”字符在命令行前,这个命令将不被 make 显示出来

3,$<     :自动化变量,表示所有的依赖目标集

4,$@     :自动化变量,表示目标集

5,$$$$  :意为一个随机编号

1.4             Make参数

1,-n:只显示命令,但不执行命令,利于调试Makefile,看看命令执行起来是什么顺序

2,-s:全面禁止命令的显示

3,-f:运行指定的 Makefile,例如:make -f make.linux

1.5             变量

1.5.1        定义

1,”=”

MyName=$(Name)

Name=wzt

变量是可以使用后面的变量来定义的(递归调用容易出问题)

2,”:=”

Name:=wzt

MyName:=$(Name)

前面的变量不能使用后面的变量,只能使用前面已定义好了的变量

推荐使用此种方法

3,”?=”

如果 FOO 没有被定义过,那么变量 FOO 的值就是“bar”

如果 FOO 先前被定义过,那么这条语将什么也不做

4,”+=”

追加变量值

objects = main.o foo.o bar.o utils.o

objects += another.o

1.5.2        变量高级用法

1变量值的替换(类似静态模式)

$(var:a=b)

把变量“var”中所有以“a”字串“结尾”的“a”替换成“b”字串。这里的“结尾”意思是“空格”或是“结束符”

2把变量的值再当成变量

x = y

y = z

a := $($(x))

    有$(a)=z

1.5.3        VPATH

若未指明此变量,make只会在当前的目录中去找寻依赖文件和目标文件,一般用来指明源文件的位置(.c文件),头文件一般使用编译选项-Idir指明

1.5.4        vpath

1vpath <pattern><directories>

为符合模式<pattern>的文件指定搜索目录<directories>

2vpath <pattern>   清除符合模式<pattern>的文件的搜索目录。

3Vpath                  清除所有已被设置好了的文件搜索目录。

例如:

vpath  %.h  ../headers:work

该语句表示,要求make ../headerswork两个目录下搜索所有以“.h”结尾的文件

1.5.5        系统预定义变量

变量名

含 义

默 认 值

AR

生成静态库库文件的程序名称

ar

AS

汇编编译器的名称

as

CC

C语言编译器的名称

cc

CPP

C语言预编译器的名称

\$(CC) -E

CXX

C++语言编译器的名称

g++

FC

FORTRAN语言编译器的名称

f77

RM

删除文件程序的名称

rm -f

ARFLAGS

生成静态库库文件程序的选项

无默认值

ASFLAGS

汇编语言编译器的编译选项

无默认值

CFLAGS

C语言编译器的编译选项

无默认值

CPPFLAGS

C语言预编译器的编译选项

无默认值

CXXFLAGS

C++语言编译器的编译选项

无默认值

FFLAGS

FORTRAN语言编译器的编译选项

无默认值

 

1.6             静态模式

静态模式可以更加容易地定义多目标的规则,可以让我们的规则变得更加的有弹性和灵活

格式:

<targets ...>: <target-pattern>:<prereq-patterns ...>

<commands>

1targets定义了一系列的目标文件,可以有通配符。是目标的一个集合(目标集)

2target-parrtern是指明了targets的模式,也就是的目标集模式(目标模式)

3prereq-parrterns是目标的依赖模式(依赖模式),它对target-parrtern形成的模式再进行一次依赖目标的定义。

foo.o bar.o: %.o: %.c

$(CC) -c $< -o $@ $(CFLAGS)

1.7             主Makefile中调用其他文件夹下的子makefile

cd subdir && $(MAKE)

         或者

$(MAKE) -C subdir

若要调用子makefileclean(伪目标)

$(MAKE) clean -C subdir

若要传递变量到下级Makefile

export <variable ...>

export variable := value

其等价于:

variable := value

export variable

1.8             Makefile常用函数

函数调用,很像变量的使用,也是以“$”来标识的,其语法为:$( )或${ }。

1.8.1        wildcard

原型:$(wildcard PATTERN)

功能:获取匹配模式的文件名

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

 

例如:

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

$(wildcard *.c)

 

1.8.2        patsubst

原型:$(patsubst pattern, replacement, text)

功能:模式替换函数

说明:函数功能是查找字符串 text 中按照空格分开的单词,将符合模式 pattern 的字符串替换成 replacement。 Pattern 中的模式可以使用通配符,当 pattern 和 replacement 中都有 % 时,符合条件的字符将被 replacement 中的替换。函数的返回值是替换后的新字符串。

例如

需要将 C 文件替换为 .o 的目标文件可以使用如下模式:

$(patsubst%.c, %.o, add.c)

上面的模式将 add.c 字符串作为输入,当扩展名为 .c 时符合模式 %.c ,其中 % 在这里代表 add,替换为 add.o,并作为输出字符串。

$(patsubst%.c, %.o, $(wildcard *.c))

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

1.8.3        foreach

原型:$(foreach VAR, LIST, TEXT)

功能:循环函数

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

例如:

对于存在 add 和 sub 的两个目录,设置 DIRS 为 "add sub ./" 包含目录 add、sub 和当前目录。表达式$(wildcard $(dir)/*.c) ,可以取出目录 add 和 sub 及当前目录中的所有扩展名为 .c 的C语言源文件:

DIRS = subadd ./

FILES =$(foreach dir, $(DIRS), $(wildcard $(dir)/*.c))

1.8.4        filter

原型:$(filter PATTERN…,TEXT)

功能:过滤函数

说明:过滤掉字串“TEXT”中所有不符合模式“PATTERN”的单词,保留所有符合此模式的单词。可以使用多个模式。模式中一般需要包含模式字符“%”。存在多个模式时,模式表达式之间使用空格分割。一般用来去除一个变量中的某些字符串

返回值:空格分割的“TEXT”字串中所有符合模式“PATTERN”的字串。

        例如:

sources := foo.c bar.c baz.s ugh.h

foo: $(sources)

cc $(filter %.c %.s,$(sources)) -o foo

        使用“$(filter %.c%.s,$(sources))”的返回值给 cc 来编译生成目标“foo”,函数返回

值为“foo.c bar.c baz.s”

1.8.5        subst

原型:$(subst FROM, TO, TEXT),

功能:替换函数

说明:即将字符串TEXT中的子串FROM变为TO。


原创粉丝点击