Makefile追加变量后依赖变量未重新评估问题
问题原因
Make的变量处理分为读取阶段和执行阶段:初始的SOURCES和OBJECTS在Make读取Makefile时就已计算完成,newlib目标中的$(eval)是在执行阶段才修改SOURCES,但此时$(BINARY)的依赖OBJECTS已经是旧值,不会重新计算,因此不会触发newlib.c的编译与链接。
解决方法
使用目标特定变量为bm目标单独配置包含newlib.c的源文件集合,同时修正目标文件生成规则,确保.S汇编文件也能正确编译为.o目标文件。
修改后的Makefile
CC=aarch64-none-elf-gcc CFLAGS=-O3 -g -static LDFLAGS=-T gcc_ddr.ld -Wl,--wrap=main -static BINARY=hello_world .DEFAULT_GOAL=$(BINARY) SRC := . OBJ := . # 基础源文件集合:排除newlib.c,包含所有.c和.S文件 SOURCES_BASE := $(filter-out ./newlib.c, $(wildcard $(SRC)/*.c)) SOURCES_BASE += $(wildcard $(SRC)/*.S) # 为bm目标设置专属源文件:基础集合 + newlib.c bm: SOURCES := $(SOURCES_BASE) $(SRC)/newlib.c # 默认目标使用基础源文件集合 $(BINARY): SOURCES := $(SOURCES_BASE) # 生成目标文件列表:分别处理.c和.S文件 OBJECTS = $(patsubst $(SRC)/%.c, $(OBJ)/%.o, $(filter %.c,$(SOURCES))) \ $(patsubst $(SRC)/%.S, $(OBJ)/%.o, $(filter %.S,$(SOURCES))) $(BINARY): $(OBJECTS) $(CC) $(LDFLAGS) $^ -o $@ # .c文件编译规则 $(OBJ)/%.o: $(SRC)/%.c $(CC) $(CFLAGS) -I$(SRC) -c $< -o $@ # .S文件编译规则(显式声明,替代内置规则) $(OBJ)/%.o: $(SRC)/%.S $(CC) $(CFLAGS) -I$(SRC) -c $< -o $@ .PHONY: bm bm: $(BINARY) .PHONY: clean clean: rm -f *.o ${BINARY}
关键修改说明
- 拆分源文件集合:将默认源文件拆分为
SOURCES_BASE,默认排除newlib.c,确保普通构建不包含该文件。 - 目标特定变量:通过
bm: SOURCES := ...为bm目标单独配置源文件,自动添加newlib.c,触发对应的编译逻辑。 - 修正目标文件生成:分别处理
.c和.S文件,确保所有源文件都生成对应的.o目标文件,避免直接使用.S文件链接的不规范行为。 - 显式汇编规则:新增
.S文件的编译规则,替代Make内置规则,提升构建的稳定性和可维护性。
验证
执行make bm -n,会输出包含newlib.c编译和链接的命令,与预期结果一致。
内容的提问来源于stack exchange,提问作者jkang
相关产品推荐
相关产品推荐

