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

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}

关键修改说明

  1. 拆分源文件集合:将默认源文件拆分为SOURCES_BASE,默认排除newlib.c,确保普通构建不包含该文件。
  2. 目标特定变量:通过bm: SOURCES := ...为bm目标单独配置源文件,自动添加newlib.c,触发对应的编译逻辑。
  3. 修正目标文件生成:分别处理.c和.S文件,确保所有源文件都生成对应的.o目标文件,避免直接使用.S文件链接的不规范行为。
  4. 显式汇编规则:新增.S文件的编译规则,替代Make内置规则,提升构建的稳定性和可维护性。

验证

执行make bm -n,会输出包含newlib.c编译和链接的命令,与预期结果一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 08:37:07