Makefile简单教程

基础规则

一个简单的 Makefile 文件包含一系列的“规则”,其样式如下:

目标(target)…: 依赖(prerequiries)…
<tab>命令(command)

如果“依赖文件”比“目标文件”更加新,那么执行“命令”来重新生成“目标文件”。命令被执行的 2 个条件:依赖文件比目标文件新,或是 目标文件还没生成

Makefile的两个函数

A. $(foreach var,list,text) 简单地说,就是 for each var in list, change it to text。 对 list 中的每一个元素,取出来赋给 var,然后把 var 改为 text 所描述的形式。

例子:

objs := a.o b.o
dep_files := $(foreach f, $(objs), .$(f).d) // 最终 dep_files := .a.o.d .b.o.d

B. $(wildcard pattern) pattern 所列出的文件是否存在,把存在的文件都列出来。 例子:

src_files := $( wildcard *.c) // 最终 src_files 中列出了当前目录下的所有.c` 文件

wildcard 用来明确表示通配符。wildcard 也可以用来匹配变量。

参考文章:(9条消息) wildcard 的理解_Simon_CB_Zhao的博客-CSDN博客_wildcard

一步步完善Makefile

第 1 个 Makefile,简单粗暴,效率低:

test : main.c sub.c sub.h
gcc -o test main.c sub.c

第 2 个 Makefile,效率高,相似规则太多太啰嗦,不支持检测头文件:

test : main.o sub.o
gcc -o test main.o sub.omain.o : main.c
gcc -c -o main.o main.csub.o : sub.c
gcc -c -o sub.o sub.cclean:
rm *.o test -f

第 3 个 Makefile,效率高,精炼,不支持检测头文件:

test : main.o sub.o
gcc -o test main.o sub.o
%.o : %.c
gcc -c -o $@ $<
clean:
rm *.o test -f

第 4 个 Makefile,效率高,精炼,支持检测头文件(但是需要手工添加头文件规则):

test : main.o sub.o
gcc -o test main.o sub.o%.o : %.c
gcc -c -o $@ $<sub.o : sub.hclean:
rm *.o test -f

第 5 个 Makefile,效率高,精炼,支持自动检测头文件:

objs := main.o sub.otest : $(objs)
gcc -o test $^# 需要判断是否存在依赖文件
# .main.o.d .sub.o.d
dep_files := $(foreach f, $(objs), .$(f).d)
dep_files := $(wildcard $(dep_files))# 把依赖文件包含进来
ifneq ($(dep_files),)include $(dep_files)
endif%.o : %.c
gcc -Wp,-MD,.$@.d -c -o $@ $<clean:
rm *.o test -fdistclean:
rm $(dep_files) *.o test -f

零星知识点

A. make 命令的使用: 执行 make 命令时,它会去当前目录下查找名为“Makefile”的文件,并根据它的指示去执行操作,生成第一个目标。

我们可以使用“-f”选项指定文件,不再使用名为“Makefile”的文件,比如:

make -f Makefile.build

我们可以使用“-C”选项指定目录,切换到其他目录里去,比如:

make -C a/ -f Makefile.build

我们可以指定目标,不再默认生成第一个目标:

make -C a/ -f Makefile.build other_target

即时变量、延时变量: 变量的定义语法形式如下:

A = xxx // 延时变量
B ?= xxx // 延时变量,只有第一次定义时赋值才成功;如果曾定义过,此赋值无效
C := xxx // 立即变量
D += yyy // 如果 D 在前面是延时变量,那么现在它还是延时变量;
// 如果 D 在前面是立即变量,那么现在它还是立即变量

在 GNU make 中对变量的赋值有两种方式:延时变量、立即变量。 上图中,变量 A 是延时变量,它的值在使用时才展开、才确定。比如:

A = $@
test:
@echo $A

变量 A 的值在执行时才确定,它等于 test,是延时变量。

$(filter-out pattern…,text) 把 text 中符合 pattern 格式的内容,filter-out(过滤)出来、扔掉。 例子:

obj-y := a.o b.o c/ d/
DIR := $(filter-out %/, $(obj-y)) //结果为:a.o b.o

我们的 Makefile 中有这样的目标:

clean:
rm -f $(shell find -name "*.o")
rm -f $(TARGET)

如果当前目录下恰好有名为“clean”的文件,那么执行“make clean”时它就不会执行那些删除命令。

这时我们需要把“clean”这个目标,设置为“假想目标”,这样可以确保执行“make clean”时那些删除命令肯定可以得到执行。

使用下面的语句把“clean”设置为假想目标:

.PHONY : clean

$(patsubst pattern,replacement,text) 寻找text’中符合格式pattern’的字,用replacement’替换它们。pattern’和`replacement’中可以使用通配符。 比如:

subdir-y := c/ d/
subdir-y := $(patsubst %/, %, $(subdir-y)) // 结果为:c d

Makefile简单教程相关推荐

  1. qt4 连接mysql_Qt4访问mysql 数据库的简单教程

    编译问题: 1.系统中安装有VC,所以头文件冲突 手工修改makefile 删除所有-I 加载VC头文件的项目 2.mysql cannot find -llibmysql 指定libmysql.a的 ...

  2. Makefile简易教程

    Reference: http://www.cnblogs.com/owlman/p/5514724.html Makefile简易教程 本文部分内容引用: 中文维基百科. 一个简单的Makefile ...

  3. Makefile 入门教程

    1.Makefile简介 Makefile 定义了软件开发过程中,项目工程编译链.链接的方法和规则. 由 IDE 自动生成或者开发者手动书写. Unix(MAC OS.Solaris)和Linux(R ...

  4. Makefile经典教程(掌握这些足够)

    http://blog.csdn.net/ruglcc/article/details/7814546 拉轰的专栏 少壮不努力 老大徒伤悲 目录视图 摘要视图 订阅 新版极客头条上线,每天一大波干货  ...

  5. Linux编写makefile详细教程

    Linux下编写 makefile 详细教程 近期在学习Linux下的C编程,买了一本叫<Linux环境下的C编程指南>读到makefile就越看越迷糊,可能是我的理解能不行. 于是goo ...

  6. ASP.NET Core 异常和错误处理 - ASP.NET Core 基础教程 - 简单教程,简单编程

    原文:ASP.NET Core 异常和错误处理 - ASP.NET Core 基础教程 - 简单教程,简单编程 ASP.NET Core 异常和错误处理 上一章节中,我们学习了 ASP.NET Cor ...

  7. idea 从svn导入多个项目_IDEA导入项目简单教程

    该教程用于IDEA初学者导入eclipse项目,或者导入其他已经写好的Java源程序的简单教程. 我们用IDEA打开一个已经写好的项目源文件时,如果没有配置好,就会出现:JDK配置失误报错.程序无法启 ...

  8. expect简单教程

    expect简单教程 一.概述 expect是Unix系统中用来进行自动化控制和测试的软件工具,由Don Libes制作,作为Tcl脚本语言的一个扩展,应用在交互式软件中如telnet,ftp,Pas ...

  9. ASP.NET Core macOS 环境配置 - ASP.NET Core 基础教程 - 简单教程,简单编程

    ASP.NET Core macOS 环境配置 - ASP.NET Core 基础教程 - 简单教程,简单编程 原文:ASP.NET Core macOS 环境配置 - ASP.NET Core 基础 ...

最新文章

  1. 如何生成符合高斯分布的数据集
  2. 初识组织社会学(part1)--勉为其难,不如顺其自然,在力所能及的层次上研究、解释问题
  3. 动态代理,动态代理设计模式 ,JDK动态代理,cglib动态代理
  4. Android之gravity=“center_vertical“和layout_gravity=“center“的效果
  5. 深度学习算法原理_用于对象检测的深度学习算法的基本原理
  6. python变量名称跟着循环_python在循环中存储每次迭代使用不同名称的输入变量
  7. 转:gcc编译C++程序
  8. android获取服务器时间格式,Android 获取服务器与客户端时差的实例代码
  9. Spring MVC使用@RestController生成JSON示例
  10. 7. 如何创建 CSS
  11. 【通信】基于matlab FDTD法研究移动通信终端电磁辐射对人体的影响【含Matlab源码 761期】
  12. 六年级上学期计算机上册教案,最新人教版六年级上册数学全册教案
  13. 锂电池及其安全使用浅析《原创》
  14. CentOS 8.3.2011 镜像在PC上安装选择安装源时提示:设置基础软件仓库时出错
  15. 四月之 诗四首和五十六句话
  16. 日光能和电池两用计算机,为什么太阳照射的光可以给太阳能转化为电,而我们的日光灯却不行?...
  17. delphi清除ie缓存的方法
  18. 万向和肖风的区块链版图
  19. HTML-img图片详解
  20. 易语言 计算机取用户名,易语言GetUserNameA获取系统当前用户名

热门文章

  1. 海康威视摄像头自带网页自动登录
  2. oracle有orcl用户吗,oracle 怎么导出和导入整个orcl数据库,包含用户和授权
  3. 转发(forword)与重定向(redirect)的区别
  4. CSS选择器详解(前端系列1)
  5. 微软将用Midori结束Windows时代(摘)
  6. 什么是SFC的IEC动作(codesys)
  7. 浪子回头之邱关源第五版P76_3_10回路电流法multisim方正及matlab解法
  8. vba ado mysql_Excel VBA 自定义类(ADO)连接数据库
  9. SpringBoot 全局异常拦截器
  10. XP和Win 7双系统安装说明和注意事项