summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Help/envvar/CMAKE_INSTALL_MODE.rst111
-rw-r--r--Modules/CMakeCCompilerId.c.in2
-rw-r--r--Modules/CMakeCUDACompilerId.cu.in2
-rw-r--r--Modules/CMakeCXXCompilerId.cpp.in2
-rw-r--r--Modules/ExternalProject.cmake16
-rw-r--r--Modules/GNUInstallDirs.cmake4
-rw-r--r--Source/cmTimestamp.cxx2
7 files changed, 118 insertions, 21 deletions
diff --git a/Help/envvar/CMAKE_INSTALL_MODE.rst b/Help/envvar/CMAKE_INSTALL_MODE.rst
index 37db0d7..4549ea1 100644
--- a/Help/envvar/CMAKE_INSTALL_MODE.rst
+++ b/Help/envvar/CMAKE_INSTALL_MODE.rst
@@ -13,25 +13,104 @@ 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``:
-* empty, unset or ``COPY``: default behavior, duplicate the file at its destination
-* ``ABS_SYMLINK``: create an *absolute* symbolic link to the source file at the destination *or fail*
-* ``ABS_SYMLINK_OR_COPY``: like ``ABS_SYMLINK`` but silently copy on error
-* ``REL_SYMLINK``: create an *relative* symbolic link to the source file at the destination *or fail*
-* ``REL_SYMLINK_OR_COPY``: like ``REL_SYMLINK`` but silently copy on error
-* ``SYMLINK``: try as if through ``REL_SYMLINK`` and fall back to ``ABS_SYMLINK`` if the referenced
- file cannot be expressed using a relative path. Fail on error.
-* ``SYMLINK_OR_COPY``: like ``SYMLINK`` but silently copy on error
+``COPY``, empty or unset
+ Duplicate the file at its destination. This is the default behavior.
+
+``ABS_SYMLINK``
+ Create an *absolute* symbolic link to the source file at the destination.
+ Halt with an error if the link cannot be created.
+
+``ABS_SYMLINK_OR_COPY``
+ Like ``ABS_SYMLINK`` but fall back to silently copying if the symlink
+ couldn't be created.
+
+``REL_SYMLINK``
+ Create a *relative* symbolic link to the source file at the destination.
+ Halt with an error if the link cannot be created.
+
+``REL_SYMLINK_OR_COPY``
+ Like ``REL_SYMLINK`` but fall back to silently copying if the symlink
+ couldn't be created.
+
+``SYMLINK``
+ Try as if through ``REL_SYMLINK`` and fall back to ``ABS_SYMLINK`` if the
+ referenced file cannot be expressed using a relative path.
+ Halt with an error if the link cannot be created.
+
+``SYMLINK_OR_COPY``
+ Like ``SYMLINK`` but fall back to silently copying if the symlink couldn't
+ be created.
+
+.. 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.
-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*.
+* 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.
-.. note:: ``CMAKE_INSTALL_MODE`` only affects files, *not* directories.
+* Combining ``CMAKE_INSTALL_MODE`` with :prop_tgt:`IOS_INSTALL_COMBINED` is
+ not supported.
-.. note:: Symbolic links are not available on all platforms.
+* 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.
diff --git a/Modules/CMakeCCompilerId.c.in b/Modules/CMakeCCompilerId.c.in
index 43ede3e..30ad9824 100644
--- a/Modules/CMakeCCompilerId.c.in
+++ b/Modules/CMakeCCompilerId.c.in
@@ -60,7 +60,7 @@ const char* info_language_standard_default =
"INFO" ":" "standard_default[" C_VERSION "]";
const char* info_language_extensions_default = "INFO" ":" "extensions_default["
-// !defined(_MSC_VER) to exclude Clang's MSVC compatibility mode.
+/* !defined(_MSC_VER) to exclude Clang's MSVC compatibility mode. */
#if (defined(__clang__) || defined(__GNUC__) || \
defined(__TI_COMPILER_VERSION__)) && \
!defined(__STRICT_ANSI__) && !defined(_MSC_VER)
diff --git a/Modules/CMakeCUDACompilerId.cu.in b/Modules/CMakeCUDACompilerId.cu.in
index bc685a7..becb9b4 100644
--- a/Modules/CMakeCUDACompilerId.cu.in
+++ b/Modules/CMakeCUDACompilerId.cu.in
@@ -33,7 +33,7 @@ const char* info_language_standard_default = "INFO" ":" "standard_default["
"]";
const char* info_language_extensions_default = "INFO" ":" "extensions_default["
-// !defined(_MSC_VER) to exclude Clang's MSVC compatibility mode.
+/* !defined(_MSC_VER) to exclude Clang's MSVC compatibility mode. */
#if (defined(__clang__) || defined(__GNUC__)) && !defined(__STRICT_ANSI__) && \
!defined(_MSC_VER)
"ON"
diff --git a/Modules/CMakeCXXCompilerId.cpp.in b/Modules/CMakeCXXCompilerId.cpp.in
index cdf9c18..e7a5487 100644
--- a/Modules/CMakeCXXCompilerId.cpp.in
+++ b/Modules/CMakeCXXCompilerId.cpp.in
@@ -66,7 +66,7 @@ const char* info_language_standard_default = "INFO" ":" "standard_default["
"]";
const char* info_language_extensions_default = "INFO" ":" "extensions_default["
-// !defined(_MSC_VER) to exclude Clang's MSVC compatibility mode.
+/* !defined(_MSC_VER) to exclude Clang's MSVC compatibility mode. */
#if (defined(__clang__) || defined(__GNUC__) || \
defined(__TI_COMPILER_VERSION__)) && \
!defined(__STRICT_ANSI__) && !defined(_MSC_VER)
diff --git a/Modules/ExternalProject.cmake b/Modules/ExternalProject.cmake
index e49faae..4004ea4 100644
--- a/Modules/ExternalProject.cmake
+++ b/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.
diff --git a/Modules/GNUInstallDirs.cmake b/Modules/GNUInstallDirs.cmake
index 6ca424a..01bd637 100644
--- a/Modules/GNUInstallDirs.cmake
+++ b/Modules/GNUInstallDirs.cmake
@@ -253,7 +253,9 @@ if(NOT DEFINED CMAKE_INSTALL_LIBDIR OR (_libdir_set
elseif(DEFINED ENV{CONDA_PREFIX})
set(conda_prefix "$ENV{CONDA_PREFIX}")
cmake_path(ABSOLUTE_PATH conda_prefix NORMALIZE)
- if("${CMAKE_INSTALL_PREFIX}" STREQUAL conda_prefix)
+ if("${CMAKE_INSTALL_PREFIX}" STREQUAL conda_prefix AND
+ NOT ("${CMAKE_INSTALL_PREFIX}" MATCHES "^/usr/?$" OR
+ "${CMAKE_INSTALL_PREFIX}" MATCHES "^/usr/local/?$"))
set(__system_type_for_install "conda")
endif()
endif()
diff --git a/Source/cmTimestamp.cxx b/Source/cmTimestamp.cxx
index c8f5a4b..3826577 100644
--- a/Source/cmTimestamp.cxx
+++ b/Source/cmTimestamp.cxx
@@ -197,7 +197,7 @@ std::string cmTimestamp::AddTimestampComponent(char flag,
#ifdef __MINGW32__
/* See a bug in MinGW: https://sourceforge.net/p/mingw-w64/bugs/793/. A work
* around is to try to use strftime() from ucrtbase.dll. */
- using T = size_t(WINAPI*)(char*, size_t, const char*, const struct tm*);
+ using T = size_t(__cdecl*)(char*, size_t, const char*, const struct tm*);
auto loadUcrtStrftime = []() -> T {
auto handle =
LoadLibraryExA("ucrtbase.dll", nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32);