make和Makefile中的规则和变量
来源:互联网 发布:淘宝卖家企业店铺 编辑:程序博客网 时间:2024/05/17 22:23
make和Makefile中的规则和变量
make机制的运行环境需要一个命令行程序make和一个文本文件Makefile。
make命令执行后有3个退出码:
表示成功执行。
如果make运行时出现任何错误,则返回1.
如果使用了make的“-q”选项,并且make使得一些目标不需要更新,那么返回2.
make的使用格式是:
make [options] [target] ...
options为make工具的参数选项,target为makefile中指定的目标。
make工具的参数选项
选项
含义
-f filename
显式地指定文件作为Makefile
-C dirname
指定make在开始运行后的工作目录为dirname
-e
不允许在Makefile中替换环境变量的赋值
-k
执行命令出错时,放弃当前目标,继续维护其他目标
-n
按实际运行时的执行顺序模拟执行命令(包括用@开头的命令),没有实际执行效果,仅仅用于显示执行过程
-p
显示makefile中所有的变量和内部规则
-r
忽略内部规则
-s
执行但不显示命令
-S
如果执行命令出错就退出
-t
修改每个目标文件的创建日期
-I
忽略运行make中执行命令的错误
-V
显示make的版本号
make操作管理Makefile文件的规则
如果这个工程没有编译过,那么所有C文件都需要被编译和链接
如果这个工程中的某几个C文件被修改,则只需编译被修改过的C文件,并连接目标程序
如果这个工程的头文件被修改了,则需要编译引用了这几个头文件的C文件,并链接目标程序
在makefile中,目标名称的指定通常有以下惯例:
all:表示编译所有的内容,时执行make时默认的最终的目标。
clean:表示清除所有目标文件。
distclean:表示清除所有的内容。
install:表示进行安装的内容。
Makefile的书写规则
Makefile的书写规则包含两个部分,一个是依赖关系,一个是生成目标的方法。
Makefile中只有一个最终目标,第一条规则中的第一个目标将被确立为最终的目标。
Makefile里主要包含了5方面的内容:显式规则、隐式规则、变量定义、文件指示和注释。
显式规则:显式规则说明了如何生成一个或多个目标。这需要由Makefile的书写者显式指出要生成的文件、文件的依赖文件及生成的命令。
隐式规则:由于make有自动推导的功能,会选择一套默认的方法进行make,所以隐式的规则可以让开发者比较简略地书写Makefile,这是由make所支持的。
变量定义:在Makefile中需要定义一系列的变量,一般都是字符串,它类似C语言中的宏,当Makefile被执行时,其中的变量都会被扩展到相应的引用位置上。
文件指示:包括三部分,第一部分是在一个Makefile中引用另一个Makefile,就像C语言中的include一样包含进来;第二部分是根据某些情况指定Makefile中的有效部分,就像C语言中的预编译宏#ifdef;第三部分就是定义一个多行的命令。
注释:Makefile中只有行注释,和UNIX的shell脚本一样,其注释符使用“#”字符,这就像C/C++中的双斜杠“//”一样。如果需要在Makefile中使用“#”字符,可以用反斜杠进行转义,如“\\#”。
Makefile文件中的命令必须要以“Tab”键开始。
Makefile的基本语法规则
Makefile的语法格式如下:
targets : prerequisites
command
...
或者是:
targets : prerequisites ; command
command
...
targets是目标文件名,多个文件以空格分开,可以使用通配符。一般说来,Makefile的目标是一个文件,但也有可能是多个文件。
prerequisites是目标所依赖的文件(或依赖目标)。
command是命令行,如果它不与”targets:prerequisites”在一行,那么必须以Tab键开头,如果和prerequisites在同一行,那么可以用分号作为分隔。如果命令太长,可以使用反斜杠“\”作为换行符。make对一行中有多少个字符没有限制。
对于Makefile文件:
all : main.c foo1.c foo2.c foo3.c
gcc main.c foo1.c foo2.c foo3.c -o all
all是Makefile时最终目标,main.c,foo1.c,foo2.c,foo3.c是目标所依赖的源文件,而只有一个命令“gcc main.c foo1.c foo2.c foo3.c -o all”是生成目标的方法:
文件的依赖的关系:可执行文件all依赖于main.c,foo1.c,foo2.c,foo3.c文件,如果main.c,foo1.c,foo2.c,foo3.c中的任何一个的修改日期比all文件日期新,或者是all不存在,那么依赖关系发生。
如何生成(或更新)all文件。那个gcc命令,说明了all这个文件生成目标的方法。
在规则中使用通配符
make支持3种通配符:“*”,“?”,“[...]”。
“~”字符在文件名中有特殊用途:比如“~/test”表示当前用户的$HOME目录下的test目录;“~zhangfan/test”则表示用户zhangfan的宿主目录下的test目录。
通配符代替了一系列的文件,如”*.c”表示了所有后缀名为.c的文件。如果文件名中含有通配符,如“*”,那么可以用转义字符斜杠”\”,如“\*”来表示真实的”*“字符,而不是任意长度的字符串。
可以使用一个特殊的标记“.PHONY”来显式地指明一个目标是伪目标,向make说明,不管是否有这个文件,这个目标都是伪目标:
.PHONY : clean
只要有这个声明,不管是否有“clean”文件,要运行“clean”这个目标,只要在命令提示符下输入命令“make clean”即可。于是整个过程可以这样写,例如:
.PHONY : clean
clean :
rm all main.o kbd.o command.o \
insert.o search.o files.o
自动生成依赖关系
可以使用GNU的C/C++编译器的“-MM”参数选项,使其自动寻找源文件中包含的头文件,并生成一个依赖关系。例如main.c文件中有defs.h头文件,那么:
gcc -MM main.c
其输出是:
main.o : main.c defs.h
变量
变量在声明时需要给予初值,而在使用时,需要在变量名前加上“$”符号,但最好用小括号“()”或是花括号”{}”把变量给引用起来。如果使用真实的”$”字符,那么需要用”$$”来表示。
下面Makefile等同:
objects=program.o foo.o utils.o
program:$(objects)
cc -o program $(objects)
$(objects):defs.h
等同于:
objects=program.o foo.o utils.o
program:program.o foo.o utils.o
cc -o program program.o foo.o utils.o
program.o foo.o utils.o:defs.h
赋值变量
1、使用“:=”操作符,使得前面的变量不能使用后面的变量,只能使用前面已定义好了的变量。
2、使用”?=”操作符:例如foo ?= bar 如果foo没有被定义过,那么变量foo的值就是“bar”,否则此语句什么也不做,这段代码等同于:
ifeq($(origin foo),undefined)
foo=bar;
endif
3、使用“+=”操作符,可以追加值,
objects=main.o foo.o bar.o
objects+=another.o
等同于
objects=main.o foo.o bar.o
objects:=$(objects) another.o
define关键字
使用define定义的命令变量中没有以“Tab”键开头。
define two-lines
echo foo
echo $(bar)
endef
这段代码将变量two-lines定义为两条命令echo foo和echo $(bar)。
override指示符
有的变量时通过make的命令行参数进行设置的,那么Makefile将忽略这个变量的赋值。如果想在Makefile中设置这类参数的值,那么可以使用“override”指示符。
override =
override :=
override +=
在define关键字中也同样可以使用override指示符:
override define foo
bar
endef
目标变量和模式变量
1、目标变量
:
:override
为目标序列,可以是各种赋值表达式,如”=”、”:=“,”+=“,”?=”。第二个语法针对于make命令行参数带入的变量,或是系统环境变量。
prog : CFLAGS=-g
prog : prog.o foo.o bar.o
$(CC) $(CFLAGS) prog.o foo.o bar.o
prog.o : prog.c
$(CC) $(CFLAGS) prog.c
foo.o : foo.c
$(CC) $(CFLAGS) foo.c
bar.o : bar.c
$(CC) $(CFLAGS) bar.c
等同于
prog : prog.c foo.c bar.o
gcc -g prog.o foo.o bar.o
prog.o : prog.c
gcc -g prog.c
foo.o : foo.c
gcc -g foo.c
bar.o : bar.c
gcc -g bar.c
2、模式变量
可以给定一种“模式”,把变量定义在符合这个模式的所有目标中。
:
:override
是模式序列,可以是多种模式,override同样是针对系统环境传入的变量或是make命令行指定的变量。
make的模式变量一般是至少含有一个“%”的,所以,可以以如下方式给所有以”.o”结尾的目标定义目标模式变量:
%.o : CFLAGS=-o
- make和Makefile中的规则和变量
- Makefile 中的变量和规则
- Makefile 和 make 规则
- makefile和make规则
- Makefile: Makefile中的变量数据库和隐含规则
- Linux中的make和makefile
- GNU中的make和makefile
- linux中的‘make’和‘makefile’
- make 的隐含规则和隐含变量
- Makefile 规则 , 规则中的变量
- Makefile常用变量和规则备忘
- Makefile中的变量和函数
- 简单的Makefile规则和Makefile自动变量
- Makefile中的变量和shell变量
- GNU make 和 makefile
- GNU make 和 makefile
- make和Makefile文件
- GNU make 和 makefile
- mybatis关联查询一对多问题解决,将表中对应的多条数据以list形式存储
- make_heap(), pop_heap(), push_heap()用法
- 如何快速开发出一个高质量的APP
- jhipster应用
- GitHub 翻译系列----入门(Hello World)
- make和Makefile中的规则和变量
- 圆形红点提示背景
- Hover-Z 日记-排名
- Fiddler (五) Mac下使用Fiddler
- 【Node.js】mongoose教程03--Schema与Model
- hdu 5587 (Array)
- PHP 字符串执行函数 公式执行函数
- Java中的Random()函数
- Ubuntu数据恢复总结