Makefile自动产生依赖文件(二)

昨天写的Makefile自动产生依赖文件(一)是我以前用的方法总结,但近期发现了GCC本来就有这个功能,只是我没发现罢了-_-!!!。

这还说着摆弄Eclipse CDT开发环境时,无意中发现Eclipse产生的Makefile异常简洁,其核心的src/subdir.mk文件如下:

CPP_SRCS += 
../src/HelloWorld.cpp 

OBJS += 
./src/HelloWorld.o 

CPP_DEPS += 
./src/HelloWorld.d 

src/%.o: ../src/%.cpp
    @echo 'Building file:
 
lt;' @echo 'Invoking: Cygwin C++ Compiler' g++ -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -o "$@" "
 
lt;" @echo 'Finished building:
 
lt;' @echo ' ' 

细看src/%.o: ../src/%.cpp的隐规则,发现多了几个参数”-MMD -MP -MF -MT”。”-MMD“我还认的,就是直接产生.d文件而不是输出到屏幕,其他就陌生了。遇到问题找Man啦,发现正好解决了我前一篇博客所说的两个问题,gcc果然不我欺也。

  • -MP: 解决重命名头文件导致的依赖破裂,跟上次的思路一样,生成了dummy目标。
  • -MF: 这个是指定输出的.d文件格式。
  • -MT: 这个解决了输出的目标文件不带路径问题,可以指定目标文件的格式。

现在可以抛弃之前的makedepend,一个Makefile文件搞定一切:)。


更新

今天发现头文件更新不起作用,看来一下.d文件如下:

xxx.d: xxx.h //这里应为xxx.o:xxx.h
xxx.h:

惊讶的发现竟然没有xxx.o的依赖,再仔细检查了gcc的依赖选项发现之前没仔细看-MT修改了依赖项变成了.d了。其实-MT不用加上,加上就修改了目标名,最后的命令是:

$(OBJS):%.o:%.c
    gcc -c $(CFLAGS) -MMD -MP -MF"$(@:%.o=%.d)" -o $@
 
lt; 

这里用到了makefile静态规则(要详细看那边《跟我一起学Makefile》),这样就保证文件名不会被gcc给截断造成依赖文件的目标名错误。

最后贴个标准的吧:

SRC_DIR= src others
CFLAGS+=-Wall -g 
CFLAGS+=$(addprefix -I, $(SRC_DIR))
CFILES=$(shell find $(SRC_DIR) -maxdepth 1 -name "*.c")
OBJS=$(CFILES:%.c=%.o)
LIBS+= 

all:$(TARGET)

-include $(addsuffix /*.d, $(SRC_DIR))

$(TARGET):$(OBJS)
    gcc $(LDFLAGS) $^ -o $@ $(LIBS)

$(OBJS):%.o:%.c
    gcc -c $(CFLAGS) -MMD -MP -MF"$(@:%.o=%.d)" -o $@
 
lt; clean: -rm -f $(addsuffix /*.d, $(SRC_DIR)) $(addsuffix /*.o, $(SRC_DIR)) $(TARGET) 

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注