This module provides utility commands for assembling standalone,
bundle-style applications with CMake, such as macOS .app bundles or
similar directory-based application bundles on other operating systems.
Load this module in CMake installation with:
include(BundleUtilities)
Note
Do not use this module at configure time (from CMakeLists.txt).
Instead, include it and invoke its commands from an install(CODE)
or install(SCRIPT).
This module provides the following commands:
Prepares a bundle for distribution by fixing up its internal dependencies:
fixup_bundle(<app> <libs> <dirs> [IGNORE_ITEM <files>...])
This command modifies the <app> bundle in-place to make it
self-contained and portable, so that it can be drag-n-drop copied to
another machine and run there, assuming all of the system libraries are
compatible.
This command collects all dependencies (keys) for the executables and
libraries in the bundle. For each dependency, it copies the required
files into the bundle and adjusts them according to their own
prerequisites. Once complete, it clears the collected keys and invokes
the verify_app() command to ensure the final bundle is truly
standalone.
The arguments are:
<app>The path to the bundle to fix. This can be an .app directory or
direct path to an executable.
<libs>A list of libraries that must be fixed up, but that cannot be
automatically determined by the otool output analysis (i.e.
plugins). If plugins are passed to this command as this parameter,
they should be installed or copied into the bundle before calling this
command.
<dirs>A list of paths where libraries might be found. These paths are searched
first when a target without any path info is given. Then standard system
locations are also searched: PATH, Framework locations, /usr/lib,
etc.
IGNORE_ITEM <files>...Added in version 3.6.
Optional list of file names to ignore
(e.g. IGNORE_ITEM "vcredist_x86.exe;vcredist_x64.exe").
Copies the bundle and fixes up the new copied bundle in-place:
copy_and_fixup_bundle(<src> <dst> <libs> <dirs>)
This command makes a copy of the bundle <src> at location <dst>
and then fixes up the new copied bundle in-place at <dst>.
The arguments are:
<src>The directory of the bundle being copied.
<dst>The destination directory of the bundle copy.
<libs>A list of libraries that must be fixed up, but that cannot be
automatically determined by the otool output analysis (i.e.
plugins). If plugins are passed to this command as this parameter,
they should be installed or copied into the bundle before calling this
command.
<dirs>A list of paths where libraries might be found. These paths are searched
first when a target without any path info is given. Then standard system
locations are also searched: PATH, Framework locations, /usr/lib,
etc.
Verifies that an application bundle appears valid based on running analysis tools on it:
verify_app(<app> [IGNORE_ITEM <files>...])
If the application fails verification, a message(FATAL_ERROR)
is issued, halting the installation process.
The arguments are:
<app>The path to the application to verify. This can be a .app directory
or a standalone executable.
IGNORE_ITEM <files>...Added in version 3.6.
Optional list of file names to ignore
(e.g. IGNORE_ITEM "vcredist_x86.exe;vcredist_x64.exe").
Retrieves the main executable within a given application bundle:
get_bundle_main_executable(<bundle> <result-var>)
The result is stored in a <result-var> variable and will contain a
full path name of the bundle's main executable file, or an error:
prefixed string if it could not be determined.
Locates the enclosing .app directory for the given executable:
get_dotapp_dir(<exe> <dotapp-dir-var>)
This command retrieves the nearest parent dir whose name ends with .app
given the full path to an executable and stores it to the
<dotapp-dir-var> variable. If there is no such parent dir, then it
simply retrieves the directory containing the executable.
The retrieved directory may or may not exist.
Takes either a .app directory name or the name of an executable
nested inside a .app directory and retrieves the path to the .app
directory and the path to its main executable:
get_bundle_and_executable(<app> <bundle-var> <executable-var> <valid-var>)
The arguments are:
<app>The name of the application being processed.
<bundle-var>Variable name in which to store the resulting path to the .app
directory. In case of any error, this variable will contain an error
message prefixed with string error:.
<executable-var>Variable name in which to store the resulting main executable. In case
of any error, this variable will contain an error message prefixed with
string error:.
<valid-var>Variable name in which the boolean result is stored whether this command was successful or not.
Gets all executables of a given bundle:
get_bundle_all_executables(<bundle> <exes-var>)
This command scans <bundle> bundle recursively for all executable
files and stores them into a variable <exes-var>.
Generates a unique key for the given item:
get_item_key(<item> <key-var>)
Given <item> file name, this command generates <key-var> key that
should be unique considering the set of libraries that need copying or
fixing up to make a bundle standalone. This is essentially the file name
including extension with . replaced by _.
This key is used as a prefix for CMake variables so that a set of variables can be associated with a given item based on its key.
Gets RPATHS (run-time search paths) for the given item:
get_item_rpaths(<item> <rpaths-var>)
This command gets RPATHS of the <item> file name and stores them to
the variable with provided name <rpaths-var>.
Clears all variables associated with keys:
clear_bundle_keys(<keys-var>)
This command loops over the <keys-var> list of keys, clearing all the
variables associated with each key. After the loop, it clears the list of
keys itself. This command should be called after the
get_bundle_keys() command, when done working with a list of keys.
Adds a key to the list of keys:
set_bundle_key_values(
<keys-var>
<context>
<item>
<exepath>
<dirs>
<copyflag>
[<rpaths>]
)
This command adds the <keys-var> key to the list (if necessary) for
the given item. If added, also set all the variables associated with
that key.
The arguments are:
<keys-var>Variable name holding the name of the key to be added to the list for the given item.
<context>The path to the top level loading path used for @loader_path
replacement on Apple operating systems. When resolving item,
@loader_path references will be resolved relative to the directory
of the given context value (presumably another library).
<item>The item for which to add the key.
<exepath>The path to the top level executable used for @executable_path
replacement on Apple operating systems.
<dirs>A list of paths where libraries might be found. These paths are searched
first when a target without any path info is given. Then standard system
locations are also searched: PATH, Framework locations, /usr/lib,
etc.
<copyflag>If set to 1 library symlink structure will be preserved.
<rpaths>Optional run-time search paths for an executable file or library to help find files.
Gets bundle keys:
get_bundle_keys(<app> <libs> <dirs> <keys-var> [IGNORE_ITEM <files>...])
This command loops over all the executable and library files within
<app> bundle (and given as extra <libs>) and accumulate a list of
keys representing them. It sets values associated with each key such
that they can be looped over all of them and copies prerequisite libs into
the bundle and then does appropriate install_name_tool fixups.
The arguments are:
<app>The path to the bundle to fix. This can be an .app directory or
direct path to an executable.
<libs>A list of libraries that must be fixed up, but that cannot be
automatically determined by the otool output analysis (i.e.
plugins). If plugins are passed to this command as this parameter,
they should be installed or copied into the bundle before calling this
command.
<dirs>A list of paths where libraries might be found. These paths are searched
first when a target without any path info is given. Then standard system
locations are also searched: PATH, Framework locations, /usr/lib,
etc.
<keys-var>Variable name holding a list of keys that represent all executable and library files within the bundle.
IGNORE_ITEM <files>...Added in version 3.6.
Optional list of file names to ignore
(e.g. IGNORE_ITEM "vcredist_x86.exe;vcredist_x64.exe").
Copies a resolved item into the bundle if necessary:
copy_resolved_item_into_bundle(<resolved-item> <resolved-embedded-item>)
Copy is not necessary, if the <resolved-item> is "the same as" the
<resolved-embedded-item>.
Copies a resolved framework into the bundle if necessary:
copy_resolved_framework_into_bundle(<resolved-item> <resolved-embedded-item>)
Copy is not necessary, if the <resolved-item> is "the same as" the
<resolved-embedded-item>.
The following variables can be set before invoking this command:
BU_COPY_FULL_FRAMEWORK_CONTENTSBy default, this variable is not set. If full frameworks should be
embedded in the bundles, set this variable to boolean true before calling
the fixup_bundle() command. By default, this command copies
the framework dylib itself plus the framework Resources directory.
Fixes up bundle item:
fixup_bundle_item(<resolved-embedded-item> <exepath> <dirs>)
This command gets the direct/non-system prerequisites of the
<resolved-embedded-item> and for each prerequisite, it changes the
way it is referenced to the value of the _EMBEDDED_ITEM keyed variable
for that prerequisite. Most likely changing to an @executable_path
style reference.
This command requires that the <resolved-embedded-item> be inside
the bundle already. In other words, if plugins are passed to
fixup_bundle() command as its <libs> parameter, they should
be installed or copied into the bundle before calling the
fixup_bundle() command.
Also, it changes the id of the item being fixed up to its own
_EMBEDDED_ITEM value.
Changes are accumulated in a local variable and one call is made to
install_name_tool command-line tool at the end of this command with
all the changes at once.
The arguments are:
<resolved-embedded-item>The bundle item to be fixed up.
<exepath>The path to the top level executable used for @executable_path
replacement on Apple operating systems.
<dirs>A list of paths where libraries might be found. These paths are searched
first when a target without any path info is given. Then standard system
locations are also searched: PATH, Framework locations, /usr/lib,
etc.
The following variables can be set before invoking this command:
BU_CHMOD_BUNDLE_ITEMSIf this variable is set to boolean true value then bundle items will be
marked writable before install_name_tool tool tries to change them.
Verifies that the sum of all prerequisites of all files inside the
bundle are contained within the bundle or are system libraries,
presumed to exist everywhere:
verify_bundle_prerequisites(
<bundle>
<result-var>
<info-var>
[IGNORE_ITEM <files>...]
)
The arguments are:
<bundle>Name of the bundle being verified.
<result-var>Name of the variable in which to store a boolean result of whether a verification was successful.
<info-var>Name of the variable holding any informational messages produced by the verification.
IGNORE_ITEM <files>...Added in version 3.6.
Optional list of file names to ignore
(e.g. IGNORE_ITEM "vcredist_x86.exe;vcredist_x64.exe").
Verifies that any symlinks found in the specified bundle point to other files that are already also in the bundle:
verify_bundle_symlinks(<bundle> <result-var> <info-var>)
Anything that points to an external file causes this command to fail the verification.
The arguments are:
<bundle>Name of the bundle being verified.
<result-var>Name of the variable in which to store a boolean result of whether a verification was successful.
<info-var>Name of the variable holding any informational messages produced by the verification.
Using this module inside the installation code that is executed at the installation phase:
CMakeLists.txt# ...
install(CODE "
include(BundleUtilities)
set(BU_CHMOD_BUNDLE_ITEMS TRUE)
fixup_bundle(
\"${fixup_exe}\"
\"${plugins}\"
\"${bin_dir};${library_dir};${binary_dir}\"
)
")