Makefile递归编译子目录失效问题求助
Makefile子目录编译异常原因分析
问题场景
目录结构
├── Makefile ├── prime_probe.c └── utils ├── Makefile ├── caches_info.c ├── caches_info.h ├── caches_util.c ├── caches_util.h ├── configure.h ├── list_struct.h ├── list_utils.c └── list_utils.h
主目录Makefile内容
THIS_DIR := $(dir $(abspath $(lastword $(MAKEFILE_LIST)))) OBJDIR = obj CFLAGS = -I./$(OBJDIR) -g -fPIC -std=gnu99 UTILS_DIR := utils OBJS_UTL = $(addprefix $(UTILS_DIR)/$(OBJDIR)/,$(notdir $(patsubst %.c,%.o,$(shell find $(UTILS_DIR)/*.c)))) SRCS_PRIME = \ prime_probe.c OBJS_PRIME = $(addprefix $(OBJDIR)/,$(patsubst %.c,%.o,$(SRCS_PRIME))) all: clean utils $(OBJS_PRIME) $(OBJDIR)/%.o: %.c | objdir $(CC) $(CFLAGS) -c $< -o $(OBJDIR)/$(notdir $@) utils: $(MAKE) -C $(UTILS_DIR) objdir: @mkdir -p $(OBJDIR) clean: rm -rf $(OBJDIR) $(MAKE) clean -C $(UTILS_DIR)/
子目录utils/Makefile内容
THIS_DIR := $(dir $(abspath $(lastword $(MAKEFILE_LIST)))) ################## # Build directory ################## OBJDIR = obj CFLAGS = -I./$(OBJDIR) -g -fPIC -std=gnu99 -static #################### # Files and folders #################### SRCS_PRIME = $(shell find ./*.c) OBJS_PRIME = $(addprefix $(OBJDIR)/,$(patsubst %.c,%.o,$(SRCS_PRIME))) ########## # Targets ########## all: $(OBJS_PRIME) $(OBJDIR)/%.o: %.c | objdir $(CC) $(CFLAGS) -c $< -g -o $@ objdir: @mkdir -p $(OBJDIR) clean: rm -rf $(OBJDIR)
执行输出
root@096b64b8fd50:/usr/local/src/gem5/programs/covert_channel# make rm -rf obj make clean -C utils/ make[1]: Entering directory '/usr/local/src/gem5/programs/covert_channel/utils' rm -rf obj make[1]: Leaving directory '/usr/local/src/gem5/programs/covert_channel/utils' cc -I./obj -g -fPIC -std=gnu99 -c prime_probe.c -o obj/prime_probe.o root@096b64b8fd50:/usr/local/src/gem5/programs/covert_channel# make utils make: 'utils' is up to date. root@096b64b8fd50:/usr/local/src/gem5/programs/covert_channel/utils# cd utils/ root@096b64b8fd50:/usr/local/src/gem5/programs/covert_channel/utils# make cc -I./obj -g -fPIC -std=gnu99 -static -c caches_info.c -g -o obj/./caches_info.o cc -I./obj -g -fPIC -std=gnu99 -static -c caches_util.c -g -o obj/./caches_util.o cc -I./obj -g -fPIC -std=gnu99 -static -c list_utils.c -g -o obj/./list_utils.o
核心原因
utils目标未标记为伪目标(.PHONY):主目录下存在同名的utils目录,Make会将utils目标与该目录文件关联。由于目录的修改时间被视为目标的时间戳,且utils目标无依赖项,Make判定该目标已处于最新状态,不会执行对应的$(MAKE) -C $(UTILS_DIR)命令。utils目标无实际依赖关联:主Makefile中虽定义了子目录的目标文件变量OBJS_UTL,但未将其设为utils目标的依赖。Make无法感知子目录需要生成的文件状态,自然不会触发编译动作。
修复方案
方案1:标记utils为伪目标
在主Makefile中添加.PHONY声明,让Make忽略同名目录,强制执行目标命令:
.PHONY: all utils clean objdir all: clean utils $(OBJS_PRIME) # 其余内容保持不变
方案2:让utils目标依赖子目录生成文件
将OBJS_UTL设为utils目标的依赖,让Make通过文件状态判断是否需要编译:
utils: $(OBJS_UTL) $(OBJS_UTL): $(MAKE) -C $(UTILS_DIR)
可选优化:修正子Makefile路径
子Makefile中生成的目标路径存在冗余的./,可简化规则:
$(OBJDIR)/%.o: %.c | objdir $(CC) $(CFLAGS) -c $< -g -o $@
内容的提问来源于stack exchange,提问作者Gerrie
相关产品推荐
相关产品推荐

