Browse Source

Merge topic 'bundleutilities-policy'

b69159324a Help: Add release notes for new BundleUtilities policy
eedd91ab08 BundleUtilities: Disallow inclusion at configure time
fd28ea35ca Help: Add note for BundleUtilities usage
3925407e76 Help: Convert BundleUtilities help to block-style comment

Acked-by: Kitware Robot <[email protected]>
Merge-request: !2379
Brad King 7 years ago
parent
commit
3523990f7b

+ 1 - 0
Help/manual/cmake-policies.7.rst

@@ -57,6 +57,7 @@ Policies Introduced by CMake 3.13
 .. toctree::
    :maxdepth: 1
 
+   CMP0080: BundleUtilities cannot be included at configure time. </policy/CMP0080>
    CMP0079: target_link_libraries allows use with targets in other directories. </policy/CMP0079>
    CMP0078: UseSWIG generates standard target names. </policy/CMP0078>
    CMP0077: option() honors normal variables. </policy/CMP0077>

+ 25 - 0
Help/policy/CMP0080.rst

@@ -0,0 +1,25 @@
+CMP0080
+-------
+
+:module:`BundleUtilities` cannot be included at configure time.
+
+The macros provided by :module:`BundleUtilities` are intended to be invoked
+at install time rather than at configure time, because they depend on the
+listed targets already existing at the time they are invoked. If they are
+invoked at configure time, the targets haven't been built yet, and the
+commands will fail.
+
+This policy restricts the inclusion of :module:`BundleUtilities` to
+``cmake -P`` style scripts and install rules. Specifically, it looks for the
+presence of :variable:`CMAKE_GENERATOR` and throws a fatal error if it exists.
+
+The ``OLD`` behavior of this policy is to allow :module:`BundleUtilities` to
+be included at configure time. The ``NEW`` behavior of this policy is to
+disallow such inclusion.
+
+This policy was introduced in CMake version 3.13.  CMake version
+|release| warns when the policy is not set and uses ``OLD`` behavior.
+Use the :command:`cmake_policy` command to set it to ``OLD`` or ``NEW``
+explicitly.
+
+.. include:: DEPRECATED.txt

+ 5 - 0
Help/release/dev/bundleutilities-policy.rst

@@ -0,0 +1,5 @@
+bundleutilities-policy
+----------------------
+
+* The :module:`BundleUtilities` module may no longer be included at configure
+  time. This was always a bug anyway. See policy :policy:`CMP0080`.

+ 236 - 217
Modules/BundleUtilities.cmake

@@ -1,223 +1,242 @@
 # Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
 # file Copyright.txt or https://cmake.org/licensing for details.
 
-#.rst:
-# BundleUtilities
-# ---------------
-#
-# Functions to help assemble a standalone bundle application.
-#
-# A collection of CMake utility functions useful for dealing with .app
-# bundles on the Mac and bundle-like directories on any OS.
-#
-# The following functions are provided by this module:
-#
-# ::
-#
-#    fixup_bundle
-#    copy_and_fixup_bundle
-#    verify_app
-#    get_bundle_main_executable
-#    get_dotapp_dir
-#    get_bundle_and_executable
-#    get_bundle_all_executables
-#    get_item_key
-#    get_item_rpaths
-#    clear_bundle_keys
-#    set_bundle_key_values
-#    get_bundle_keys
-#    copy_resolved_item_into_bundle
-#    copy_resolved_framework_into_bundle
-#    fixup_bundle_item
-#    verify_bundle_prerequisites
-#    verify_bundle_symlinks
-#
-# Requires CMake 2.6 or greater because it uses function, break and
-# PARENT_SCOPE.  Also depends on GetPrerequisites.cmake.
-#
-# ::
-#
-#   FIXUP_BUNDLE(<app> <libs> <dirs>)
-#
-# Fix up a bundle in-place and make it standalone, such that it can be
-# drag-n-drop copied to another machine and run on that machine as long
-# as all of the system libraries are compatible.
-#
-# If you pass plugins to fixup_bundle as the libs parameter, you should
-# install them or copy them into the bundle before calling fixup_bundle.
-# The "libs" parameter is a list of libraries that must be fixed up, but
-# that cannot be determined by otool output analysis.  (i.e., plugins)
-#
-# Gather all the keys for all the executables and libraries in a bundle,
-# and then, for each key, copy each prerequisite into the bundle.  Then
-# fix each one up according to its own list of prerequisites.
-#
-# Then clear all the keys and call verify_app on the final bundle to
-# ensure that it is truly standalone.
-#
-# As an optional parameter (IGNORE_ITEM) a list of file names can be passed,
-# which are then ignored (e.g. IGNORE_ITEM "vcredist_x86.exe;vcredist_x64.exe")
-#
-# ::
-#
-#   COPY_AND_FIXUP_BUNDLE(<src> <dst> <libs> <dirs>)
-#
-# Makes a copy of the bundle <src> at location <dst> and then fixes up
-# the new copied bundle in-place at <dst>...
-#
-# ::
-#
-#   VERIFY_APP(<app>)
-#
-# Verifies that an application <app> appears valid based on running
-# analysis tools on it.  Calls "message(FATAL_ERROR" if the application
-# is not verified.
-#
-# As an optional parameter (IGNORE_ITEM) a list of file names can be passed,
-# which are then ignored (e.g. IGNORE_ITEM "vcredist_x86.exe;vcredist_x64.exe")
-#
-# ::
-#
-#   GET_BUNDLE_MAIN_EXECUTABLE(<bundle> <result_var>)
-#
-# The result will be the full path name of the bundle's main executable
-# file or an "error:" prefixed string if it could not be determined.
-#
-# ::
-#
-#   GET_DOTAPP_DIR(<exe> <dotapp_dir_var>)
-#
-# Returns the nearest parent dir whose name ends with ".app" given the
-# full path to an executable.  If there is no such parent dir, then
-# simply return the dir containing the executable.
-#
-# The returned directory may or may not exist.
-#
-# ::
-#
-#   GET_BUNDLE_AND_EXECUTABLE(<app> <bundle_var> <executable_var> <valid_var>)
-#
-# Takes either a ".app" directory name or the name of an executable
-# nested inside a ".app" directory and returns the path to the ".app"
-# directory in <bundle_var> and the path to its main executable in
-# <executable_var>
-#
-# ::
-#
-#   GET_BUNDLE_ALL_EXECUTABLES(<bundle> <exes_var>)
-#
-# Scans the given bundle recursively for all executable files and
-# accumulates them into a variable.
-#
-# ::
-#
-#   GET_ITEM_KEY(<item> <key_var>)
-#
-# Given a file (item) name, generate a 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 we can
-# associate a set of variables with a given item based on its key.
-#
-# ::
-#
-#   CLEAR_BUNDLE_KEYS(<keys_var>)
-#
-# Loop over the list of keys, clearing all the variables associated with
-# each key.  After the loop, clear the list of keys itself.
-#
-# Caller of get_bundle_keys should call clear_bundle_keys when done with
-# list of keys.
-#
-# ::
-#
-#   SET_BUNDLE_KEY_VALUES(<keys_var> <context> <item> <exepath> <dirs>
-#                         <copyflag> [<rpaths>])
-#
-# Add a key to the list (if necessary) for the given item.  If added,
-# also set all the variables associated with that key.
-#
-# ::
-#
-#   GET_BUNDLE_KEYS(<app> <libs> <dirs> <keys_var>)
-#
-# Loop over all the executable and library files within the bundle (and
-# given as extra <libs>) and accumulate a list of keys representing
-# them.  Set values associated with each key such that we can loop over
-# all of them and copy prerequisite libs into the bundle and then do
-# appropriate install_name_tool fixups.
-#
-# As an optional parameter (IGNORE_ITEM) a list of file names can be passed,
-# which are then ignored (e.g. IGNORE_ITEM "vcredist_x86.exe;vcredist_x64.exe")
-#
-# ::
-#
-#   COPY_RESOLVED_ITEM_INTO_BUNDLE(<resolved_item> <resolved_embedded_item>)
-#
-# Copy a resolved item into the bundle if necessary.  Copy is not
-# necessary if the resolved_item is "the same as" the
-# resolved_embedded_item.
-#
-# ::
-#
-#   COPY_RESOLVED_FRAMEWORK_INTO_BUNDLE(<resolved_item> <resolved_embedded_item>)
-#
-# Copy a resolved framework into the bundle if necessary.  Copy is not
-# necessary if the resolved_item is "the same as" the
-# resolved_embedded_item.
-#
-# By default, BU_COPY_FULL_FRAMEWORK_CONTENTS is not set.  If you want
-# full frameworks embedded in your bundles, set
-# BU_COPY_FULL_FRAMEWORK_CONTENTS to ON before calling fixup_bundle.  By
-# default, COPY_RESOLVED_FRAMEWORK_INTO_BUNDLE copies the framework
-# dylib itself plus the framework Resources directory.
-#
-# ::
-#
-#   FIXUP_BUNDLE_ITEM(<resolved_embedded_item> <exepath> <dirs>)
-#
-# Get the direct/non-system prerequisites of the resolved embedded item.
-# For each prerequisite, change 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 function requires that the resolved_embedded_item be "inside" the
-# bundle already.  In other words, if you pass plugins to fixup_bundle
-# as the libs parameter, you should install them or copy them into the
-# bundle before calling fixup_bundle.  The "libs" parameter is a list of
-# libraries that must be fixed up, but that cannot be determined by
-# otool output analysis.  (i.e., plugins)
-#
-# Also, change the id of the item being fixed up to its own
-# _EMBEDDED_ITEM value.
-#
-# Accumulate changes in a local variable and make *one* call to
-# install_name_tool at the end of the function with all the changes at
-# once.
-#
-# If the BU_CHMOD_BUNDLE_ITEMS variable is set then bundle items will be
-# marked writable before install_name_tool tries to change them.
-#
-# ::
-#
-#   VERIFY_BUNDLE_PREREQUISITES(<bundle> <result_var> <info_var>)
-#
-# 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.
-#
-# As an optional parameter (IGNORE_ITEM) a list of file names can be passed,
-# which are then ignored (e.g. IGNORE_ITEM "vcredist_x86.exe;vcredist_x64.exe")
-#
-# ::
-#
-#   VERIFY_BUNDLE_SYMLINKS(<bundle> <result_var> <info_var>)
-#
-# Verifies that any symlinks found in the bundle point to other files
-# that are already also in the bundle...  Anything that points to an
-# external file causes this function to fail the verification.
+#[=======================================================================[.rst:
+BundleUtilities
+---------------
+
+Functions to help assemble a standalone bundle application.
+
+A collection of CMake utility functions useful for dealing with .app
+bundles on the Mac and bundle-like directories on any OS.
+
+The following functions are provided by this module:
+
+::
+
+   fixup_bundle
+   copy_and_fixup_bundle
+   verify_app
+   get_bundle_main_executable
+   get_dotapp_dir
+   get_bundle_and_executable
+   get_bundle_all_executables
+   get_item_key
+   get_item_rpaths
+   clear_bundle_keys
+   set_bundle_key_values
+   get_bundle_keys
+   copy_resolved_item_into_bundle
+   copy_resolved_framework_into_bundle
+   fixup_bundle_item
+   verify_bundle_prerequisites
+   verify_bundle_symlinks
+
+Requires CMake 2.6 or greater because it uses function, break and
+PARENT_SCOPE.  Also depends on GetPrerequisites.cmake.
+
+DO NOT USE THESE FUNCTIONS AT CONFIGURE TIME (from ``CMakeLists.txt``)!
+Instead, invoke them from an :command:`install(CODE)` or
+:command:`install(SCRIPT)` rule.
+
+::
+
+  FIXUP_BUNDLE(<app> <libs> <dirs>)
+
+Fix up a bundle in-place and make it standalone, such that it can be
+drag-n-drop copied to another machine and run on that machine as long
+as all of the system libraries are compatible.
+
+If you pass plugins to fixup_bundle as the libs parameter, you should
+install them or copy them into the bundle before calling fixup_bundle.
+The "libs" parameter is a list of libraries that must be fixed up, but
+that cannot be determined by otool output analysis.  (i.e., plugins)
+
+Gather all the keys for all the executables and libraries in a bundle,
+and then, for each key, copy each prerequisite into the bundle.  Then
+fix each one up according to its own list of prerequisites.
+
+Then clear all the keys and call verify_app on the final bundle to
+ensure that it is truly standalone.
+
+As an optional parameter (IGNORE_ITEM) a list of file names can be passed,
+which are then ignored (e.g. IGNORE_ITEM "vcredist_x86.exe;vcredist_x64.exe")
+
+::
+
+  COPY_AND_FIXUP_BUNDLE(<src> <dst> <libs> <dirs>)
+
+Makes a copy of the bundle <src> at location <dst> and then fixes up
+the new copied bundle in-place at <dst>...
+
+::
+
+  VERIFY_APP(<app>)
+
+Verifies that an application <app> appears valid based on running
+analysis tools on it.  Calls "message(FATAL_ERROR" if the application
+is not verified.
+
+As an optional parameter (IGNORE_ITEM) a list of file names can be passed,
+which are then ignored (e.g. IGNORE_ITEM "vcredist_x86.exe;vcredist_x64.exe")
+
+::
+
+  GET_BUNDLE_MAIN_EXECUTABLE(<bundle> <result_var>)
+
+The result will be the full path name of the bundle's main executable
+file or an "error:" prefixed string if it could not be determined.
+
+::
+
+  GET_DOTAPP_DIR(<exe> <dotapp_dir_var>)
+
+Returns the nearest parent dir whose name ends with ".app" given the
+full path to an executable.  If there is no such parent dir, then
+simply return the dir containing the executable.
+
+The returned directory may or may not exist.
+
+::
+
+  GET_BUNDLE_AND_EXECUTABLE(<app> <bundle_var> <executable_var> <valid_var>)
+
+Takes either a ".app" directory name or the name of an executable
+nested inside a ".app" directory and returns the path to the ".app"
+directory in <bundle_var> and the path to its main executable in
+<executable_var>
+
+::
+
+  GET_BUNDLE_ALL_EXECUTABLES(<bundle> <exes_var>)
+
+Scans the given bundle recursively for all executable files and
+accumulates them into a variable.
+
+::
+
+  GET_ITEM_KEY(<item> <key_var>)
+
+Given a file (item) name, generate a 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 we can
+associate a set of variables with a given item based on its key.
+
+::
+
+  CLEAR_BUNDLE_KEYS(<keys_var>)
+
+Loop over the list of keys, clearing all the variables associated with
+each key.  After the loop, clear the list of keys itself.
+
+Caller of get_bundle_keys should call clear_bundle_keys when done with
+list of keys.
+
+::
+
+  SET_BUNDLE_KEY_VALUES(<keys_var> <context> <item> <exepath> <dirs>
+                        <copyflag> [<rpaths>])
+
+Add a key to the list (if necessary) for the given item.  If added,
+also set all the variables associated with that key.
+
+::
+
+  GET_BUNDLE_KEYS(<app> <libs> <dirs> <keys_var>)
+
+Loop over all the executable and library files within the bundle (and
+given as extra <libs>) and accumulate a list of keys representing
+them.  Set values associated with each key such that we can loop over
+all of them and copy prerequisite libs into the bundle and then do
+appropriate install_name_tool fixups.
+
+As an optional parameter (IGNORE_ITEM) a list of file names can be passed,
+which are then ignored (e.g. IGNORE_ITEM "vcredist_x86.exe;vcredist_x64.exe")
+
+::
+
+  COPY_RESOLVED_ITEM_INTO_BUNDLE(<resolved_item> <resolved_embedded_item>)
+
+Copy a resolved item into the bundle if necessary.  Copy is not
+necessary if the resolved_item is "the same as" the
+resolved_embedded_item.
+
+::
+
+  COPY_RESOLVED_FRAMEWORK_INTO_BUNDLE(<resolved_item> <resolved_embedded_item>)
+
+Copy a resolved framework into the bundle if necessary.  Copy is not
+necessary if the resolved_item is "the same as" the
+resolved_embedded_item.
+
+By default, BU_COPY_FULL_FRAMEWORK_CONTENTS is not set.  If you want
+full frameworks embedded in your bundles, set
+BU_COPY_FULL_FRAMEWORK_CONTENTS to ON before calling fixup_bundle.  By
+default, COPY_RESOLVED_FRAMEWORK_INTO_BUNDLE copies the framework
+dylib itself plus the framework Resources directory.
+
+::
+
+  FIXUP_BUNDLE_ITEM(<resolved_embedded_item> <exepath> <dirs>)
+
+Get the direct/non-system prerequisites of the resolved embedded item.
+For each prerequisite, change 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 function requires that the resolved_embedded_item be "inside" the
+bundle already.  In other words, if you pass plugins to fixup_bundle
+as the libs parameter, you should install them or copy them into the
+bundle before calling fixup_bundle.  The "libs" parameter is a list of
+libraries that must be fixed up, but that cannot be determined by
+otool output analysis.  (i.e., plugins)
+
+Also, change the id of the item being fixed up to its own
+_EMBEDDED_ITEM value.
+
+Accumulate changes in a local variable and make *one* call to
+install_name_tool at the end of the function with all the changes at
+once.
+
+If the BU_CHMOD_BUNDLE_ITEMS variable is set then bundle items will be
+marked writable before install_name_tool tries to change them.
+
+::
+
+  VERIFY_BUNDLE_PREREQUISITES(<bundle> <result_var> <info_var>)
+
+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.
+
+As an optional parameter (IGNORE_ITEM) a list of file names can be passed,
+which are then ignored (e.g. IGNORE_ITEM "vcredist_x86.exe;vcredist_x64.exe")
+
+::
+
+  VERIFY_BUNDLE_SYMLINKS(<bundle> <result_var> <info_var>)
+
+Verifies that any symlinks found in the bundle point to other files
+that are already also in the bundle...  Anything that points to an
+external file causes this function to fail the verification.
+#]=======================================================================]
+
+# Do not include this module at configure time!
+if(DEFINED CMAKE_GENERATOR)
+  cmake_policy(GET CMP0080 _BundleUtilities_CMP0080)
+  if(_BundleUtilities_CMP0080 STREQUAL "NEW")
+    message(FATAL_ERROR "BundleUtilities cannot be included at configure time!")
+  elseif(NOT _BundleUtilities_CMP0080 STREQUAL "OLD")
+    message(AUTHOR_WARNING
+      "Policy CMP0080 is not set: BundleUtilities prefers not to be included at configure time. "
+      "Run \"cmake --help-policy CMP0080\" for policy details. "
+      "Use the cmake_policy command to set the policy and suppress this warning."
+      )
+  endif()
+endif()
 
 # The functions defined in this file depend on the get_prerequisites function
 # (and possibly others) found in:

+ 4 - 1
Source/cmPolicies.h

@@ -234,7 +234,10 @@ class cmMakefile;
   SELECT(                                                                     \
     POLICY, CMP0079,                                                          \
     "target_link_libraries allows use with targets in other directories.", 3, \
-    13, 0, cmPolicies::WARN)
+    13, 0, cmPolicies::WARN)                                                  \
+  SELECT(POLICY, CMP0080,                                                     \
+         "BundleUtilities cannot be included at configure time", 3, 13, 0,    \
+         cmPolicies::WARN)
 
 #define CM_SELECT_ID(F, A1, A2, A3, A4, A5, A6) F(A1)
 #define CM_FOR_EACH_POLICY_ID(POLICY)                                         \

+ 5 - 0
Tests/RunCMake/BundleUtilities/CMP0080-COMMAND.cmake

@@ -0,0 +1,5 @@
+if(DEFINED CMP0080_VALUE)
+  cmake_policy(SET CMP0080 ${CMP0080_VALUE})
+endif()
+
+include(BundleUtilities)

+ 1 - 0
Tests/RunCMake/BundleUtilities/CMP0080-NEW-result.txt

@@ -0,0 +1 @@
+1

+ 2 - 0
Tests/RunCMake/BundleUtilities/CMP0080-NEW-stderr.txt

@@ -0,0 +1,2 @@
+CMake Error at .*/Modules/BundleUtilities\.cmake:[0-9]+ \(message\):
+  BundleUtilities cannot be included at configure time!

+ 2 - 0
Tests/RunCMake/BundleUtilities/CMP0080-NEW.cmake

@@ -0,0 +1,2 @@
+cmake_policy(SET CMP0080 NEW)
+include(BundleUtilities)

+ 2 - 0
Tests/RunCMake/BundleUtilities/CMP0080-OLD.cmake

@@ -0,0 +1,2 @@
+cmake_policy(SET CMP0080 OLD)
+include(BundleUtilities)

+ 4 - 0
Tests/RunCMake/BundleUtilities/CMP0080-WARN-stderr.txt

@@ -0,0 +1,4 @@
+CMake Warning \(dev\) at .*/Modules/BundleUtilities\.cmake:[0-9]+ \(message\):
+  Policy CMP0080 is not set: BundleUtilities prefers not to be included at
+  configure time\.  Run "cmake --help-policy CMP0080" for policy details\.  Use
+  the cmake_policy command to set the policy and suppress this warning\.

+ 1 - 0
Tests/RunCMake/BundleUtilities/CMP0080-WARN.cmake

@@ -0,0 +1 @@
+include(BundleUtilities)

+ 3 - 0
Tests/RunCMake/BundleUtilities/CMakeLists.txt

@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.4)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)

+ 11 - 0
Tests/RunCMake/BundleUtilities/RunCMakeTest.cmake

@@ -0,0 +1,11 @@
+cmake_minimum_required(VERSION 3.4)
+include(RunCMake)
+
+# TODO Migrate Tests/BundleUtilities here
+
+run_cmake(CMP0080-OLD)
+run_cmake(CMP0080-NEW)
+run_cmake(CMP0080-WARN)
+run_cmake_command(CMP0080-COMMAND-OLD ${CMAKE_COMMAND} -DCMP0080_VALUE:STRING=OLD -P ${RunCMake_SOURCE_DIR}/CMP0080-COMMAND.cmake)
+run_cmake_command(CMP0080-COMMAND-NEW ${CMAKE_COMMAND} -DCMP0080_VALUE:STRING=NEW -P ${RunCMake_SOURCE_DIR}/CMP0080-COMMAND.cmake)
+run_cmake_command(CMP0080-COMMAND-WARN ${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}/CMP0080-COMMAND.cmake)

+ 1 - 0
Tests/RunCMake/CMakeLists.txt

@@ -251,6 +251,7 @@ add_RunCMake_test(separate_arguments)
 add_RunCMake_test(set_property)
 add_RunCMake_test(string)
 add_RunCMake_test(test_include_dirs)
+add_RunCMake_test(BundleUtilities)
 
 function(add_RunCMake_test_try_compile)
   if(CMAKE_VERSION VERSION_LESS 3.9.20170907 AND "x${CMAKE_CXX_COMPILER_ID}" STREQUAL "xMSVC")