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

修改源文件后Makefile未触发重新构建问题排查

Fixing Incremental Builds with Mirroring src/obj Directories in Makefile

Hey there! Let's get to the bottom of why your incremental builds aren't working. The issue is almost certainly that your current rule isn't properly telling Make which source file each object file depends on—so when you modify a .c file, Make doesn't know it needs to rebuild the corresponding .o. Here's how to fix it while keeping your directory mirroring intact:

Step 1: Generate Source and Object File Lists First

First, capture all your source files and map them to their corresponding object files. This ensures we have a complete list of targets to build:

# Find all .c files under src/ (works for nested directories)
SRC_FILES := $(shell find src -type f -name "*.c")

# Convert each src/xxx.c path to obj/xxx.o (mirrors the directory structure)
OBJ_FILES := $(patsubst src/%.c, obj/%.o, $(SRC_FILES))

The key fix is using a pattern rule that explicitly connects each obj/%.o file to its src/%.c counterpart. This lets Make correctly track the dependency between the two files:

# Pattern rule: build obj/xxx.o from src/xxx.c (works for nested paths!)
obj/%.o: src/%.c
	# Create the target directory if it doesn't exist (mirrors src structure)
	@mkdir -p $(dir $@)
	# Compile the source file into the object file
	$(CC) $(CFLAGS) -c $< -o $@

Step 3: Set Up the Default Target

Add a default target to build all your object files:

all: $(OBJ_FILES)

Step 4: Keep Your Clean Target

Your existing clean target should still work to wipe the obj directory:

clean:
	rm -rf obj

Why This Works

  • The obj/%.o: src/%.c pattern rule uses Make's built-in wildcard matching (%) to handle nested directories automatically. For example, obj/utils/logger.o will match src/utils/logger.c perfectly.
  • $(dir $@) gets the directory part of the target object file (like obj/utils/), so mkdir -p creates any missing directories to mirror the src structure.
  • Make now directly tracks the modification time of each .c file against its .o file—so if you edit src/utils/logger.c, Make will only rebuild obj/utils/logger.o, not everything.

What Was Wrong Before?

If you were using subst in the dependency line (like %.o: $(subst obj,src,$@).c), Make can't properly resolve that dependency during its initial dependency scanning phase. Pattern rules with explicit path matching are far more reliable for this kind of directory mirroring scenario.

Give this setup a try—modify a source file and run make again, and it should rebuild only the corresponding object file.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 10:06:31