2012-09-05 191 views
0

我过去一直在使用qmakeCMake而没有任何问题来生成我的makefile。然而,最近我想到了一些运行我的代码的集群,这些工具很难找到/安装,所以我决定编写裸机Makefile。除此之外,我还可以学习一些关于Makefiles的东西;)GNU Makefile自动依赖关系解析

我的项目涉及到几个带有源文件/头文件的目录,并且通常在它们之间交叉依赖。我通过SO了解到,使用-MM标志来自动生成依赖信息。我的Makefile文件看起来像这样

include $(HEAD_DIR)/common.mk 

OBJS_DIR = objs 
LIBS_DIR = libs 

SRCS = Matrix.cpp MatrixFull.cpp 
OBJS = $(patsubst %,$(OBJS_DIR)/%,$(SRCS:.cpp=.o)) 
LIB_0 = $(patsubst %, $(LIBS_DIR)/%,libalgebra.a) 

DEPS := $(patsubst %,$(OBJS_DIR)/%,$(SRCS:.cpp=.d)) 
-include $(DEPS) 

.PHONY: all 
all:  
    @echo " ===== Building dependencies in lib/algebra ===== " 
    @$(MKDIR) $(OBJS_DIR) 
    @$(MAKE) $(OBJS) 
    @$(MKDIR) $(LIBS_DIR) 
    @$(MAKE) $(LIB_0) 
    @echo " ===================== done ===================== " 

$(OBJS_DIR)/%.o: %.cpp 
    @echo " compiling source file: $< ..." 
    $(CXX) -c $(CXXFLAGS) -I$(INCLUDE_PATH) -MM $< -o [email protected] 

$(LIB_0): $($(OBJS_DIR)/%.o) 
    @echo " generating library file: $(@F) ..." 
    @$(AR) $(AR_FLAGS) [email protected] $^ 

.PHONY: clean 
clean: 
    @$(RM) $(OBJS_DIR) $(LIBS_DIR) 

这通常工作得很好,但我想,以提高两件事: 1)当我改变一个头文件和我发出make,不知何故编译器不挑all和似乎默认为DEPS。这应该发生在这个makefile?我如何使all为默认规则? 2)如何使依赖性文件不可见?我试过DEPS := $(patsubst %,$(OBJS_DIR)/.%,$(SRCS:.cpp=.d))但是没有帮助 3)如果你认为这个Makefile可以用其他方式改进,是否有任何具体的建议可以给我?

编辑:说实话,我甚至不知道如何调用编译器来生成依赖关系:p ...我没有看到任何明确的规则。它是不是隐藏在DEPS := $(patsubst %,$(OBJS_DIR)/%,$(SRCS:.cpp=.d))

回答

1

1)将-include $(DEPS)向下移动到all规则的下方。第一个规则是默认规则(除非您故意设置一些特殊变量),所以如果includeall:以上的规则中取得,那将是默认规则。

2)我推测,通过“让它们隐形”,你的意思是你想要.foo.d而不是foo.d。您必须修改,使它们的规则:

$(OBJS_DIR)/%.o: %.cpp 
    @echo " compiling source file: $< ..." 
    $(CXX) -c $(CXXFLAGS) -I$(INCLUDE_PATH) -MM $< -o [email protected] 
    @mv $(OBJS_DIR)/$*.d $(OBJS_DIR)/.$*.d 

,然后是发现他们的变量:

DEPS := $(patsubst %.cpp,$(OBJS_DIR)/.%.d,$(SRCS)) 

3)我想摆脱递归调用($(MAKE) ...),但你应该确保其他一切正常工作。我很惊讶$(OBJS_DIR)/%.o规则不会在common.mk去。除此之外,它看起来不错。

4(?))$(OBJS_DIR)/%.o规则中的编译器命令使用-MM标志,因此编译器会生成依赖文件作为副作用。