定义Make规则修改变量引发链接错误,求问题原因及解决
问题分析与解决
核心错误点
依赖被误识别为链接文件
你把ld_prel_def作为main_ld的依赖项,Make会默认它是一个需要参与链接的目标文件,所以链接器会尝试查找名为ld_prel_def的文件,自然找不到,触发报错。变量设置时机滞后
就算解决依赖问题,$(eval)是在执行ld_prel_def规则时才修改LD_PREL,但此时$(OBJ)对应的.o文件已经编译完成(如果之前执行过make),Make不会重新编译这些.o文件,所以-DWITH_LD_PRELOAD根本不会被应用到编译过程中。
修正方案
方案1:伪目标+强制重新编译
把ld_prel_def声明为伪目标,同时强制让.o文件重新编译,确保变量修改后能覆盖旧的编译结果:
LD_PREL:= .PHONY: all main main_ld ld_prel_def clean all: main main: $(OBJ) $(COMP) $(DEBUG) $(FLAGS) $^ -shared -o libname.so $(LIBS) main_ld: ld_prel_def $(OBJ) $(COMP) $(DEBUG) $(FLAGS) $^ -shared -o libname_ld.so $(LIBS) ld_prel_def: $(eval LD_PREL:=-DWITH_LD_PRELOAD) # 强制触发所有.o文件的重新编译 $(foreach obj,$(OBJ),touch $(obj)) $(OBJDIR)/%.o: src/%.c $(DEPS) $(COMP) $(DEBUG) $(FLAGS) $(DDEFS) $(TDEFS) $(LD_PREL) $(WARN) -c -fPIC -o $@ $< clean: rm -f $(OBJDIR)/*.o libname.so libname_ld.so
方案2:目标特定变量(更简洁)
利用Make的目标特定变量特性,直接为main_ld绑定专属的LD_PREL值,同时通过伪目标强制重新编译:
LD_PREL:= .PHONY: all main main_ld clean .FORCE all: main main: $(OBJ) $(COMP) $(DEBUG) $(FLAGS) $^ -shared -o libname.so $(LIBS) # 为main_ld目标设置专属变量 main_ld: LD_PREL:=-DWITH_LD_PRELOAD main_ld: $(OBJ) $(COMP) $(DEBUG) $(FLAGS) $^ -shared -o libname_ld.so $(LIBS) # 执行main_ld时,强制重新编译所有.o文件 $(OBJDIR)/%.o: src/%.c $(DEPS) | $(if $(filter main_ld,$(MAKECMDGOALS)),.FORCE) $(COMP) $(DEBUG) $(FLAGS) $(DDEFS) $(TDEFS) $(LD_PREL) $(WARN) -c -fPIC -o $@ $< .FORCE: clean: rm -f $(OBJDIR)/*.o libname.so libname_ld.so
方案3:命令行传参(最直接)
如果只是临时启用条件编译,无需修改Makefile,直接在命令行传递变量:
make LD_PREL=-DWITH_LD_PRELOAD main_ld
内容的提问来源于stack exchange,提问作者mEm
相关产品推荐
相关产品推荐

