使用-MM在Makefile中生成依赖项时出现问题

时间:2009-12-30 12:18:55

标签: makefile

我是Makefiles和g ++的新手,我在使用-MM标志生成项目文件的依赖项时遇到了问题。我正在发布我正在使用的Makefile供你考虑。请看一下。

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

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

-include $(DEPS)

objects:$(OBJS) $(DEPS)

title: $(OBJS)
 @$(CC) $< -o $@

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

使用“-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.

提前致谢。

2 个答案:

答案 0 :(得分:8)

看起来您正在尝试为每个.cpp文件生成一个依赖文件(通过makefile规则调用* .d)。这不是我对如何使用依赖文件的理解。

使用-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 :(得分:3)

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

使用:=分配的变量会立即展开 - 所有$(VAR)值在赋值期间都会替换为变量的值。分配有=的变量在使用时会被扩展,因此它们可以执行诸如引用尚未定义的变量之类的操作。

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

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

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

扩展为:

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

mcdave刚刚发布了我用来生成依赖文件的代码。您可以切换到单个依赖项文件样式,也可以将-MM命令更改为:

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

您可能还必须修复-include语句,因为我认为它不支持要包含的文件列表。