一般编译器都可以产生cpp文件和头文件之间的依赖关系,对于gcc可以使用如下的命令:
gcc -MM sourcefile.cpp
产生的结果可能如下:
sourcefile.o: sourcefile.cpp header1.h header2.h
利用这个功能,我们就可以编写一个可以自动更新依赖关系的makefile,具体如下:
文件AutoMakeCore:
# this file is the core of the automatically update of the
# dependent relation among the sources and headers.
# firstly, an imexplicit rule to build the object file from the cpp file
# secondly, by the help of '-MM' option of gcc, a dependent file will be
# generate to the object files' directory, which will be include by the makefile
# the implicit rule for the obj file
$(OBJECTS_DIR)/%.o:%.cpp
$(CXX) $(CXXFLAGS) $(INCPATH) $< -o $@
# automatically generate the dependencs relationship of the
# src files and header files
# 1.remove all dependence files first
# 2.generate the dependence file ,it's like '*.o:*.cpp *.h'(use gcc -MM option)
# 3.modify the dependence file,like '*.o *.d:*.cpp *.h'
$(DEPENDS):$(OBJECTS_DIR)/%.d:%.cpp
@mkdir -p $(OBJECTS_DIR);set -e; rm -f $@;/
$(CXX) -MM $(CXXFLAGS) $(INCPATH) $< | sed -e 's,/($*/)/.o,$(OBJECTS_DIR)//& $@,g'> $@
-include $(DEPENDS)
具体的Makefile
####### Compiler, tools and options
CXX = g++
CXXFLAGS = -c -pipe -Wall -w -DUNIX_PLATFORM -D_GCC_VER
INCPATH = -I. -I../johnlib/include -I../ -I../pccts/antlr -I../pccts/h
LINK = g++
AR = ar cqs
COPY = cp -f
COPY_FILE= $(COPY)
COPY_DIR = $(COPY) -r
DEL_FILE = rm -f
SYMLINK = ln -sf
DEL_DIR = rmdir
MOVE = mv -f
CHK_DIR_EXISTS= test -d
MKDIR = mkdir -p
AUTO_MAKE_CORE = ../AutoMakeCore
####### Output directory
OBJECTS_DIR = release
### build type
BUILD = $(MAKECMDGOALS)
ifeq ($(BUILD),)
BUILD = debug
endif
ifeq ($(BUILD),debug)
CXXFLAGS += -g
OBJECTS_DIR = debug
endif
ifeq ($(BUILD),release)
CXXFLAGS += -O2
OBJECTS_DIR = release
endif
####### Files
SOURCES = $(shell echo *.cpp)
OBJECTS = $(SOURCES:%.cpp=$(OBJECTS_DIR)/%.o)
DEPENDS = $(SOURCES:%.cpp=$(OBJECTS_DIR)/%.d)
TARGET = $(OBJECTS_DIR)/libcpp.a
####### Build rules
all: obj_dir Makefile $(TARGET)
obj_dir:
$(MKDIR) $(OBJECTS_DIR)
$(TARGET): Makefile $(AUTO_MAKE_CORE) $(DEPENDS) $(OBJECTS)
-$(DEL_FILE) $(TARGET)
$(AR) $(TARGET) $(OBJECTS)
clean:
-$(DEL_FILE) debug/*
-$(DEL_FILE) release/*
-$(DEL_FILE) *~ core *.core
####### Compile
include $(AUTO_MAKE_CORE)
#######
.PHONY: debug release clean
debug:all
release:all