makefile学习笔记

1.程序在编译成.o文件时,编译链检测语法,函数和变量是否申明。而在链接成执行文件时,编译链只会检测函数和变量是否定义,将所有的.o文件链接在一起,即将所有的执行方法与变量的地址链接起来,并不会管源文件,而当.o文件太多时将其打包成库,即.a文件。编译和链接可以分步进行。

2.Makefile执行流程:

    2.1、读入所有的 Makefile。

    2.2、读入被 include 的其它 Makefile。

    2.3、初始化文件中的变量。

    2.4、推导隐晦规则,并分析所有规则。

    2.5、为所有的目标文件创建依赖关系链。

   2.6、根据依赖关系,决定哪些目标要重新生成。

   2.7、执行生成命令。

3.Makefile的语法的中心是  target:prerequisites

Command

或者是 targets : prerequisites ; command

command

...

目标,依赖文件,命令,其中命令必须以一个table建开始,Makefile文件才能识别,命令为任意shell命令,如果命令太长,你可以使用反斜框(‘\’)作为换行符。

4.makefile中隐匿规则会将.o目标的依赖文件自动视为.c如果找不到.c会去找其他的相关文件.xxx,然后使用默认的编译规则编译,所以在特别熟练前尽量不要让隐匿规则发生作用。

5.伪目标:.PHONY : clean

clean :

rm edit $(objects)

.PHONY为伪目标环境变量,其后面的是make的执行目标,可以使make分块运行你想执行的部分。如 make clean 。伪目标一般没有依赖的文件。其语法为

伪目标1:目标1 目标2 目标3...

伪目标2:目标4 目标5 目标6 ...

伪目标3:伪目标1 伪目标2 ...

伪目标申明环境变量:伪目标1 伪目标2 伪目标3...

相关目标语句...例子:

all : prog1 prog2 prog3

.PHONY : all

prog1 : prog1.o utils.o

cc -o prog1 prog1.o utils.o

prog2 : prog2.o

cc -o prog2 prog2.o

prog3 : prog3.o sort.o utils.o

cc -o prog3 prog3.o sort.o utils.o

6.Makefile指定运行文件时  make -f XXX(文件名),指定运行文件里面某一个目标时, make  MMM(目标或者伪目标)。如果这个Makefile文件包含其他Makefile文件则include xxx1 xxx2(其他Makefile文件名)

7.源文件搜索路径环境变量:VPATH,使用方法,VPATH = src:../headers,目录使用冒号分开。

8.通配符:*,*在命令中使用时,会展开,如clean:

rm -f *.o

在目标中不会,如print: *.c;lpr -p $?;touch print,这个*.c就是文件*.c

如果在目标中使用*.c来展开使用函数wildcard,函数使用方法参照后面。

9.静态模式,目标变量和模式变量,多行变量,环境变量:

静态模式:里面包含模式符号%,其语法为

objects = foo.o bar.o   

$(objects): %.o: %.c 目标集:目标模式:依赖文件模式

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

目标集就是一系列目标,可以用通配符*(wildcard),其作用是将目标集中 的全部目标由相应的依赖文件生成,省略目标集,那么Makefile会寻找整 个工程中的目标模式依次执行命令。

目标变量:

prog : CFLAGS = -g 目标:赋值表达式(变量赋值)

prog : prog.o foo.o bar.o 目标:依赖文件

$(CC) $(CFLAGS) prog.o foo.o bar.o command

当我们设置了这样一个变量,这个变量会作用到由这个目标所引发的所有的规则中去。其他地方变量的值保持不变。

模式变量:%.o : CFLAGS = -O

同样,模式变量的语法和“目标变量”一样。作用一样。

多行变量:define two-lines

echo foo

echo $(bar)

endef

define 指示符后面跟的是变量的名字,而重起一行定义变量的值,定义是以 endef 关键字结束。其工作方式和“=”操作符一样。变量的值可以包含函数、命令、文字,或是其它变量

环境变量:make运行时的系统环境变量可以在make开始运行时被载入到Makefile文件中,但是如果Makefile中已定义了这个变量,或是这个变量由make命令行带入,那么系统的环境变量的值将被覆盖。

10.make执行过程中,会将执行命令显示出来,在命令前面加上@,命令将不会打印出来显示。

11.当命令在同一行用分隔符表示时,后面的命令会在之前命令的行为上执行,如cd /home/hchen cd /home/hchen;pwd

pwd   打印当前路径     打印切换以后的命令

12.我们可以在 Makefile 的命令行前加一个减号“-”(在 Tab 键之后),标记为不管命令出不出错都认为是成功的。

13.命令包的格式  define 变量名

Command1

Command2

....

 endef   使用方法和变量使用的方法一样。变量会像一个宏一样展开。在需要使用到这个命令集合的地方$(变量名)即可。

14.赋值方法:   =     

右侧中的变量不一定非要是已定义好的值,其也可以使用后面定义的值,A = $(B);B = $(A)  容易发生递归赋值 少用

:=     

正常赋值,右边使用变量时只能是已经定义好的,否则为空。

FOO ?= bar    

其含义是,如果 FOO 没有被定义过,那么变量 FOO 的值就是“bar”,如果 FOO 先前被定义过,那么这条语将什么也不做。可以用来保存编译器的名字

+= 追加赋值

15.在Makefile中,所有变量的赋值有个特点就是易变的会覆盖不变的(局部覆盖全局)。想要相反处理需要相关设置,

①Make命令行的参数会覆盖Makefile中赋值的变量的值(环境变量值等),如果你想在Makefile中进行赋值语句,在赋值语句之前加入override <variable> += <more text>

②在make命令行加入-e  系统环境变量将覆盖 Makefile 中定义的环境变量

③总控 Makefile 的变量可以传递到下级的 Makefile 中(如果你显示的声明),但是不会覆盖下层的 Makefile 中所定义的变量,除非指定了“-e”参数。

④如果你不想让某些变量传递到下级 Makefile 中,那么你可以这样声明:

unexport <variable ...>。

16.Makefile的参数和函数,以及系统环境变量需要多看,多记多使用。和正则表达式元字符一样,都很重要。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值