0

我有一组用于构建“大”C 项目的生成文件。我现在正试图在我的 C++ 项目中重用一些,并且遇到了我无法弄清楚的头痛问题。

生成文件看起来像这样

SOURCES = \
elements/blue.cpp

# Dont edit anything below here

VPATH = $(addprefix $(SOURCE_DIR)/, $(dir $(SOURCES)))

CXXFLAGS = $(OPT_FLAGS) -MMD -MF $(BUILD_DIR)/$*.d -D_LINUX -DNDEBUG -pipe
DCXXFLAGS = $(DEBUG_FLAGS) -MMD -MF $(BUILD_DIR)/$*.d -v -D_LINUX -D_DEBUG -pipe

OBJECTS := $(patsubst %.cpp, $(BUILD_DIR)/Release/%.o, $(notdir $(SOURCES)))
DOBJECTS := $(patsubst %.cpp, $(BUILD_DIR)/Debug/%.o, $(notdir $(SOURCES)))

$(OBJECTS): $(BUILD_DIR)/Release/%.o: %.cpp
    +@[ -d $(dir $@) ] || mkdir -p $(dir $@)
    $(CPP) $(INCLUDE) $(CXXFLAGS) $(DEFINES) -o $@ -c $<

它有点复杂,但它在 C 中所做的是构建 SOURCES 中定义的所有 %.c 文件并将目标文件放在 BUILD_DIR 中。它在 c 中工作得很好,但这不适用于 cpp 文件。我明白了

make: *** No rule to make target `blue.cpp', needed by `build/Release/blue.o'.  Stop.

它就像 VPATH 根本不工作。我试过

vpath %.cpp src/elements

但这也不起作用。

令人惊讶的是,将 blue.cpp 重命名为 blue.c 并将 makefile 编辑回 %.c 用法确实有效,它编译得很好。

我在这里疯了吗?

4

3 回答 3

3

从您的示例来看,您似乎没有激活 Makefile 规则来编译 C++ 文件。也许您%的扩展不正确?

尝试

$(OBJECTS): %.o: %.cpp
    ...

并在规则部分指定目的地,$(basename ..)在适当的地方使用。

它适用于 C for,blue.c因为 Make 具有用于编译 C 文件的内置默认规则。我怀疑使用该--no-builtin-rules选项运行 Make 也会导致blue.c文件停止工作。

从文档中,

$(CC) -c $(CPPFLAGS) $(CFLAGS)'. Compiling C++ programs n.o is made automatically from n.cc, n.cpp, or n.C with a command of the form使用$(CXX) -c $(CPPFLAGS) $(CXXFLAGS)'形式的命令从 nc 自动编译 C 程序 no 。我们鼓励您使用后缀.cc' for C++ source files instead of.C'。

一个默认的 C++ 规则,但由于另一个规则或错误的变量,它可能不会对您起作用。最好明确地写出规则来确定。

您需要一个规则,例如:

%.o: %.cpp
    $(CPP) $(CPP_OPTS) -c -o $@ $<

要从源代码编译目标文件,您有:

executable: $(OBJECTS)
    ... compile objects into final blob ...

某种格式的对象%.o触发依赖的地方。或者使用Autotools/Autoconf为你构建你的 Makefile。这是我编写的一个示例,它只是将 C++ 文件构建到对象目录中:

SOURCES=$(wildcard path/to/src/*.cpp)
OBJECTS=$(SOURCES: .cpp=.o)
CC=g++

final: $(OBJECTS)
    mv $(OBJECTS) /path/to/build_dir

%.o: %.cpp:
    g++ -c -o $@ $<

无论如何都不是一个完整的例子,但你明白了。在final规则中,您复制目标文件,但您可以在此处执行任何操作或更改-o选项以在特定位置构建文件。

于 2010-01-25T23:12:41.687 回答
3

你真的需要VPATH吗?过去我除了麻烦之外什么都没有。事实上,我似乎记得 VPATH 依赖于扩展,所以这符合 Aiden 的理论。在我的 makefile 中,我明确给出了源目录 SDIR:

SDIR = ./somewhere
... 
$(ODIR)/%.o: $(SDIR)/%.cpp 
    $(CC) -c $(INC) -o $@ $< $(CFLAGS) 

.

编辑:如果您热衷于使用 VPATH,那么您需要研究 vpath 指令的使用(注意大小写差异)。例如:

vpath %.cpp foo:bar

在 foo 和 bar 目录中查找 .cpp 文件。但正如我所说,我在使用它时遇到了麻烦。

于 2010-01-25T23:43:00.760 回答
0

好吧,伙计们,我在这里发现了它,这是一个很大的错误。

经过更多的实验后,我在 make-bugs 列表上发布了一个错误,并打开了调试输出以准确地告诉他们发生了什么。事实证明我之前应该这样做,因为它让我找到了解决方案。

我使用了一个从http://mad-scientist.net/make/autodep.html开发的自动依赖生成方案,令人惊讶的是,它打破了 make。这条线出现问题

-include $(patsubst %.c, $(BUILD_DIR)/%.d, $(notdir $(SOURCES)))

我没有将其更改为 %.cpp 并且由于某种原因试图包含 blue.cpp 导致 make 在尝试解析时无法使用 vpath 搜索它

$(OBJECTS): $(BUILD_DIR)/Release/%.o: %.cpp

所以解决方案就是正确移植makefile,doh!

于 2010-01-26T15:08:06.780 回答