Browse Source

Help: Clarify CMAKE_INSTALL_MODE documentation

Fixes: #22869
Co-Authored-By: Craig Scott <[email protected]>
Felix Lelchuk 4 years ago
parent
commit
3caeee0c86
2 changed files with 86 additions and 10 deletions
  1. 70 10
      Help/envvar/CMAKE_INSTALL_MODE.rst
  2. 16 0
      Modules/ExternalProject.cmake

+ 70 - 10
Help/envvar/CMAKE_INSTALL_MODE.rst

@@ -13,9 +13,22 @@ source directory into a destination directory. This environment variable
 however allows the user to override this behavior, causing CMake to create
 symbolic links instead.
 
-.. note::
-  A symbolic link consists of a reference file path rather than contents of its own,
-  hence there are two ways to express the relation, either by a relative or an absolute path.
+Usage Scenarios
+^^^^^^^^^^^^^^^
+
+Installing symbolic links rather than copying files can help in the following
+ways:
+
+* Conserving storage space because files do not have to be duplicated on disk.
+* Changes to the source of the symbolic link are seen at the install
+  destination without having to re-run the install step.
+* Editing through the link at the install destination will modify the source
+  of the link. This may be useful when dealing with CMake project hierarchies,
+  i.e. using :module:`ExternalProject` and consistent source navigation and
+  refactoring is desired across projects.
+
+Allowed Values
+^^^^^^^^^^^^^^
 
 The following values are allowed for ``CMAKE_INSTALL_MODE``:
 
@@ -47,10 +60,57 @@ The following values are allowed for ``CMAKE_INSTALL_MODE``:
   Like ``SYMLINK`` but fall back to silently copying if the symlink couldn't
   be created.
 
-Installing symbolic links rather than copying files can help conserve storage space because files do
-not have to be duplicated on disk. However, modifications applied to the source immediately affects
-the symbolic link and vice versa. *Use with caution*.
-
-.. note:: ``CMAKE_INSTALL_MODE`` only affects files, *not* directories.
-
-.. note:: Symbolic links are not available on all platforms.
+.. note::
+  A symbolic link consists of a reference file path rather than contents of its
+  own, hence there are two ways to express the relation, either by a *relative*
+  or an *absolute* path.
+
+When To Set The Environment Variable
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+For the environment variable to take effect, it must be set during the correct
+build phase(s).
+
+* If the project calls :command:`file(INSTALL)` directly, the environment
+  variable must be set during the configuration phase.
+* In order to apply to :command:`install()`, the environment variable must be
+  set during installation.  This could be during a build if using the
+  ``install`` or ``package`` build targets, or separate from the build when
+  invoking an install or running :manual:`cpack <cpack(1)>` from the command
+  line.
+* When using :module:`ExternalProject`, it might be required during the build
+  phase, since the external project's own configure, build and install steps
+  will execute during the main project's build phase.
+
+Given the above, it is recommended to set the environment variable consistently
+across all phases (configure, build and install).
+
+Caveats
+^^^^^^^
+
+Use this environment variable with caution. The following highlights some
+points to be considered:
+
+* ``CMAKE_INSTALL_MODE`` only affects files, not directories.
+
+* Symbolic links are not available on all platforms.
+
+* The way this environment variable interacts with the install step of
+  :module:`ExternalProject` is more complex. For further details, see that
+  module's documentation.
+
+* A symbolic link ties the destination to the source in a persistent way.
+  Writing to either of the two affects both file system objects.
+  This is in contrast to normal install behavior which only copies files as
+  they were at the time the install was performed, with no enduring
+  relationship between the source and destination of the install.
+
+* Combining ``CMAKE_INSTALL_MODE`` with :prop_tgt:`IOS_INSTALL_COMBINED` is
+  not supported.
+
+* Changing ``CMAKE_INSTALL_MODE`` from what it was on a previous run can lead
+  to unexpected results.  Moving from a non-symlinking mode to a symlinking
+  mode will discard any previous file at the destination, but the reverse is
+  not true.  Once a symlink exists at the destination, even if you switch to a
+  non-symlink mode, the symlink will continue to exist at the destination and
+  will not be replaced by an actual file.

+ 16 - 0
Modules/ExternalProject.cmake

@@ -637,6 +637,22 @@ External Project Definition
       supported). Passing an empty string as the ``<cmd>`` makes the install
       step do nothing.
 
+    .. note::
+      If the :envvar:`CMAKE_INSTALL_MODE` environment variable is set when the
+      main project is built, it will only have an effect if the following
+      conditions are met:
+
+      * The main project's configure step assumed the external project uses
+        CMake as its build system.
+      * The external project's install command actually runs. Note that due
+        to the way ``ExternalProject`` may use timestamps internally, if
+        nothing the install step depends on needs to be re-executed, the
+        install command might also not need to run.
+
+      Note also that ``ExternalProject`` does not check whether the
+      :envvar:`CMAKE_INSTALL_MODE` environment variable changes from one run
+      to another.
+
   **Test Step Options:**
     The test step is only defined if at least one of the following ``TEST_...``
     options are provided.