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

如何在Makefile中编写生成可执行文件的通用规则?

Makefile通用可执行编译模式问题排查与解决

问题背景

原Makefile包含重复的编译规则:

test_variance : test_variance.o
    $(CPP) -o test_variance.exe $(CFLAGS) test_variance.o $(LIBDIR) $(LIBS)

test_variance_incremental: test_variance_incremental.o 
    $(CPP) -o test_variance_incremental.exe $(CFLAGS) test_variance_incremental.o $(LIBDIR) $(LIBS)

test_hyper: test_hyper.o 
    $(CPP) -o test_hyper.exe $(CFLAGS) test_hyper.o $(LIBDIR) $(LIBS)

test_hyper.o: test_hyper.cpp
    $(CPP)  $(CFLAGS) $(INCLUDES) -c test_hyper.cpp

test_variance_incremental.o: test_variance_incremental.cpp
    $(CPP)  $(CFLAGS) $(INCLUDES) -c test_variance_incremental.cpp

test_variance.o : test_variance.cpp 
    $(CPP)  $(CFLAGS) $(INCLUDES) -c test_variance.cpp

已用模式规则简化目标文件编译:

%.o: %.cpp
    $(CPP)  $(CFLAGS) $(INCLUDES) -c $<

尝试用以下写法简化可执行文件编译,但Make提示“没有输入文件”:

TARGETS = test_variance test_variance_incremental test_hyper

$(TARGETS): $@.o
    $(CPP) -o $@.exe $^ $(CFLAGS) $(LIBDIR) $(LIBS)

错误原因

$@是自动变量,仅在规则的命令部分有效,不能用在依赖列表中。Make解析依赖时,$@还未被替换为具体目标名,导致依赖被识别为无效的$@.o,找不到对应的输入文件。

解决方法

方法1:使用静态模式规则

静态模式规则可以为一组目标指定统一的依赖和命令,适合你的场景:

TARGETS = test_variance test_variance_incremental test_hyper

$(TARGETS): %: %.o
    $(CPP) -o $@.exe $^ $(CFLAGS) $(LIBDIR) $(LIBS)
  • %是通配符,匹配TARGETS中的每个目标,自动关联对应的%.o依赖
  • 命令部分的$@会被替换为当前目标名,$^代表所有依赖(即对应的.o文件)

方法2:直接为可执行文件写模式规则(可选)

如果你的可执行文件命名规则是%.exe对应%.o,也可以直接写模式规则,无需单独定义TARGETS:

%.exe: %.o
    $(CPP) -o $@ $^ $(CFLAGS) $(LIBDIR) $(LIBS)

之后执行make test_variance.exe、make test_hyper.exe即可编译对应的可执行文件,或者搭配all: $(addsuffix .exe, $(TARGETS))实现批量编译。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 11:54:31