【问题标题】:VPATH out-of-source buildVPATH 外源构建
【发布时间】:2018-03-02 15:11:02
【问题描述】:

背景

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

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

configure.acMakefile.am 控制mex/build/matlab/mex/build/octave/ 和我们在non-mex-source/ 中创建的非mex 二进制文件中的配置和编译。

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

Matlab 构建系统位于mex/build/matlab/。这里的configure.acMakefile.am是通过AC_CONFIG_SUBDIRS([mex/build/matlab])从根目录下的configure.ac调用的。同样的设置也适用于/mex/build/octave/,其中configure.ac 已被修改以查找特定于 Octave 的头文件和库。

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

mex_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 所做的更改,我们正在转向非递归构建。我已经提出了一个解决方案,将源软链接到 /mex/build/matlab/mex*//mex/build/octave/mex*/ 目录(使用 BUILT_SOURCES = .mexfileslinked 并设置源以依赖于该文件的存在;规则为当第一次编译源代码时,此文件将链接到源代码和touch .mexfileslinked)。这很好用,但我认为必须有一个更优雅的解决方案。

我创建了一个最小的工作示例,它显示了当前设置和运行autoreconf -si 时遇到的警告。文件如下:

root_dir/configure.ac:

AC_PREREQ([2.69])
AC_INIT([soquestion], [2.0])
AC_CONFIG_SRCDIR([configure.ac])
AM_INIT_AUTOMAKE([1.15.1 foreign])

# config stuff for other, non-mex binaries we are building

AC_CONFIG_SUBDIRS([mex/build/matlab])
AC_CONFIG_SUBDIRS([mex/build/octave])

AC_CONFIG_FILES([Makefile])

AC_OUTPUT

root_dir/Makefile.am:

SUBDIRS = mex/build/matlab mex/build/octave

root_dir/mex/build/mex1.am:

mex_PROGRAMS = mex1

mexdir = $(libdir)/mex/matlab

nodist_mex1_SOURCES = \
    $(top_srcdir)/../../sources/mex1/mex1.cc

root_dir/mex/build/matlab/configure.acroot_dir/mex/build/octave/configure.ac:

AC_PREREQ([2.69])
AC_INIT([soquestion], [2.0])
AC_CONFIG_SRCDIR([configure.ac])
AM_INIT_AUTOMAKE([1.15.1 foreign])

AC_PROG_CXX

AC_CONFIG_FILES([Makefile])

AC_OUTPUT

root_dir/mex/build/matlab/Makefile.amroot_dir/mex/build/octave/Makefile.am

include ../mex1.am

root_dir 运行autoreconf -si 会导致警告:

../mex1.am:5: warning: source file '$(top_srcdir)/../../sources/mex1/mex1.cc' is in a subdirectory,
../mex1.am:5: but option 'subdir-objects' is disabled
Makefile.am:1:   '../mex1.am' included from here
automake: warning: possible forward-incompatibility.
automake: At least a source file is in a subdirectory, but the 'subdir-objects'
automake: automake option hasn't been enabled.  For now, the corresponding output
automake: object file(s) will be placed in the top-level directory.  However,
automake: this behaviour will change in future Automake versions: they will
automake: unconditionally cause object files to be placed in the same subdirectory
automake: of the corresponding sources.
automake: You are advised to start using 'subdir-objects' option throughout your
automake: project, to avoid future incompatibilities.
../mex1.am:5: warning: source file '$(top_srcdir)/../../sources/mex1/mex1.cc' is in a subdirectory,
../mex1.am:5: but option 'subdir-objects' is disabled
Makefile.am:1:   '../mex1.am' included from here
automake: warning: possible forward-incompatibility.
automake: At least a source file is in a subdirectory, but the 'subdir-objects'
automake: automake option hasn't been enabled.  For now, the corresponding output
automake: object file(s) will be placed in the top-level directory.  However,
automake: this behaviour will change in future Automake versions: they will
automake: unconditionally cause object files to be placed in the same subdirectory
automake: of the corresponding sources.
automake: You are advised to start using 'subdir-objects' option throughout your
automake: project, to avoid future incompatibilities.

当然,我可以简单地将subdir-objects 添加到AM_INIT_AUTOMAKE 命令以删除警告。但是,然后我会遇到here 概述的问题,其中 matlab 构建创建的目标文件被 octave 构建视为有效,导致 octave 构建失败(八度构建在 matlab 构建之后运行)。

为了解决这个问题,我想从 mex/build/matlab/objects 构建 Matlab .mex 文件和从 mex/build/octave/objects 构建 Octave .mex 文件(或者,更好的是,mex/build/matlab/objects/mex1 ... mex/build/matlab/objects/mexN )。我知道我们通常可以切换到这些目录然后运行../configure,但我不知道如何从root_dir/configure.ac 执行此操作,因为AC_CONFIG_SUBDIRS 仅将子目录作为参数。

【问题讨论】:

    标签: makefile build autotools automake autoconf


    【解决方案1】:

    我已经提出了一个解决方案,将源软链接到 /mex/build/matlab/mex*//mex/build/octave/mex*/ 目录 [...] 但我认为必须有一个更优雅的解决方案。

    确实,正如我在回答您之前的问题时所写的那样,最优雅的解决方案通常是使用 Autotools 自动为您提供的源外构建。至少还有另一种选择,我稍后会描述。

    你接着说,

    从 root_dir 运行 autoreconf -si 会导致 [关于不使用 Automake 的 subdir-objects 选项的警告 ....] 当然,我可以简单地将 subdir-objects 添加到 AM_INIT_AUTOMAKE 命令以删除警告。但是,然后我会遇到[在我之前的问题中]概述的问题。

    源代码外构建通常仍然是此类问题的最佳解决方案。您可以为您的源外构建打开subdir-objects 以使警告静音;当它们不同时,构建的文件仍将进入构建树,而不是源代码树。启用该选项后,它们将在构建树中以与源树的目录结构平行的目录结构排列,这是一件好事和有用的事情。因此,如果您为每种目标类型进行单独的源外构建,那么您将拥有单独的输出。

    为了解决这个问题,我想从mex/build/matlab/objects 构建Matlab .mex 文件和从mex/build/octave/objects 构建Octave .mex 文件(或者,更好的是,mex/build/matlab/objects/mex1 ... mex/build/matlab/objects/mexN )。

    您似乎专注于特定的解决方案,而不是更广泛地考虑整体问题。您可以在您选择的目录中构建中间对象文件。为此,您需要创建显式的make 规则以在所需的目标目录中构建它们,以及从这些目标目录构建最终输出的附加显式规则。到那时,您将放弃 Automake 提供的许多优势,而大多只是直接编写普通的 Makefile。如果你愿意,你可以这样做,但我认为你会花费比必要的更多的努力,并产生一个比你本来可以做的更脆弱的构建系统。

    在这方面,您需要了解构建目标文件的目录的名称,如make 所表示的,就make 而言,是该目标标识符的组成部分。您不能通过拨动开关在不同的目录中构建相同的文件——如果您在不同的目录中构建某些东西,那么出于这个原因,它就是一个不同的文件。所有涉及该文件作为目标或依赖项的make 规则都需要更改。

    我知道我们通常可以切换到这些目录然后运行 ​​../configure 但我不知道如何从 root_dir/configure.ac 执行此操作,因为 AC_CONFIG_SUBDIRS 仅将子目录作为参数。

    好吧,根目录configure.ac 是您在上一个问题中没有提到的一个新问题。通过使用AC_CONFIG_SUBDIRSmex 组件关联为更大项目的子项目,您将失去为这两个执行单独的源外构建的能力,至少在主项目的一个构建的上下文中.此外,正如您之前的问题所断言的那样,您因此生成非递归构建 - 您只是稍微扁平化了您的构建。至少,顶级 Makefile 仍会递归到子项目 Makefiles。

    但是,如果顶级项目对子项目的构建输出没有构建依赖项,那很好。在这种情况下,相对于主要项目,非递归构建相对于递归构建的优势基本上都不适用于这些文件。这为子项目使用源外构建打开了大门,但您需要使用与AC_CONFIG_SUBDIRS 不同的机制来配置它们。

    我建议使用AC_CONFIG_COMMANDS 来设置单独的源外构建。这不会像AC_CONFIG_SUBDIRS 那样干净,它放弃了递归帮助,但它提供了所需的灵活性。也许是这些方面的东西(未经测试):

    AC_CONFIG_COMMANDS([mex-matlab], [
      mkdir -p mex-matlab
      cd mex-matlab
      "$[]top_srcdir"/mex/build/matlab/configure
      ], [top_srcdir=`dirname "$[]0"`])
    
    AC_CONFIG_COMMANDS([mex-octave], [
      mkdir -p mex-octave
      cd mex-octave
      "$[]top_srcdir"/mex/build/octave/configure
      ], [top_srcdir=`dirname "$[]0"`])
    

    然后,顶层 Makefile.am 需要在其 SUBDIRS 变量中指定子项目构建目录(上例中的 mex-matlab 和 mex-octave)。


    还有至少另一种完全不同的方法:Automake 具有内置支持,可以使用不同的选项从相同的源构建不同的目标。您没有在当前的构建系统中利用它,因为您已将 octave 和 matlab 位分离到单独的构建中,但是如果您将它们合并到一个基于 Automake 的构建系统中,该构建系统构建了两个部分(可能有条件),那么 Automake 应该注意避免需要的目标文件冲突。它通过为中间文件使用不同的名称来实现这一点,而不是将它们放在不同的目录中。因此,使用这种方法,您也可以添加 subdir-objects 选项来解决 Automake 的警告。

    关键部分可能遵循以下一般模式:

    文件(注意:)mex/build/Makefile.am

    mex_PROGRAMS += matlab/mexI octave/mexI
    
    nodist_matlab_mexI_SOURCES = \
        ../sources/mexI/mexI.c \
        ../sources/mexI/mexI_file1.c \
        ../sources/mexI/mexI_fileN.c
    # Need at least one target-specific flags variable, but that will
    # come naturally in your case
    matlab_mexI_CPPFLAGS = ...
    
    nodist_octave_mexI_SOURCES = \
        ../sources/mexI/mexI.c \
        ../sources/mexI/mexI_file1.c \
        ../sources/mexI/mexI_fileN.c
    # ...
    

    当然,由于使用这种方法您不希望为 mex 文件单独构建系统,因此您可以考虑完全或部分展平 mex/build 子树。

    我第二次提到这个替代方案是因为它可能需要对您现有的构建系统进行比另一个更重要的修改,并且还因为我已经在回答您的其他问题时谈到了源代码外构建。但是,对于当前的问题,您当前将 mex 位设置为主项目的子项目的复杂性会稍微改变微积分。从 Autotools 的角度来看,这种替代方案比为子项目安排单独的外源构建更简洁。

    【讨论】:

    • 非常感谢您的回复。是的,我应该在上一个问题中提到更大的构建环境,因此存在误解。我会试试这个并回复你,可能下周。再次感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-06
    • 2010-09-13
    • 1970-01-01
    • 1970-01-01
    • 2017-05-07
    • 1970-01-01
    相关资源
    最近更新 更多