diff options
Diffstat (limited to 'Tests')
34 files changed, 851 insertions, 20 deletions
diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index ef8c84648c..9dab5b9f77 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -1648,6 +1648,54 @@ if(BUILD_TESTING) WORKING_DIRECTORY ${CMake_SOURCE_DIR}/Tests/ExternalProjectUpdate DEPENDS ExternalProjectUpdateSetup ) + execute_process( + COMMAND ${CMAKE_CMAKE_COMMAND} + "-E" create_symlink + "${CMake_SOURCE_DIR}/Tests/CMakeLists.txt" # random source file that exists + "${CMake_BINARY_DIR}/Tests/try_to_create_symlink" # random target file in existing directory + RESULT_VARIABLE _failed + ) + if(_failed) + message("Failed to create a simple symlink on this machine. Skipping InstallMode tests.") + else() + function(add_installmode_test _mode) + set(ENV{CMAKE_INSTALL_MODE} _mode) + set(_maybe_InstallMode_CTEST_OPTIONS) + set(_maybe_BUILD_OPTIONS) + if(_isMultiConfig) + set(_maybe_CTEST_OPTIONS -C $<CONFIGURATION>) + else() + set(_maybe_BUILD_OPTIONS "-DCMAKE_BUILD_TYPE=$<CONFIGURATION>") + endif() + add_test( + NAME "InstallMode-${_mode}" + COMMAND + ${CMAKE_CTEST_COMMAND} -V ${_maybe_CTEST_OPTIONS} + --build-and-test + "${CMake_SOURCE_DIR}/Tests/InstallMode" + "${CMake_BINARY_DIR}/Tests/InstallMode-${_mode}" + ${build_generator_args} + --build-project superpro + --build-exe-dir "${CMake_BINARY_DIR}/Tests/InstallMode-${_mode}" + --force-new-ctest-process + --build-options + ${_maybe_BUILD_OPTIONS} + "-DCMAKE_INSTALL_PREFIX:PATH=${CMake_BINARY_DIR}/Tests/InstallMode-${_mode}/install" + ) + list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/InstallMode-${_mode}") + unset(ENV{CMAKE_INSTALL_MODE}) + endfunction() + + add_installmode_test(COPY) + add_installmode_test(REL_SYMLINK) + add_installmode_test(REL_SYMLINK_OR_COPY) + add_installmode_test(ABS_SYMLINK) + add_installmode_test(ABS_SYMLINK_OR_COPY) + add_installmode_test(SYMLINK) + add_installmode_test(SYMLINK_OR_COPY) + endif() + + # do each of the tutorial steps function(add_tutorial_test step_name use_mymath tutorial_arg pass_regex) set(tutorial_test_name Tutorial${step_name}) diff --git a/Tests/InstallMode/CMakeLists.txt b/Tests/InstallMode/CMakeLists.txt new file mode 100644 index 0000000000..96c83a05d5 --- /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 0000000000..a4316ebb53 --- /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 0000000000..e4354d67ee --- /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 0000000000..46c8fa1dae --- /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 0000000000..7cd32cc6ef --- /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 0000000000..0fe72c91f5 --- /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 0000000000..bd82d2eea5 --- /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 0000000000..fe1cd854a7 --- /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 0000000000..eb118c9a1b --- /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 0000000000..0fe72c91f5 --- /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 0000000000..fd960db019 --- /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 0000000000..2820d5d02f --- /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 0000000000..e397c02e19 --- /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 0000000000..89f3755598 --- /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 0000000000..0fe72c91f5 --- /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 0000000000..245f9d48c7 --- /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 0000000000..c405056eb7 --- /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 0000000000..e139446edc --- /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 0000000000..45a177a531 --- /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 0000000000..5056814f40 --- /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 0000000000..cd2c9321ea --- /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 0000000000..9847227573 --- /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 0000000000..ec12004af4 --- /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 0000000000..ae4d25c1f3 --- /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 0000000000..aacbb96442 --- /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 0000000000..aacbb96442 --- /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 0000000000..16a481ba18 --- /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 0000000000..eac97823b1 --- /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. diff --git a/Tests/RunCMake/GoogleTest/GoogleTest-test3-stdout.txt b/Tests/RunCMake/GoogleTest/GoogleTest-test3-stdout.txt new file mode 100644 index 0000000000..cf082670f7 --- /dev/null +++ b/Tests/RunCMake/GoogleTest/GoogleTest-test3-stdout.txt @@ -0,0 +1,16 @@ +Test project .* + Start 27: TEST:basic\.case_foo!3 +1/4 Test #27: TEST:basic\.case_foo!3 \.+ +Passed +[0-9.]+ sec + Start 28: TEST:basic\.case_bar!3 +2/4 Test #28: TEST:basic\.case_bar!3 \.+ +Passed +[0-9.]+ sec + Start 29: TEST:basic\.disabled_case!3 +3/4 Test #29: TEST:basic\.disabled_case!3 \.+\*+Not Run \(Disabled\) +[0-9.]+ sec + Start 30: TEST:basic\.DISABLEDnot_really_case!3 +4/4 Test #30: TEST:basic\.DISABLEDnot_really_case!3 \.+ +Passed +[0-9.]+ sec + +100% tests passed, 0 tests failed out of 3 + +Total Test time \(real\) = +[0-9.]+ sec + +The following tests did not run: +.*29 - TEST:basic.disabled_case!3 \(Disabled\) diff --git a/Tests/RunCMake/GoogleTest/GoogleTest-test4-stdout.txt b/Tests/RunCMake/GoogleTest/GoogleTest-test4-stdout.txt new file mode 100644 index 0000000000..4a9d75b787 --- /dev/null +++ b/Tests/RunCMake/GoogleTest/GoogleTest-test4-stdout.txt @@ -0,0 +1,9 @@ +Test project .* + Start 31: TEST:typed/short\.case!4 +1/2 Test #31: TEST:typed/short\.case!4 \.+ +Passed +[0-9.]+ sec + Start 32: TEST:typed/float\.case!4 +2/2 Test #32: TEST:typed/float\.case!4 \.+ +Passed +[0-9.]+ sec + +100% tests passed, 0 tests failed out of 2 + +Total Test time \(real\) = +[0-9.]+ sec diff --git a/Tests/RunCMake/GoogleTest/GoogleTest.cmake b/Tests/RunCMake/GoogleTest/GoogleTest.cmake index 8efd1171de..221d6adac4 100644 --- a/Tests/RunCMake/GoogleTest/GoogleTest.cmake +++ b/Tests/RunCMake/GoogleTest/GoogleTest.cmake @@ -24,6 +24,24 @@ gtest_discover_tests( PROPERTIES LABELS TEST2 ) +gtest_discover_tests( + fake_gtest + TEST_PREFIX TEST: + TEST_SUFFIX !3 + TEST_FILTER basic* + EXTRA_ARGS how now "\"brown\" cow" + PROPERTIES LABELS TEST3 +) + +gtest_discover_tests( + fake_gtest + TEST_PREFIX TEST: + TEST_SUFFIX !4 + TEST_FILTER typed* + EXTRA_ARGS how now "\"brown\" cow" + PROPERTIES LABELS TEST4 +) + add_executable(no_tests_defined no_tests_defined.cpp) xcode_sign_adhoc(no_tests_defined) diff --git a/Tests/RunCMake/GoogleTest/RunCMakeTest.cmake b/Tests/RunCMake/GoogleTest/RunCMakeTest.cmake index 530c8abe5a..c5c592507f 100644 --- a/Tests/RunCMake/GoogleTest/RunCMakeTest.cmake +++ b/Tests/RunCMake/GoogleTest/RunCMakeTest.cmake @@ -40,6 +40,20 @@ function(run_GoogleTest DISCOVERY_MODE) --no-label-summary ) + run_cmake_command(GoogleTest-test3 + ${CMAKE_CTEST_COMMAND} + -C Debug + -L TEST3 + --no-label-summary + ) + + run_cmake_command(GoogleTest-test4 + ${CMAKE_CTEST_COMMAND} + -C Debug + -L TEST4 + --no-label-summary + ) + run_cmake_command(GoogleTest-test-missing ${CMAKE_CTEST_COMMAND} -C Debug diff --git a/Tests/RunCMake/GoogleTest/fake_gtest.cpp b/Tests/RunCMake/GoogleTest/fake_gtest.cpp index 1956c37fe8..b2a5cb443f 100644 --- a/Tests/RunCMake/GoogleTest/fake_gtest.cpp +++ b/Tests/RunCMake/GoogleTest/fake_gtest.cpp @@ -7,27 +7,42 @@ int main(int argc, char** argv) // it only requires that we produces output in the expected format when // invoked with --gtest_list_tests. Thus, we fake that here. This allows us // to test the module without actually needing Google Test. + bool is_filtered = + argc > 2 && std::string(argv[2]).find("--gtest_filter=") == 0; + bool is_basic_only = + is_filtered && std::string(argv[2]).find("basic*") != std::string::npos; + bool is_typed_only = + is_filtered && std::string(argv[2]).find("typed*") != std::string::npos; + if (argc > 1 && std::string(argv[1]) == "--gtest_list_tests") { - std::cout << "basic." << std::endl; - std::cout << " case_foo" << std::endl; - std::cout << " case_bar" << std::endl; - std::cout << " DISABLED_disabled_case" << std::endl; - std::cout << " DISABLEDnot_really_case" << std::endl; - std::cout << "DISABLED_disabled." << std::endl; - std::cout << " case" << std::endl; - std::cout << "DISABLEDnotreally." << std::endl; - std::cout << " case" << std::endl; - std::cout << "typed/0. # TypeParam = short" << std::endl; - std::cout << " case" << std::endl; - std::cout << "typed/1. # TypeParam = float" << std::endl; - std::cout << " case" << std::endl; - std::cout << "value/test." << std::endl; - std::cout << " case/0 # GetParam() = 1" << std::endl; - std::cout << " case/1 # GetParam() = \"foo\"" << std::endl; - std::cout << "param/special." << std::endl; - std::cout << " case/0 # GetParam() = \"semicolon;\"" << std::endl; - std::cout << " case/1 # GetParam() = \"backslash\\\"" << std::endl; - std::cout << " case/2 # GetParam() = \"${var}\"" << std::endl; + if (!is_typed_only) { + std::cout << "basic." << std::endl; + std::cout << " case_foo" << std::endl; + std::cout << " case_bar" << std::endl; + std::cout << " DISABLED_disabled_case" << std::endl; + std::cout << " DISABLEDnot_really_case" << std::endl; + } + if (!is_basic_only && !is_typed_only) { + std::cout << "DISABLED_disabled." << std::endl; + std::cout << " case" << std::endl; + std::cout << "DISABLEDnotreally." << std::endl; + std::cout << " case" << std::endl; + } + if (!is_basic_only) { + std::cout << "typed/0. # TypeParam = short" << std::endl; + std::cout << " case" << std::endl; + std::cout << "typed/1. # TypeParam = float" << std::endl; + std::cout << " case" << std::endl; + } + if (!is_basic_only && !is_typed_only) { + std::cout << "value/test." << std::endl; + std::cout << " case/0 # GetParam() = 1" << std::endl; + std::cout << " case/1 # GetParam() = \"foo\"" << std::endl; + std::cout << "param/special." << std::endl; + std::cout << " case/0 # GetParam() = \"semicolon;\"" << std::endl; + std::cout << " case/1 # GetParam() = \"backslash\\\"" << std::endl; + std::cout << " case/2 # GetParam() = \"${var}\"" << std::endl; + } return 0; } |