将对象文件放在非递归构建中的不同目录中

时间:2017-09-18 10:13:46

标签: makefile build autotools autoconf automake

背景

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

                      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文件。 configure.ac中存在类似的Makefile.am/mex/build/octave/文件,经过修改以查找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中执行此操作。当然,除非那里有一个更优雅的解决方案。

1 个答案:

答案 0 :(得分:1)

  

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

我首先观察到编译的目标文件放在源文件旁边,因为是你所说的,它给了Automake subdir-objects选项并执行源内构建(或实际上是两个)。将它们放置在其他地方有几种选择,但其中有两种脱颖而出,因为它们直接与问题的原因联系在一起:

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

  2. 执行out-of-source而不是in-source构建,每个主目标(octave / matlab)一个,每个都在自己的构建树中。与你的想法相反,那就是你现在正在做什么,至少不是来自Autotools'透视。当您执行源外构建时,所有生成的文件都将写入构建树,因此为octave和matlab提供单独的构建树应该可以彻底解决您的问题。这是我推荐的选项。

  3. 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和Automake支持各种条件,可以使用这些和其他标准来调整构建的细节。这可能是分别维护并行构建系统的一大胜利。这可以非常好地与源外构建协同工作。