You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Makefile+Clang编译时,如何单规则同时遍历$(obj)与$(src)列表?

解决Makefile中同时遍历目标文件和源文件列表的问题

先指出你原代码里的两个问题:

  1. src_files = $(notdir ($src)) 多了一层括号,正确写法是 $(notdir $(src))
  2. 原规则 $(obj): $(src) 会让每个目标文件依赖所有源文件,编译时还把所有源文件传给clang,导致所有代码被打包到同一个.o文件里,完全不符合编译单个源文件生成对应目标文件的预期。

要实现每个目标文件对应单个源文件的编译,用静态模式规则是最直接的方案,既能遍历目标列表,又能精准匹配对应的源文件:

修正后的完整Makefile

# 自动获取src目录下所有.c文件
src = $(wildcard src/*.c)
# 直接把src路径转换为build目录下的.o文件,省去中间变量更简洁
obj = $(src:src/%.c=build/%.o)

.PHONY: all clean

all: $(obj)

# 静态模式规则:每个build/%.o对应src/%.c
$(obj): build/%.o : src/%.c
    # 确保build目录存在,避免第一次编译报错
    @mkdir -p build
    # $< 表示当前目标对应的源文件,$@ 表示当前目标文件
    clang $(clang_options) -c $< -o $@

clean:
    rm -rf build

关键说明

  • 静态模式规则 $(obj): build/%.o : src/%.c 会逐个匹配$(obj)里的每个目标(比如build/main.o),自动关联对应的源文件src/main.c
  • 自动变量$<展开为当前目标对应的单个源文件,$@展开为当前目标文件,完美实现目标与源文件的一一对应遍历
  • @mkdir -p build用于自动创建build目录,避免因目录不存在导致编译失败,@符号是让这条命令不在终端输出

如果不想用静态模式,也可以用普通模式规则,效果完全一致:

build/%.o: src/%.c
    @mkdir -p build
    clang $(clang_options) -c $< -o $@

内容的提问来源于stack exchange,提问作者WKali

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 08:23:55