Makefile 可以工作 %.c,不能工作 %.cpp

发布于 2024-08-18 23:46:47 字数 1106 浏览 8 评论 0原文

我有一组 makefile,用于构建“大”C 项目。我现在正尝试在我的 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 用法确实有效,它编译得很好。

我在这里要疯了吗?

I have a set of makefiles I use to build a 'big' C project. I am now trying to reuse some in my C++ project and have run into this headache that I just cannot figure out.

The makefile looks like this

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 
lt;

Its a little complicated but what it does in C is build all the %.c files defined in SOURCES and put the object files in BUILD_DIR. It works great in c, but this does not work with cpp files. I get

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

Its like VPATH is not working at all. I tried

vpath %.cpp src/elements

but that does not work either.

Amazingly enough, renaming blue.cpp to blue.c and editing the makefile back to the %.c usage does work, it compiles just fine.

Am I going crazy here?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

┼── 2024-08-25 23:46:47

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

尝试

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

并在规则部分中指定目标,在适当的情况下使用 $(basename ..)

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

从文档中,

编译C程序
no 是使用 $(CC) -c 形式的命令从 nc 自动生成的
$(CPPFLAGS) $(CFLAGS)'。编译C++
节目
no 是通过 n.cc、n.cpp 或 nC 自动生成的,命令为
形式
$(CXX) -c $(CPPFLAGS)
$(CXXFLAGS)'。我们鼓励您使用
C++ 源文件的后缀 .cc'
而不是
.C'。

有一个默认的 C++ 规则,但由于另一个规则或错误的变量,它可能不会为您发挥作用。为了确定起见,最好明确地编写规则。

您需要一个规则,例如:

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

对于从源代码编译对象文件,那么您有:

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

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

From your example, it looks like you don't have a Makefile rule being activated for compiling the C++ files. Maybe your % are expanding incorrectly?

Try

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

And specify the destination in the rule part, using $(basename ..) where appropriate.

It works for C for blue.c because Make has a built-in default rule for compiling C files. I suspect running Make with the --no-builtin-rules option would cause the blue.c file to stop working too.

From the docs,

Compiling C programs
n.o is made automatically from n.c with a command of the form $(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)'. We encourage you to use
the suffix .cc' for C++ source files
instead of
.C'.

There is a default C++ rule, but it might not be kicking in for you because of another rule or bad variables. It is better to write the rule explicitly to be sure.

You need a rule such as:

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

For compiling your object files from source, then you have:

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

Where the objects of some format %.o trigger the dependency. Or use Autotools/Autoconf to build your Makefile for you. Here is an example I wrote that just builds C++ files into a directory of objects:

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

Not a complete example by any means, but you get the idea. In the final rule, you copy the object files, but you can do whatever here or change the -o option to plonk build files in a specific location.

舞袖。长 2024-08-25 23:46:47

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

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

.

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

vpath %.cpp foo:bar

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

Do you really need VPATH - I've had nothing but trouble with it in the past. And in fact, I seem to remember that VPATH is dependent on extensions, so that would fit Aiden's theory. In my makefiles, I give the source directory SDIR explicitly:

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

.

Edit: If you are wedded to the use of VPATH, then you need to investigate the use of the vpath directive (note case difference). For example:

vpath %.cpp foo:bar

looks for .cpp fies in foo and bar directories. But as I said, I've had nothing but trouble using this.

黯然#的苍凉 2024-08-25 23:46:47

好吧,伙计们,我在这里弄清楚了,这是一个大混乱的错误。

经过更多实验后,我在 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,哦!

Ok guys I figured it out here and its a big mess of a bug.

After some more experimentation I went to post a bug on the make-bugs list and turned on debug output to tell them exactly what was going on. Turns out I should have done this before because it led me right to the solution.

I use an automatic dependency generation scheme developed from http://mad-scientist.net/make/autodep.html and amazingly enough that was breaking make. Trouble occurred in with this line

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

I did not change that to %.cpp and for some reason trying to include blue.cpp caused make to not search for it using vpath when it tried to resolve

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

So the solution was just to port the makefile correctly, doh!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文