makefile使cpp文件依赖头文件

读代码时发现目前工程中的makefile文件中有一个问题或bug,.即cpp文件没有和该.cpp文件include的头文件建立依赖性。这个危害是,当头文件被修改后,受影响的.cpp文件对应的.o文件不会被重新创建。

 

而目前的代码中大量使用C++模板,模板的实现全部写在.h文件中.

我做了个实验,修改了单件模板的实现文件 SingletonHolder.h。虽然这个修改影响了大量include了SingletonHolder.h的.cpp文件,但它们对应的.o全被没有被重新编译。

 

解决方法是用g++编译器提供的 -MM 选项。这个选项会让g++在把.cpp依赖的头文件(除系统头文件)全部列出来。具体的使用方法可以查阅手册。思路是,把cpp文件和头文件的依赖性写入到.d文件,在主makefile文件中include所有的.d文件。

 

以tcpd工程为列,修改后的makefile如下(亦见附件),该makefile可以检查到.cpp依赖的头文件被修改,使得重新生成目标文件。

 

 

include ./makefile.def

SRCS = $(wildcard *.cpp)

OBJS = $(patsubst %.cpp,%.o,$(SRCS))

# 每个.cpp都对应一个.d文件,.d文件由g++ -MM生成,列出了.cpp依赖的头文件.

DEPENDENCIES = $(subst .cpp,.d,$(SRCS))

TARGET = tcpd

OK = \\e[1m\\e[32m OK \\e[m

FAILURE = \\e[1m\\e[31m FAILURE \\e[m

all:$(TARGET)

 

# 使包含.d文件,.d文件指定了.o文件依赖哪些头文件。

# 如果不是make clean 就include所有的.d文件。

ifneq "$(MAKECMDGOALS)" "clean"

  -include $(DEPENDENCIES)

endif

 

# 此函数生成.d文件,参考g++的 -MM -MF -MT选项

#$(call make-depend,source-file,object-file,depend-file)

define make-depend

  g++ -MM -MF $3 -MT $2 $(CXXFLAGS) $(CPPFLAGS) $(TARGET_ARCH) $1

endef

 

 

$(TARGET):$(OBJS)

              @echo -ne Linking $(TARGET) …

              @$(CXX) $(C_FLAGS)  $(INC) -fPIC -o $@ $^ $(LIB) && echo  -e $(OK) || echo -e $(FAILURE)

 

%.o:%.cpp

#如果.cpp文件被修改,就重新生成.d文件.

              $(call make-depend, $<,$@,$(subst .o,.d,$@))

              @echo -ne Compiling $<  …

              @$(CXX) $(C_FLAGS)  $(INC) -fPIC -c -o $@ $< && echo  -e $(OK) || echo -e $(FAILURE)

             

clean:

       @rm -f *.o

       @rm -f ./$(TARGET)

 

install:clean all

#     strip $(TARGET)