【问题标题】:placing object files in different directories in nonrecursive build在非递归构建中将目标文件放在不同的目录中
【发布时间】:2017-09-18 10:13:45
【问题描述】:

背景

我们为 Matlab 和 Octave 构建 .mex 文件。源代码对 Matlab 和 Octave 都是通用的,但在这里和那里稍作修改(通过代码中的宏条件处理)。供参考,源码结构为:

                      mex/
                       |
              ------------------------------
              |                            |
           sources/                      build/
              |                            |
        -----------            -------------------------------
        |         |            |          |        |         |
       mex1/ ... mexN/       octave/  mex1.am ... mexN.am  matlab/
        |                      |                             |
    -----------           -------------                -------------
    |         |           |           |                |           |
file1.cc ... fileM.cc  configure.ac  Makefile.am   configure.ac  Makefile.am

.mex 源文件位于mex/sources/mex*/,我们编译多个.mex 文件。

Matlab 构建系统位于 mex/build/matlab/,我们在其中运行“./configure”来定位编译 Matlab .mex 文件所需链接的头文件/库。 /mex/build/octave/ 中存在类似的 configure.acMakefile.am 文件,已修改以查找 Octave 头文件和库。

Matlab 和 Octave 共有的 automake 构建指令(源文件的路径,要构建的 .mex 文件)存在于名为 /mex/build/mex*.am 的文件中,通常如下所示:

mexI_PROGRAMS += mexI

nodist_mexI_SOURCES = \
    ../../sources/mexI/mexI.c \
    ../../sources/mexI/mexI_file1.c \
    ../../sources/mexI/mexI_fileN.c

递归 make 非常适合我们的设置(我们曾经有名为 /mex/build/matlab/mex*//mex/build/octave/mex*/ 的目录,其中包含 Makefile.am 文件;目标文件将在那里编译,输出文件将位于那里)。现在,鉴于 GNU subdir-objects 发生的变化,我们正在转向非递归构建。从 Matlab 构建开始,我能够将其修改为以非递归方式工作而没有任何问题。

问题

在转向非递归构建时,目标文件现在与其源文件在同一目录中生成,/mex/sources/mex*/。由于我已经编译了 Matlab .mex 文件,*.o 文件存在于这些源目录中。因此,当我编译 Octave 文件时,make 直接跳到链接步骤,因为它已经在目录中看到了最近的 *.o 文件。当然,问题是这些*.o 文件是使用 Matlab 头文件编译的,因此在 Octave 构建中不起作用。

最简单的解决方案是简单地定义一个放置目标文件的目录。目前,典型的构建编译命令如下所示(删除标志):

gcc ... -o ../../sources/mex1/mex1.o ../../sources/mex1/mex1.c

我只想更改传递给-o 标志的文件的位置,但不知道如何在 automake 中执行此操作。 当然,除非有更优雅的方法解决方案。

【问题讨论】:

  • 所以,在您的问题描述中,您已经给出了答案。只需定义将放置目标文件的目录。并为 matlab 和 octave 对象以不同的方式命名该目录。它需要一些GNU make 函数和/或一些bash 脚本,我猜...
  • @igagis 感谢您的回复。如果我编写脚本将.o. 文件移动到不同的目录,make 不会在后续运行中重新编译所有内容,而不仅仅是那些已更改的文件?另外,我必须编写特定的链接规则,并且不能使用autoconf 创建的规则。我错了吗?
  • 由于您提到的原因,移动对象文件不是一个好主意。看看这里的my answer,我认为它可以满足您的需求。

标签: makefile build autotools autoconf automake


【解决方案1】:

我只想更改传递给 -o 标志的文件的位置,但看不到如何在 automake 中执行此操作。当然,除非有更优雅的解决方案。

我首先观察到编译的目标文件被放置在源文件旁边,因为这就是你所说的,通过给 Automake 提供 subdir-objects 选项并执行源内构建(或实际上是两个)。将它们放置在其他地方有多种选​​择,但其中有两个比较突出,因为它们与问题的原因直接相关:

  1. 删除 subdir-objects Automake 选项。然后,您的中间 .o 文件应最终位于运行 make 的构建目录中。这有点混乱,但这不应该是一个问题,因为生成的 Makefile 知道它们是哪些文件,因此可以在必要时将它们与可安装产品区分开来。这里的主要问题是,与为同一目标构建的不同 .mex 文件关联的目标文件之间可能会发生冲突。

  2. 执行源外构建而不是源内构建,每个主要目标(octave / matlab)一个,每个在自己的构建树中。与您的想法相反,这不是您现在正在做的事情,至少从 Autotools 的角度来看不是。当您执行源外构建时,所有生成的文件都将写入构建树,因此为 octave 和 matlab 分别构建树应该可以干净地解决您的问题。这是我推荐的选项。

Autotools 自动提供对源外构建的支持。您需要做的就是创建所需的构建目录,将其设为您的工作目录,然后从那里运行项目的configure 脚本。如果您愿意,构建目录可以是源根目录的子目录,但并非必须如此。要理解的关键是“顶级源目录”是包含configure 脚​​本的目录,而“顶级构建目录”是您运行该脚本的工作目录。因此,如果您在项目根目录中,您可能会这样做:

$ cd build
$ mkdir build-octave build-matlab

$ cd build-octave
$ ../octave/configure
$ make
$ make install

$ cd ../build-matlab
$ ../matlab/configure
$ make
$ make install

但是可以通过假设源代码构建来以破坏该支持的方式编写您的Makefile.am 文件。您提供的Makefile.am 摘录正是通过依赖从构建目录到源的特定相对路径来实现的。如果您的Makefile.am 想要引用相对于顶级源目录的源文件(而不是构建文件),那么它可以使用 Automake 提供的自动$(top_srcdir) 变量。 (这也不会干扰源内构建。)例如,您应该能够这样做:

nodist_mexI_SOURCES = \
    $(top_srcdir)/../../sources/mexI/mexI.c \
    $(top_srcdir)/../../sources/mexI/mexI_file1.c \
    $(top_srcdir)/../../sources/mexI/mexI_fileN.c

我不太喜欢引用顶级源目录以上的资源,但它应该可以工作。


更新:

考虑同时修改 Autotooling 以使两种目标类型只有一个构建系统。 Autoconf 支持定义您自己的--enable--with 选项,您可以在运行configure 时使用它们来选择目标类型。 Autoconf 和 A​​utomake 支持各种可以使用这些和其他标准来调整构建细节的条件。与单独维护并行构建系统相比,这可能是一个巨大的胜利。这可以很好地与源代码外构建一起工作。

【讨论】:

  • 感谢您花时间回答@John Bollinger。当我尝试1.2. 时,当我运行autoreconf -siautomake: At least a source file is in a subdirectory, but the 'subdir-objects' automake option hasn't been enabled. 时,我得到了与当前构建系统中相同的警告:消除此警告是我进行这些更改的原因。我在某处犯错了吗?
  • 顺便说一句,我目前的想法似乎可行,是通过为Makefile.am 提供链接它们的BUILT_SOURCES 参数,将源文件软链接到mex/build/matlab/mexI 目录。跨度>
  • @houtanb,您的问题是两个版本之间的目标文件冲突。这是我已经回答的。如果这不是您真正想知道的,请编辑您的问题以澄清,甚至提出一个全新的问题。
  • @houtanb,如果您这样做,请务必提供minimal reproducible example,包括但不限于您正在使用的自动工具的版本。在我的测试中,我没有收到关于不使用 subdir-objects 的警告。
  • @houtanb,顺便说一句,软链接源是一个古老的、众所周知的想法。它可以工作,但它是基于 VPATH 的源代码外构建(例如 Autotools 和 GNU make 免费提供的)的混乱、劣质替代方案。
猜你喜欢
  • 2014-07-27
  • 1970-01-01
  • 2018-07-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-19
  • 1970-01-01
相关资源
最近更新 更多