【问题标题】:Clean way to write a Makefile to perform an out of source build编写 Makefile 以执行源外构建的简洁方法
【发布时间】:2019-11-11 08:57:41
【问题描述】:

使用带有项目文件夹的文件夹结构的简单场景,在这个根目录中有一个构建和一个源文件夹:

project
- build
- sources

在源文件夹中有 hello.cpp:

#include <iostream>

using namespace std;

int main() {
  cout << "Hello world!\n";
}

还有一个 Makefile:

SOURCE_DIRECTORIES = ../ch1

vpath %.cpp $(SOURCE_DIRECTORIES)

hello: hello.cpp
    g++ ${SOURCE_DIRECTORIES}/hello.cpp -o hello

我从构建文件夹这样运行:

make -f ../sources/Makefile

上述方法有效,但 vpath 不是那么有用。即使使用 vpath,我也必须在命令行中添加 SOURCE_DIRECTORIES 路径。我还不如不使用 vpath,只在需要的地方使用 $(SOURCE_DIRECTORIES)。

这也有点脆弱,因为构建文件夹必须与源文件夹处于同一级别。但我可以忍受。

这是最好的方法吗?我在想一定有更好的方法来做到这一点。

【问题讨论】:

标签: c++ makefile build


【解决方案1】:

您不需要使用vpath,这是一种将makefile 放在源目录中并让它在相关构建目录中使用BUILD 变量的方法:

-include makefile.in # optionally read in config file

BUILD ?= build # or some other default...

$(BUILD)/hello: $(BUILD)/hello.o
    $(CXX) -o $@ $<

$(BUILD)/%.o: %.cpp
    $(CXX) $(CXXFLAGS) $(CPPFLAGS) -o $@ -c $<

这样,默认是在 src/build 中输出所有内容(因此,没有真正的 out-of-source-build),但您可以简单地使用 makefile.in“配置”文件更改该行为,这可以简单地是

BUILD = ../build

这在makefile 中就足够了,BUILD ?= 确保变量仅在尚未定义的情况下设置到右侧。

【讨论】:

  • 我在运行它时遇到问题。我在源文件夹中创建了 makefile.in。尝试从构建文件夹运行,然后得到 makefile.in: no such file or directory
  • 我明白了...这是从源目录调用的设置。那样有用吗?还要注意include前面的-对于使makefile.in的存在是可选的。
  • 它在源文件夹中工作 - 很好。但是,没有 makefile.in 获取 make: *** 没有规则来制作目标 '%.cpp','build' 需要。停止。
  • 问题是默认构建目录不存在。如果没有找到makefile.in,则BUILD 被初始化为build,因此makefile 假定源目录中有一个名为build 的现有目录。如果您创建了那个,它应该可以工作。您还可以将默认的BUILD 更改为BUILD ?= ../build
  • 嗯...你在使用 GNU make 吗?也许这个 makefile 中的某些内容是特定于make 的 GNU 实现的?!
猜你喜欢
  • 1970-01-01
  • 2011-07-16
  • 1970-01-01
  • 2010-12-06
  • 2014-10-02
  • 2014-01-26
相关资源
最近更新 更多