我有一组用于构建“大”C项目的makefile。我现在正试图在我的C ++项目中重用一些,并且遇到了我无法弄清楚的头痛。
makefile看起来像这样
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使用确实有效,它编译得很好。
我在这里疯了吗?
答案 0 :(得分:3)
从您的示例中,您似乎没有激活Makefile规则来编译C ++文件。也许您的%
扩展不正确?
尝试
$(OBJECTS): %.o: %.cpp
...
并在规则部分中指定目的地,并在适当的位置使用$(basename ..)
。
适用于blue.c
的C,因为Make有一个 built-in default rule 来编译C文件。我怀疑使用--no-builtin-rules
选项运行Make会导致blue.c
文件停止工作。
来自文档,
编译C程序 n.o是从n.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)”。我们鼓励您使用 后缀.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
选项更改为特定位置的plonk构建文件。
答案 1 :(得分: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 fies。但正如我所说的那样,除了使用它之外我什么都没有。
答案 2 :(得分: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!