Autotools

The Autotools 构建助手是 autotools 命令行调用的一个包装器。它将 ./configuremake 等调用抽象为 Python 方法调用。

用法

from conan import ConanFile
from conan.tools.gnu import Autotools

class App(ConanFile):
    settings = "os", "arch", "compiler", "build_type"

    def build(self):
        autotools = Autotools(self)
        autotools.configure()
        autotools.make()

它将读取由 AutotoolsToolchain 生成的 conanbuild.conf 文件,以读取调用 configure 和 make 脚本所需的参数。

  • configure_args: 调用 configure 脚本的参数。

  • make_args: 调用 make 脚本的参数。

参考

class Autotools(conanfile, namespace=None)
参数:
  • conanfile – 当前的 recipe 对象。始终使用 self

  • namespace – 此参数用于避免在同一个 recipe 中多次调用 toolchain 时发生冲突。设置此参数后,用于向 toolchain 传递信息的 conanbuild.conf 文件将被命名为:<namespace>_conanbuild.conf。默认值是 None,意味着生成的文件名为 conanbuild.conf。AutotoolsToolchain 的构造函数中也必须设置此命名空间为相同的值,以便从正确的文件中读取信息。

configure(build_script_folder=None, args=None)

调用 configure 脚本。

参数:
  • args – 用于 configure 调用的参数列表。

  • build_script_folder – configure 脚本所在的子文件夹。如果未指定,则使用 conanfile.source_folder。

make(target=None, args=None)

调用 make 程序。

参数:
  • target – (可选,默认为 None): 选择要构建的目标。这允许构建例如文档、共享库或执行某些 AutoTools 项目的安装。

  • args – (可选,默认为 None): 用于 make 调用的参数列表。

install(args=None, target='install')

这只是 self.make(target="install") 的一个“别名”。

参数:
  • args – (可选,默认为 None): 用于 make 调用的参数列表。默认情况下,如果传入值为 None,则会向调用中添加一个参数 DESTDIR=unix_path(self.package_folder)。有关 tools.microsoft.unix_path() 函数的更多信息,请参阅。

  • target – (可选,默认为 None): 选择要安装的目标。

autoreconf(build_script_folder=None, args=None)

调用 autoreconf

参数:
  • args – (可选,默认为 None): 用于 autoreconf 调用的参数列表。

  • build_script_folder – configure 脚本所在的子文件夹。如果未指定,则使用 conanfile.source_folder。

关于使用 Autotools 构建助手在 macOS 上构建可重定位共享库的说明

在 macOS 上使用 Autotools 构建共享库时,会向 .dylib 中添加一个 LC_ID_DYLIB 部分和另一个 LC_LOAD_DYLIB 部分。这些部分存储 install_name 信息,该信息是库或其依赖项安装位置的文件夹路径。您可以使用 otool 命令检查共享库的 install_name。

$ otool -l path/to/libMyLib.dylib
...
cmd LC_ID_DYLIB
    cmdsize 48
        name path/to/libMyLib.dylib (offset 24)
time stamp 1 Thu Jan  1 01:00:01 1970
    current version 1.0.0
compatibility version 1.0.0
...
Load command 11
        cmd LC_LOAD_DYLIB
    cmdsize 48
        name path/to/dependency.dylib (offset 24)
time stamp 2 Thu Jan  1 01:00:02 1970
    current version 1.0.0
compatibility version 1.0.0
...

在使用 Conan 时,这为什么是一个问题?

使用 Conan 时,库将在本地缓存中构建,这意味着该位置将指向库安装所在的 Conan 本地缓存文件夹。这个位置是库告诉使用它的任何其他二进制文件在运行时从何处加载它的地方。这是一个问题,因为您可以在一台机器上构建共享库,然后将其上传到服务器并在另一台机器上安装以使用它。在这种情况下,正如 Autotools 默认的行为那样,您会得到一个存储 install_name 的库,该 install_name 指向您当前机器上不存在的文件夹,因此在构建时会遇到链接器错误。

如何在 Conan 中解决此问题

Conan 唯一能使这些共享库可重定位的方法是在安装后修补构建的二进制文件。为此,当使用 Autotools 构建助手时,并在运行 Makefile 的 install() 步骤后,您可以使用 fix_apple_shared_install_name() 工具搜索构建的 .dylib 文件并对其进行修补,方法是运行 install_name_tool macOS 工具,如下所示:

from conan.tools.apple import fix_apple_shared_install_name
class HelloConan(ConanFile):
  ...
  def package(self):
      autotools = Autotools(self)
      autotools.install()
      fix_apple_shared_install_name(self)

这将把 .dylib 文件中的 LC_ID_DYLIBLC_LOAD_DYLIB 部分的值更改为:

$ otool -l path/to/libMyLib.dylib
...
cmd LC_ID_DYLIB
    cmdsize 48
        name @rpath/libMyLib.dylib (offset 24)
time stamp 1 Thu Jan  1 01:00:01 1970
    current version 1.0.0
compatibility version 1.0.0
...
Load command 11
        cmd LC_LOAD_DYLIB
    cmdsize 48
        name @rpath/dependency.dylib (offset 24)
time stamp 2 Thu Jan  1 01:00:02 1970
    current version 1.0.0
compatibility version 1.0.0

@rpath 特殊关键字将告诉加载器搜索路径列表以查找库。这些路径可以由该库的使用者通过定义 LC_RPATH 字段来指定。这是通过在构建该库的使用者时传递 -Wl,-rpath -Wl,/path/to/libMyLib.dylib 链接器标志来实现的。然后,如果 Conan 构建了一个使用 libMyLib.dylib 库的可执行文件,它将自动添加 -Wl,-rpath -Wl,/path/to/libMyLib.dylib 标志,以便在构建时正确找到库。