6

我正在使用 automake 进行 VPATH 构建。我现在也在使用生成的源代码,带有 SWIG。我有Makefile.am这样的规则:

dist_noinst_DATA = whatever.swig

whatever.cpp: whatever.swig
    swig -c++ -php $^

然后该文件稍后使用:

myprogram_SOURCES = ... whatever.cpp

时工作正常$builddir == $srcdir。但是在进行 VPATH 构建(例如mkdir build; cd build; ../configure; make)时,我收到有关缺少的错误消息whatever.cpp

生成的源文件应该转到$builddir还是$srcdir?(我估计可能$builddir。)

应该如何指定依赖项和规则以将生成的文件放在正确的位置?

4

2 回答 2

3

简单的答案

你应该假设它$srcdir是只读的,所以你不能在那里写任何东西。因此,您生成的源代码将以$(builddir).

默认情况下,自动工具生成的 Makefile 只会在 中查找源文件$srcdir,因此您也必须告诉它进行检查$builddir。将以下内容添加到您的Makefile.am应该会有所帮助:

VPATH = $(srcdir) $(builddir)

之后,您可能会遇到no rule to make target ...错误,您应该可以通过更新源生成规则来修复该错误,如下所示:

$(builddir)/whatever.cpp: whatever.swig
        # ...

更好的解决方案

您可能会注意到,在您当前的设置中,发布 tarball(由 创建make dist)将包含该whatever.cpp文件作为源的一部分,因为您将此文件添加到myprogram_SOURCES. 如果您不希望这样做(例如,因为这可能意味着构建过程将真正采用预生成的文件而不是再次生成它),您可能想要使用类似以下的内容。它使用一个包装器源文件 ( whatever_includer.cpp),它只包含生成的文件,-I$(builddir)然后用于查找生成的文件。

生成文件.am:

dist_noinst_DATA = whatever.swig

whatever.cpp: whatever.swig
    swig -c++ -php $^

whatever_includer.cpp: whatever.cpp

myprogram_SOURCES = ... whatever_includer.cpp
myprogram_CPPFLAGS = ... -I$(builddir)

clean-local::
    rm -f $(builddir)/whatever.cpp

不管是什么includer.cpp:

#include "whatever.cpp"
于 2013-08-22T14:34:38.223 回答
1

通常,您希望保持$srcdir只读,例如,如果源是在 CDROM 上解压缩分发的,您仍然可以/.../configure从文件系统的其他部分运行。

但是,如果您使用 SWIG 为包装库生成源代码,您可能还希望分发该 SWIG 生成的代码,以便您的用户不需要安装 SWIG 来编译您的代码。那么您确实有一个选择:您可以决定 SWIG 生成的代码应该以结尾$builddir(没关系:make dist将在那里收集它并将其包含在 tarball 中),或者您可以决定输出 SWIG 生成的代码,$srcdir因为它确实是从分布式包的角度来看的一个来源。保留它的一个优点$srcdir是,当make distcheck尝试从只读源目录构建包时,任何尝试调用 SWIG 以重新生成包装器源的尝试都会失败。如果你有你的包装源$builddir,你可能没有注意到你有一些破坏规则导致 SWIG 在用户的主机上运行;通过在$srcdir您中生成确保您的用户不需要 SWIG。

所以我的偏好是在$srcdir. 对 Python 包装器的设置如下所示:

EXTRA_DIST = spot.i
python_PYTHON = $(srcdir)/spot.py    # _PYTHON is distributed by default
pyexec_LTLIBRARIES = _spot.la

MAINTAINERCLEANFILES = $(srcdir)/spot_wrap.cxx $(srcdir)/spot.py

_spot_la_SOURCES = $(srcdir)/spot_wrap.cxx $(srcdir)/spot_wrap.h
_spot_la_LDFLAGS = -avoid-version -module
_spot_la_LIBADD = $(top_builddir)/src/libspot.la

$(srcdir)/spot_wrap.cxx: $(srcdir)/spot.i
        $(SWIG) -c++ -python -I$(srcdir) -I$(top_srcdir)/src $(srcdir)/spot.i

# Handle the multi-file output of SWIG.
$(srcdir)/spot.py: $(srcdir)/spot.i
        $(MAKE) $(AM_MAKEFLAGS) spot_wrap.cxx

请注意,我将$(srcdir)其用于所有目标,因为该VPATH功能对各种make. 我处理 SWIG 输出的多个文件的设置可以改进,但由于这些规则不是由用户运行的,它从来没有给我带来任何问题,我不打扰。

于 2013-08-26T09:50:08.160 回答