Makefile 将对象文件放置在非递归生成中的不同目录中
背景 我们为Matlab和Octave构建Makefile 将对象文件放置在非递归生成中的不同目录中,makefile,build,autotools,autoconf,automake,Makefile,Build,Autotools,Autoconf,Automake,背景 我们为Matlab和Octave构建.mex文件。源代码对于Matlab和Octave都是通用的,但是在这里和那里都有轻微的修改(通过代码中的宏条件进行处理)。作为参考,源结构为: mex/ | ------------------------------ | | sou
.mex
文件。源代码对于Matlab和Octave都是通用的,但是在这里和那里都有轻微的修改(通过代码中的宏条件进行处理)。作为参考,源结构为:
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 build系统位于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
文件;对象文件将在那里编译,输出文件将位于那里)。现在,考虑到GNUsubdir对象的变化,我们将转向非递归构建。从Matlab构建开始,我能够修改它,使其以非递归方式工作,没有任何问题
问题
在移动到非递归构建时,对象文件现在与源文件在相同的目录中生成,即/mex/sources/mex*/
。由于我已经编译了Matlab.mex
文件,因此*.o
文件存在于这些源目录中。因此,当我编译倍频程文件时,make
直接跳过链接步骤,因为它已经在目录中看到最近的*.o
文件。当然,问题是这些*.o
文件是用Matlab头编译的,因此不能在倍频程构建中工作
最简单的解决方案是简单地定义一个目录,对象文件将放在其中。当前,典型的生成编译命令如下所示(删除标志):
我只想更改传递到-o
标志的文件的位置,但不知道如何在automake中执行此操作。当然,除非有更优雅的解决方案
我只想更改传递到-o标志的文件的位置,但不知道如何在automake中执行此操作。当然,除非有更优雅的解决方案
首先,我注意到编译后的对象文件被放置在源文件旁边,因为这就是您所说的,通过给Automakesubdir objects
选项并执行源代码内构建(或者实际上是两个)。将它们放在其他地方有几种选择,但其中两种选择很突出,因为它们与问题的原因直接相关:
删除subdir对象
Automake选项。然后,您的中间.o文件应该在运行make
的生成目录中结束。这有点混乱,但这不应该引起关注,因为生成的Makefile知道它们是哪些文件,因此可以在必要时将它们与可安装产品区分开来。这里的主要问题是,与为同一目标生成的不同.mex
文件关联的对象文件之间可能会发生冲突
执行源代码外构建,而不是源代码内构建,每个主目标(octave/matlab)一个构建,每个构建在自己的构建树中。与你可能认为的相反,这不是你现在正在做的,至少从自动工具的角度来看不是这样。当您执行源代码外构建时,所有生成的文件都会写入构建树,因此为octave和matlab创建单独的构建树应该可以清楚地解决您的问题。这是我推荐的选择
自动工具可自动为源代码外的构建提供支持。您只需创建所需的构建目录,将其设置为工作目录,然后从那里运行项目的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\u srcdir)
变量。(这也不会干扰源代码构建。)例如,您应该能够做到:
nodist_mexI_SOURCES = \
$(top_srcdir)/../../sources/mexI/mexI.c \
$(top_srcdir)/../../sources/mexI/mexI_file1.c \
$(top_srcdir)/../../sources/mexI/mexI_fileN.c
我不太喜欢引用顶级源代码目录之上的资源,但它应该可以工作
更新:
还可以考虑修改自动冷却,使两种目标类型都只有一个生成系统。Autoconf支持使用
选项定义自己的--启用和--您可以使用这些选项在运行配置时选择目标类型。Autoconf和Automake支持各种条件,可以使用这些条件和其他条件来调整buil的详细信息
nodist_mexI_SOURCES = \
$(top_srcdir)/../../sources/mexI/mexI.c \
$(top_srcdir)/../../sources/mexI/mexI_file1.c \
$(top_srcdir)/../../sources/mexI/mexI_fileN.c