BundleUtilities

本模块提供了实用命令,用于使用 CMake 组装独立的捆绑式应用程序,例如 macOS .app 捆绑包或在其他操作系统上类似的基于目录的应用程序捆绑包。

在 CMake 安装中加载此模块

include(BundleUtilities)

注意

不要在配置时(从 CMakeLists.txt)使用此模块。相反,请将其包含并从 install(CODE)install(SCRIPT) 调用其命令。

命令

本模块提供以下命令

fixup_bundle

通过修复其内部依赖项来准备分发捆绑包

fixup_bundle(<app> <libs> <dirs> [IGNORE_ITEM <files>...])

此命令会就地修改 <app> 捆绑包,使其自包含且可移植,以便可以拖放复制到另一台机器并运行,假设所有系统库都兼容。

此命令收集捆绑包中可执行文件和库的所有依赖项(键)。对于每个依赖项,它将所需文件复制到捆绑包中,并根据其自身的先决条件进行调整。完成后,它会清除收集的键并调用 verify_app() 命令,以确保最终捆绑包是真正的独立包。

参数为

<app>

要修复的捆绑包的路径。这可以是 .app 目录或可执行文件的直接路径。

<libs>

必须修复的库列表,但不能通过 otool 输出分析自动确定(即 plugins)。如果插件作为此参数传递给此命令,则应在调用此命令之前将其安装或复制到捆绑包中。

<dirs>

可能找到库的路径列表。当给定没有路径信息的 targets 时,首先搜索这些路径。然后还搜索标准系统位置:PATH、框架位置、/usr/lib 等。

IGNORE_ITEM <files>...

3.6 版本新增。

要忽略的可选文件名列表(例如 IGNORE_ITEM "vcredist_x86.exe;vcredist_x64.exe")。

copy_and_fixup_bundle

复制捆绑包并就地修复新复制的捆绑包

copy_and_fixup_bundle(<src> <dst> <libs> <dirs>)

此命令在 <dst> 位置制作捆绑包 <src> 的副本,然后就地修复 <dst> 处的新复制捆绑包。

参数为

<src>

要复制的捆绑包的目录。

<dst>

捆绑包副本的目标目录。

<libs>

必须修复的库列表,但不能通过 otool 输出分析自动确定(即 plugins)。如果插件作为此参数传递给此命令,则应在调用此命令之前将其安装或复制到捆绑包中。

<dirs>

可能找到库的路径列表。当给定没有路径信息的 targets 时,首先搜索这些路径。然后还搜索标准系统位置:PATH、框架位置、/usr/lib 等。

verify_app

基于运行分析工具验证应用程序捆绑包是否有效

verify_app(<app> [IGNORE_ITEM <files>...])

如果应用程序验证失败,则会发出 message(FATAL_ERROR),停止安装过程。

参数为

<app>

要验证的应用程序的路径。这可以是 .app 目录或独立的可执行文件。

IGNORE_ITEM <files>...

3.6 版本新增。

要忽略的可选文件名列表(例如 IGNORE_ITEM "vcredist_x86.exe;vcredist_x64.exe")。

get_bundle_main_executable

检索给定应用程序捆绑包中的主可执行文件

get_bundle_main_executable(<bundle> <result-var>)

结果存储在 <result-var> 变量中,并将包含捆绑包主可执行文件的完整路径名,如果无法确定,则为以 error: 为前缀的字符串。

get_dotapp_dir

找到给定可执行文件的包含 .app 目录

get_dotapp_dir(<exe> <dotapp-dir-var>)

此命令根据可执行文件的完整路径检索名称以 .app 结尾的最近父目录,并将其存储到 <dotapp-dir-var> 变量中。如果没有此类父目录,则它只检索包含可执行文件的目录。

检索到的目录可能存在也可能不存在。

get_bundle_and_executable

接受 .app 目录名称或嵌套在 .app 目录中的可执行文件名称,并检索 .app 目录的路径及其主可执行文件的路径

get_bundle_and_executable(<app> <bundle-var> <executable-var> <valid-var>)

参数为

<app>

正在处理的应用程序的名称。

<bundle-var>

用于存储 .app 目录结果路径的变量名。如果发生任何错误,此变量将包含以字符串 error: 为前缀的错误消息。

<executable-var>

用于存储结果主可执行文件的变量名。如果发生任何错误,此变量将包含以字符串 error: 为前缀的错误消息。

<valid-var>

用于存储此命令是否成功的布尔结果的变量名。

get_bundle_all_executables

获取给定捆绑包的所有可执行文件

get_bundle_all_executables(<bundle> <exes-var>)

此命令递归扫描 <bundle> 捆绑包中的所有可执行文件,并将它们存储到变量 <exes-var> 中。

get_item_key

为给定项生成唯一键

get_item_key(<item> <key-var>)

给定 <item> 文件名,此命令生成 <key-var> 键,该键在需要复制或修复以使捆绑包独立的一组库中应该是唯一的。这本质上是包含扩展名的文件名,其中 . 已替换为 _

此键用作 CMake 变量的前缀,以便可以根据其键将一组变量与给定项关联起来。

get_item_rpaths

获取给定项的 RPATHS(运行时搜索路径)

get_item_rpaths(<item> <rpaths-var>)

此命令获取 <item> 文件名的 RPATHS 并将其存储到指定名称的变量 <rpaths-var> 中。

clear_bundle_keys

清除与键关联的所有变量

clear_bundle_keys(<keys-var>)

此命令遍历 <keys-var> 键列表,清除与每个键关联的所有变量。循环结束后,它会清除键列表本身。此命令应在完成处理键列表后,在 get_bundle_keys() 命令之后调用。

set_bundle_key_values

将键添加到键列表

set_bundle_key_values(
  <keys-var>
  <context>
  <item>
  <exepath>
  <dirs>
  <copyflag>
  [<rpaths>]
)

此命令将 <keys-var> 键添加到给定项的列表(如果需要)。如果添加,还会设置与该键关联的所有变量。

参数为

<keys-var>

变量名,保存要添加到给定项列表中的键的名称。

<context>

在 Apple 操作系统上用于 @loader_path 替换的顶层加载路径。解析项时,@loader_path 引用将相对于给定上下文值(可能是另一个库)的目录解析。

<item>

要添加键的项。

<exepath>

在 Apple 操作系统上用于 @executable_path 替换的顶层可执行文件的路径。

<dirs>

可能找到库的路径列表。当给定没有路径信息的 targets 时,首先搜索这些路径。然后还搜索标准系统位置:PATH、框架位置、/usr/lib 等。

<copyflag>

如果设置为 1,则会保留库符号链接结构。

<rpaths>

可选的运行时搜索路径,用于可执行文件或库以帮助查找文件。

get_bundle_keys

获取捆绑包键

get_bundle_keys(<app> <libs> <dirs> <keys-var> [IGNORE_ITEM <files>...])

此命令遍历 <app> 捆绑包中(以及作为额外 <libs> 提供的)所有可执行文件和库文件,并积累表示它们的键列表。它设置与每个键关联的值,以便可以遍历所有这些键并将先决条件库复制到捆绑包中,然后执行适当的 install_name_tool 修复。

参数为

<app>

要修复的捆绑包的路径。这可以是 .app 目录或可执行文件的直接路径。

<libs>

必须修复的库列表,但不能通过 otool 输出分析自动确定(即 plugins)。如果插件作为此参数传递给此命令,则应在调用此命令之前将其安装或复制到捆绑包中。

<dirs>

可能找到库的路径列表。当给定没有路径信息的 targets 时,首先搜索这些路径。然后还搜索标准系统位置:PATH、框架位置、/usr/lib 等。

<keys-var>

变量名称,包含表示捆绑包中所有可执行文件和库文件的键列表。

IGNORE_ITEM <files>...

3.6 版本新增。

要忽略的可选文件名列表(例如 IGNORE_ITEM "vcredist_x86.exe;vcredist_x64.exe")。

copy_resolved_item_into_bundle

如果必要,将已解析的项复制到捆绑包中

copy_resolved_item_into_bundle(<resolved-item> <resolved-embedded-item>)

如果 <resolved-item><resolved-embedded-item> “相同”,则无需复制。

copy_resolved_framework_into_bundle

如果必要,将已解析的框架复制到捆绑包中

copy_resolved_framework_into_bundle(<resolved-item> <resolved-embedded-item>)

如果 <resolved-item><resolved-embedded-item> “相同”,则无需复制。

在调用此命令之前可以设置以下变量

BU_COPY_FULL_FRAMEWORK_CONTENTS

默认情况下,此变量未设置。如果完整的框架应嵌入到捆绑包中,请在调用 fixup_bundle() 命令之前将此变量设置为布尔真。默认情况下,此命令复制框架 dylib 本身以及框架 Resources 目录。

fixup_bundle_item

修复捆绑包项

fixup_bundle_item(<resolved-embedded-item> <exepath> <dirs>)

此命令获取 <resolved-embedded-item> 的直接/非系统先决条件,对于每个先决条件,它将其引用方式更改为该先决条件的 _EMBEDDED_ITEM 键变量的值。最有可能更改为 @executable_path 样式的引用。

此命令要求 <resolved-embedded-item> 已经 捆绑包内部。换句话说,如果将插件作为 <libs> 参数传递给 fixup_bundle() 命令,则应在调用 fixup_bundle() 命令之前将其安装或复制到捆绑包中。

此外,它还将正在修复的项的 id 更改为其自身的 _EMBEDDED_ITEM 值。

更改累积在局部变量中,并在此命令结束时一次性调用 install_name_tool 命令行工具,包含所有更改。

参数为

<resolved-embedded-item>

要修复的捆绑包项。

<exepath>

在 Apple 操作系统上用于 @executable_path 替换的顶层可执行文件的路径。

<dirs>

可能找到库的路径列表。当给定没有路径信息的 targets 时,首先搜索这些路径。然后还搜索标准系统位置:PATH、框架位置、/usr/lib 等。

在调用此命令之前可以设置以下变量

BU_CHMOD_BUNDLE_ITEMS

如果此变量设置为布尔真值,则在 install_name_tool 工具尝试更改捆绑包项之前,捆绑包项将被标记为可写。

verify_bundle_prerequisites

验证捆绑包内所有文件的所有先决条件的总和都包含在捆绑包中,或者它们是 系统 库,假定无处不在

verify_bundle_prerequisites(
  <bundle>
  <result-var>
  <info-var>
  [IGNORE_ITEM <files>...]
)

参数为

<bundle>

正在验证的捆绑包的名称。

<result-var>

用于存储验证是否成功的布尔结果的变量名称。

<info-var>

包含验证产生的任何信息消息的变量名称。

IGNORE_ITEM <files>...

3.6 版本新增。

要忽略的可选文件名列表(例如 IGNORE_ITEM "vcredist_x86.exe;vcredist_x64.exe")。

验证指定捆绑包中找到的任何符号链接是否指向捆绑包中已有的其他文件

verify_bundle_symlinks(<bundle> <result-var> <info-var>)

任何指向外部文件的操作都会导致此命令验证失败。

参数为

<bundle>

正在验证的捆绑包的名称。

<result-var>

用于存储验证是否成功的布尔结果的变量名称。

<info-var>

包含验证产生的任何信息消息的变量名称。

示例

在安装阶段执行的安装代码中使用此模块

CMakeLists.txt
# ...

install(CODE "
  include(BundleUtilities)
  set(BU_CHMOD_BUNDLE_ITEMS TRUE)
  fixup_bundle(
    \"${fixup_exe}\"
    \"${plugins}\"
    \"${bin_dir};${library_dir};${binary_dir}\"
  )
")