Makefile学习(一)程序的编译链接

前言

源文件 – 中间目标文件 – 执行文件
编译:检查程序语法、函数、变量声明(函数未声明编译器给警告,可生成ObjectFile)
链接:在所有Object File中找函数的实现。否则报错Link 2001


一、MakeFile 规则

1、如果这个工程没编译过,所有c文件编译并被链接
2、某几个C文件被修改,只编译被修改的C文件,并链接目标
3、如果工程头文件被改变了。编译引用了这几个头文件的C文件

target... : prerequisites ..
    command
...
...
target:		目标文件 || 执行文件 || 标签,以空格分开,可以使用通配符
prerequisites:生成target所需要的目标或目标
comman:	make 需要执行的命令(任意的shell命令),不和target:prerequisites,[tab]开头,和prerequisites可用分号做分隔
 如果命令太长可用 "\" 做换行符

二、MakeFile主要内容:

显示规则
如何生成一个或多个文件
隐晦规则
变量定义
文件指示
注释
***Makefile命令中,以[Tab]键开始

MakeFIie引用其他的Makefile

include <filename>		不能以[Tab]开始
make开始时找寻	include指的其他MakeFile。
make -I  或--include-dir 的参数
/usr/local/bin	以及/usr/include 

Make工作方式

读入所有的Makefile
读入被include的其他MakeFile
初始化文件中的变量
推导隐晦规则,并分析所有规则
为所有的目标文件创建依赖关系链

根据依赖关系,决定那些目标需要重新生成
执行生成命令

MakeFile 书写规则

MakeFile中的变量就是宏
objects = *.o					# 表示objects就是*.o,并不会展开

文件搜索

VPATH	指定依赖文件的目录,目录由:分开
VPATH = src:../headers					#指定src	和 ../headers
使用make 的 vpath的关键字
vpath <pattern>	<directories>		为符合模式<pattern>的文件指定搜索目录<directories>
vpath <pattern>						清除符合模式<pattern>的文件搜索目录
vpath								清除所有已被设置好的文件搜索目录

伪目标

.PHONY : clean
伪目标总是被执行

静态模式

objects = foo.o bar.o
all:$(objects)
$(objects): %.o: %.c
$(CC) -c $(CFLAGS) $< -o $@			#$<表示所有依赖目标集, $@表示所有目标集
 
 
等同于:
foo.o : foo.c
$(CC) -c $(CFLAGS) foo.c -o foo.o
bar.o : bar.c
$(CC) -c $(CFLAGS) bar.c -o bar.o

自动生成依赖性

CC -M main.c		(自动找寻源文件中包含的头文件,并生成一个依赖关系)

书写命令:

显示命令

@命令		#隐藏命令
make执行时,make -n或--just-print		#只是显示命令,不会执行命令
  make -s或 --slient		#全面禁止命令显示

命令执行

如果上一条的命令用于下一条,写在一行并用;分隔

命令出错

在命令前[Tab]后加-,标记不管命令出不出错都认为是成功的
或给make加上-i 或 --ignore-errors MakeFile所有命令都会忽略错误
make参数-k 或  --keep-going	如果规则中命令出错,终止该规则执行,但继续执行其他规则

嵌套make

总控MakeFile
	传递变量到下级MakeFile		export<variable ...>
	不传递变量到下级MakeFile		unexport<variable ...>
	传递所有变量	export
	SHELL、MAKEFLAGS(上层make参数)		#总能传到下级Makefile
	-w或--print-directory		#-C时-w自动打开,	-S(-slient)-w失效

定义命令包

	以define,endef结束定义命令序列、

define run-yacc yacc $(firstword $^) mv y.tab.c $@ endef

使用变量

变量用法

= (右侧的变量值可以是后面定义的值)
:= 前面的变量不能使用后面的变量,只能使用前面已经定义好了的变量
?= 如果F00没被定义过,定义,如果之前定义过,什么也不干
+= 追加变量值

变量值替换

foo := a.o b.o c.o 
bar := $(foo:.o=.c)

把$(foo)所有.o字串全部替换为.c 
    
x = variable1 variable2 := Hello y => $(subst 1,2,$(x))									#把$(x)所有1替换为2   
z = y a := $($($(Z)))

条件判断

<conditional-directive>
<text-if-true>
else
<text-if-false>
endif
<conditional-directive>包括
	ifeq	ifeq (<arg1>, <arg2>)	判断arg1==arg2则为真
	ifneq	ifneq (<arg1>, <arg2>)	判断arg1!=argv2则为真
	ifdef	ifdef <variable-name>	判断<variable-name>值为非空,则为真
	ifndef	ifndef <variable-name>	判断<variable-name>值为空,则为真
	
在<conditional-directive>中,不能以[Tab]键作为开始

********make是在读取MakeFile计算条件表达式,并根据条件表达式来选择语句,不要把自动变量($@)加入条件表达式中,自动变量在运行时才有

  • 0
    点赞
  • 0
    收藏 更改收藏夹
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

奶糖盐

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值