GNU Makefile自动依赖解析

时间:2012-09-05 19:03:26

标签: c++ build makefile

过去我一直在使用qmakeCMake而没有任何问题来生成我的makefile。但是,最近我想到了一些集群,我运行我的代码,这些工具更难找到/安装所以我决定编写裸Makefiles。除此之外,我还可以学习一些关于Makefile的内容;)

我的项目涉及多个目录,其中包含源/头文件,并且最常见的是它们之间的依赖关系。我通过SO了解到使用-MM标志来自动生成依赖信息。我的Makefiles看起来像这样

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 $@

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

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

这通常很好但我想改进几件事情: 1)当我更改头文件并发出make时,编译器不会选择all并且似​​乎默认为DEPS。这应该发生在这个makefile中吗?如何使all成为默认规则? 2)如何使dependnency文件不可见?我试过DEPS := $(patsubst %,$(OBJS_DIR)/.%,$(SRCS:.cpp=.d)),但这没有帮助 3)如果您认为Makefile可以通过其他方式进行改进,是否有任何具体建议可以给我?

编辑:老实说,我甚至不确定make如何调用编译器来生成依赖项:p ...我没有看到任何明确的规则。它以某种方式隐藏在DEPS := $(patsubst %,$(OBJS_DIR)/%,$(SRCS:.cpp=.d))

1 个答案:

答案 0 :(得分:1)

1)将-include $(DEPS)向下移动到all规则下方。第一条规则是默认规则(除非您故意设置一些特殊变量),因此如果include引入规则all:以上,那将是默认规则。

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

$(OBJS_DIR)/%.o: %.cpp
    @echo " compiling source file:   $< ..."
    $(CXX) -c $(CXXFLAGS) -I$(INCLUDE_PATH) -MM $< -o $@
    @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标志,因此编译器会生成依赖文件作为副作用。