将预编译的二进制文件作为包裹提供

一个常见的依赖项情况,特别是在 Windows 上,是需要将依赖项作为预编译的二进制文件提供,而不是从头开始构建的 Meson 项目。常见原因包括:无法访问源代码、没有时间和精力将遗留系统的构建定义重写为 Meson,或者只是编译依赖项项目花费的时间太长。

打包项目很简单。例如,让我们看一下项目包含一个名为 bob 的静态库和一些头文件的情况。要创建一个二进制依赖项项目,我们将静态库放在顶层,并将头文件放在名为 include 的子目录中。Meson 构建定义如下所示。

project('bob', 'c')

# Do some sanity checking so that meson can fail early instead of at final link time
if not (host_machine.system() == 'windows' and host_machine.cpu_family() == 'x86_64')
  error('This wrap of libbob is a binary wrap for x64_64 Windows, and will not work on your system')
endif

cc = meson.get_compiler('c')
bob_dep = declare_dependency(
  dependencies : cc.find_library('bob', dirs : meson.current_source_dir()),
  include_directories : include_directories('include'))

meson.override_dependency('bob', bob_dep)

现在,您可以像使用 Meson 项目一样使用这个子项目

project('using dep', 'c')
bob_dep = dependency('bob')
executable('prog', 'prog.c', dependencies : bob_dep)

请注意,通常使用不同编译器(甚至编译器标志)编译的库可能不兼容。如果这样做,那么您有责任验证您的库是否兼容,Meson 不会为您检查。

使用包裹文件

为了使这一切自动工作,一个项目将需要一个 包裹文件,以及上面的 meson.build 定义。对于这个例子,我们的依赖项被称为 bob

包裹 ini(subprojects/bob.wrap)

[wrap-file]
directory = libbob-1.0
source_url = https://libbob.example.com/libbob-1.0.zip
source_filename = libbob-1.0.zip
source_hash = 5ebeea0dfb75d090ea0e7ff84799b2a7a1550db3fe61eb5f6f61c2e971e57663
patch_directory = libbob

[provide]
dependency_names = bob

然后创建 subprojects/packagefiles/libbob/,并将上面的 meson.build 放在该目录中。有了这些,调用 dependency('bob') 将首先尝试您的系统上的标准发现方法(例如 pkg-config、cmake 和任何内置的 meson 查找方法),然后在无法在系统上找到依赖项的情况下回退到使用二进制包裹。Meson 提供了 --force-fallback-for=bob 命令行选项来强制使用回退。

Linux 库说明

预编译的 Linux 共享库 (.so) 需要一个 soname 字段才能正确安装。如果缺少 soname 字段,引用该库的二进制文件将需要在安装时硬链接到该库的位置(/path/to/your/project/subprojects/precompiledlibrary/lib.so 而不是 $INSTALL_PREFIX/lib/lib.so)在安装后。

您应该更改预编译库的编译选项以避免此问题。如果重新编译不可行,您可以使用 patchelf 工具使用命令 patchelf --set-soname libfoo.so libfoo.so 在事后编辑预编译库。

Meson 通常保证它编译的任何库都有一个 soname。一个显著的例外是使用 shared_module() 函数构建的库。

搜索结果为