背景
我们为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.ac
和Makefile.am
控制mex/build/matlab/
,mex/build/octave/
和我们在non-mex-source/
中创建的非mex二进制文件中的配置和编译。
.mex
源文件位于mex/sources/mex*/
,我们会编译多个.mex
文件。
Matlab构建系统位于mex/build/matlab/
。这里的configure.ac
和Makefile.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.ac
和
root_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.am
和root_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
仅将子目录作为参数
答案 0 :(得分:1)
我已经提出了一个解决方案,其中源代码软链接到
/mex/build/matlab/mex*/
和/mex/build/octave/mex*/
目录[...]但我仍然认为必须有一个更优雅的解决方案
事实上,正如我在回答您之前提出的问题时所写的那样,最优雅的解决方案通常是使用动态源代码构建,Autotools会自动为您提供这些构建。至少还有另一种替代方案,我将在后面描述。
你继续说,
从root_dir运行autoreconf -si导致[警告不使用Automake'
subdir-objects
选项....]当然,我可以简单地将子目标对象添加到AM_INIT_AUTOMAKE命令中以删除警告。但是,我会遇到[在我之前的问题中]概述的问题。
源外构建通常仍然是此类问题的最佳解决方案。您可以为您的源外构建打开subdir-objects
以使警告静音;当这些文件不同时,构建的文件仍会进入构建树,而不是源树。启用该选项后,它们将在构建树中排列在与源树平行的目录结构中,这是一个很好的有用的东西。因此,如果您为每个目标类型执行单独的源代码构建,那么您将具有单独的输出。
要解决这个问题,我想从
.mex
构建Matlabmex/build/matlab/objects
文件,从.mex
构建Octavemex/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.ac
将AC_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的角度来看,这种替代方案比为子项目安排单独的源外构建更清晰。