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 使用了变量 CCCFLAGSTARGETSOURCES,并定义了一个 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 支持条件语句,可以根据条件来执行不同的规则或命令。通常使用 ifeqifdef 这两个条件语句。

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 入门教程的更多相关文章

  1. Makefile入门教程

    Makefile介绍 make是一个命令工具,它解释Makefile 中的指令(应该说是规则).在Makefile文件中描述了整个工程所有文件的编译顺序.编译规则.Makefile 有自己的书写格式. ...

  2. CMake快速入门教程-实战

    http://www.ibm.com/developerworks/cn/linux/l-cn-cmake/ http://blog.csdn.net/dbzhang800/article/detai ...

  3. 转:CMake快速入门教程-实战

    CMake快速入门教程:实战 收藏人:londonKu     2012-05-07 | 阅:10128  转:34    |   来源   |  分享               0. 前言一个多月 ...

  4. 转:asm.js 和 Emscripten 入门教程

    转:http://www.ruanyifeng.com/blog/2017/09/asmjs_emscripten.html asm.js 和 Emscripten 入门教程 作者: 阮一峰 日期:  ...

  5. CMake入门教程(转帖)

    本文转自:https://www.cnblogs.com/never--more/p/6921837.html CMake入门教程 参考文献:http://www.ibm.com/developerw ...

  6. Linux 新手入门教程

    Linux 新手入门教程 1991年10月5日,Linus Torvalds 在互联网上发布消息,宣布他自己开发的内核系统诞生了.他将内核源代码保存在芬兰最大的 FTP 网站上,命名为 Linux,取 ...

  7. 《Redis5.x入门教程》之准备工作、数据类型

    关注公众号:CoderBuff,回复"redis"获取<Redis5.x入门教程>完整版PDF. 第一章 · 准备工作 Redis安装 Redis5.0.7下载地址:h ...

  8. [深度学习] fast-reid入门教程

    fast-reid入门教程 ReID,全拼为Re-identification,目的是利用各种智能算法在图像数据库中找到与要搜索的目标相似的对象.ReID是图像检索的一个子任务,本质上是图像检索而不是 ...

  9. wepack+sass+vue 入门教程(三)

    十一.安装sass文件转换为css需要的相关依赖包 npm install --save-dev sass-loader style-loader css-loader loader的作用是辅助web ...

  10. wepack+sass+vue 入门教程(二)

    六.新建webpack配置文件 webpack.config.js 文件整体框架内容如下,后续会详细说明每个配置项的配置 webpack.config.js直接放在项目demo目录下 module.e ...

随机推荐

  1. 1.1 Metasploit 工具简介

    Metasploit 简称(MSF)是一款流行的开源渗透测试框架,由Rapid7公司开发,可以帮助安全和IT专业人士识别安全性问题,验证漏洞的缓解措施,并管理专家驱动的安全性进行评估,提供真正的安全风 ...

  2. node使用jsonwebtoken生成token与验证是否过期

    场景 我们可以使用 cookie,session,token 来做鉴权. 下面我们来看一下, 如何使用 token 来做鉴权 jwt.sign 的简单介绍 npm install jsonwebtok ...

  3. Github入门教程(新版)

    GitHub 的介绍与使用 GitHub 注册一个账号 直接在首页注册即可啦 要注意的是 第一项 username 别人是可见的 后面修改也会比较麻烦,所以起个好名字很重要 个人主页介绍 刚注册好的页 ...

  4. 基于AidLux的自动驾驶智能预警应用方案

    ### 1. 自动驾驶感知算法及AidLux相关方案介绍 #### 1.1自动驾驶 自动驾驶汽车,又称无人驾驶车.电脑驾驶车.无人车.自驾车,是一种需要驾驶员辅助驾驶或者完全不需要操控的车辆.作为自动 ...

  5. 查询mysql数据库目前有哪些链接 具体ip及数量

    SELECT substring_index(host, ':',1) AS host_name,state,count(*) FROM information_schema.processlist ...

  6. 活动干货|泛娱乐App出海东南亚深度解析

    泛娱乐社交出海,还有哪些机会点? 为助力出海企业把握增长红利,即构科技特开设<出海"构"有料--泛娱乐出海系列直播>,从热门国家的特性洞察.玩法解决方案到技术服务经验分 ...

  7. Tauri-Admin通用后台管理系统|tauri+vue3+pinia桌面端后台EXE

    基于tauri+vite4+pinia2跨端后台管理系统应用实例TauriAdmin. tauri-admin 基于最新跨端技术 Tauri Rust webview2 整合 Vite4 构建桌面端通 ...

  8. pe文件对齐

    PE中规定了三类对齐:数据在内存中的对齐. 数据在文件中的对齐.资源文件资源数据的对齐. 1.内存对齐 由于windows操作系统对内存属性的设置以也为单位,所以通常情况下,节在内存中的对齐单位必须至 ...

  9. .NET 如何实现ChatGPT的Stream传输

    .NET 如何实现ChatGPT的Stream传输 ChatGPT是如何实现不适用websocket进行一个一个字返回到前端的? 下面我们会介绍一下EventSource EventSource Ev ...

  10. Go命令

    build: 编译包和依赖 clean: 移除对象文件 doc: 显示包或者符号的文档 env: 打印go的环境信息 bug: 启动错误报告 fix: 运行go tool fix fmt: 运行gof ...