Makefile:基于foreach参数为同一目标设置不同ptxas编译标志
解决Makefile中
EWP_SC_SETTER仅获取最后一个值的问题 看来你碰到了Makefile里变量作用域和规则生成的典型坑——批量处理规则时,如果没处理好变量展开时机,很容易出现变量被最后一次赋值覆盖的情况。下面针对你的需求给出完整的解决方案:
核心思路
- 拆分测试用例:把传入的测试用例列表拆分为第一个需要
-ewp编译的用例和剩余用-c编译的用例 - 分情况生成规则:为第一个用例单独编写带
-ewp的ptxas编译规则,为剩余用例批量生成带-c的规则 - 关联依赖链:让最终的可执行文件依赖所有编译生成的目标文件,确保编译顺序正确
完整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
相关产品推荐
相关产品推荐

