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 输出分析自动确定的库列表(即 插件)。如果将插件作为此参数传递给此命令,则它们应在调用此命令之前安装或复制到包中。

<dirs>

可能找到库的路径列表。当给出不带路径信息的目录时,会首先搜索这些路径。然后还会搜索标准系统位置: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 输出分析自动确定的库列表(即 插件)。如果将插件作为此参数传递给此命令,则它们应在调用此命令之前安装或复制到包中。

<dirs>

可能找到库的路径列表。当给出不带路径信息的目录时,会首先搜索这些路径。然后还会搜索标准系统位置: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

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

get_item_rpaths(<item> <rpaths-var>)

此命令获取 <item> 文件名的 RPATH,并将其存储到具有指定名称 <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>

可能找到库的路径列表。当给出不带路径信息的目录时,会首先搜索这些路径。然后还会搜索标准系统位置: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 输出分析自动确定的库列表(即 插件)。如果将插件作为此参数传递给此命令,则它们应在调用此命令之前安装或复制到包中。

<dirs>

可能找到库的路径列表。当给出不带路径信息的目录时,会首先搜索这些路径。然后还会搜索标准系统位置: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() 命令之前将此变量设置为布尔值 true。默认情况下,此命令会复制框架 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>

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

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

BU_CHMOD_BUNDLE_ITEMS

如果此变量设置为布尔值 true,则在 install_name_tool 工具尝试修改包项之前,它们将被标记为可写。

verify_bundle_prerequisites

验证包内所有文件的所有先决条件总和是否包含在包内,或者是否为 system 库(假设存在于任何地方)。

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}\"
  )
")