diff options
-rw-r--r-- | Help/envvar/CMAKE_INSTALL_MODE.rst | 111 | ||||
-rw-r--r-- | Modules/CMakeCCompilerId.c.in | 2 | ||||
-rw-r--r-- | Modules/CMakeCUDACompilerId.cu.in | 2 | ||||
-rw-r--r-- | Modules/CMakeCXXCompilerId.cpp.in | 2 | ||||
-rw-r--r-- | Modules/ExternalProject.cmake | 16 | ||||
-rw-r--r-- | Modules/GNUInstallDirs.cmake | 4 | ||||
-rw-r--r-- | Source/cmTimestamp.cxx | 2 |
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); |