diff options
author | Felix Lelchuk <felix.lelchuk@gmx.de> | 2021-08-02 17:42:26 (GMT) |
---|---|---|
committer | Felix Lelchuk <felix.lelchuk@gmx.de> | 2021-08-02 17:42:26 (GMT) |
commit | 58d10cf6f13493db124af18e3cac127b2164ea59 (patch) | |
tree | 593dc156eae14ffe6584fa1a31e17f9a18d88a2f /Tests/InstallMode | |
parent | c15bb6f8b8c2eac691138e35d96570d537cc6d69 (diff) | |
download | CMake-58d10cf6f13493db124af18e3cac127b2164ea59.zip CMake-58d10cf6f13493db124af18e3cac127b2164ea59.tar.gz CMake-58d10cf6f13493db124af18e3cac127b2164ea59.tar.bz2 |
Alternative symlink-creating mode for file(INSTALL ...)
An new environment variable 'CMAKE_INSTALL_MODE' is introduced,
which can be used to ask CMake to create symbolic links
instead of copying files during a file(INSTALL ...).
The operation is at the file level only, directory trees are
still created using actual directories, not links.
Signed-off-by: Felix Lelchuk <felix.lelchuk@gmx.de>
Diffstat (limited to 'Tests/InstallMode')
28 files changed, 711 insertions, 0 deletions
diff --git a/Tests/InstallMode/CMakeLists.txt b/Tests/InstallMode/CMakeLists.txt new file mode 100644 index 0000000..96c83a0 --- /dev/null +++ b/Tests/InstallMode/CMakeLists.txt @@ -0,0 +1,124 @@ +cmake_minimum_required(VERSION 3.20.0) + +project(superpro LANGUAGES NONE) + +add_subdirectory(superpro) + +include(Subproject.cmake) +add_subproject(static_lib DIR subpro_a_static_lib) +add_subproject(shared_lib DIR subpro_b_shared_lib) +add_subproject(nested_lib DIR subpro_c_nested_lib NO_INSTALL) +add_subproject(executable DIR subpro_d_executable + DEPENDS + static_lib + shared_lib + nested_lib +) + +include(CTest) +if(BUILD_TESTING) + enable_language(CXX) # required by GNUInstallDirs + include(GNUInstallDirs) + + macro(testme _name _path _symlink) + add_test( + NAME "${_name}" + WORKING_DIRECTORY "${CMAKE_BINARY_DIR}" + COMMAND + "${CMAKE_COMMAND}" + "-DFILE_PATH=${CMAKE_INSTALL_PREFIX}/${_path}" + "-DEXPECT_SYMLINK:BOOL=${_symlink}" + "-DEXPECT_ABSOLUTE:BOOL=${ARGN}" + "-P" "${CMAKE_SOURCE_DIR}/Test.cmake" + ) + endmacro() + + set(_mode $ENV{CMAKE_INSTALL_MODE}) + if(NOT "${_mode}" OR "${_mode}" STREQUAL "COPY") + set(expect_symlink NO) + elseif("${_mode}" MATCHES "(REL_)?SYMLINK(_OR_COPY)?") + set(expect_symlink YES) + set(expect_absolute NO) + elseif("${_mode}" MATCHES "ABS_SYMLINK(_OR_COPY)?") + set(expect_symlink YES) + set(expect_absolute YES) + endif() + + # toplevel project should respect CMAKE_INSTALL_MODE + + testme(superproj_file_copy + "file_copy.txt" NO) + testme(superproj_file_copy_file + "file_copy_file.txt" NO) + testme(superproj_file_install + "file_install.txt" + ${expect_symlink} + ${expect_absolute}) + testme(superproj_file_create_link_symbolic + "file_create_link_symbolic.txt" YES YES) + + # subprojects should receive and respect CMAKE_INSTALL_MODE too + + testme(subpro_a_static_lib_header + "${CMAKE_INSTALL_INCLUDEDIR}/static_lib.h" + ${expect_symlink} + ${expect_absolute} + ) + testme(subpro_a_static_lib_libfile + "${CMAKE_INSTALL_LIBDIR}/${CMAKE_STATIC_LIBRARY_PREFIX}the_static_lib${CMAKE_STATIC_LIBRARY_SUFFIX}" + ${expect_symlink} + ${expect_absolute} + ) + + testme(subpro_b_shared_lib_header + "${CMAKE_INSTALL_INCLUDEDIR}/shared_lib.h" + ${expect_symlink} + ${expect_absolute} + ) + + if(CMAKE_SHARED_LIBRARY_SONAME_CXX_FLAG AND + "${CMAKE_CXX_CREATE_SHARED_MODULE}" MATCHES "SONAME_FLAG") + # due to semver, this is always a link + testme(subpro_b_shared_lib_libfile + "${CMAKE_INSTALL_LIBDIR}/${CMAKE_SHARED_LIBRARY_PREFIX}the_shared_lib${CMAKE_SHARED_LIBRARY_SUFFIX}" + YES + ${expect_absolute} + ) + # this is the actual shared lib, so should follow CMAKE_INSTALL_MODE rules + testme(subpro_b_shared_lib_libfile_versuffix + "${CMAKE_INSTALL_LIBDIR}/${CMAKE_SHARED_LIBRARY_PREFIX}the_shared_lib${CMAKE_SHARED_LIBRARY_SUFFIX}.2.3.4" + ${expect_symlink} + ${expect_absolute} + ) + endif() + + testme(subpro_d_executable_exefile + "${CMAKE_INSTALL_BINDIR}/the_executable${CMAKE_EXECUTABLE_SUFFIX}" + ${expect_symlink} + ${expect_absolute} + ) + + # nested subprojects should receive and respect CMAKE_INSTALL_MODE too + + testme(subsubpro_c1_header + "${CMAKE_INSTALL_INCLUDEDIR}/c1_lib.h" + ${expect_symlink} + ${expect_absolute} + ) + testme(subsubpro_c1_libfile + "${CMAKE_INSTALL_LIBDIR}/${CMAKE_STATIC_LIBRARY_PREFIX}the_c1_lib${CMAKE_STATIC_LIBRARY_SUFFIX}" + ${expect_symlink} + ${expect_absolute} + ) + + testme(subsubpro_c2_header + "${CMAKE_INSTALL_INCLUDEDIR}/c2_lib.h" + ${expect_symlink} + ${expect_absolute} + ) + testme(subsubpro_c2_libfile + "${CMAKE_INSTALL_LIBDIR}/${CMAKE_STATIC_LIBRARY_PREFIX}the_c2_lib${CMAKE_STATIC_LIBRARY_SUFFIX}" + ${expect_symlink} + ${expect_absolute} + ) +endif() diff --git a/Tests/InstallMode/README.txt b/Tests/InstallMode/README.txt new file mode 100644 index 0000000..a4316eb --- /dev/null +++ b/Tests/InstallMode/README.txt @@ -0,0 +1,43 @@ +This is an example superbuild project to demonstrate the use of the +CMAKE_INSTALL_MODE environment variable on. + +The project hierarchy is like (B = Builds / D = Link Dependency): + ++---------------------------------------------------------------------+ +| Superbuild (Top) | ++---------------------------------------------------------------------+ + | | | | + | | | | + (B) (B) (B) (B) + | | | | + v v v v ++---------------+ +---------------+ +---------------+ +---------------+ +| A: Static Lib | | B: Shared Lib | | C: Nested | | D: Executable | +| Project | | Project | | Superbuild | | Project | ++---------------+ +---------------+ +---------------+ +---------------+ + ^ ^ | | | | | + | | (B) (B) | | | + | | | | | | | + | | v | | | | + | | +----------------+ | | | | + | | | C1: Static Lib | | | | | + | | | Project | | (D) (D) (D) + | | +----------------+ | | | | + | | ^ | | | | + | | | v | | | + | | (D) +----------------+ | | | + | | | | C2: Static Lib |<---+ | | + | | +--| Project | | | + | | +----------------+ | | + | | | | + | +------------------------------------+ | + | | + +--------------------------------------------------------+ + +The superbuild system is built on top of ExternalProject_Add(). + +NOTE that the subprojects will configure, build and install +during the build phase ('make') of the top-level project. +There is no install target in the top-level project! +The CMAKE_INSTALL_PREFIX is therefore populated during the build +phase already. diff --git a/Tests/InstallMode/Subproject.cmake b/Tests/InstallMode/Subproject.cmake new file mode 100644 index 0000000..e4354d6 --- /dev/null +++ b/Tests/InstallMode/Subproject.cmake @@ -0,0 +1,76 @@ +include(ExternalProject) + +# add_subproject(<name> [NO_INSTALL] [DIR <dirname>] [DEPENDS [subpro_dep ...]]) +function(add_subproject _name) + cmake_parse_arguments(_arg "NO_INSTALL" "DIR" "DEPENDS" ${ARGN}) + + if(_arg_UNPARSED_ARGUMENTS) + message(FATAL_ERROR "There are unparsed arguments") + endif() + + set(_maybe_NO_INSTALL) + if(_arg_NO_INSTALL) + set(_maybe_NO_INSTALL "INSTALL_COMMAND") + else() + # This is a trick to get a valid call. + # Since we set UPDATE_COMMAND to "" + # explicitly below, this won't harm. + set(_maybe_NO_INSTALL "UPDATE_COMMAND") + endif() + + if(CMAKE_GENERATOR MATCHES "Ninja Multi-Config") + # Replace list separator before passing on to ExternalProject_Add + string(REPLACE ";" "|" _CONFIGURATION_TYPES "${CMAKE_CONFIGURATION_TYPES}") + string(REPLACE ";" "|" _CROSS_CONFIGS "${CMAKE_CROSS_CONFIGS}") + string(REPLACE ";" "|" _DEFAULT_CONFIGS "${CMAKE_DEFAULT_CONFIGS}") + + set(_maybe_NINJA_MULTICONFIG_ARGS + "-DCMAKE_CONFIGURATION_TYPES:STRINGS=${_CONFIGURATION_TYPES}" + "-DCMAKE_CROSS_CONFIGS:STRINGS=${_CROSS_CONFIGS}" + "-DCMAKE_DEFAULT_BUILD_TYPE:STRING=${CMAKE_DEFAULT_BUILD_TYPE}" + "-DCMAKE_DEFAULT_CONFIGS:STRINGS=${_DEFAULT_CONFIGS}" + ) + endif() + + ExternalProject_Add("${_name}" + DOWNLOAD_COMMAND "" + UPDATE_COMMAND "" + ${_maybe_NO_INSTALL} "" + + BUILD_ALWAYS ON + + LOG_DOWNLOAD OFF + LOG_UPDATE OFF + LOG_PATCH OFF + LOG_CONFIGURE OFF + LOG_BUILD OFF + LOG_INSTALL OFF + + SOURCE_DIR "${PROJECT_SOURCE_DIR}/${_arg_DIR}" + + # Private build directory per subproject + BINARY_DIR "${PROJECT_BINARY_DIR}/subproject/${_arg_DIR}" + + # Common install directory, populated immediately + # during build (during build - not install - of superproject) + INSTALL_DIR "${CMAKE_INSTALL_PREFIX}" + + DEPENDS + ${_arg_DEPENDS} + + LIST_SEPARATOR "|" + CMAKE_ARGS + "-DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>" + + # We can rely on ExternalProject to pick the right + # generator (and architecture/toolset where applicable), + # however, we need to explicitly inherit other parent + # project's build settings. + "-DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE}" + ${_maybe_NINJA_MULTICONFIG_ARGS} + + # Subproject progress reports clutter up the output, disable + "-DCMAKE_TARGET_MESSAGES:BOOL=OFF" + "-DCMAKE_RULE_MESSAGES:BOOL=OFF" + ) +endfunction() diff --git a/Tests/InstallMode/Test.cmake b/Tests/InstallMode/Test.cmake new file mode 100644 index 0000000..46c8fa1 --- /dev/null +++ b/Tests/InstallMode/Test.cmake @@ -0,0 +1,38 @@ +message("Testing...") +message("FILE_PATH = ${FILE_PATH}") +message("EXPECT_SYMLINK = ${EXPECT_SYMLINK}") +message("EXPECT_ABSOLUTE = ${EXPECT_ABSOLUTE}") + +if(NOT DEFINED FILE_PATH) + message(FATAL_ERROR "FILE_PATH variable must be defined") +endif() + +if(NOT EXISTS "${FILE_PATH}") + message(FATAL_ERROR "File ${FILE_PATH} does not exist") +endif() + +if(NOT DEFINED EXPECT_SYMLINK) + message(FATAL_ERROR "EXPECT_SYMLINK must be defined") +endif() + +if(EXPECT_SYMLINK) + if(NOT DEFINED EXPECT_ABSOLUTE) + message(FATAL_ERROR "EXPECT_ABSOLUTE variable must be defined") + endif() + + if(NOT IS_SYMLINK "${FILE_PATH}") + message(FATAL_ERROR "${FILE_PATH} must be a symlink") + endif() + + file(READ_SYMLINK "${FILE_PATH}" TARGET_PATH) + + if(EXPECT_ABSOLUTE AND NOT IS_ABSOLUTE "${TARGET_PATH}") + message(FATAL_ERROR "${FILE_PATH} must be an absolute symlink") + elseif(NOT EXPECT_ABSOLUTE AND IS_ABSOLUTE "${TARGET_PATH}") + message(FATAL_ERROR "${FILE_PATH} must be a relative symlink") + endif() +else() + if(IS_SYMLINK "${FILE_PATH}") + message(FATAL_ERROR "${FILE_PATH} must NOT be a symlink") + endif() +endif() diff --git a/Tests/InstallMode/subpro_a_static_lib/CMakeLists.txt b/Tests/InstallMode/subpro_a_static_lib/CMakeLists.txt new file mode 100644 index 0000000..7cd32cc --- /dev/null +++ b/Tests/InstallMode/subpro_a_static_lib/CMakeLists.txt @@ -0,0 +1,60 @@ +# This CMakeLists.txt is part of the subproject A (ExternalProject_Add). + +cmake_minimum_required(VERSION 3.20) +project(static_lib_project VERSION 1.2.3 LANGUAGES CXX) + +include(GNUInstallDirs) + +add_library(the_static_lib STATIC + "include/static_lib.h" + "src/static_lib.cpp" +) + +target_include_directories(the_static_lib PUBLIC + $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include> + $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}> +) + +install( + DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/include/" + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" +) + +install( + TARGETS + the_static_lib + EXPORT main + ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" + LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" +) + +set(INSTALL_CMAKE_DIR "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}") + +include(CMakePackageConfigHelpers) + +configure_package_config_file( + "cmake/PackageConfig.cmake.in" + "${PROJECT_NAME}Config.cmake" + INSTALL_DESTINATION "${INSTALL_CMAKE_DIR}" + PATH_VARS + CMAKE_INSTALL_INCLUDEDIR + CMAKE_INSTALL_LIBDIR +) + +write_basic_package_version_file("${PROJECT_NAME}Version.cmake" + VERSION "${PROJECT_VERSION}" + COMPATIBILITY SameMajorVersion +) + +install( + EXPORT main + FILE "${PROJECT_NAME}Targets.cmake" + DESTINATION "${INSTALL_CMAKE_DIR}" +) + +install( + FILES + "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake" + "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Version.cmake" + DESTINATION "${INSTALL_CMAKE_DIR}" +) diff --git a/Tests/InstallMode/subpro_a_static_lib/cmake/PackageConfig.cmake.in b/Tests/InstallMode/subpro_a_static_lib/cmake/PackageConfig.cmake.in new file mode 100644 index 0000000..0fe72c9 --- /dev/null +++ b/Tests/InstallMode/subpro_a_static_lib/cmake/PackageConfig.cmake.in @@ -0,0 +1,8 @@ +set(@PROJECT_NAME@_VERSION @PROJECT_VERSION@) + +@PACKAGE_INIT@ + +include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake") + +set_and_check(@PROJECT_NAME@_INCLUDE_DIR "@PACKAGE_CMAKE_INSTALL_INCLUDEDIR@") +set_and_check(@PROJECT_NAME@_LIB_DIR "@PACKAGE_CMAKE_INSTALL_LIBDIR@") diff --git a/Tests/InstallMode/subpro_a_static_lib/include/static_lib.h b/Tests/InstallMode/subpro_a_static_lib/include/static_lib.h new file mode 100644 index 0000000..bd82d2e --- /dev/null +++ b/Tests/InstallMode/subpro_a_static_lib/include/static_lib.h @@ -0,0 +1,3 @@ +#pragma once + +void static_hello(); diff --git a/Tests/InstallMode/subpro_a_static_lib/src/static_lib.cpp b/Tests/InstallMode/subpro_a_static_lib/src/static_lib.cpp new file mode 100644 index 0000000..fe1cd85 --- /dev/null +++ b/Tests/InstallMode/subpro_a_static_lib/src/static_lib.cpp @@ -0,0 +1,10 @@ +#include <iostream> + +#include <static_lib.h> + +using namespace std; + +void static_hello() +{ + cout << "Hello from static_lib" << endl; +} diff --git a/Tests/InstallMode/subpro_b_shared_lib/CMakeLists.txt b/Tests/InstallMode/subpro_b_shared_lib/CMakeLists.txt new file mode 100644 index 0000000..eb118c9 --- /dev/null +++ b/Tests/InstallMode/subpro_b_shared_lib/CMakeLists.txt @@ -0,0 +1,66 @@ +# This CMakeLists.txt is part of the subproject B (ExternalProject_Add). + +cmake_minimum_required(VERSION 3.20) +project(shared_lib_project VERSION 2.3.4 LANGUAGES CXX) + +include(GNUInstallDirs) + +add_library(the_shared_lib SHARED + "include/shared_lib.h" + "src/shared_lib.cpp" +) + +set_target_properties(the_shared_lib + PROPERTIES + VERSION "${PROJECT_VERSION}" + SOVERSION "${PROJECT_VERSION}" +) + +target_include_directories(the_shared_lib PUBLIC + $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include> + $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}> +) + +install( + DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/include/" + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" +) + +install( + TARGETS + the_shared_lib + EXPORT main + ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" + LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" +) + +set(INSTALL_CMAKE_DIR "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}") + +include(CMakePackageConfigHelpers) + +configure_package_config_file( + "cmake/PackageConfig.cmake.in" + "${PROJECT_NAME}Config.cmake" + INSTALL_DESTINATION "${INSTALL_CMAKE_DIR}" + PATH_VARS + CMAKE_INSTALL_INCLUDEDIR + CMAKE_INSTALL_LIBDIR +) + +write_basic_package_version_file("${PROJECT_NAME}Version.cmake" + VERSION "${PROJECT_VERSION}" + COMPATIBILITY SameMajorVersion +) + +install( + EXPORT main + FILE "${PROJECT_NAME}Targets.cmake" + DESTINATION "${INSTALL_CMAKE_DIR}" +) + +install( + FILES + "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake" + "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Version.cmake" + DESTINATION "${INSTALL_CMAKE_DIR}" +) diff --git a/Tests/InstallMode/subpro_b_shared_lib/cmake/PackageConfig.cmake.in b/Tests/InstallMode/subpro_b_shared_lib/cmake/PackageConfig.cmake.in new file mode 100644 index 0000000..0fe72c9 --- /dev/null +++ b/Tests/InstallMode/subpro_b_shared_lib/cmake/PackageConfig.cmake.in @@ -0,0 +1,8 @@ +set(@PROJECT_NAME@_VERSION @PROJECT_VERSION@) + +@PACKAGE_INIT@ + +include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake") + +set_and_check(@PROJECT_NAME@_INCLUDE_DIR "@PACKAGE_CMAKE_INSTALL_INCLUDEDIR@") +set_and_check(@PROJECT_NAME@_LIB_DIR "@PACKAGE_CMAKE_INSTALL_LIBDIR@") diff --git a/Tests/InstallMode/subpro_b_shared_lib/include/shared_lib.h b/Tests/InstallMode/subpro_b_shared_lib/include/shared_lib.h new file mode 100644 index 0000000..fd960db --- /dev/null +++ b/Tests/InstallMode/subpro_b_shared_lib/include/shared_lib.h @@ -0,0 +1,3 @@ +#pragma once + +void shared_hello(); diff --git a/Tests/InstallMode/subpro_b_shared_lib/src/shared_lib.cpp b/Tests/InstallMode/subpro_b_shared_lib/src/shared_lib.cpp new file mode 100644 index 0000000..2820d5d --- /dev/null +++ b/Tests/InstallMode/subpro_b_shared_lib/src/shared_lib.cpp @@ -0,0 +1,10 @@ +#include <iostream> + +#include <shared_lib.h> + +using namespace std; + +void shared_hello() +{ + cout << "Hello from shared_lib" << endl; +} diff --git a/Tests/InstallMode/subpro_c_nested_lib/CMakeLists.txt b/Tests/InstallMode/subpro_c_nested_lib/CMakeLists.txt new file mode 100644 index 0000000..e397c02 --- /dev/null +++ b/Tests/InstallMode/subpro_c_nested_lib/CMakeLists.txt @@ -0,0 +1,10 @@ +cmake_minimum_required(VERSION 3.20.0) + +project(subpro_c_nested_lib LANGUAGES NONE) + +include(../Subproject.cmake) +add_subproject(c1_lib DIR subsubpro_c1_lib) +add_subproject(c2_lib DIR subsubpro_c2_lib + DEPENDS + c1_lib +) diff --git a/Tests/InstallMode/subpro_c_nested_lib/subsubpro_c1_lib/CMakeLists.txt b/Tests/InstallMode/subpro_c_nested_lib/subsubpro_c1_lib/CMakeLists.txt new file mode 100644 index 0000000..89f3755 --- /dev/null +++ b/Tests/InstallMode/subpro_c_nested_lib/subsubpro_c1_lib/CMakeLists.txt @@ -0,0 +1,61 @@ +# This CMakeLists.txt is a nested subproject of the +# subproject C (ExternalProject_Add). + +cmake_minimum_required(VERSION 3.20) +project(c1_lib_project VERSION 1.2.3 LANGUAGES CXX) + +include(GNUInstallDirs) + +add_library(the_c1_lib STATIC + "include/c1_lib.h" + "src/c1_lib.cpp" +) + +target_include_directories(the_c1_lib PUBLIC + $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include> + $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}> +) + +install( + DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/include/" + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" +) + +install( + TARGETS + the_c1_lib + EXPORT main + ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" + LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" +) + +set(INSTALL_CMAKE_DIR "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}") + +include(CMakePackageConfigHelpers) + +configure_package_config_file( + "cmake/PackageConfig.cmake.in" + "${PROJECT_NAME}Config.cmake" + INSTALL_DESTINATION "${INSTALL_CMAKE_DIR}" + PATH_VARS + CMAKE_INSTALL_INCLUDEDIR + CMAKE_INSTALL_LIBDIR +) + +write_basic_package_version_file("${PROJECT_NAME}Version.cmake" + VERSION "${PROJECT_VERSION}" + COMPATIBILITY SameMajorVersion +) + +install( + EXPORT main + FILE "${PROJECT_NAME}Targets.cmake" + DESTINATION "${INSTALL_CMAKE_DIR}" +) + +install( + FILES + "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake" + "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Version.cmake" + DESTINATION "${INSTALL_CMAKE_DIR}" +) diff --git a/Tests/InstallMode/subpro_c_nested_lib/subsubpro_c1_lib/cmake/PackageConfig.cmake.in b/Tests/InstallMode/subpro_c_nested_lib/subsubpro_c1_lib/cmake/PackageConfig.cmake.in new file mode 100644 index 0000000..0fe72c9 --- /dev/null +++ b/Tests/InstallMode/subpro_c_nested_lib/subsubpro_c1_lib/cmake/PackageConfig.cmake.in @@ -0,0 +1,8 @@ +set(@PROJECT_NAME@_VERSION @PROJECT_VERSION@) + +@PACKAGE_INIT@ + +include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake") + +set_and_check(@PROJECT_NAME@_INCLUDE_DIR "@PACKAGE_CMAKE_INSTALL_INCLUDEDIR@") +set_and_check(@PROJECT_NAME@_LIB_DIR "@PACKAGE_CMAKE_INSTALL_LIBDIR@") diff --git a/Tests/InstallMode/subpro_c_nested_lib/subsubpro_c1_lib/include/c1_lib.h b/Tests/InstallMode/subpro_c_nested_lib/subsubpro_c1_lib/include/c1_lib.h new file mode 100644 index 0000000..245f9d4 --- /dev/null +++ b/Tests/InstallMode/subpro_c_nested_lib/subsubpro_c1_lib/include/c1_lib.h @@ -0,0 +1,3 @@ +#pragma once + +void c1_hello(); diff --git a/Tests/InstallMode/subpro_c_nested_lib/subsubpro_c1_lib/src/c1_lib.cpp b/Tests/InstallMode/subpro_c_nested_lib/subsubpro_c1_lib/src/c1_lib.cpp new file mode 100644 index 0000000..c405056 --- /dev/null +++ b/Tests/InstallMode/subpro_c_nested_lib/subsubpro_c1_lib/src/c1_lib.cpp @@ -0,0 +1,10 @@ +#include <iostream> + +#include <c1_lib.h> + +using namespace std; + +void c1_hello() +{ + cout << "Hello from c1_lib" << endl; +} diff --git a/Tests/InstallMode/subpro_c_nested_lib/subsubpro_c2_lib/CMakeLists.txt b/Tests/InstallMode/subpro_c_nested_lib/subsubpro_c2_lib/CMakeLists.txt new file mode 100644 index 0000000..e139446 --- /dev/null +++ b/Tests/InstallMode/subpro_c_nested_lib/subsubpro_c2_lib/CMakeLists.txt @@ -0,0 +1,68 @@ +# This CMakeLists.txt is a nested subproject of the +# subproject C (ExternalProject_Add). + +cmake_minimum_required(VERSION 3.20) +project(c2_lib_project VERSION 1.2.3 LANGUAGES CXX) + +find_package(c1_lib_project REQUIRED) + +include(GNUInstallDirs) + +add_library(the_c2_lib STATIC + "include/c2_lib.h" + "src/c2_lib.cpp" +) + +target_link_libraries(the_c2_lib + PUBLIC + the_c1_lib +) + +target_include_directories(the_c2_lib PUBLIC + $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include> + $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}> +) + +install( + DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/include/" + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" +) + +install( + TARGETS + the_c2_lib + EXPORT main + ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" + LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" +) + +set(INSTALL_CMAKE_DIR "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}") + +include(CMakePackageConfigHelpers) + +configure_package_config_file( + "cmake/PackageConfig.cmake.in" + "${PROJECT_NAME}Config.cmake" + INSTALL_DESTINATION "${INSTALL_CMAKE_DIR}" + PATH_VARS + CMAKE_INSTALL_INCLUDEDIR + CMAKE_INSTALL_LIBDIR +) + +write_basic_package_version_file("${PROJECT_NAME}Version.cmake" + VERSION "${PROJECT_VERSION}" + COMPATIBILITY SameMajorVersion +) + +install( + EXPORT main + FILE "${PROJECT_NAME}Targets.cmake" + DESTINATION "${INSTALL_CMAKE_DIR}" +) + +install( + FILES + "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake" + "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Version.cmake" + DESTINATION "${INSTALL_CMAKE_DIR}" +) diff --git a/Tests/InstallMode/subpro_c_nested_lib/subsubpro_c2_lib/cmake/PackageConfig.cmake.in b/Tests/InstallMode/subpro_c_nested_lib/subsubpro_c2_lib/cmake/PackageConfig.cmake.in new file mode 100644 index 0000000..45a177a --- /dev/null +++ b/Tests/InstallMode/subpro_c_nested_lib/subsubpro_c2_lib/cmake/PackageConfig.cmake.in @@ -0,0 +1,11 @@ +set(@PROJECT_NAME@_VERSION @PROJECT_VERSION@) + +@PACKAGE_INIT@ + +include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake") + +set_and_check(@PROJECT_NAME@_INCLUDE_DIR "@PACKAGE_CMAKE_INSTALL_INCLUDEDIR@") +set_and_check(@PROJECT_NAME@_LIB_DIR "@PACKAGE_CMAKE_INSTALL_LIBDIR@") + +include(CMakeFindDependencyMacro) +find_dependency(c1_lib_project REQUIRED) diff --git a/Tests/InstallMode/subpro_c_nested_lib/subsubpro_c2_lib/include/c2_lib.h b/Tests/InstallMode/subpro_c_nested_lib/subsubpro_c2_lib/include/c2_lib.h new file mode 100644 index 0000000..5056814 --- /dev/null +++ b/Tests/InstallMode/subpro_c_nested_lib/subsubpro_c2_lib/include/c2_lib.h @@ -0,0 +1,3 @@ +#pragma once + +void c2_hello(); diff --git a/Tests/InstallMode/subpro_c_nested_lib/subsubpro_c2_lib/src/c2_lib.cpp b/Tests/InstallMode/subpro_c_nested_lib/subsubpro_c2_lib/src/c2_lib.cpp new file mode 100644 index 0000000..cd2c932 --- /dev/null +++ b/Tests/InstallMode/subpro_c_nested_lib/subsubpro_c2_lib/src/c2_lib.cpp @@ -0,0 +1,12 @@ +#include <iostream> + +#include <c1_lib.h> +#include <c2_lib.h> + +using namespace std; + +void c2_hello() +{ + cout << "Hello from c2_lib and also..." << endl; + c1_hello(); +} diff --git a/Tests/InstallMode/subpro_d_executable/CMakeLists.txt b/Tests/InstallMode/subpro_d_executable/CMakeLists.txt new file mode 100644 index 0000000..9847227 --- /dev/null +++ b/Tests/InstallMode/subpro_d_executable/CMakeLists.txt @@ -0,0 +1,24 @@ +# This CMakeLists.txt is part of the subproject B (ExternalProject_Add). + +cmake_minimum_required(VERSION 3.20) +project(subpro_d_executable LANGUAGES CXX) + +find_package(static_lib_project REQUIRED) +find_package(shared_lib_project REQUIRED) +find_package(c2_lib_project REQUIRED) + +add_executable(the_executable + "src/main.cpp" +) + +target_link_libraries(the_executable PRIVATE + the_static_lib + the_shared_lib + the_c2_lib +) + +install( + TARGETS + the_executable + RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" +) diff --git a/Tests/InstallMode/subpro_d_executable/src/main.cpp b/Tests/InstallMode/subpro_d_executable/src/main.cpp new file mode 100644 index 0000000..ec12004 --- /dev/null +++ b/Tests/InstallMode/subpro_d_executable/src/main.cpp @@ -0,0 +1,13 @@ +#include <cstdlib> + +#include <c2_lib.h> +#include <shared_lib.h> +#include <static_lib.h> + +int main() +{ + static_hello(); + shared_hello(); + c2_hello(); + return EXIT_SUCCESS; +} diff --git a/Tests/InstallMode/superpro/CMakeLists.txt b/Tests/InstallMode/superpro/CMakeLists.txt new file mode 100644 index 0000000..ae4d25c --- /dev/null +++ b/Tests/InstallMode/superpro/CMakeLists.txt @@ -0,0 +1,29 @@ +# This CMakeLists.txt is part of the superproject (add_subdirectory). + +# Below file transfers are executed at configuration time! + +file( + COPY + "file_copy.txt" + DESTINATION + "${CMAKE_INSTALL_PREFIX}" +) + +file(COPY_FILE + "${CMAKE_CURRENT_SOURCE_DIR}/file_copy_file.txt" + "${CMAKE_INSTALL_PREFIX}/file_copy_file.txt" +) + +file( + INSTALL + "file_install.txt" + DESTINATION + "${CMAKE_INSTALL_PREFIX}" +) + +file( + CREATE_LINK + "${CMAKE_CURRENT_SOURCE_DIR}/file_create_link_symbolic.txt" + "${CMAKE_INSTALL_PREFIX}/file_create_link_symbolic.txt" + SYMBOLIC +) diff --git a/Tests/InstallMode/superpro/file_copy.txt b/Tests/InstallMode/superpro/file_copy.txt new file mode 100644 index 0000000..aacbb96 --- /dev/null +++ b/Tests/InstallMode/superpro/file_copy.txt @@ -0,0 +1 @@ +This file should always be copied into CMAKE_INSTALL_PREFIX. diff --git a/Tests/InstallMode/superpro/file_copy_file.txt b/Tests/InstallMode/superpro/file_copy_file.txt new file mode 100644 index 0000000..aacbb96 --- /dev/null +++ b/Tests/InstallMode/superpro/file_copy_file.txt @@ -0,0 +1 @@ +This file should always be copied into CMAKE_INSTALL_PREFIX. diff --git a/Tests/InstallMode/superpro/file_create_link_symbolic.txt b/Tests/InstallMode/superpro/file_create_link_symbolic.txt new file mode 100644 index 0000000..16a481b --- /dev/null +++ b/Tests/InstallMode/superpro/file_create_link_symbolic.txt @@ -0,0 +1,2 @@ +This file should always be installed into CMAKE_INSTALL_PREFIX +as a symbolic link to the original file. diff --git a/Tests/InstallMode/superpro/file_install.txt b/Tests/InstallMode/superpro/file_install.txt new file mode 100644 index 0000000..eac9782 --- /dev/null +++ b/Tests/InstallMode/superpro/file_install.txt @@ -0,0 +1,6 @@ +This file should be placed in CMAKE_INSTALL_PREFIX +as a copy if the CMAKE_INSTALL_MODE environment variable +is unset or equals "COPY". +If the variable's value is "SYMLINK" or "SYMLINK_OR_COPY", +the CMAKE_INSTALL_PREFIX should rather receive a symbolic +link to this file. |