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

Makefile:基于foreach参数为同一目标设置不同ptxas编译标志

解决Makefile中EWP_SC_SETTER仅获取最后一个值的问题

看来你碰到了Makefile里变量作用域和规则生成的典型坑——批量处理规则时,如果没处理好变量展开时机,很容易出现变量被最后一次赋值覆盖的情况。下面针对你的需求给出完整的解决方案:

核心思路

  1. 拆分测试用例:把传入的测试用例列表拆分为第一个需要-ewp编译的用例和剩余用-c编译的用例
  2. 分情况生成规则:为第一个用例单独编写带-ewp的ptxas编译规则,为剩余用例批量生成带-c的规则
  3. 关联依赖链:让最终的可执行文件依赖所有编译生成的目标文件,确保编译顺序正确

完整Makefile实现

# 定义ADD_PTXTEST_EWP函数,实现差异化编译规则
define ADD_PTXTEST_EWP
# 拆分参数:$1为可执行文件名,$2为测试用例列表
# 提取第一个需要-ewp编译的测试用例
EWP_TARGET := $(firstword $(2))
# 提取剩余需要-c编译的测试用例
C_TARGETS := $(wordlist 2,$(words $(2)),$(2))

# 为第一个测试用例生成-ewp编译规则
$(EWP_TARGET).o: $(EWP_TARGET).cu
	ptxas -ewp $< -o $@

# 为剩余测试用例批量生成-c编译规则(必须用eval让Makefile解析规则)
$(foreach test,$(C_TARGETS),$(eval \
$(test).o: $(test).cu
	ptxas -c $< -o $@
))

# 让最终可执行文件依赖所有编译出的.o文件
$(1): $(addsuffix .o,$(2))
	# 这里替换成你的链接命令,比如nvcc
	nvcc $^ -o $@
endef

# 调用示例:生成可执行文件div_sc,依赖三个测试用例
$(call ADD_PTXTEST_EWP, div_sc, div_sc div_sc1 div_sc2)

# 清理生成文件的规则
clean:
	rm -f div_sc *.o

关键细节解释

  • 拆分列表的技巧:用$(firstword)获取列表首元素,$(wordlist 2,$(words $(2)),$(2))截取从第2个到末尾的所有元素,精准区分两种编译需求
  • eval的必要性:foreach本身只是文本展开,必须搭配$(eval)才能让Makefile真正解析循环生成的规则。如果不用eval,循环输出的内容只会被当作普通文本,不会成为有效规则
  • 自动变量的使用:用$<(当前规则的依赖文件)和$@(当前规则的目标文件)避免硬编码,确保每个规则都能独立对应自己的源文件和目标文件,从根源上避免变量覆盖问题

为什么之前变量只取最后一个值?

大概率是你在循环中直接用了普通变量赋值(比如EWP_SC_SETTER = ...),而没有用eval生成独立规则。Makefile的变量是全局作用域,循环中每次赋值都会覆盖之前的内容,最终变量就只剩最后一次循环的结果。而用eval生成的每个规则都是独立的,各自使用自动变量,不会互相干扰。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 10:44:06