Makefile 入门教程
Makefile 是一个非常强大的构建自动化工具,用于管理项目的编译、链接和其他构建任务。以下是一个详细的 Makefile 使用文档,包括基本概念、语法、示例和常见任务。
1. 基本概念
- 目标 (Targets):在 Makefile 中,目标是要生成的文件或执行的操作的名称。目标可以是文件名,也可以是伪目标,用于执行特定任务而不生成文件。
- 依赖项 (Dependencies):依赖项是与目标相关联的文件或其他目标,它们在目标生成之前必须存在或已经生成。
- 规则 (Rules):规则定义了如何生成目标以及生成目标所需的命令。
- 命令 (Commands):命令是在生成目标时要执行的操作。命令必须以 Tab 键开头。
- 变量 (Variables):变量用于存储文本或命令,并可以在整个 Makefile 中重复使用。
- 伪目标 (Phony Targets):伪目标是不代表实际文件的目标,而是用于执行特定操作的标记。
2. Makefile 语法
一个基本的 Makefile 规则的语法如下:
target: dependencies
command
target:要生成的目标的名称。dependencies:生成目标所需的文件或其他目标的列表。command:生成目标的命令,必须以 Tab 键开头。
3. 示例 Makefile
以下是一个简单的示例 Makefile,用于编译一个 C 程序:
CC = gcc
CFLAGS = -Wall
TARGET = myprogram
SOURCES = main.c utils.c
$(TARGET): $(SOURCES)
$(CC) $(CFLAGS) -o $(TARGET) $(SOURCES)
clean:
rm -f $(TARGET)
这个 Makefile 使用了变量 CC、CFLAGS、TARGET 和 SOURCES,并定义了一个 all 目标用于编译程序,以及一个 clean 目标用于清理生成的文件。
4. 常见任务
4.1 编译项目
all: $(TARGET)
$(TARGET): $(SOURCES)
$(CC) $(CFLAGS) -o $(TARGET) $(SOURCES)
4.2 清理生成的文件
clean:
rm -f $(TARGET)
4.3 使用变量
CC = gcc
CFLAGS = -Wall
TARGET = myprogram
SOURCES = main.c utils.c
$(TARGET): $(SOURCES)
$(CC) $(CFLAGS) -o $(TARGET) $(SOURCES)
4.4 伪目标
.PHONY: clean
clean:
rm -f $(TARGET)
5. 高级用法
除了基本用法外,还支持一些高级用法,可以用来处理更复杂的构建需求。以下是一些高级用法的详细介绍:
5.1 条件语句和函数
条件语句
Makefile 支持条件语句,可以根据条件来执行不同的规则或命令。通常使用 ifeq 和 ifdef 这两个条件语句。
ifeq ($(VARIABLE), value)
# 条件为真时的规则和命令
else
# 条件为假时的规则和命令
endif
例如,可以根据是否定义了 DEBUG 变量来设置不同的编译选项:
ifeq ($(DEBUG), 1)
CFLAGS = -g
else
CFLAGS = -O2
endif
函数
Makefile 还提供了一些内置函数,用于处理文本和文件列表。以下是一些常见的函数:
$(shell command):执行 shell 命令并返回结果。$(wildcard pattern):匹配文件名模式并返回符合条件的文件列表。$(foreach var, list, text):对列表中的每个元素执行指定的操作。$(strip string):删除字符串开头和结尾的空白字符。$(subst find,replace,text):替换文本中的字符串。$(filter pattern, text):从文本中筛选出匹配指定模式的字符串。$(patsubst pattern,replacement,text):用指定字符串替换文本中的模式。$(notdir names):从文件路径中提取文件名。
这些函数可以在 Makefile 中用于各种目的,例如文件操作、文本处理和条件判断。
5.2 自动化依赖关系生成
通常,Makefile 中的依赖关系需要手动维护。但是,对于 C/C++ 项目,您可以使用编译器提供的 -M 选项来自动生成依赖关系。例如:
SOURCES = main.c utils.c
DEPS = $(SOURCES:.c=.d)
%.d: %.c
$(CC) -M $< -o $@
-include $(DEPS)
在这个示例中,%.d: %.c 规则用于自动生成 .d 文件,其中包含了 .c 文件的依赖关系。然后使用 -include 指令来包含这些 .d 文件,以自动跟踪依赖关系。
5.3 多目录项目
对于大型项目,通常需要将 Makefile 拆分成多个子目录,每个子目录都有自己的 Makefile。然后,可以使用递归或变量传递来管理这些子目录之间的依赖关系。例如:
SUBDIRS = dir1 dir2
all: $(SUBDIRS)
$(SUBDIRS):
$(MAKE) -C $@
clean:
for dir in $(SUBDIRS); do \
$(MAKE) -C $$dir clean; \
done
在这个示例中,SUBDIRS 变量包含了子目录的列表。$(MAKE) 是一个 Makefile 中的特殊变量,用于启动另一个 Makefile。
5.4 高级变量操作
Makefile 支持高级的变量操作,包括字符串操作、条件赋值、变量展开等。以下是一些示例:
字符串操作
STR1 = hello
STR2 = world
STR3 = $(STR1) $(STR2)
在这个示例中,STR3 的值将是 "hello world"。
条件赋值
FOO ?= default_value
如果 FOO 变量未定义,则将其赋值为 default_value。
变量展开
VAR1 = $(VAR2)
VAR2 = value
在这个示例中,VAR1 的值将是 value,因为 Make 会递归地展开变量。
声明:本作品采用署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)进行许可,使用时请注明出处。
Author: mengbin
blog: mengbin
Github: mengbin92
cnblogs: 恋水无意
Makefile 入门教程的更多相关文章
- Makefile入门教程
Makefile介绍 make是一个命令工具,它解释Makefile 中的指令(应该说是规则).在Makefile文件中描述了整个工程所有文件的编译顺序.编译规则.Makefile 有自己的书写格式. ...
- CMake快速入门教程-实战
http://www.ibm.com/developerworks/cn/linux/l-cn-cmake/ http://blog.csdn.net/dbzhang800/article/detai ...
- 转:CMake快速入门教程-实战
CMake快速入门教程:实战 收藏人:londonKu 2012-05-07 | 阅:10128 转:34 | 来源 | 分享 0. 前言一个多月 ...
- 转:asm.js 和 Emscripten 入门教程
转:http://www.ruanyifeng.com/blog/2017/09/asmjs_emscripten.html asm.js 和 Emscripten 入门教程 作者: 阮一峰 日期: ...
- CMake入门教程(转帖)
本文转自:https://www.cnblogs.com/never--more/p/6921837.html CMake入门教程 参考文献:http://www.ibm.com/developerw ...
- Linux 新手入门教程
Linux 新手入门教程 1991年10月5日,Linus Torvalds 在互联网上发布消息,宣布他自己开发的内核系统诞生了.他将内核源代码保存在芬兰最大的 FTP 网站上,命名为 Linux,取 ...
- 《Redis5.x入门教程》之准备工作、数据类型
关注公众号:CoderBuff,回复"redis"获取<Redis5.x入门教程>完整版PDF. 第一章 · 准备工作 Redis安装 Redis5.0.7下载地址:h ...
- [深度学习] fast-reid入门教程
fast-reid入门教程 ReID,全拼为Re-identification,目的是利用各种智能算法在图像数据库中找到与要搜索的目标相似的对象.ReID是图像检索的一个子任务,本质上是图像检索而不是 ...
- wepack+sass+vue 入门教程(三)
十一.安装sass文件转换为css需要的相关依赖包 npm install --save-dev sass-loader style-loader css-loader loader的作用是辅助web ...
- wepack+sass+vue 入门教程(二)
六.新建webpack配置文件 webpack.config.js 文件整体框架内容如下,后续会详细说明每个配置项的配置 webpack.config.js直接放在项目demo目录下 module.e ...
随机推荐
- ARC114F Permutation Division
题意 给定一个 \(1 \sim N\) 的排列,Alice 把它划分成 \(k\) 段,Bob 把这 \(k\) 段任意排列.Alice 想让字典序最小,Bob 想让字典序最大.请问最后的排列. 数 ...
- 【翻译】高效numpy指北
ref:link why numpy 运算高效 numpy 内存结构 一块内存区域 dtype 确定了内存区域数据类型 metadata 比如 shape.strides etc 注:numpy 内存 ...
- Java 使用ArrayList获取10个1-20之间的随机数,要求不能重复
代码如下: public static void main(String[] args) { List<Integer> nums = new ArrayList<Integer&g ...
- 踏入数字天地之中 | Metaworld SDK 2.0进化纵览
ZEGO从未停止对技术边界的探索,我们力图让用户能够更高效.便捷地使用技术去创造价值. 去年8月,ZEGO打造的元宇宙智能互动引擎首次与大家见面,Metaworld SDK作为其中的核心能力组件, ...
- Blazor前后端框架Known-V1.2.5
V1.2.5 Known是基于C#和Blazor开发的前后端分离快速开发框架,开箱即用,跨平台,一处代码,多处运行. Gitee: https://gitee.com/known/Known Gith ...
- Linux 命令:gpasswd 管理用户组
工作中经常需要将用户加入docker组,可执行如下操作: sudo gpasswd -a ec2-user docker newgrp # 不用加sudo gpasswd gpasswd -h Usa ...
- 如何在Avalonia11中设置自定义字体
如何在Avalonia11中设置自定义字体 由于avalonia默认的中文字体显示的效果不太理想,我们需要下载一些自定义的字体,来优化UI的显示效果.avalonia的官方文档地址. 对我在项目中运用 ...
- upload-libs通关攻略
pass01 第一关是一个前端验证,只要把Javascript禁止再上传就可以绕过了. 上传成功,到上传的地址查看结果如下: pass-02 这是一个MIME绕过,用bp抓包后修改文件类型即可将下面这 ...
- 解决AccessDatabaseEngine.exe 32位64位安装失败问题
cmd下执行 你的路径\AccessDatabaseEngine.exe /quiet 转载于:https://www.cnblogs.com/64mb/p/10844676.html
- nuitka 将程序编译为单个exe
原文链接:https://github.com/Nuitka/Nuitka 在Windows上,有两种模式,一种是将其复制到您公司指定的AppData,也将其用作缓存,另一种是在临时目录中进行.您需要 ...