Makefile基础

什么是Makefile?

  • 一个工程中的源文件不计其数,其按类型、功能、模块分别放在若干个目录中,Makefile定义了一系列规则来制定,哪些文件需要先编译,哪些文件需要重新编译,如何进行链接等操作。
  • Makefile就是"自动化编译",告诉make命令如何编译和链接。
  • Makefile也是make命令的配置脚本,默认情况下GUN make会在当前目录下寻找文件,按照优先级依次寻找 GNUmakefile -> makefile -> Makefile。也可使用 make -f/-file “文件名" 手动指定Makefile文件

Makefile文件内容

  • 显示规则
    • 如何生成一个或多个目标文件
  • 隐晦规则
    • 依赖于Makefile自动推导,可以简略书写Makefile
  • 变量定义
    • 可以定义变量 一般为String,类似于“宏”,当Makefile被执行时,变量会扩展到相应的引用位置上
  • 文件指示
    • 一个Makefile引用另外一个Makefile。类似于C的include
    • 根据情况,指定Makefile有效部分。类似于C的预编译
    • 定义多行命令
  • 注释
    • 只有行注释“#”

Makefile的规则

target ... : prerequisites ...
    command
或
target ... : prerequisites ... ; command
  • target: 目标文件。可以是Object File,也可以是执行文件,还可以是标签(Label)。
    • 如果是多文件用空格隔开。
    • 也可使用通配符
  • prerequisites:依赖文件,即要生成那个target所需要的文件或其他target
  • command:make需要执行的命令
    如果命令太长可以使用“\”作为换行符进行换行

Makefile的规则就是告诉make 文件的依赖关系以及如何生成目标文件;

target的文件依赖prerequisite文件,生成规则在command中

如果prerequisite有一个以上的文件比target新,target会被认为是过时的需要重新生成,command将被执行,从而生成新的target。
示例

# 当前目录存在main.c、tool.c、tool.h三个文件
# 要生成一个main目标文件依赖于main.o tool.o
main: main.o tool.o
# 生成目标的命令
    gcc main.o tool.o -o main
# .PHONY:显式的指明clean是一个“伪目标”
.PHONY: clean
# clean: 标签,不会生成“clean”文件,这样的target称之为“伪目标”,伪目标的名字不能和文件名重复。clean一般放在文件最后
clean:
# -rm “-” 表示如果某些文件出现问题 跳过
    -rm main *.o

clean伪目标需要make显式调用make clean

makefile执行效果如下

makefile执行效果

Makefile是如何工作的

默认方式下,输入make命令后:

  • make会在当前目录下找名字叫“Makefile”或“makefile”的文件。
  • 如果找到,它会找文件中第一个目标文件(target),并把这个target作为最终目标文件,如前面示例中的“main”。
  • 如果main文件不存在,或main所依赖的.o的修改时间要比main文件新,那么它会执行后面所定义的命令来生成main文件
  • 如果main所依赖的.o文件也存在,那么make会在当前文件中找目标为.o文件的依赖性,若找到则根据规则生成.o文件。
  • make再用.o文件声明make的终极任务,也就是可执行文件“main”。

make会层层找文件依赖关系,直到最终编译出第一个目标文件,如果在找的过程出现错误,make会退出并抛出错误。Make只管文件的依赖性,编译错误不会理会

Makef中变量的使用

​ 如果工程需要加入一个新的“.o”文件 Makefile需要修改多处,为了易维护,在Makefile中我们可以使用变量。比如,我们声明一个变量为objects,这样就可以方便的在Makefile中以$(objects)的方式使用这个变量了。

我们修改一下刚刚的Makefile文件

objects = main.o tool.o
main: $(objects)
    gcc $(objects) -o main
.PHONY: clean
clean:
    -rm main $(object)

引用其他的Makefile

在实际开发中我们会按类型将源文件会分成不同的模块,每个模块有一个单独的Makefile文件,那么编译时就需要引入其他模块的Makefile,在Makefile中可以使用include关键字引入其他模块

# 语法格式
include <filename>
# 如果文件找不到,而你希望make时不理会那些无法读取的文件而继续执行,可以在include前加"-"
-include <filename>

环境变量 MAKEFILES

​ 如果当前环境中定义了环境变量MAKEFILES,make会把这个变量中的值做一个类似于include的动作。这个变量中的值是其它的Makefile,用空格分隔。只是,它和include不同的是,从这个环境变量中引入的Makefile的“目标”不会起作用,如果环境变量中定义的文件发现错误,make也会不理。但是建议不要使用这个环境变量,因为只要这个变量一被定义,那么当你使用make时,所有的Makefile都会受到它的影响。

​ 也许有时候Makefile出现了奇怪的事,可以查看当前环境中有没有定义这个变量。

Makefile预定义变量

Makefile预定义变量

Makefile自动变量

Makefile自动变量

函数

# 不带参数
define FUNC
$(info echo "hello")
endef

# 调用 FUNC函数 输出hello
$(call FUNC)

# 带参数
define FUNC1
$(info echo $(1) $(2))  
endef

# 调用FUNC1函数 输出hello world
$(call FUNC1,hello,world)

make的工作流程

  1. 读入所有的Makefile。
  2. 读入被include的其他Makefile。
  3. 初始化文件中的变量。
  4. 推导隐晦规则,并分析所有规则。
  5. 为所有的目标文件创建依赖关系链。
  6. 根据依赖关系,决定哪些目标要重新生成。
  7. 执行生成命令。

上面的流程分两个阶段:1-5 为第一阶段、6、7为第二阶段

在第一阶段中如果定义的变量被使用了,make会把变量展开在使用的位置,但不完全展开,如果变量出现在依赖关系的规则中,只有依赖被使用的时候,变量才会被展开

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,457评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,837评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,696评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,183评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,057评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,105评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,520评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,211评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,482评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,574评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,353评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,213评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,576评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,897评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,489评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,683评论 2 335

推荐阅读更多精彩内容