当前位置:首页 > 技术 > 正文内容

Makefile 实用技巧

访客 技术 2026年6月2日 1

1. 字符串替换函数: patsubst

$(patsubst PATTERN,REPLACEMENT,TEXT) 函数用于在 TEXT 中以空格分隔的单词里查找匹配 PATTERN 的部分,并将其替换为 REPLACEMENT,最后返回替换后的单词列表。

2. 自动化变量

  • $@: 指代规则中的目标文件。
  • $(@D): 指代目标文件的目录。
  • $(@F): 指代目标文件的基本名称(不含目录)。
  • $<: 指代第一个依赖文件。
  • $?: 指代所有比目标文件新的依赖文件列表,以空格分隔。
  • $^: 指代规则中所有依赖文件的列表,不含重复项,以空格分隔。
  • $+: 类似于 $^,也是所有依赖文件的集合,但会保留重复项。
  • $(%F): 当目标文件是静态库时,代表库的一个成员名。例如,目标是 libfoo.a(bar.o),则 $(%F)bar.o$@libfoo.a。如果目标不是静态库,则为空。

3. 特殊字符与命令

  • @: 在命令前加上 @,可以阻止 Makefile 在执行时打印该命令本身,只显示命令的输出。
  • -: 在命令前加上 -,可以忽略该命令执行失败的错误,继续执行后续命令。
  • $: 用于引用 Makefile 中定义的变量。
  • $$: 用于引用 Shell 变量。
  • include: 用于包含其他 Makefile 文件。

4. Shell 语句: set -e

在 Makefile 的 Shell 命令中,可以使用 set -e 来确保只要有任何一个命令执行失败,整个脚本就会立即终止。这有助于防止错误蔓延。需要注意的是,在 Makefile 中,set -e 的作用范围通常仅限于单行命令。可以通过分号将多个命令写在同一行,或者使用反斜杠 \ 进行行续写来扩展其管辖范围。

# 示例:
RUN_COMMANDS = \
    @echo "Starting process..." ; \
    set -e ; \
    ./script1.sh ; \
    ./script2.sh ; \
    @echo "Process finished."
    

5. 动态依赖生成

可以通过编译器选项(如 GCC 的 -MMD-MM)来自动生成源文件的依赖关系。然后,将这些依赖关系转换成 Makefile 的格式,并使用 -include 指令将它们包含进来。这样,当源文件发生变化时,只有受影响的文件及其依赖项会被重新编译,而不是全部重新编译。

CC = g++
CFLAGS = -Wall -O2 -std=c++11 -MMD -MP

SRC_DIR = src
OBJ_DIR = obj
BIN_DIR = bin

SRCS = $(wildcard $(SRC_DIR)/*.cpp)
OBJS = $(patsubst $(SRC_DIR)/%.cpp, $(OBJ_DIR)/%.o, $(SRCS))
DEPS = $(patsubst $(SRC_DIR)/%.cpp, $(OBJ_DIR)/%.d, $(SRCS))

TARGET = $(BIN_DIR)/my_program

all: $(TARGET)

$(TARGET): $(OBJS)
	@mkdir -p $(@D)
	$(CC) $^ -o $@ $(CFLAGS)

$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp
	@mkdir -p $(@D)
	$(CC) -c $< -o $@ $(CFLAGS)

# 自动包含依赖文件
-include $(DEPS)

clean:
	@rm -rf $(OBJ_DIR)
	@rm -rf $(BIN_DIR)
    

相关文章

Linux crontab 详解

1) crontab 是什么cron 是 Linux 的定时任务守护进程;crontab 是用来编辑/查看“按时间周期执行命令”的表(cron table)。常见两类:用户 crontab:每个用户一份(crontab -e 编辑)系统级 crontab / cron.d:可指定执行用户(/etc/crontab、/etc/cron.d/*)2) crontab 时间...

富文本里可以允许的 HTML 属性

一、所有标签默认允许的安全属性(极少)class        (可选)id           (通常建议禁用)title️ 注意:id 容易被滥用做锚点注入,很多系统直接禁用class 允许的话最好只允许固定前缀(如 editor-*)二、a 标签允许属性<a href="" t...

Mac 安装 Node.js 指南

方法一:通过官网安装包(最简单,适合初学者)如果你只是想快速安装并开始使用,这是最直接的方法。访问 Node.js 官网。页面会显示两个版本:LTS (Recommended For Most Users):长期支持版,最稳定。建议选这个。Current:最新特性版,包含最新功能但可能不够稳定。下载 .pkg 安装包并运行。按照安装向导点击“下一步”即可完成。方法二:使用 Homebrew 安装(...

Dom\HTML_NO_DEFAULT_NS 的副作用:自动加闭合标签

在使用Dom\HTMLDocument时,Dom\HTML_NO_DEFAULT_NS 将禁止在解析过程中设置元素的命名空间, 此设置是为了与DOMDocument向后兼容而存在的。当使用它时,已知的一个副作用就是:自动加闭合标签例如 </img> 为什么会这样?当你使用:Dom\HTML_NO_DEFAULT_NS文档会变成 无命名空间模式,此时内部更接近 XML...

Laravel 事件和监听器创建

在 Laravel 中,使用 Artisan 命令创建 Events(事件) 和 Listeners(监听器) 是非常高效的。你可以通过以下几种方式来实现:1. 手动创建单个 Event如果你只想创建一个事件类,可以使用 make:event 命令:Bashphp artisan make:event UserRegistered执行后,文件将生成在 app/Even...

自定义域名解析神器 dnsmasq

什么是 dnsmasq?dnsmasq 是一个轻量级、功能强大的网络服务工具,专为小型和中等规模网络设计。它是一个综合的网络基础设施解决方案[1]。dnsmasq 能做什么?功能说明应用场景DNS 转发与缓存将 DNS 查询转发到上游服务器(ISP、Google DNS 等),并在本地缓存结果加快 DNS 查询速度,减少外部 DNS 流量本地 DNS解析本地网络设备的主机名,无需编辑&n...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。