背景
我们为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中执行此操作。当然,除非那里有一个更优雅的解决方案。
答案 0 :(得分:1)
我只想更改传递给-o标志的文件的位置,但是不知道如何在automake中执行此操作。当然,除非有更优雅的解决方案。
我首先观察到编译的目标文件放在源文件旁边,因为是你所说的,它给了Automake subdir-objects
选项并执行源内构建(或实际上是两个)。将它们放置在其他地方有几种选择,但其中有两种脱颖而出,因为它们直接与问题的原因联系在一起:
删除subdir-objects
Automake选项。然后,您的中间.o文件应该在运行make
的构建目录中结束。这有点乱,但这不应该是一个问题,因为生成的Makefile知道它们是哪些文件,因此可以在必要时将它们与可安装产品区分开来。这里的主要问题是,您可能会遇到与为同一目标构建的不同.mex
文件关联的目标文件之间发生冲突的问题。
执行out-of-source而不是in-source构建,每个主目标(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和Automake支持各种条件,可以使用这些和其他标准来调整构建的细节。这可能是分别维护并行构建系统的一大胜利。这可以非常好地与源外构建协同工作。