VPATH源外构建

时间:2017-09-21 10:01:04

标签: makefile build autotools automake autoconf

背景

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

                     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是通过configure.ac从根目录中的AC_CONFIG_SUBDIRS([mex/build/matlab])调用的。同样的设置适用于/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

autoreconf -si运行root_dir会产生警告:

../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构建创建的目标文件被八度构建视为有效,导致八度构建失败(八度构建在matlab构建之后运行) )。

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

1 个答案:

答案 0 :(得分:1)

  

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

事实上,正如我在回答您之前提出的问题时所写的那样,最优雅的解决方案通常是使用动态源代码构建,Autotools会自动为您提供这些构建。至少还有另一种替代方案,我将在后面描述。

你继续说,

  

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

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

  

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

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

在这方面,您需要了解构建目标文件的目录的名称(表示为make)是该目标的标识符的一个组成部分,直至{ {1}}令人担忧。您不能通过翻转开关在不同的目录中构建相同的文件 - 如果您在不同的目录中构建某些内容,那么出于这个原因,它是一个不同的文件。然后,需要更改涉及该文件作为目标或依赖项的所有make规则。

  

我知道我们通常可以更改为这些目录然后运行../configure但是我不知道如何从root_dir / configure.ac中执行此操作,因为AC_CONFIG_SUBDIRS仅将子目录作为参数。< / p>

嗯,根目录make是你在上一个问题中没有提到的新皱纹。通过使用configure.acAC_CONFIG_SUBDIRS组件关联为较大项目的子项目,您将无法为这两个组件执行单独的源外构建,至少在一个构建的上下文中主项目。此外,因为您之前的问题断言,因此生成非递归构建 - 您只是将构建稍微扁平化了。至少,顶级Makefile仍将递归到子项目Makefile中。

如果顶级项目对子项目没有构建依赖关系&#39;然而,建立输出,那就好了。在这种情况下,相对于主要项目而言,非递归构建与递归构建相比基本上没有任何优点适用于那些文件。这为子项目使用源外构建打开了大门,但您需要使用与mex不同的机制来配置它们。

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

AC_CONFIG_SUBDIRS

然后,顶级Makefile.am需要在其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"`]) 变量中指定子项目构建目录(上例中的mex-matlab和mex-octave)。

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

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

文件(注意:) subdir-objects

mex/build/Makefile.am

当然,由于采用这种方法,您不希望为mex文件单独构建系统,因此您可能会考虑完全或部分展平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位设置为主项目的子项目的复杂性会稍微改变微积分。从Autotools的角度来看,这种替代方案比为子项目安排单独的源外构建更清晰。