如何让Makefile目标c获取目标a、b的变量赋值并追加内容?
解决Makefile目标复用其他目标变量的问题
这个问题其实是因为没搞清楚Makefile里全局变量和目标特定变量的作用域差异,咱们一步步来解决:
最优方案:抽离独立的配置变量
最清晰、最易维护的方式是把每个目标的CFLAGS配置片段单独定义成变量,然后在各个目标中组合使用,完全符合你的需求:
# 先定义各个目标的专属CFLAGS片段 A_CFLAGS := -I/path/to/libA/include -DA_ENABLE # 对应目标a的libA头文件等配置 B_CFLAGS := -L/path/to/libB/lib -lb -DB_DEBUG # 对应目标b的相关配置 # 全局基础CFLAGS(可选,比如通用编译选项) CFLAGS := -Wall -O2 # 目标a:仅使用A的配置 a: CFLAGS += $(A_CFLAGS) a: a.o $(CC) $(CFLAGS) $^ -o $@ # 目标b:仅使用B的配置 b: CFLAGS += $(B_CFLAGS) b: b.o $(CC) $(CFLAGS) $^ -o $@ # 目标c:合并A、B的配置,再追加自己的内容 c: CFLAGS += $(A_CFLAGS) $(B_CFLAGS) -DC_OPTIMIZE c: c.o $(CC) $(CFLAGS) $^ -o $@
这样目标c的CFLAGS会是全局基础值 + A的配置 + B的配置 + 自己追加的值,完全满足你期望的“合并+追加”需求,而且各个目标的配置互不干扰,维护起来也方便。
备选方案:用eval动态传递变量(不推荐,仅作参考)
如果你坚持要从目标a和b中直接“获取”变量值(比如不想抽离单独变量),可以借助eval命令修改全局变量,但这种方式有副作用(会污染全局变量),需要谨慎使用:
.PHONY: a b c CFLAGS := # 初始化全局CFLAGS为空 # 目标a:通过eval修改全局CFLAGS a: $(eval CFLAGS += 1 2) # 目标b:通过eval修改全局CFLAGS b: $(eval CFLAGS += 3 4) # 目标c:依赖a和b,先执行它们的规则修改全局CFLAGS,再追加自己的值 c: a b $(eval CFLAGS += 5) @echo "最终CFLAGS: $(CFLAGS)" # 这里写你的编译命令,比如 $(CC) $(CFLAGS) -o c c.c
执行make c时,会先执行a和b的规则,把1 2和3 4加入全局CFLAGS,再追加5,最终得到类似1 2 3 4 5的结果。但要注意:如果之前单独执行过make a或make b,全局CFLAGS会被残留的值污染,所以最好每次执行前重置变量。
为什么你之前的尝试失败?
大概率是这两个原因之一:
- 误用目标特定变量:你可能给
a和b用了a: CFLAGS += ...这种写法,这是目标特定变量,它的作用域仅限于目标a及其依赖,不会自动传递给目标c,所以c的CFLAGS不会包含a和b的配置。 - 未触发目标执行:如果你用的是全局
CFLAGS += ...,但没有让c依赖a和b,那么执行make c时不会自动执行a和b的规则,全局CFLAGS也就不会被a和b修改。
内容的提问来源于stack exchange,提问作者Badiboy
相关产品推荐
相关产品推荐

