Makefile无修改仍全量重编译问题求助
问题分析与解决方案
你的Makefile每次执行rls或dbg都会全量编译的核心原因:
rls目标没有关联实际生成的输出文件,而是直接执行一串编译命令,Make无法追踪这些命令生成的nave.o、master等文件的状态,因此每次都会从头执行所有命令。- 当前编译逻辑重复编译
common_ipcs.c和utils.c,既浪费时间,也违背了Make的增量编译设计。
以下是修复后的Makefile,同时优化了编译流程:
# basic rules CC = gcc LDFLAGS = -lm COMMON_SRCS = common_ipcs.c utils.c COMMON_OBJS = $(COMMON_SRCS:.c=.o) TARGET = master # 拆分各可执行文件对应的源文件 EXEC_SRCS = nave.c porto.c meteo.c master.c EXECS = $(EXEC_SRCS:.c=) # directories DIRSRC = source DIRHDR = headers DIRDBG = debug DIRRLS = release # 给文件路径添加目录前缀 SRC_COMMON = $(addprefix $(DIRSRC)/, $(COMMON_SRCS)) OBJS_COMMON_RLS = $(addprefix $(DIRRLS)/, $(COMMON_OBJS)) OBJS_COMMON_DBG = $(addprefix $(DIRDBG)/, $(COMMON_OBJS)) SRC_EXEC = $(addprefix $(DIRSRC)/, $(EXEC_SRCS)) EXECS_RLS = $(addprefix $(DIRRLS)/, $(EXECS)) EXECS_DBG = $(addprefix $(DIRDBG)/, $(EXECS)) # compiling flags CFLAGS = -std=c89 -I$(DIRHDR) # 添加头文件搜索路径 DCFLAGS = $(CFLAGS) -g -O0 -pedantic -DDEBUG RCFLAGS = $(CFLAGS) -O2 -Wall -Wextra -DNDEBUG .PHONY: all prep rls dbg drun run clean all: clean prep rls prep: @mkdir -p $(DIRDBG) $(DIRRLS) # ------------------------------ # Release 编译规则 # ------------------------------ # 编译通用模块的目标文件(只编译不链接) $(DIRRLS)/%.o: $(DIRSRC)/%.c $(CC) $(RCFLAGS) -c $< -o $@ # 编译各可执行文件(nave/porto/meteo需要链接通用模块) $(DIRRLS)/nave: $(DIRRLS)/nave.o $(OBJS_COMMON_RLS) $(CC) $^ -o $@ $(LDFLAGS) $(DIRRLS)/porto: $(DIRRLS)/porto.o $(OBJS_COMMON_RLS) $(CC) $^ -o $@ $(LDFLAGS) $(DIRRLS)/meteo: $(DIRRLS)/meteo.o $(OBJS_COMMON_RLS) $(CC) $^ -o $@ $(LDFLAGS) # master的编译规则(若无需链接通用模块,可移除$(OBJS_COMMON_RLS)) $(DIRRLS)/$(TARGET): $(DIRRLS)/master.o $(OBJS_COMMON_RLS) $(CC) $^ -o $@ $(LDFLAGS) # rls目标依赖所有release目录下的可执行文件 rls: $(EXECS_RLS) # ------------------------------ # Debug 编译规则(参照Release逻辑) # ------------------------------ $(DIRDBG)/%.o: $(DIRSRC)/%.c $(CC) $(DCFLAGS) -c $< -o $@ $(DIRDBG)/nave: $(DIRDBG)/nave.o $(OBJS_COMMON_DBG) $(CC) $^ -o $@ $(LDFLAGS) $(DIRDBG)/porto: $(DIRDBG)/porto.o $(OBJS_COMMON_DBG) $(CC) $^ -o $@ $(LDFLAGS) $(DIRDBG)/meteo: $(DIRDBG)/meteo.o $(OBJS_COMMON_DBG) $(CC) $^ -o $@ $(LDFLAGS) $(DIRDBG)/$(TARGET): $(DIRDBG)/master.o $(OBJS_COMMON_DBG) $(CC) $^ -o $@ $(LDFLAGS) dbg: $(EXECS_DBG) # 清理规则 clean: rm -rf $(DIRDBG) $(DIRRLS)
关键修改说明
- 拆分编译与链接步骤:用
-c参数先将每个.c文件编译成.o目标文件,再链接成可执行文件。这样单个源文件修改时,只需要重新编译对应的.o,无需全量编译。 - 关联实际输出文件:让
rls/dbg目标依赖最终生成的可执行文件,Make会自动检查源文件与输出文件的时间戳,仅重新编译更新过的部分。 - 复用通用模块:将
common_ipcs.c和utils.c单独编译成目标文件,避免重复编译,提升效率。 - 添加头文件路径:通过
-I$(DIRHDR)让gcc能正确找到headers目录下的头文件。
内容的提问来源于stack exchange,提问作者rith
相关产品推荐
相关产品推荐

