Makefile目标内ifeq始终进入else分支问题求助
问题原因
你写的ifeq判断失效是因为Makefile的条件判断(如ifeq)是在解析Makefile的预处理阶段执行的,而自动变量$<只有在规则实际执行时才会被替换为具体的依赖文件路径。预处理阶段$<是空值,所以你的ifeq判断始终不成立,必然进入else分支。而你看到的$(info)输出是在规则执行阶段才打印的,此时$<已经有了正确值,所以会显示Core,但这时候ifeq的判断早就完成了。
解决方案
有两种可靠的实现方式:
方式一:拆分模式规则(推荐)
针对Core目录和非Core目录分别编写模式规则,Make会优先匹配更具体的模式:
# 处理Core目录下的所有C文件 $(BUILD_DIR)/%.o: Core/%.c Makefile | $(BUILD_DIR) $(info Hit if...) $(CC) -c $(C_CORE_FLAGS) -Wa,-a,-ad,-alms=$(BUILD_DIR)/$(notdir $<:.c=.lst) $< -o $@ # 处理非Core目录下的所有C文件 $(BUILD_DIR)/%.o: %.c Makefile | $(BUILD_DIR) $(info Hit else...) $(CC) -c $(CFLAGS) -Wa,-a,-ad,-alms=$(BUILD_DIR)/$(notdir $<:.c=.lst) $< -o $@
这种方式更符合Makefile的设计逻辑,可读性和维护性更好。
方式二:在shell命令中做条件判断
如果需要在同一个规则里处理,可以用shell的if语句(注意语法细节,用反斜杠换行,分号分隔命令):
$(BUILD_DIR)/%.o: %.c Makefile | $(BUILD_DIR) @if echo "$<" | grep -q "^Core/"; then \ echo "Hit if..."; \ $(CC) -c $(C_CORE_FLAGS) -Wa,-a,-ad,-alms=$(BUILD_DIR)/$(notdir $<:.c=.lst) $< -o $@; \ else \ echo "$(dir $<)"; \ echo "$(strip $(firstword $(findstring Core,$(dir $<))))"; \ echo "Hit else..."; \ $(CC) -c $(CFLAGS) -Wa,-a,-ad,-alms=$(BUILD_DIR)/$(notdir $<:.c=.lst) $< -o $@; \ fi
这里@用来抑制shell命令本身的输出(如果不需要可以去掉),grep -q "^Core/"用来检查文件路径是否以Core/开头,匹配成功则执行Core对应的编译命令。
补充说明
你之前尝试用bash的if语句没输出,大概率是语法错误:比如没有用反斜杠换行、缺少分号分隔shell命令,或者没有正确处理Make的变量转义。上面的shell版本已经修正了这些问题,可以直接使用。
内容的提问来源于stack exchange,提问作者cvanbeek
相关产品推荐
相关产品推荐

