Makefile工作%.c,不起作用%.cpp

时间:2010-01-25 22:51:38

标签: c++ gnu-make

我有一组用于构建“大”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使用确实有效,它编译得很好。

我在这里疯了吗?

3 个答案:

答案 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!