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

Windows NMake中是否存在与GNU Make filter-out等效的功能?

在NMake中替代GNU Make的filter-out及相关问题解决方案

首先明确说:NMake并没有和GNU Make的filter-out完全等价的内置关键字,你遇到的报错正是因为NMake无法识别filter-out里的连字符(它把filter-out当成了一个非法的宏名称)。不过我们可以用NMake的原生语法实现相同的逻辑,同时也帮你解决+=和文件匹配的问题。

1. 实现filter-out的等价逻辑

GNU Make里的OBJS_TEST = $(filter-out $(EXE_OBJ), $(OBJS))作用是从OBJS列表中移除EXE_OBJ对应的项,在NMake里可以通过循环遍历+条件判断来实现:

# 先初始化空的OBJS_TEST
OBJS_TEST =
# 遍历OBJS中的每个对象
!FOR obj IN ($(OBJS))
!  # 跳过和EXE_OBJ相同的项
!  IF "$(obj)" != "$(EXE_OBJ)"
OBJS_TEST = $(OBJS_TEST) $(obj)
!  ENDIF
!ENDIF

这段代码会逐个检查OBJS里的元素,只把不等于EXE_OBJ的项添加到OBJS_TEST中,和filter-out的效果完全一致。

2. 修复+=与文件匹配问题

你提到+=在NMake中无法生效,其实NMake是支持+=语法的,问题可能出在你用的wildcard——NMake没有内置的wildcard宏,直接写$(wildcard tests/*.cpp)会被当作原始字符串保留,而不是展开成文件列表。

要实现GNU Make中wildcard的效果,我们可以用NMake的!DIR命令来获取文件列表:

# 先获取tests目录下的所有.cpp文件
!DIR /B tests\*.cpp > test_files.tmp
# 初始化CPP_TEST并导入文件列表
CPP_TEST =
!INCLUDE test_files.tmp
# 删除临时文件
!DEL test_files.tmp
# 现在可以正常用+=添加额外文件了
CPP_TEST += uiuc\catch\catchmain.cpp

如果不想生成临时文件,也可以用!FOR循环直接遍历文件:

CPP_TEST =
!FOR file IN (!DIR /B tests\*.cpp)
CPP_TEST = $(CPP_TEST) $(file)
!ENDIF
CPP_TEST += uiuc\catch\catchmain.cpp

3. 关于你遇到的语法错误

报错fatal error U1001: syntax error : illegal character '-' in macro的原因很直接:NMake的宏名称里不允许出现连字符-,它把filter-out当成了一个宏的名字,自然就报错了。替换成上面的循环逻辑后,这个错误就会消失。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 10:52:32