2009-12-30 55 views
6

我是新来的Makefile和g ++,我同时使用-MM标志项目文件的生成依赖的一个问题击中。我正在发布我正在使用的Makefile以供您考虑。请看一下。使用问题产生Makefile中的依赖-MM

OUTPUT_ROOT := output/ 
SOURCE_ROOT := source/ 

TITLE_NAME := TestProj 

SOURCES := \ 
MyFile.cpp \ 
stdAfx.cpp \ 
Main.cpp \ 

OUT_DIR := $(OUTPUT_ROOT) 

OUT_O_DIR := $(OUT_DIR) 

OBJS = $(SOURCES:%.cpp=$(OUT_O_DIR)%.o) 
DEPS = $(OBJS:%.o=%.d) 
DIRS = $(subst /,/,$(sort $(dir $(OBJS)))) 
SOURCE_TARGET = $(SOURCES:%.cpp=$(SOURCE_ROOT)%.cpp) 
OUTPUT_TARGET = $(OUT_DIR)$(TITLE_NAME) 

#--------------------------------------------------------------------- 
# executables 
#--------------------------------------------------------------------- 
MD := mkdir -p 
RM := rm 
CC := g++ 

#--------------------------------------------------------------------- 
# rules 
#--------------------------------------------------------------------- 
.PHONY: clean directories objects title 

all: directories objects title 

directories: 
@$(MD) $(DIRS) 

clean: 
$(RM) -rf $(OUT_DIR) 

$(OBJS): $(SOURCE_TARGET) 
@$(CC) -c $< -o [email protected] 

$(DEPS): $(SOURCE_TARGET) 
@$(CC) -c -MM $< > $(DEPS) 

-include $(DEPS) 

objects:$(OBJS) $(DEPS) 

title: $(OBJS) 
@$(CC) $< -o [email protected] 

我尝试了几个选项,sooo很多次。我搜索了解决方案,但找不到任何。

是使用“-MM”标志,以生成依赖正确的选择?如果不是,请给我建议正确的方法来生成依赖关系。我想自动生成依赖关系,因为我的项目会有很多文件。我认为这是比手动编写evey依赖关系更好的选择。

这是我收到提前

g++: stdAfx.d: No such file or directory 
g++: Main.d: No such file or directory 
make: *** No rule to make target `stdAfx.d', needed by `objects'. Stop. 

感谢错误。

+0

什么是“DEPS = $(OBJS:%。o =%。d)”应该是在做什么?为什么你有时使用':=',有时'='? – 2009-12-30 12:23:12

+0

它使用对象目录中对象的名称创建DEPS。我只是测试'='和':='选项,但不知道确切的差异b/w他们 – Jabez 2009-12-30 12:27:08

回答

8

它看起来像你想生成依赖文件(称为* .D,通过你的Makefile规则)为每个.cpp文件。这不是我对如何使用依赖关系文件的理解。

使用-M选项生成您的项目单一依赖文件,然后包括依赖文件。

DEPS = $(OUR_DIR)/make.dep 

$(DEPS): $(SOURCE_TARGET) 
    @$(CC) -M $(SOURCE_TARGET) > $(DEPS) 

include $(DEPS) 

编辑你的依赖文件也应该取决于你的头

$(DEPS): $(SOURCE_TARGET) $(HEADER_TARGET) 
    @$(CC) -M $(SOURCE_TARGET) > $(DEPS) 

其中HEADER_TARGET定义一样SOURCE_TARGET。这样,当头文件被改变时,依赖文件被重建。

+1

谢谢mcdave,这是一个非常好的技巧。我认为生成单个文件比生成很多...再次感谢您 – Jabez 2009-12-30 13:53:38

+1

只需指出'-MM'排除了系统头文件(或多或少),因为分配的文件比较少,所以可能会使编译速度更快1)检查2)构建依赖列表的过程。例如用一些stl include创建foo.cpp包含并运行'g ++ -M foo.cpp'来查看它吐出一个近100个依赖关系的列表,其中没有任何一个会发生变化,所有这些都将检查每个构建。 – 2010-05-10 08:40:30

+0

@Robert:感谢您的提示 - 我不知道这一点,并会更新我的makefiles,使它们更有效率! – mcdave 2010-05-10 12:16:14

3

对于初学者,你正在做一些异国情调的东西。你应该从简单开始,只使用你100%理解和信任的Makefile中的代码。即使在拥有数百个文件的大型项目中,您也不会花太多时间来维护Makefile。

与指派变量:=立即被展开 - 所有$(VAR)的值代入分配期间的变量的值。分配给=的变量在使用时展开,因此它们可以执行诸如引用尚未定义的变量之类的事情。

关于g的-MM标志++会生成一个生成文件依赖行,例如foo.o:foo.cc foo.hh,但我从未发现它有用。我有一个虚假的“依赖”目标,生成一个依赖文件。你用这些线依赖关系创建一堆* .d文件的想法可能会奏效,但最终你会得到很多这些文件。

你得到的错误是来自g ++,而不是来自make。这是因为当$(DEPS)是整个* .d文件列表时,它就像是单个文件一样。什么情况是这一行:

@$(CC) -c -MM $< > $(DEPS) 

被扩展为:

g++ -c -MM MyFile.cpp > MyFile.d stdAfx.d Main.cpp 

mcdave刚刚发布我用生成的依赖文件的代码。您可以切换到单一依赖文件风格,或者改变你-MM命令是:

@$(CC) -MM $< > [email protected] 

您可能还需要修复-include说法,因为我不认为它支持的文件到列表做包括。

+0

谢谢你,我现在使用单个文件,而不是许多多个文件。谢谢你告诉比较b/w'='和':=',这肯定帮助我很多。 – Jabez 2009-12-30 13:51:54