在GNU中提供了一个用于管理多个C源代码文件的项目管理工具,用户只需按照一定的语法规则编写这个Makefile文件。输入make命令,系统会自动的根据当前文件的修改情况确定哪些文件需要重编译,一旦文件被修改,make工具只会执行依赖于该文件的一系列规则,这样节省了整个编译和链接时间。

1.1 Make规则

Makefile是由若干规则组成,每个规则定义了生成对应目标文件和它的依赖关系、产生目标文件需要执行的命令。

它的核心在于只要依赖的文件时间比目标更新,则执行产生目标的命令,不存在执行后续既定的命令。注:这里的目标既可以是一个目标文件,也可以是可执行文件,也可能是伪目标(命令必须从tab键开头)

目标: 依赖文件列表
<tab>命令 

如执行

#Makefile 文件1
appex: main.o app.o mod.o lib.o@echo "正在编译模块..."gcc -o appex main.o app.o mod.o lib.omain.o: main.c app.hgcc -c main.c
app.o: app.c app.hgcc -c app.c
mod.o: mod.cgcc -c mod.c
lib.o: lib.c lib.hgcc -c lib.cclean:rm -f *.o

有几点需要说明:

  • 关于GCC的参数使用,参考理解C语言(零) 导读(上)的第一节
  • Make目标规则中支持三个通配符:*、 ?、 [...]
  • 若未指定目标,则运行make命令默认执行第一个目标。运行make clean命令,清除所有的目标文件(clean是一个伪目标,并不生成clean这个文件,它只是一个标签)。还有很多这样的命令,如
    all: 一般是编译所有的目标;
    install: 把已经编译号的目标执行文件拷贝到指定目标中去
    tar: 把源程序打包备份,tar文件;
    dist: 创建一个压缩文件
    TAGS: 更新所有的目标,以备完整的编译使用

为避免和目标文件重名的情况,通常使用一个特殊的标记.PHONY来显式地指明这是一个伪目标,如:

.PHONY: doc
doc:command.PHONY: distclean clean
distclean: clean$(MAKE) -C test distcleanrm -rf autom4te.cache/rm -f Makefilerm -f $(CILLYDIR)/App/$(CILLYMOD)/CilConfig.pmrm -f config.hrm -f config.logrm -f config.mkrm -f config.statusrm -f doc/header.htmlrm -f doc/index.htmlrm -f src/machdep-ml.c src/cilversion.mlrm -f stamp-hclean: $(CILLYDIR)/Makefilerm -rf $(OBJDIR)rm -f $(BINDIR)/$(CILLY).*rm -rf lib/cil share/rm -f METArm -rf doc/html/rm -rf doc/cilcode.tmp/rm -f doc/cil.version.*rm -f doc/cilpp.*$(MAKE) -C $(CILLYDIR) cleanrm -f $(CILLYDIR)/App/$(CILLYMOD).pmrm -f $(CILLYDIR)/Makefile.old$(MAKE) -C test clean
  • 规则支持多目标,因为有可能我们的多个目标同时依赖于一个文件,我们就把它合并起来,建议使用自动变量$@表示目前规则中所有的目标集合,如:

    bigoutput littleoutput : text.g
    generate text.g -$(subst output,,$@) > $@
  • 定义多目标规则-使用到了自动化变量$<(表示所有的依赖目标集),$@(表示所有的目标集合)。例如

    objects= foo.o bar.o
    all: $(objects)
    $(objects): %.o : %.c
    $(CC) -c $(CFLAGS) $< -o $@

    该例子的意思是:我们的目标从$objects中获取-所有.o结尾的目标,就是foo.o/bar.o,依赖的模式是对应的%.c文件。目标文件较多时,采取这种静态模式规则更为方便,灵活

  • 字符在命令行前表示在命令执行前输出信息到屏幕上
  • 如果命令模式里含有多个命令需要连续执行,应使用;分隔命令
  • 嵌套make执行-每个子目录中都有一个Makefile,根目录有一个Makefile,根目录的Makefile应如下书写,它表示先进入这个子目录中,再执行make命令

    search:
    cd suddir && $(MAKE)

在Makefile中,主要包含了以下内容: 变量定义、显式规则、隐含规则。

1.2 变量

A. 变量基础
变量名的命名规则:变量名=变量值(字符串),引用变量时在变量前加上$符号,也可用"()"或者"{}"把变量给包起来(为了安全使用)。如果使用变量来定义变量的值,有两种方式: "="或者":="

# =符号允许变量可以使用后面的变量定义,但出现递归引用,就不行
foo = $(bar)
bar = $(ugh)
ugh = Huh?
all :echo $(foo)x := foo
y := $(x) bar
x := later
# 使用:=,前面的变量就不能使用后面的变量

操作符"?="表示如果变量没有定义过,则变量值就是后面的形式,若先前被定义,什么都不做。追加变量sh值使用"+=",如:

# 结合条件选择是否追加相应参数,摘自CIL代码
CILHOME := ..
CILLY := $(CILHOME)/bin/cillyifdef _MSVCinclude Makefile.msvc
else
ifdef _GNUCCinclude Makefile.gcc
endif
endifCILLY += --mode=$(COMPILERNAME) --decil
CILLY += --save-temps $(EXTRAARGS)

目标变量:我们还可以为目标设置局部变量,这个变量只会作用在这条规则和连带规则中,而不影响其他规则链以外的值。如:

prog: CFLAGS = -g
prog: prog.o foo.o$(CC) $(CFLAGS) prog.o foo.o -o progprog.o : prog.c$(CC) $(CFLAGS) prog.c

如果我们想在多个目标中定义,则使用模式变量,如%.o: CFLAG= -O

B. 条件判断

  • ifeq (arg1,arg2)... else ...endif 如果两个参数的值相等,则表达式为真,相反的是ifneq
  • ifdef var-name ... else ... endif 如果定义了某变量值非空,则表达式为真,相反的是ifndef

例如:

ifeq ($(CC),gcc)libs=$(libs_for_gcc)
elselibs=$(normal_libs)
endififndef NOCHECKCILLY += --strictcheck
endififdef OCAMLDEBUGCILLY+= --ocamldebug
endif

1.3 隐含规则、模式规则及其使用的变量

GNU make中定义了内置各种隐含规则,在不给出产生目标文件的命令时由make自动添加,例如未定义如何产生目标的命令,如:

demo.o: demo.c app.h
# make会自动添加如下规则
# $(CC) $(CFLAGS) $(CPPFLAGS) ... -c $< -o $@

我们看到在隐含规则中基本上都使用了一些预定义的变量,你可以在文件中进行重新定义。只要设定了这些预定义变量,就会对隐含规则起作用。这些预定义变量分为两种类型:命令相关,参数相关。

命令相关:

  • AR: 函数库打包程序,默认命令ar;AS: 汇编语言编译程序,默认as
  • CC: C编译器,默认cc; CXX: C++编译器,默认g++; CPP: C程序的预处理,默认$(CC) -E
  • RM: 删除文件命令,默认rm -f

参数相关:

  • CFLAGS: C编译器参数,可添加加入非标准的目录-I dir或者调试信息-g选项
  • CPPFLAGS: C预处理参数;CXXFLAGS: C++编译器参数
  • LDFLAGS: 链接器参数,通常可添加-lxxx指定的库文件(如-lm)或者指定的库搜索路径-L dir
  • LEX: 词法分析器,默认lex; 语法分析器,默认yacc

还注意到刚才已经多次提到了自动变量,它的值是与规则中的目标和依赖对象有关,即把模式中定义的一些列文件自动地取出,直至所有的符合模式的文件都取完,自动化变量只出现在规则的命令中。如下:

  • $@ : 匹配规则中的目标文件集合
  • $^ : 所有的依赖目标集合,以空格分隔,有重复去除($+,不去除重复)
  • $< : 第一个依赖文件,如果依赖目标是以模式%定义的,表示符合模式的一系列文件
  • $* : 不包含扩展名的目标文件名称
  • $? : 所有比目标新的依赖目标的集合,以空格分隔。

希望只对更新过的依赖文件操作,$?就很有用,例如一个库文件lib,由其他几个目标文件更新,那么把几个目标打包的高效率的规则如下:

lib : x.o y.o z.oar r lib $?

结合这些采取不同的规则修改上面我们定义的Makefile文件

  • 使用自动变量
OBJS= main.o app.o mod.o lib.o
appex: $(OBJS)@echo "正在编译模块..."$(CC) -o $@ $^main.o: main.c app.h$(CC) -c -o $@ $<
app.o: app.c app.h$(CC) -c -o $@ $<
mod.o: mod.c$(CC) -c -o $@ $<
lib.o: lib.c lib.h$(CC) -c -o $@ $<clean:rm -f *.o
  • 使用隐含规则
OBJS= main.o app.o mod.o lib.o
appex: $(OBJS)@echo "正在编译模块..."$(CC) -o $@ $^main.o: main.c app.h
app.o: app.c app.h
mod.o: mod.c
lib.o: lib.c lib.hclean:rm -f *.o
  • 使用模式规则,把具有相同行为特点的规则,进行通配表示
*.o : *.c$(CC) -c $< -o $@OBJS= main.o app.o mod.o lib.o
appex: $(OBJS)@echo "正在编译模块..."$(CC) -o $@ $^main.o: main.c app.h
app.o: app.c app.h
mod.o: mod.c
lib.o: lib.c lib.hclean:rm -f *.o

一篇还不错的介绍make的文章相关推荐

  1. 【思维导图】探秘脑科学,科学家尚未打开的黑匣子!(一篇还不错的脑科学的科普文,涉及到多个层面,也比较浅显)

    这里主要涉及的是fmri,其他脑成像设备也值得进行探究 通过脑成像手段探求精神疾病是我很感兴趣的方向 中国的脑计划上马的有点慢啊,提了好多年了 整理自公众号:阿兹海默症 原文链接(可能会失效):htt ...

  2. The Clean Architecture--一篇很不错的关于架构的文章

    翻译水平有限,见谅! Uncle Bob 13 Aug 2012 Architecture Craftsmanship Over the last several years we've seen a ...

  3. 转载一篇介绍 WordPress 的文章

    Wordpress简明使用指南 从今年9月到现在,我用Wordpress也有大约3个月了.现将自己使用中的一些体会分简介.安装.一般使用.主题.插件.代码修改等几个部分逐一概述如下. 1. 简介 Wo ...

  4. 看了一篇关于游戏外挂类型总结的文章,感觉很有用,离我还很远。。

    看了一篇关于游戏外挂类型总结的文章,感觉很有用,离我还很远.. 网络游戏安全小议(端游/页游/手游) 一.网络游戏安全很有趣 一直很想知道魔兽的游戏安全工程师是如何做游戏安全的,毫无疑问,魔兽是目前最 ...

  5. 国企央企OFFER收割全攻略 | 银行篇之行业整体介绍

    国企央企OFFER收割全攻略 | 银行篇之行业整体介绍 大家好,这里是小黛.最近完成了一些工作上的事情,因此更新推迟了一些. 这篇银行求职全攻略,千呼万唤始出来,耗费了小黛非常非常非常多的心血,反复加 ...

  6. 量化投资之定投,无脑却收益还不错,记得周三来

    目标: 本系列开始重点研究量化,逐步改善模型,改善策略,然后评估各个策略的优劣. 本文是第一篇,也是最容易最无脑投资的一篇,每周三定投,收益还不错. 内容: 如果工作太忙没法投资,闲钱无处放,不妨看看 ...

  7. 第六十二期:看完这篇还不了解Nginx,那我就哭了!

    看完这篇还不了解Nginx,那我就哭了! Nginx 同 Apache 一样都是一种 Web 服务器.基于 REST 架构风格,以统一资源描述符(Uniform Resources Identifie ...

  8. CCNA-第十五篇-DHCP配置+SDN介绍(最后一章)

    CCNA-第十五篇-DHCP配置+SDN介绍 各位好,如果有一直看下来的谢谢支持 这里是CCNA的最后一篇了,如果真的能吸收很多内容,那么普通的东西基本上都没什么大问题了.除非就是工作经验 下一篇就到 ...

  9. python 把numpy.ndarray转为图像_Python 让蔡徐坤在我的命令行里打篮球?打得还不错...

    这是恋习Python推荐的第83篇好文 作者:顾个城管打天下 作者自称是一个经常逛 B 站的肥宅.最近 B 站上流行的视频素材除了"换脸",其次就要属"蔡xx打球&quo ...

最新文章

  1. 2.0Tonmcat高级配置和jDK的安装配置
  2. 古巴雪茄高希霸世纪1.2.3.4.5.6.半世纪7款雪茄的区别?
  3. .net core 注入中的三种模式:Singleton、Scoped 和 Transient
  4. MongoDB日志文件过大
  5. MySQL运维实战 之 PHP访问MySQL你使用对了吗
  6. 《原力计划【第二季】》第 8 周周榜揭晓!!!
  7. Java垃圾回收精粹 — Part4
  8. AAAI'22 | 基于Profile信息的口语语言理解基准
  9. mysql的数据库文件在哪里_MySQL数据库文件其具体的存放位置简述
  10. Centos7配置阿里YUM源
  11. 建立自己的JS库【初始篇】
  12. CSS特效二:按钮动画效果
  13. 微信机器人接口,个人号API二次开发
  14. 照片损坏怎么办,怎么恢复受损照片
  15. 数学一年级应用题_一年级数学下册应用题大全(附带答案)
  16. 香港美食(3)——源记喳咋
  17. 让手机变成电脑摄像头
  18. 《第1阶段》——正交试验法
  19. 谷歌 招聘_为什么我不与Google招聘人员交谈
  20. Java后端接收前端post方式传来的表单数据

热门文章

  1. PXA270处理器PCMCIA/CF接口设计及WinCE 5.0驱动实现 ----eetchina.com
  2. Linux Debian利用Dockefile将Python的py文件项目代码打包为Docker Podman镜像
  3. 『Python学习笔记』使用pycharts包画地图!
  4. 【财富空间】北京航空航天大学王田苗教授:人工智能与机器人前沿科技发展与投资布局
  5. f5 shape最新版逆向分析
  6. wangeditor封装使用
  7. 【肌电信号】脉搏信号分析(去噪+特征提取)【含GUI Matlab源码 862期】
  8. 【PostgreSQL的模板库存在连接导致创建数据库失败】
  9. uml点餐系统活动图_UML活动图(转载)
  10. 切片器可以设置日期格式?_Excel中如何使用切片器,这个太高大上了