diff options
Diffstat (limited to 'Modules')
283 files changed, 7902 insertions, 2801 deletions
diff --git a/Modules/BasicConfigVersion-AnyNewerVersion.cmake.in b/Modules/BasicConfigVersion-AnyNewerVersion.cmake.in index 46b8b2a..aeac0d9 100644 --- a/Modules/BasicConfigVersion-AnyNewerVersion.cmake.in +++ b/Modules/BasicConfigVersion-AnyNewerVersion.cmake.in @@ -29,20 +29,4 @@ else() endif() endif() - -# if the installed project requested no architecture check, don't perform the check -if("@CVF_ARCH_INDEPENDENT@") - return() -endif() - -# if the installed or the using project don't have CMAKE_SIZEOF_VOID_P set, ignore it: -if("${CMAKE_SIZEOF_VOID_P}" STREQUAL "" OR "@CMAKE_SIZEOF_VOID_P@" STREQUAL "") - return() -endif() - -# check that the installed version has the same 32/64bit-ness as the one which is currently searching: -if(NOT CMAKE_SIZEOF_VOID_P STREQUAL "@CMAKE_SIZEOF_VOID_P@") - math(EXPR installedBits "@CMAKE_SIZEOF_VOID_P@ * 8") - set(PACKAGE_VERSION "${PACKAGE_VERSION} (${installedBits}bit)") - set(PACKAGE_VERSION_UNSUITABLE TRUE) -endif() +@CVF_ARCH_INDEPENDENT_CHECK@ diff --git a/Modules/BasicConfigVersion-ExactVersion.cmake.in b/Modules/BasicConfigVersion-ExactVersion.cmake.in index c8d2695..8dac2af 100644 --- a/Modules/BasicConfigVersion-ExactVersion.cmake.in +++ b/Modules/BasicConfigVersion-ExactVersion.cmake.in @@ -69,20 +69,4 @@ if(PACKAGE_FIND_VERSION STREQUAL PACKAGE_VERSION) set(PACKAGE_VERSION_EXACT TRUE) endif() - -# if the installed project requested no architecture check, don't perform the check -if("@CVF_ARCH_INDEPENDENT@") - return() -endif() - -# if the installed or the using project don't have CMAKE_SIZEOF_VOID_P set, ignore it: -if("${CMAKE_SIZEOF_VOID_P}" STREQUAL "" OR "@CMAKE_SIZEOF_VOID_P@" STREQUAL "") - return() -endif() - -# check that the installed version has the same 32/64bit-ness as the one which is currently searching: -if(NOT CMAKE_SIZEOF_VOID_P STREQUAL "@CMAKE_SIZEOF_VOID_P@") - math(EXPR installedBits "@CMAKE_SIZEOF_VOID_P@ * 8") - set(PACKAGE_VERSION "${PACKAGE_VERSION} (${installedBits}bit)") - set(PACKAGE_VERSION_UNSUITABLE TRUE) -endif() +@CVF_ARCH_INDEPENDENT_CHECK@ diff --git a/Modules/BasicConfigVersion-SameMajorVersion.cmake.in b/Modules/BasicConfigVersion-SameMajorVersion.cmake.in index cf73f60..85a0355 100644 --- a/Modules/BasicConfigVersion-SameMajorVersion.cmake.in +++ b/Modules/BasicConfigVersion-SameMajorVersion.cmake.in @@ -51,20 +51,4 @@ else() endif() endif() - -# if the installed project requested no architecture check, don't perform the check -if("@CVF_ARCH_INDEPENDENT@") - return() -endif() - -# if the installed or the using project don't have CMAKE_SIZEOF_VOID_P set, ignore it: -if("${CMAKE_SIZEOF_VOID_P}" STREQUAL "" OR "@CMAKE_SIZEOF_VOID_P@" STREQUAL "") - return() -endif() - -# check that the installed version has the same 32/64bit-ness as the one which is currently searching: -if(NOT CMAKE_SIZEOF_VOID_P STREQUAL "@CMAKE_SIZEOF_VOID_P@") - math(EXPR installedBits "@CMAKE_SIZEOF_VOID_P@ * 8") - set(PACKAGE_VERSION "${PACKAGE_VERSION} (${installedBits}bit)") - set(PACKAGE_VERSION_UNSUITABLE TRUE) -endif() +@CVF_ARCH_INDEPENDENT_CHECK@ diff --git a/Modules/BasicConfigVersion-SameMinorVersion.cmake.in b/Modules/BasicConfigVersion-SameMinorVersion.cmake.in index ef21df6..87c4930 100644 --- a/Modules/BasicConfigVersion-SameMinorVersion.cmake.in +++ b/Modules/BasicConfigVersion-SameMinorVersion.cmake.in @@ -71,20 +71,4 @@ else() endif() endif() - -# if the installed project requested no architecture check, don't perform the check -if("@CVF_ARCH_INDEPENDENT@") - return() -endif() - -# if the installed or the using project don't have CMAKE_SIZEOF_VOID_P set, ignore it: -if("${CMAKE_SIZEOF_VOID_P}" STREQUAL "" OR "@CMAKE_SIZEOF_VOID_P@" STREQUAL "") - return() -endif() - -# check that the installed version has the same 32/64bit-ness as the one which is currently searching: -if(NOT CMAKE_SIZEOF_VOID_P STREQUAL "@CMAKE_SIZEOF_VOID_P@") - math(EXPR installedBits "@CMAKE_SIZEOF_VOID_P@ * 8") - set(PACKAGE_VERSION "${PACKAGE_VERSION} (${installedBits}bit)") - set(PACKAGE_VERSION_UNSUITABLE TRUE) -endif() +@CVF_ARCH_INDEPENDENT_CHECK@ diff --git a/Modules/BundleUtilities.cmake b/Modules/BundleUtilities.cmake index 0beff04..5307901 100644 --- a/Modules/BundleUtilities.cmake +++ b/Modules/BundleUtilities.cmake @@ -870,10 +870,6 @@ function(fixup_bundle_item resolved_embedded_item exepath dirs) endif() endforeach() - if(BU_CHMOD_BUNDLE_ITEMS) - execute_process(COMMAND chmod u+w "${resolved_embedded_item}") - endif() - # CMAKE_INSTALL_NAME_TOOL may not be set if executed in script mode # Duplicated from CMakeFindBinUtils.cmake find_program(CMAKE_INSTALL_NAME_TOOL NAMES install_name_tool HINTS ${_CMAKE_TOOLCHAIN_LOCATION}) @@ -903,6 +899,9 @@ function(fixup_bundle_item resolved_embedded_item exepath dirs) if(NOT "${resolved_embedded_item}" MATCHES "\\.(bat|c?sh|bash|ksh|cmd)$" AND NOT file_contents MATCHES "^#!") set(cmd ${CMAKE_INSTALL_NAME_TOOL} ${changes} "${resolved_embedded_item}") + if(BU_CHMOD_BUNDLE_ITEMS) + execute_process(COMMAND chmod u+w "${resolved_embedded_item}") + endif() execute_process(COMMAND ${cmd} RESULT_VARIABLE install_name_tool_result) if(NOT install_name_tool_result EQUAL 0) string(REPLACE ";" "' '" msg "'${cmd}'") diff --git a/Modules/CMakeASM_MARMASMInformation.cmake b/Modules/CMakeASM_MARMASMInformation.cmake new file mode 100644 index 0000000..2026c17 --- /dev/null +++ b/Modules/CMakeASM_MARMASMInformation.cmake @@ -0,0 +1,24 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + + +# support for the MS ARM assembler, marmasm and marmasm64 + +set(ASM_DIALECT "_MARMASM") + +set(CMAKE_ASM${ASM_DIALECT}_SOURCE_FILE_EXTENSIONS asm) + +set(CMAKE_ASM${ASM_DIALECT}_COMPILE_OBJECT "<CMAKE_ASM${ASM_DIALECT}_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -o <OBJECT> <SOURCE>") + +# The ASM_MARMASM compiler id for this compiler is "MSVC", so fill out the runtime library table. +set(CMAKE_ASM${ASM_DIALECT}_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreaded "") +set(CMAKE_ASM${ASM_DIALECT}_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDLL "") +set(CMAKE_ASM${ASM_DIALECT}_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDebug "") +set(CMAKE_ASM${ASM_DIALECT}_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDebugDLL "") + +set(CMAKE_ASM${ASM_DIALECT}_COMPILE_OPTIONS_MSVC_DEBUG_INFORMATION_FORMAT_Embedded "-g") +set(CMAKE_ASM${ASM_DIALECT}_COMPILE_OPTIONS_MSVC_DEBUG_INFORMATION_FORMAT_ProgramDatabase "") +set(CMAKE_ASM${ASM_DIALECT}_COMPILE_OPTIONS_MSVC_DEBUG_INFORMATION_FORMAT_EditAndContinue "") + +include(CMakeASMInformation) +set(ASM_DIALECT) diff --git a/Modules/CMakeASM_MASMInformation.cmake b/Modules/CMakeASM_MASMInformation.cmake index 656b75e..11b83662 100644 --- a/Modules/CMakeASM_MASMInformation.cmake +++ b/Modules/CMakeASM_MASMInformation.cmake @@ -16,5 +16,9 @@ set(CMAKE_ASM${ASM_DIALECT}_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDL set(CMAKE_ASM${ASM_DIALECT}_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDebug "") set(CMAKE_ASM${ASM_DIALECT}_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDebugDLL "") +set(CMAKE_ASM${ASM_DIALECT}_COMPILE_OPTIONS_MSVC_DEBUG_INFORMATION_FORMAT_Embedded "-Zi") +set(CMAKE_ASM${ASM_DIALECT}_COMPILE_OPTIONS_MSVC_DEBUG_INFORMATION_FORMAT_ProgramDatabase "") +set(CMAKE_ASM${ASM_DIALECT}_COMPILE_OPTIONS_MSVC_DEBUG_INFORMATION_FORMAT_EditAndContinue "") + include(CMakeASMInformation) set(ASM_DIALECT) diff --git a/Modules/CMakeCCompilerABI.c b/Modules/CMakeCCompilerABI.c index f0ee21a..63596be 100644 --- a/Modules/CMakeCCompilerABI.c +++ b/Modules/CMakeCCompilerABI.c @@ -9,7 +9,8 @@ #include "CMakeCompilerABI.h" #ifdef __CLASSIC_C__ -int main(argc, argv) int argc; +int main(argc, argv) +int argc; char* argv[]; #else int main(int argc, char* argv[]) diff --git a/Modules/CMakeCUDACompiler.cmake.in b/Modules/CMakeCUDACompiler.cmake.in index 9f2e213..57d595a 100644 --- a/Modules/CMakeCUDACompiler.cmake.in +++ b/Modules/CMakeCUDACompiler.cmake.in @@ -55,6 +55,7 @@ set(CMAKE_CUDA_COMPILER_LIBRARY_ROOT "@CMAKE_CUDA_COMPILER_LIBRARY_ROOT@") set(CMAKE_CUDA_ARCHITECTURES_ALL "@CMAKE_CUDA_ARCHITECTURES_ALL@") set(CMAKE_CUDA_ARCHITECTURES_ALL_MAJOR "@CMAKE_CUDA_ARCHITECTURES_ALL_MAJOR@") +set(CMAKE_CUDA_ARCHITECTURES_NATIVE "@CMAKE_CUDA_ARCHITECTURES_NATIVE@") set(CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES "@CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES@") diff --git a/Modules/CMakeCUDACompilerABI.cu b/Modules/CMakeCUDACompilerABI.cu index 449a079..8463e86 100644 --- a/Modules/CMakeCUDACompilerABI.cu +++ b/Modules/CMakeCUDACompilerABI.cu @@ -2,6 +2,10 @@ # error "A C or C++ compiler has been selected for CUDA" #endif +#include <cstdio> + +#include <cuda_runtime.h> + #include "CMakeCompilerABI.h" int main(int argc, char* argv[]) @@ -13,6 +17,31 @@ int main(int argc, char* argv[]) #if defined(ABI_ID) require += info_abi[argc]; #endif - (void)argv; - return require; + static_cast<void>(argv); + + int count = 0; + if (cudaGetDeviceCount(&count) != cudaSuccess || count == 0) { + std::fprintf(stderr, "No CUDA devices found.\n"); + return -1; + } + + int found = 0; + const char* sep = ""; + for (int device = 0; device < count; ++device) { + cudaDeviceProp prop; + if (cudaGetDeviceProperties(&prop, device) == cudaSuccess) { + std::printf("%s%d%d", sep, prop.major, prop.minor); + sep = ";"; + found = 1; + } + } + + if (!found) { + std::fprintf(stderr, "No CUDA architecture detected from any devices.\n"); + // Convince the compiler that the non-zero return value depends + // on the info strings so they are not optimized out. + return require ? -1 : 1; + } + + return 0; } diff --git a/Modules/CMakeCXXCompilerId.cpp.in b/Modules/CMakeCXXCompilerId.cpp.in index f19bc97..2643326 100644 --- a/Modules/CMakeCXXCompilerId.cpp.in +++ b/Modules/CMakeCXXCompilerId.cpp.in @@ -82,6 +82,7 @@ int main(int argc, char* argv[]) int require = 0; require += info_compiler[argc]; require += info_platform[argc]; + require += info_arch[argc]; #ifdef COMPILER_VERSION_MAJOR require += info_version[argc]; #endif diff --git a/Modules/CMakeCheckCompilerFlagCommonPatterns.cmake b/Modules/CMakeCheckCompilerFlagCommonPatterns.cmake index bda1d71..cd978d5 100644 --- a/Modules/CMakeCheckCompilerFlagCommonPatterns.cmake +++ b/Modules/CMakeCheckCompilerFlagCommonPatterns.cmake @@ -12,6 +12,7 @@ macro (CHECK_COMPILER_FLAG_COMMON_PATTERNS _VAR) FAIL_REGEX "switch .* is no longer supported" # GNU FAIL_REGEX "unknown .*option" # Clang FAIL_REGEX "optimization flag .* not supported" # Clang + FAIL_REGEX "argument unused during compilation: .*" # Clang FAIL_REGEX "unknown argument ignored" # Clang (cl) FAIL_REGEX "ignoring unknown option" # MSVC, Intel FAIL_REGEX "warning D9002" # MSVC, any lang diff --git a/Modules/CMakeCompilerIdDetection.cmake b/Modules/CMakeCompilerIdDetection.cmake index f15974a..75d33e8 100644 --- a/Modules/CMakeCompilerIdDetection.cmake +++ b/Modules/CMakeCompilerIdDetection.cmake @@ -70,6 +70,7 @@ function(compiler_id_detection outvar lang) FujitsuClang Fujitsu GHS + Tasking ) if ("x${lang}" STREQUAL "xC") list(APPEND ordered_compilers diff --git a/Modules/CMakeDependentOption.cmake b/Modules/CMakeDependentOption.cmake index ac0e262..9a3c940 100644 --- a/Modules/CMakeDependentOption.cmake +++ b/Modules/CMakeDependentOption.cmake @@ -84,7 +84,7 @@ macro(CMAKE_DEPENDENT_OPTION option doc default depends force) else() set(${option} "${${option}_ISSET}") endif() - if("x${_CDO_CMP0127}x" STREQUAL "xx" AND "x${depends}x" MATCHES "[^A-Za-z0-9_; ]") + if("x${_CDO_CMP0127}x" STREQUAL "xx" AND "x${depends}x" MATCHES "[^A-Za-z0-9_.; ]") cmake_policy(GET_WARNING CMP0127 _CDO_CMP0127_WARNING) message(AUTHOR_WARNING "${_CDO_CMP0127_WARNING}") endif() diff --git a/Modules/CMakeDetermineASMCompiler.cmake b/Modules/CMakeDetermineASMCompiler.cmake index d03cbef..5ec2972 100644 --- a/Modules/CMakeDetermineASMCompiler.cmake +++ b/Modules/CMakeDetermineASMCompiler.cmake @@ -129,14 +129,13 @@ if(NOT CMAKE_ASM${ASM_DIALECT}_COMPILER_ID) if("x${CMAKE_ASM${ASM_DIALECT}_COMPILER_ID}" STREQUAL "xIAR") # primary necessary to detect architecture, so the right archiver and linker can be picked # eg. "IAR Assembler V8.10.1.12857/W32 for ARM" or "IAR Assembler V4.11.1.4666 for Renesas RX" - # Cut out identification first, newline handling is a pain + # Earlier versions did not provide `--version`, so grep the full output to extract Assembler ID string string(REGEX MATCH "IAR Assembler[^\r\n]*" _compileid "${CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_OUTPUT}") if("${_compileid}" MATCHES "V([0-9]+\\.[0-9]+\\.[0-9]+)") set(CMAKE_ASM${ASM_DIALECT}_COMPILER_VERSION ${CMAKE_MATCH_1}) endif() - string(REGEX MATCHALL "([A-Za-z0-9-]+)" _all_compileid_matches "${_compileid}") - if(_all_compileid_matches) - list(GET _all_compileid_matches "-1" CMAKE_ASM${ASM_DIALECT}_COMPILER_ARCHITECTURE_ID) + if("${_compileid}" MATCHES "for.*(MSP430|8051|ARM|AVR|RH850|RISC-?V|RL78|RX|STM8|V850)") + set(CMAKE_ASM${ASM_DIALECT}_COMPILER_ARCHITECTURE_ID ${CMAKE_MATCH_1}) endif() elseif("x${CMAKE_ASM${ASM_DIALECT}_COMPILER_ID}" STREQUAL "xClang") # Test whether an MSVC-like command-line option works. diff --git a/Modules/CMakeDetermineASM_MARMASMCompiler.cmake b/Modules/CMakeDetermineASM_MARMASMCompiler.cmake new file mode 100644 index 0000000..26714dd --- /dev/null +++ b/Modules/CMakeDetermineASM_MARMASMCompiler.cmake @@ -0,0 +1,18 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + + +# Find the MS ARM assembler (marmasm or marmasm64) + +set(ASM_DIALECT "_MARMASM") + +# if we are using the 64bit cl compiler, assume we also want the 64bit assembler +if(";${CMAKE_VS_PLATFORM_NAME};${CMAKE_C_COMPILER_ARCHITECTURE_ID};${CMAKE_CXX_COMPILER_ARCHITECTURE_ID};" + MATCHES ";(ARM64);") + set(CMAKE_ASM${ASM_DIALECT}_COMPILER_INIT armasm64) +else() + set(CMAKE_ASM${ASM_DIALECT}_COMPILER_INIT armasm) +endif() + +include(CMakeDetermineASMCompiler) +set(ASM_DIALECT) diff --git a/Modules/CMakeDetermineCSharpCompiler.cmake b/Modules/CMakeDetermineCSharpCompiler.cmake index da860a8..fe98469 100644 --- a/Modules/CMakeDetermineCSharpCompiler.cmake +++ b/Modules/CMakeDetermineCSharpCompiler.cmake @@ -3,7 +3,7 @@ if(NOT ${CMAKE_GENERATOR} MATCHES "Visual Studio ([^9]|[9][0-9])") message(FATAL_ERROR - "C# is currently only supported for Microsoft Visual Studio 2010 and later.") + "C# is currently only supported for Microsoft Visual Studio 11 2012 and later.") endif() include(${CMAKE_ROOT}/Modules/CMakeDetermineCompiler.cmake) diff --git a/Modules/CMakeDetermineCUDACompiler.cmake b/Modules/CMakeDetermineCUDACompiler.cmake index 2649441..53c5f78 100644 --- a/Modules/CMakeDetermineCUDACompiler.cmake +++ b/Modules/CMakeDetermineCUDACompiler.cmake @@ -248,9 +248,6 @@ if(NOT CMAKE_CUDA_COMPILER_ID_RUN) if(CMAKE_CUDA_COMPILER_ID_OUTPUT MATCHES [=[V([0-9]+\.[0-9]+\.[0-9]+)]=]) set(CMAKE_CUDA_COMPILER_TOOLKIT_VERSION "${CMAKE_MATCH_1}") endif() - - # Make the all and all-major architecture information available. - include(${CMAKE_ROOT}/Modules/CUDA/architectures.cmake) endif() set(CMAKE_CUDA_COMPILER_ID_FLAGS_ALWAYS "-v") @@ -259,11 +256,11 @@ if(NOT CMAKE_CUDA_COMPILER_ID_RUN) set(nvcc_test_flags "--keep --keep-dir tmp") if(CMAKE_CUDA_HOST_COMPILER) string(APPEND nvcc_test_flags " -ccbin=\"${CMAKE_CUDA_HOST_COMPILER}\"") - - # If the user has specified a host compiler we should fail instead of trying without. - # Succeeding detection without may result in confusing errors later on, see #21076. - set(CMAKE_CUDA_COMPILER_ID_REQUIRE_SUCCESS ON) endif() + # If we have extracted the vendor as NVIDIA we should require detection to + # work. If we don't, users will get confusing errors later about failure + # to detect a default value for CMAKE_CUDA_ARCHITECTURES + set(CMAKE_CUDA_COMPILER_ID_REQUIRE_SUCCESS ON) elseif(CMAKE_CUDA_COMPILER_ID STREQUAL "Clang") set(clang_test_flags "--cuda-path=\"${CMAKE_CUDA_COMPILER_LIBRARY_ROOT}\"") if(CMAKE_CROSSCOMPILING) @@ -272,64 +269,35 @@ if(NOT CMAKE_CUDA_COMPILER_ID_RUN) endif() endif() - if(DEFINED CMAKE_CUDA_ARCHITECTURES) - if(CMAKE_CUDA_ARCHITECTURES MATCHES "^(all|all-major)$") - # For sufficiently new NVCC we can just use the all and all-major flags. - # For VS we don't test since we can't figure out the version this early (see #23161). - # For others select based on version. - if(CMAKE_CUDA_COMPILER_ID STREQUAL "NVIDIA" AND CMAKE_CUDA_COMPILER_TOOLKIT_VERSION VERSION_GREATER_EQUAL 11.5) - string(APPEND nvcc_test_flags " -arch=${CMAKE_CUDA_ARCHITECTURES}") - set(architectures_tested "${CMAKE_CUDA_ARCHITECTURES}") - elseif(CMAKE_GENERATOR MATCHES "Visual Studio") - set(architectures_tested "${CMAKE_CUDA_ARCHITECTURES}") - else() - if(CMAKE_CUDA_ARCHITECTURES STREQUAL "all") - set(architectures_test ${CMAKE_CUDA_ARCHITECTURES_ALL}) - elseif(CMAKE_CUDA_ARCHITECTURES STREQUAL "all-major") - set(architectures_test ${CMAKE_CUDA_ARCHITECTURES_ALL_MAJOR}) - endif() - endif() - elseif(CMAKE_CUDA_ARCHITECTURES OR "${CMAKE_CUDA_ARCHITECTURES}" STREQUAL "") - # Explicit architectures. Test them during detection. - set(architectures_explicit TRUE) - set(architectures_test ${CMAKE_CUDA_ARCHITECTURES}) - endif() - endif() - - foreach(arch ${architectures_test}) - # Strip specifiers as PTX vs binary doesn't matter. - string(REGEX MATCH "[0-9]+" arch_name "${arch}") - string(APPEND clang_test_flags " --cuda-gpu-arch=sm_${arch_name}") - string(APPEND nvcc_test_flags " -gencode=arch=compute_${arch_name},code=sm_${arch_name}") - list(APPEND architectures_tested "${arch_name}") - endforeach() - # Rest of the code treats an empty value as equivalent to "use the defaults". # Error out early to prevent confusing errors as a result of this. # Note that this also catches invalid non-numerical values such as "a". - if(DEFINED architectures_explicit AND "${architectures_tested}" STREQUAL "") - message(FATAL_ERROR "CMAKE_CUDA_ARCHITECTURES must be valid if set.") + if(DEFINED CMAKE_CUDA_ARCHITECTURES) + if(CMAKE_CUDA_ARCHITECTURES STREQUAL "") + message(FATAL_ERROR "CMAKE_CUDA_ARCHITECTURES must be non-empty if set.") + elseif(CMAKE_CUDA_ARCHITECTURES AND NOT CMAKE_CUDA_ARCHITECTURES MATCHES "^([0-9]+a?(-real|-virtual)?(;[0-9]+a?(-real|-virtual)?|;)*|all|all-major|native)$") + message(FATAL_ERROR + "CMAKE_CUDA_ARCHITECTURES:\n" + " ${CMAKE_CUDA_ARCHITECTURES}\n" + "is not one of the following:\n" + " * a semicolon-separated list of integers, each optionally\n" + " followed by '-real' or '-virtual'\n" + " * a special value: all, all-major, native\n" + ) + endif() endif() if(CMAKE_CUDA_COMPILER_ID STREQUAL "Clang") - if(NOT CMAKE_CUDA_ARCHITECTURES) - # Clang doesn't automatically select an architecture supported by the SDK. - # Try in reverse order of deprecation with the most recent at front (i.e. the most likely to work for new setups). - foreach(arch "52" "30" "20") - list(APPEND CMAKE_CUDA_COMPILER_ID_TEST_FLAGS_FIRST "${clang_test_flags} --cuda-gpu-arch=sm_${arch}") - endforeach() - endif() - - # If the user specified CMAKE_CUDA_ARCHITECTURES this will include all the architecture flags. - # Otherwise this won't include any architecture flags and we'll fallback to Clang's defaults. - list(APPEND CMAKE_CUDA_COMPILER_ID_TEST_FLAGS_FIRST "${clang_test_flags}") + # Clang doesn't automatically select an architecture supported by the SDK. + # Try in reverse order of deprecation with the most recent at front (i.e. the most likely to work for new setups). + foreach(arch "52" "30" "20") + list(APPEND CMAKE_CUDA_COMPILER_ID_TEST_FLAGS_FIRST "${clang_test_flags} --cuda-gpu-arch=sm_${arch}") + endforeach() elseif(CMAKE_CUDA_COMPILER_ID STREQUAL "NVIDIA") list(APPEND CMAKE_CUDA_COMPILER_ID_TEST_FLAGS_FIRST "${nvcc_test_flags}") endif() # We perform compiler identification for a second time to extract implicit linking info and host compiler for NVCC. - # We also use it to verify that CMAKE_CUDA_ARCHITECTURES and additionally on Clang that CUDA toolkit path works. - # The latter could be done during compiler testing in the future to avoid doing this for Clang. # We need to unset the compiler ID otherwise CMAKE_DETERMINE_COMPILER_ID() doesn't work. set(CMAKE_CUDA_COMPILER_ID) set(CMAKE_CUDA_PLATFORM_ID) @@ -344,11 +312,12 @@ if(NOT CMAKE_CUDA_COMPILER_ID_RUN) get_filename_component(CMAKE_CUDA_COMPILER_TOOLKIT_ROOT "${CMAKE_CUDA_COMPILER_TOOLKIT_ROOT}" DIRECTORY) set(CMAKE_CUDA_COMPILER_LIBRARY_ROOT "${CMAKE_CUDA_COMPILER_TOOLKIT_ROOT}") - # We now know the version, so make the architecture variables available. + # The compiler comes with the toolkit, so the versions are the same. set(CMAKE_CUDA_COMPILER_TOOLKIT_VERSION ${CMAKE_CUDA_COMPILER_VERSION}) - include(${CMAKE_ROOT}/Modules/CUDA/architectures.cmake) endif() + include(${CMAKE_ROOT}/Modules/CUDA/architectures.cmake) + _cmake_find_compiler_sysroot(CUDA) endif() @@ -534,7 +503,8 @@ elseif(CMAKE_CUDA_COMPILER_ID STREQUAL "NVIDIA") CMAKE_CUDA_HOST_IMPLICIT_LINK_DIRECTORIES CMAKE_CUDA_HOST_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES log - "${CMAKE_CUDA_IMPLICIT_OBJECT_REGEX}") + "${CMAKE_CUDA_IMPLICIT_OBJECT_REGEX}" + LANGUAGE CUDA) # Detect CMAKE_CUDA_RUNTIME_LIBRARY_DEFAULT from the compiler by looking at which # cudart library exists in the implicit link libraries passed to the host linker. @@ -550,10 +520,10 @@ elseif(CMAKE_CUDA_COMPILER_ID STREQUAL "NVIDIA") set(_SET_CMAKE_CUDA_RUNTIME_LIBRARY_DEFAULT "set(CMAKE_CUDA_RUNTIME_LIBRARY_DEFAULT \"${CMAKE_CUDA_RUNTIME_LIBRARY_DEFAULT}\")") - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log - "Parsed CUDA nvcc implicit link information from above output:\n${_nvcc_log}\n${log}\n\n") + message(CONFIGURE_LOG + "Parsed CUDA nvcc implicit link information:\n${_nvcc_log}\n${log}\n\n") else() - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log + message(CONFIGURE_LOG "Failed to parse CUDA nvcc implicit link information:\n${_nvcc_log}\n\n") message(FATAL_ERROR "Failed to extract nvcc implicit link line.") endif() @@ -606,10 +576,10 @@ if(CMAKE_CUDA_COMPILER_ID STREQUAL "NVIDIA") list(APPEND CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES "${line}") endforeach() - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log - "Parsed CUDA nvcc include information from above output:\n${_nvcc_log}\n${log}\n\n") + message(CONFIGURE_LOG + "Parsed CUDA nvcc include information:\n${_nvcc_log}\n${log}\n\n") else() - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log + message(CONFIGURE_LOG "Failed to detect CUDA nvcc include information:\n${_nvcc_log}\n\n") endif() @@ -633,31 +603,6 @@ if("${CMAKE_CUDA_ARCHITECTURES}" STREQUAL "") message(FATAL_ERROR "Failed to detect a default CUDA architecture.\n\nCompiler output:\n${CMAKE_CUDA_COMPILER_PRODUCED_OUTPUT}") endif() endif() -elseif(CMAKE_CUDA_ARCHITECTURES AND NOT "${architectures_tested}" MATCHES "^(all|all-major)$") - # Sort since order mustn't matter. - list(SORT architectures_detected) - list(SORT architectures_tested) - - # We don't distinguish real/virtual architectures during testing. - # For "70-real;70-virtual" we detect "70" as working and architectures_tested is "70;70". - # Thus we need to remove duplicates before checking if they're equal. - list(REMOVE_DUPLICATES architectures_tested) - - # Print the actual architectures for generic values (all and all-major). - if(NOT DEFINED architectures_explicit) - set(architectures_error "${CMAKE_CUDA_ARCHITECTURES} (${architectures_tested})") - else() - set(architectures_error "${architectures_tested}") - endif() - - if(NOT "${architectures_detected}" STREQUAL "${architectures_tested}") - message(FATAL_ERROR - "The CMAKE_CUDA_ARCHITECTURES:\n" - " ${architectures_error}\n" - "do not all work with this compiler. Try:\n" - " ${architectures_detected}\n" - "instead.") - endif() endif() # configure all variables set in this file @@ -673,9 +618,7 @@ unset(_CUDA_LIBRARY_DIR) unset(_CUDA_TARGET_DIR) unset(_CUDA_TARGET_NAME) -unset(architectures_explicit) unset(architectures_detected) -unset(architectures_tested) set(CMAKE_CUDA_COMPILER_ENV_VAR "CUDACXX") set(CMAKE_CUDA_HOST_COMPILER_ENV_VAR "CUDAHOSTCXX") diff --git a/Modules/CMakeDetermineCompileFeatures.cmake b/Modules/CMakeDetermineCompileFeatures.cmake index a08e597..09de7b1 100644 --- a/Modules/CMakeDetermineCompileFeatures.cmake +++ b/Modules/CMakeDetermineCompileFeatures.cmake @@ -63,6 +63,7 @@ function(cmake_determine_compile_features lang) set(CMAKE_CXX17_COMPILE_FEATURES) set(CMAKE_CXX20_COMPILE_FEATURES) set(CMAKE_CXX23_COMPILE_FEATURES) + set(CMAKE_CXX26_COMPILE_FEATURES) include("${CMAKE_ROOT}/Modules/Internal/FeatureTesting.cmake") @@ -73,6 +74,9 @@ function(cmake_determine_compile_features lang) return() endif() + if (CMAKE_CXX23_COMPILE_FEATURES AND CMAKE_CXX26_COMPILE_FEATURES) + list(REMOVE_ITEM CMAKE_CXX26_COMPILE_FEATURES ${CMAKE_CXX23_COMPILE_FEATURES}) + endif() if (CMAKE_CXX20_COMPILE_FEATURES AND CMAKE_CXX23_COMPILE_FEATURES) list(REMOVE_ITEM CMAKE_CXX23_COMPILE_FEATURES ${CMAKE_CXX20_COMPILE_FEATURES}) endif() @@ -97,6 +101,7 @@ function(cmake_determine_compile_features lang) ${CMAKE_CXX17_COMPILE_FEATURES} ${CMAKE_CXX20_COMPILE_FEATURES} ${CMAKE_CXX23_COMPILE_FEATURES} + ${CMAKE_CXX26_COMPILE_FEATURES} ) endif() @@ -107,6 +112,7 @@ function(cmake_determine_compile_features lang) set(CMAKE_CXX17_COMPILE_FEATURES ${CMAKE_CXX17_COMPILE_FEATURES} PARENT_SCOPE) set(CMAKE_CXX20_COMPILE_FEATURES ${CMAKE_CXX20_COMPILE_FEATURES} PARENT_SCOPE) set(CMAKE_CXX23_COMPILE_FEATURES ${CMAKE_CXX23_COMPILE_FEATURES} PARENT_SCOPE) + set(CMAKE_CXX26_COMPILE_FEATURES ${CMAKE_CXX26_COMPILE_FEATURES} PARENT_SCOPE) message(CHECK_PASS "done") @@ -119,6 +125,7 @@ function(cmake_determine_compile_features lang) set(CMAKE_CUDA17_COMPILE_FEATURES) set(CMAKE_CUDA20_COMPILE_FEATURES) set(CMAKE_CUDA23_COMPILE_FEATURES) + set(CMAKE_CUDA26_COMPILE_FEATURES) include("${CMAKE_ROOT}/Modules/Internal/FeatureTesting.cmake") @@ -129,6 +136,9 @@ function(cmake_determine_compile_features lang) return() endif() + if (CMAKE_CUDA23_COMPILE_FEATURES AND CMAKE_CUDA26_COMPILE_FEATURES) + list(REMOVE_ITEM CMAKE_CUDA26_COMPILE_FEATURES ${CMAKE_CUDA23_COMPILE_FEATURES}) + endif() if (CMAKE_CUDA20_COMPILE_FEATURES AND CMAKE_CUDA23_COMPILE_FEATURES) list(REMOVE_ITEM CMAKE_CUDA23_COMPILE_FEATURES ${CMAKE_CUDA20_COMPILE_FEATURES}) endif() @@ -153,6 +163,7 @@ function(cmake_determine_compile_features lang) ${CMAKE_CUDA17_COMPILE_FEATURES} ${CMAKE_CUDA20_COMPILE_FEATURES} ${CMAKE_CUDA23_COMPILE_FEATURES} + ${CMAKE_CUDA26_COMPILE_FEATURES} ) endif() @@ -163,6 +174,7 @@ function(cmake_determine_compile_features lang) set(CMAKE_CUDA17_COMPILE_FEATURES ${CMAKE_CUDA17_COMPILE_FEATURES} PARENT_SCOPE) set(CMAKE_CUDA20_COMPILE_FEATURES ${CMAKE_CUDA20_COMPILE_FEATURES} PARENT_SCOPE) set(CMAKE_CUDA23_COMPILE_FEATURES ${CMAKE_CUDA23_COMPILE_FEATURES} PARENT_SCOPE) + set(CMAKE_CUDA26_COMPILE_FEATURES ${CMAKE_CUDA26_COMPILE_FEATURES} PARENT_SCOPE) message(CHECK_PASS "done") @@ -175,6 +187,8 @@ function(cmake_determine_compile_features lang) set(CMAKE_HIP17_COMPILE_FEATURES) set(CMAKE_HIP20_COMPILE_FEATURES) set(CMAKE_HIP23_COMPILE_FEATURES) + set(CMAKE_HIP26_COMPILE_FEATURES) + include("${CMAKE_ROOT}/Modules/Internal/FeatureTesting.cmake") @@ -185,6 +199,9 @@ function(cmake_determine_compile_features lang) return() endif() + if (CMAKE_HIP23_COMPILE_FEATURES AND CMAKE_HIP26_COMPILE_FEATURES) + list(REMOVE_ITEM CMAKE_HIP26_COMPILE_FEATURES ${CMAKE_HIP23_COMPILE_FEATURES}) + endif() if (CMAKE_HIP20_COMPILE_FEATURES AND CMAKE_HIP23_COMPILE_FEATURES) list(REMOVE_ITEM CMAKE_HIP23_COMPILE_FEATURES ${CMAKE_HIP20_COMPILE_FEATURES}) endif() @@ -209,6 +226,7 @@ function(cmake_determine_compile_features lang) ${CMAKE_HIP17_COMPILE_FEATURES} ${CMAKE_HIP20_COMPILE_FEATURES} ${CMAKE_HIP23_COMPILE_FEATURES} + ${CMAKE_HIP26_COMPILE_FEATURES} ) endif() @@ -219,6 +237,7 @@ function(cmake_determine_compile_features lang) set(CMAKE_HIP17_COMPILE_FEATURES ${CMAKE_HIP17_COMPILE_FEATURES} PARENT_SCOPE) set(CMAKE_HIP20_COMPILE_FEATURES ${CMAKE_HIP20_COMPILE_FEATURES} PARENT_SCOPE) set(CMAKE_HIP23_COMPILE_FEATURES ${CMAKE_HIP23_COMPILE_FEATURES} PARENT_SCOPE) + set(CMAKE_HIP26_COMPILE_FEATURES ${CMAKE_HIP26_COMPILE_FEATURES} PARENT_SCOPE) message(CHECK_PASS "done") diff --git a/Modules/CMakeDetermineCompiler.cmake b/Modules/CMakeDetermineCompiler.cmake index aec86d9..3156ca9 100644 --- a/Modules/CMakeDetermineCompiler.cmake +++ b/Modules/CMakeDetermineCompiler.cmake @@ -53,10 +53,9 @@ macro(_cmake_find_compiler lang) NO_DEFAULT_PATH DOC "${lang} compiler") endif() - if(CMAKE_HOST_WIN32 AND CMAKE_GENERATOR MATCHES "Ninja") - # On Windows command-line builds, the Makefile generators each imply - # a preferred compiler tool. The Ninja generator does not imply a - # compiler tool, so use the compiler that occurs first in PATH. + if(CMAKE_HOST_WIN32 AND CMAKE_GENERATOR MATCHES "Ninja|MSYS Makefiles|MinGW Makefiles") + # On Windows command-line builds, some generators imply a preferred compiler tool. + # These generators do not, so use the compiler that occurs first in PATH. find_program(CMAKE_${lang}_COMPILER NAMES ${CMAKE_${lang}_COMPILER_LIST} NAMES_PER_DIR @@ -119,9 +118,15 @@ macro(_cmake_find_compiler_path lang) # (e.g. via ctest) or set in CMAKE_TOOLCHAIN_FILE # if CMAKE_${lang}_COMPILER is a list, use the first item as # CMAKE_${lang}_COMPILER and the rest as CMAKE_${lang}_COMPILER_ARG1 - set(CMAKE_${lang}_COMPILER_ARG1 "${CMAKE_${lang}_COMPILER}") - list(POP_FRONT CMAKE_${lang}_COMPILER_ARG1 CMAKE_${lang}_COMPILER) - list(JOIN CMAKE_${lang}_COMPILER_ARG1 " " CMAKE_${lang}_COMPILER_ARG1) + # Otherwise, preserve any existing CMAKE_${lang}_COMPILER_ARG1 that might + # have been saved by CMakeDetermine${lang}Compiler in a previous run. + list(LENGTH CMAKE_${lang}_COMPILER _CMAKE_${lang}_COMPILER_LENGTH) + if(_CMAKE_${lang}_COMPILER_LENGTH GREATER 1) + set(CMAKE_${lang}_COMPILER_ARG1 "${CMAKE_${lang}_COMPILER}") + list(POP_FRONT CMAKE_${lang}_COMPILER_ARG1 CMAKE_${lang}_COMPILER) + list(JOIN CMAKE_${lang}_COMPILER_ARG1 " " CMAKE_${lang}_COMPILER_ARG1) + endif() + unset(_CMAKE_${lang}_COMPILER_LENGTH) # find the compiler in the PATH if necessary # if compiler (and arguments) comes from cache then synchronize cache with updated CMAKE_<LANG>_COMPILER diff --git a/Modules/CMakeDetermineCompilerABI.cmake b/Modules/CMakeDetermineCompilerABI.cmake index 8191d81..4169734 100644 --- a/Modules/CMakeDetermineCompilerABI.cmake +++ b/Modules/CMakeDetermineCompilerABI.cmake @@ -26,6 +26,14 @@ function(CMAKE_DETERMINE_COMPILER_ABI lang src) if(DEFINED CMAKE_${lang}_VERBOSE_COMPILE_FLAG) set(COMPILE_DEFINITIONS "${CMAKE_${lang}_VERBOSE_COMPILE_FLAG}") endif() + if(lang STREQUAL "CUDA") + if(CMAKE_CUDA_ARCHITECTURES STREQUAL "native") + # We are about to detect the native architectures, so we do + # not yet know them. Use all architectures during detection. + set(CMAKE_CUDA_ARCHITECTURES "all") + endif() + set(CMAKE_CUDA_RUNTIME_LIBRARY "Static") + endif() if(NOT "x${CMAKE_${lang}_COMPILER_ID}" STREQUAL "xMSVC") # Avoid adding our own platform standard libraries for compilers # from which we might detect implicit link libraries. @@ -47,7 +55,7 @@ function(CMAKE_DETERMINE_COMPILER_ABI lang src) set(ENV{LANG} C) try_compile(CMAKE_${lang}_ABI_COMPILED - ${CMAKE_BINARY_DIR} ${src} + SOURCES ${src} CMAKE_FLAGS ${CMAKE_FLAGS} # Ignore unused flags when we are just determining the ABI. "--no-warn-unused-cli" @@ -74,8 +82,6 @@ function(CMAKE_DETERMINE_COMPILER_ABI lang src) # Load the resulting information strings. if(CMAKE_${lang}_ABI_COMPILED) message(CHECK_PASS "done") - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log - "Detecting ${lang} compiler ABI info compiled with the following output:\n${OUTPUT}\n\n") file(STRINGS "${BIN}" ABI_STRINGS LIMIT_COUNT 32 REGEX "INFO:[A-Za-z0-9_]+\\[[^]]*\\]") set(ABI_SIZEOF_DPTR "NOTFOUND") set(ABI_BYTE_ORDER "NOTFOUND") @@ -118,8 +124,8 @@ function(CMAKE_DETERMINE_COMPILER_ABI lang src) set (implicit_incdirs "") cmake_parse_implicit_include_info("${OUTPUT}" "${lang}" implicit_incdirs log rv) - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log - "Parsed ${lang} implicit include dir info from above output: rv=${rv}\n${log}\n\n") + message(CONFIGURE_LOG + "Parsed ${lang} implicit include dir info: rv=${rv}\n${log}\n\n") if("${rv}" STREQUAL "done") # Entries that we have been told to explicitly pass as standard include # directories will not be implicitly added by the compiler. @@ -141,9 +147,10 @@ function(CMAKE_DETERMINE_COMPILER_ABI lang src) if(CMAKE_${lang}_VERBOSE_FLAG) CMAKE_PARSE_IMPLICIT_LINK_INFO("${OUTPUT}" implicit_libs implicit_dirs implicit_fwks log "${CMAKE_${lang}_IMPLICIT_OBJECT_REGEX}" - COMPUTE_IMPLICIT_OBJECTS implicit_objs) - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log - "Parsed ${lang} implicit link information from above output:\n${log}\n\n") + COMPUTE_IMPLICIT_OBJECTS implicit_objs + LANGUAGE ${lang}) + message(CONFIGURE_LOG + "Parsed ${lang} implicit link information:\n${log}\n\n") endif() # for VS IDE Intel Fortran we have to figure out the # implicit link path for the fortran run time using @@ -153,8 +160,9 @@ function(CMAKE_DETERMINE_COMPILER_ABI lang src) message(CHECK_START "Determine Intel Fortran Compiler Implicit Link Path") # Build a sample project which reports symbols. try_compile(IFORT_LIB_PATH_COMPILED - ${CMAKE_BINARY_DIR}/CMakeFiles/IntelVSImplicitPath - ${CMAKE_ROOT}/Modules/IntelVSImplicitPath + PROJECT IntelFortranImplicit + SOURCE_DIR ${CMAKE_ROOT}/Modules/IntelVSImplicitPath + BINARY_DIR ${CMAKE_BINARY_DIR}/CMakeFiles/IntelVSImplicitPath IntelFortranImplicit CMAKE_FLAGS "-DCMAKE_Fortran_FLAGS:STRING=${CMAKE_Fortran_FLAGS}" @@ -185,8 +193,6 @@ function(CMAKE_DETERMINE_COMPILER_ABI lang src) else() message(CHECK_FAIL "failed") - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log - "Detecting ${lang} compiler ABI info failed to compile with the following output:\n${OUTPUT}\n${_copy_error}\n\n") endif() endif() endfunction() diff --git a/Modules/CMakeDetermineCompilerId.cmake b/Modules/CMakeDetermineCompilerId.cmake index c2e0fa8..41e0e1a 100644 --- a/Modules/CMakeDetermineCompilerId.cmake +++ b/Modules/CMakeDetermineCompilerId.cmake @@ -2,6 +2,8 @@ # file Copyright.txt or https://cmake.org/licensing for details. macro(__determine_compiler_id_test testflags_var userflags_var) + set(_CMAKE_${lang}_COMPILER_ID_LOG "") + separate_arguments(testflags UNIX_COMMAND "${${testflags_var}}") CMAKE_DETERMINE_COMPILER_ID_BUILD("${lang}" "${testflags}" "${${userflags_var}}" "${src}") CMAKE_DETERMINE_COMPILER_ID_MATCH_VENDOR("${lang}" "${COMPILER_${lang}_PRODUCED_OUTPUT}") @@ -11,6 +13,9 @@ macro(__determine_compiler_id_test testflags_var userflags_var) CMAKE_DETERMINE_COMPILER_ID_CHECK("${lang}" "${CMAKE_${lang}_COMPILER_ID_DIR}/${file}" "${src}") endforeach() endif() + + message(CONFIGURE_LOG "${_CMAKE_${lang}_COMPILER_ID_LOG}") + unset(_CMAKE_${lang}_COMPILER_ID_LOG) endmacro() # Function to compile a source file to identify the compiler. This is @@ -85,8 +90,6 @@ function(CMAKE_DETERMINE_COMPILER_ID lang flagvar src) # If the compiler is still unknown, fallback to GHS if(NOT CMAKE_${lang}_COMPILER_ID AND "${CMAKE_GENERATOR}" MATCHES "Green Hills MULTI") set(CMAKE_${lang}_COMPILER_ID GHS) - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log - "The ${lang} compiler identification is falling back to GHS.\n\n") endif() # CUDA < 7.5 is missing version macros @@ -116,7 +119,7 @@ function(CMAKE_DETERMINE_COMPILER_ID lang flagvar src) RESULT_VARIABLE result TIMEOUT 10 ) - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log + message(CONFIGURE_LOG "Running the ${lang} compiler: \"${CMAKE_${lang}_COMPILER}\" -version\n" "${output}\n" ) @@ -140,7 +143,7 @@ function(CMAKE_DETERMINE_COMPILER_ID lang flagvar src) RESULT_VARIABLE result TIMEOUT 10 ) - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log + message(CONFIGURE_LOG "Running the ${lang} compiler: \"${CMAKE_${lang}_COMPILER}\" -version\n" "${output}\n" ) @@ -160,7 +163,7 @@ function(CMAKE_DETERMINE_COMPILER_ID lang flagvar src) RESULT_VARIABLE result TIMEOUT 10 ) - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log + message(CONFIGURE_LOG "Running the ${lang} compiler: \"${CMAKE_${lang}_COMPILER}\" --version\n" "${output}\n" ) @@ -216,6 +219,9 @@ function(CMAKE_DETERMINE_COMPILER_ID lang flagvar src) AND MSVC_${lang}_ARCHITECTURE_ID) foreach(userflags "${CMAKE_${lang}_COMPILER_ID_FLAGS_LIST}" "") CMAKE_DETERMINE_MSVC_SHOWINCLUDES_PREFIX(${lang} "${userflags}") + if(CMAKE_${lang}_CL_SHOWINCLUDES_PREFIX) + break() + endif() endforeach() else() set(CMAKE_${lang}_CL_SHOWINCLUDES_PREFIX "") @@ -243,8 +249,12 @@ function(CMAKE_DETERMINE_COMPILER_ID lang flagvar src) else() set(CMAKE_${lang}_COMPILER_FRONTEND_VARIANT "GNU") endif() - elseif("x${CMAKE_${lang}_COMPILER_ID}" STREQUAL "xFujitsuClang") + elseif("x${CMAKE_${lang}_COMPILER_ID}" STREQUAL "xGNU" + OR "x${CMAKE_${lang}_COMPILER_ID}" STREQUAL "xAppleClang" + OR "x${CMAKE_${lang}_COMPILER_ID}" STREQUAL "xFujitsuClang") set(CMAKE_${lang}_COMPILER_FRONTEND_VARIANT "GNU") + elseif("x${CMAKE_${lang}_COMPILER_ID}" STREQUAL "xMSVC") + set(CMAKE_${lang}_COMPILER_FRONTEND_VARIANT "MSVC") else() set(CMAKE_${lang}_COMPILER_FRONTEND_VARIANT "") endif() @@ -495,13 +505,7 @@ Id flags: ${testflags} ${CMAKE_${lang}_COMPILER_ID_FLAGS_ALWAYS} if(CMAKE_VS_PLATFORM_NAME STREQUAL x64) set(cuda_target "<TargetMachinePlatform>64</TargetMachinePlatform>") endif() - if(CMAKE_CUDA_ARCHITECTURES AND NOT CMAKE_CUDA_ARCHITECTURES MATCHES "^(all|all-major)$") - foreach(arch ${CMAKE_CUDA_ARCHITECTURES}) - string(REGEX MATCH "[0-9]+" arch_name "${arch}") - string(APPEND cuda_codegen "compute_${arch_name},sm_${arch_name};") - endforeach() - endif() - set(id_ItemDefinitionGroup_entry "<CudaCompile>${cuda_target}<AdditionalOptions>%(AdditionalOptions)-v</AdditionalOptions><CodeGeneration>${cuda_codegen}</CodeGeneration></CudaCompile>") + set(id_ItemDefinitionGroup_entry "<CudaCompile>${cuda_target}<AdditionalOptions>%(AdditionalOptions)-v</AdditionalOptions></CudaCompile>") set(id_PostBuildEvent_Command [[echo CMAKE_CUDA_COMPILER=$(CudaToolkitBinDir)\nvcc.exe]]) if(CMAKE_VS_PLATFORM_TOOLSET_CUDA_CUSTOM_DIR) # check for legacy cuda custom toolkit folder structure @@ -736,13 +740,19 @@ ${CMAKE_${lang}_COMPILER_ID_OUTPUT} ") # Log the output unless we recognize it as a known-bad case. if(NOT CMAKE_${lang}_COMPILER_ID_OUTPUT MATCHES "warning #5117: Bad # preprocessor line") - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log "${MSG}") + string(APPEND _CMAKE_${lang}_COMPILER_ID_LOG "${MSG}") endif() + string(APPEND _CMAKE_DETERMINE_COMPILER_ID_BUILD_MSG "${MSG}") + # Some languages may know the correct/desired set of flags and want to fail right away if they don't work. # This is currently only used by CUDA. if(__compiler_id_require_success) - message(FATAL_ERROR "${MSG}") + message(FATAL_ERROR "${_CMAKE_DETERMINE_COMPILER_ID_BUILD_MSG}") + elseif(CMAKE_${lang}_COMPILER_ID_REQUIRE_SUCCESS) + # Build up the outputs for compiler detection attempts so that users + # can see all set of flags tried, instead of just last + set(_CMAKE_DETERMINE_COMPILER_ID_BUILD_MSG "${_CMAKE_DETERMINE_COMPILER_ID_BUILD_MSG}" PARENT_SCOPE) endif() # No output files should be inspected. @@ -750,7 +760,7 @@ ${CMAKE_${lang}_COMPILER_ID_OUTPUT} set(COMPILER_${lang}_PRODUCED_OUTPUT) else() # Compilation succeeded. - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log + string(APPEND _CMAKE_${lang}_COMPILER_ID_LOG "Compiling the ${lang} compiler identification source file \"${src}\" succeeded. ${COMPILER_DESCRIPTION} The output was: @@ -779,7 +789,7 @@ ${CMAKE_${lang}_COMPILER_ID_OUTPUT} foreach(file ${files}) if(NOT IS_DIRECTORY ${CMAKE_${lang}_COMPILER_ID_DIR}/${file}) list(APPEND COMPILER_${lang}_PRODUCED_FILES ${file}) - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log + string(APPEND _CMAKE_${lang}_COMPILER_ID_LOG "Compilation of the ${lang} compiler identification source \"" "${src}\" produced \"${file}\"\n\n") endif() @@ -787,7 +797,7 @@ ${CMAKE_${lang}_COMPILER_ID_OUTPUT} if(NOT COMPILER_${lang}_PRODUCED_FILES) # No executable was found. - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log + string(APPEND _CMAKE_${lang}_COMPILER_ID_LOG "Compilation of the ${lang} compiler identification source \"" "${src}\" did not produce an executable in \"" "${CMAKE_${lang}_COMPILER_ID_DIR}\".\n\n") @@ -799,6 +809,7 @@ ${CMAKE_${lang}_COMPILER_ID_OUTPUT} # Return the files produced by the compilation. set(COMPILER_${lang}_PRODUCED_FILES "${COMPILER_${lang}_PRODUCED_FILES}" PARENT_SCOPE) set(COMPILER_${lang}_PRODUCED_OUTPUT "${COMPILER_${lang}_PRODUCED_OUTPUT}" PARENT_SCOPE) + set(_CMAKE_${lang}_COMPILER_ID_LOG "${_CMAKE_${lang}_COMPILER_ID_LOG}" PARENT_SCOPE) endfunction() @@ -843,15 +854,24 @@ function(CMAKE_DETERMINE_COMPILER_ID_CHECK lang file) set(ARCHITECTURE_ID) set(SIMULATE_ID) set(SIMULATE_VERSION) + set(CMAKE_${lang}_COMPILER_ID_STRING_REGEX ".?I.?N.?F.?O.?:.?[A-Za-z0-9_]+\\[[^]]*\\]") foreach(encoding "" "ENCODING;UTF-16LE" "ENCODING;UTF-16BE") file(STRINGS "${file}" CMAKE_${lang}_COMPILER_ID_STRINGS LIMIT_COUNT 38 ${encoding} - REGEX ".?I.?N.?F.?O.?:.?[A-Za-z0-9_]+\\[[^]]*\\]") + REGEX "${CMAKE_${lang}_COMPILER_ID_STRING_REGEX}") if(NOT CMAKE_${lang}_COMPILER_ID_STRINGS STREQUAL "") break() endif() endforeach() + # Some ADSP processors result in characters being detected as separate strings + if(CMAKE_${lang}_COMPILER_ID_STRINGS STREQUAL "") + file(STRINGS "${file}" CMAKE_${lang}_COMPILER_ID_STRINGS LENGTH_MAXIMUM 1) + string(REGEX REPLACE ";" "" CMAKE_${lang}_COMPILER_ID_STRING "${CMAKE_${lang}_COMPILER_ID_STRINGS}") + string(REGEX MATCHALL "${CMAKE_${lang}_COMPILER_ID_STRING_REGEX}" + CMAKE_${lang}_COMPILER_ID_STRINGS "${CMAKE_${lang}_COMPILER_ID_STRING}") + endif() + # With the IAR Compiler, some strings are found twice, first time as incomplete # list like "?<Constant "INFO:compiler[IAR]">". Remove the incomplete copies. list(FILTER CMAKE_${lang}_COMPILER_ID_STRINGS EXCLUDE REGEX "\\?<Constant \\\"") @@ -983,15 +1003,16 @@ function(CMAKE_DETERMINE_COMPILER_ID_CHECK lang file) # Check the compiler identification string. if(CMAKE_${lang}_COMPILER_ID) # The compiler identification was found. - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log - "The ${lang} compiler identification is ${CMAKE_${lang}_COMPILER_ID}, found in \"" - "${file}\"\n\n") + string(APPEND _CMAKE_${lang}_COMPILER_ID_LOG + "The ${lang} compiler identification is ${CMAKE_${lang}_COMPILER_ID}, found in:\n" + " ${file}\n\n") else() # The compiler identification could not be found. - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log - "The ${lang} compiler identification could not be found in \"" - "${file}\"\n\n") + string(APPEND _CMAKE_${lang}_COMPILER_ID_LOG + "The ${lang} compiler identification could not be found in:\n" + " ${file}\n\n") endif() + set(_CMAKE_${lang}_COMPILER_ID_LOG "${_CMAKE_${lang}_COMPILER_ID_LOG}" PARENT_SCOPE) endif() # try to figure out the executable format: ELF, COFF, Mach-O @@ -1078,7 +1099,7 @@ function(CMAKE_DETERMINE_COMPILER_ID_VENDOR lang userflags) ) if("${output}" MATCHES "${regex}") - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log + message(CONFIGURE_LOG "Checking whether the ${lang} compiler is ${vendor} using \"${flags}\" " "matched \"${regex}\":\n${output}") set(CMAKE_${lang}_COMPILER_ID "${vendor}" PARENT_SCOPE) @@ -1087,11 +1108,11 @@ function(CMAKE_DETERMINE_COMPILER_ID_VENDOR lang userflags) break() else() if("${result}" MATCHES "timeout") - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log + message(CONFIGURE_LOG "Checking whether the ${lang} compiler is ${vendor} using \"${flags}\" " "terminated after 10 s due to timeout.") else() - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log + message(CONFIGURE_LOG "Checking whether the ${lang} compiler is ${vendor} using \"${flags}\" " "did not match \"${regex}\":\n${output}") endif() @@ -1120,11 +1141,14 @@ function(CMAKE_DETERMINE_MSVC_SHOWINCLUDES_PREFIX lang userflags) OUTPUT_VARIABLE out ERROR_VARIABLE err RESULT_VARIABLE res - ENCODING AUTO # cl prints in current code page + ENCODING AUTO # cl prints in console output code page ) - if(res EQUAL 0 AND "${out}" MATCHES "(^|\n)([^:\n]*:[^:\n]*:[ \t]*)") + string(REPLACE "\n" "\n " msg " ${out}") + if(res EQUAL 0 AND "${out}" MATCHES "(^|\n)([^:\n][^:\n]+:[^:\n]*[^: \n][^: \n]:?[ \t]+)[A-Za-z]:\\\\") set(CMAKE_${lang}_CL_SHOWINCLUDES_PREFIX "${CMAKE_MATCH_2}" PARENT_SCOPE) + string(APPEND msg "\nFound prefix \"${CMAKE_MATCH_2}\"") else() set(CMAKE_${lang}_CL_SHOWINCLUDES_PREFIX "" PARENT_SCOPE) endif() + message(CONFIGURE_LOG "Detecting ${lang} compiler /showIncludes prefix:\n${msg}\n") endfunction() diff --git a/Modules/CMakeDetermineFortranCompiler.cmake b/Modules/CMakeDetermineFortranCompiler.cmake index 1c4b6ea..8cbaf70 100644 --- a/Modules/CMakeDetermineFortranCompiler.cmake +++ b/Modules/CMakeDetermineFortranCompiler.cmake @@ -44,17 +44,14 @@ else() # finally list compilers to try if(NOT CMAKE_Fortran_COMPILER_INIT) # Known compilers: - # f77/f90/f95: generic compiler names # ftn: Cray fortran compiler wrapper - # g77: GNU Fortran 77 compiler # gfortran: putative GNU Fortran 95+ compiler (in progress) - # fort77: native F77 compiler under HP-UX (and some older Crays) - # frt: Fujitsu F77 compiler + # frt: Fujitsu Fortran compiler # pathf90/pathf95/pathf2003: PathScale Fortran compiler - # pgf77/pgf90/pgf95/pgfortran: Portland Group F77/F90/F95 compilers + # pgfortran: Portland Group Fortran compilers # nvfortran: NVHPC Fotran compiler # flang: Flang Fortran compiler - # xlf/xlf90/xlf95: IBM (AIX) F77/F90/F95 compilers + # xlf: IBM (AIX) Fortran compiler # lf95: Lahey-Fujitsu F95 compiler # fl32: Microsoft Fortran 77 "PowerStation" compiler # af77: Apogee F77 compiler for Intergraph hardware running CLIX @@ -62,35 +59,25 @@ else() # fort: Compaq (now HP) Fortran 90/95 compiler for Tru64 and Linux/Alpha # ifx: Intel Fortran LLVM-based compiler # ifort: Intel Classic Fortran compiler - # ifc: Intel Fortran 95 compiler for Linux/x86 - # efc: Intel Fortran 95 compiler for IA64 # nagfor: NAG Fortran compiler # - # The order is 95 or newer compilers first, then 90, - # then 77 or older compilers, gnu is always last in the group, + # GNU is last to be searched, # so if you paid for a compiler it is picked by default. - if(CMAKE_HOST_WIN32) - set(CMAKE_Fortran_COMPILER_LIST - ifort ifx pgf95 pgfortran nvfortran lf95 fort - flang gfortran gfortran-4 g95 f90 pgf90 - pgf77 g77 f77 nag - ) - else() - set(CMAKE_Fortran_COMPILER_LIST - ftn - ifort ifc ifx efc pgf95 pgfortran nvfortran lf95 xlf95 fort - flang lfortran gfortran gfortran-4 g95 f90 pgf90 - frt pgf77 xlf g77 f77 nag - ) - endif() + set(CMAKE_Fortran_COMPILER_LIST + ftn + ifx ifort nvfortran pgfortran lf95 xlf fort + flang lfortran frt nagfor + gfortran + ) # Vendor-specific compiler names. set(_Fortran_COMPILER_NAMES_LCC lfortran gfortran) - set(_Fortran_COMPILER_NAMES_GNU gfortran gfortran-4 g95 g77) + set(_Fortran_COMPILER_NAMES_GNU gfortran) set(_Fortran_COMPILER_NAMES_Intel ifort ifc efc ifx) set(_Fortran_COMPILER_NAMES_Absoft af95 af90 af77) set(_Fortran_COMPILER_NAMES_PGI pgf95 pgfortran pgf90 pgf77) set(_Fortran_COMPILER_NAMES_Flang flang) + set(_Fortran_COMPILER_NAMES_LLVMFlang flang) set(_Fortran_COMPILER_NAMES_PathScale pathf2003 pathf95 pathf90) set(_Fortran_COMPILER_NAMES_XL xlf) set(_Fortran_COMPILER_NAMES_VisualAge xlf95 xlf90 xlf) @@ -200,11 +187,11 @@ if(NOT CMAKE_Fortran_COMPILER_ID_RUN) if(NOT CMAKE_COMPILER_RETURN) if(CMAKE_COMPILER_OUTPUT MATCHES "THIS_IS_GNU") set(CMAKE_Fortran_COMPILER_ID "GNU") - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log + message(CONFIGURE_LOG "Determining if the Fortran compiler is GNU succeeded with " "the following output:\n${CMAKE_COMPILER_OUTPUT}\n\n") else() - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log + message(CONFIGURE_LOG "Determining if the Fortran compiler is GNU failed with " "the following output:\n${CMAKE_COMPILER_OUTPUT}\n\n") endif() @@ -297,6 +284,9 @@ if(MSVC_Fortran_ARCHITECTURE_ID) set(SET_MSVC_Fortran_ARCHITECTURE_ID "set(MSVC_Fortran_ARCHITECTURE_ID ${MSVC_Fortran_ARCHITECTURE_ID})") endif() +if(CMAKE_Fortran_COMPILER_ID STREQUAL "NVHPC") + set(CMAKE_Fortran_VENDOR_SOURCE_FILE_EXTENSIONS ";cuf;CUF") +endif() # configure variables set in this file for fast reload later on configure_file(${CMAKE_ROOT}/Modules/CMakeFortranCompiler.cmake.in ${CMAKE_PLATFORM_INFO_DIR}/CMakeFortranCompiler.cmake diff --git a/Modules/CMakeDetermineHIPCompiler.cmake b/Modules/CMakeDetermineHIPCompiler.cmake index 7b7d7a3..6294d04 100644 --- a/Modules/CMakeDetermineHIPCompiler.cmake +++ b/Modules/CMakeDetermineHIPCompiler.cmake @@ -86,6 +86,7 @@ if(NOT CMAKE_HIP_COMPILER_ROCM_ROOT AND CMAKE_HIP_COMPILER_ID STREQUAL "Clang") if(_CMAKE_HIP_COMPILER_RESULT EQUAL 0 AND _CMAKE_HIP_COMPILER_STDERR MATCHES "Found HIP installation: *([^,]*)[,\n]") set(CMAKE_HIP_COMPILER_ROCM_ROOT "${CMAKE_MATCH_1}") + file(TO_CMAKE_PATH "${CMAKE_HIP_COMPILER_ROCM_ROOT}" CMAKE_HIP_COMPILER_ROCM_ROOT) endif() endif() if(NOT CMAKE_HIP_COMPILER_ROCM_ROOT) diff --git a/Modules/CMakeDetermineRCCompiler.cmake b/Modules/CMakeDetermineRCCompiler.cmake index f8d55a5..d22741b 100644 --- a/Modules/CMakeDetermineRCCompiler.cmake +++ b/Modules/CMakeDetermineRCCompiler.cmake @@ -30,16 +30,19 @@ if(NOT CMAKE_RC_COMPILER) # finally list compilers to try if(CMAKE_RC_COMPILER_INIT) - set(CMAKE_RC_COMPILER_LIST ${CMAKE_RC_COMPILER_INIT}) - else() - set(CMAKE_RC_COMPILER_LIST rc) + set(_CMAKE_RC_COMPILER_LIST ${CMAKE_RC_COMPILER_INIT}) + set(_CMAKE_RC_COMPILER_FALLBACK ${CMAKE_RC_COMPILER_INIT}) + elseif(NOT _CMAKE_RC_COMPILER_LIST) + set(_CMAKE_RC_COMPILER_LIST rc) endif() # Find the compiler. - find_program(CMAKE_RC_COMPILER NAMES ${CMAKE_RC_COMPILER_LIST} DOC "RC compiler") - if(CMAKE_RC_COMPILER_INIT AND NOT CMAKE_RC_COMPILER) - set(CMAKE_RC_COMPILER "${CMAKE_RC_COMPILER_INIT}" CACHE FILEPATH "RC compiler" FORCE) + find_program(CMAKE_RC_COMPILER NAMES ${_CMAKE_RC_COMPILER_LIST} DOC "RC compiler") + if(_CMAKE_RC_COMPILER_FALLBACK AND NOT CMAKE_RC_COMPILER) + set(CMAKE_RC_COMPILER "${_CMAKE_RC_COMPILER_FALLBACK}" CACHE FILEPATH "RC compiler" FORCE) endif() + unset(_CMAKE_RC_COMPILER_FALLBACK) + unset(_CMAKE_RC_COMPILER_LIST) endif() mark_as_advanced(CMAKE_RC_COMPILER) diff --git a/Modules/CMakeDetermineSystem.cmake b/Modules/CMakeDetermineSystem.cmake index 8c7af06..d4dcc62 100644 --- a/Modules/CMakeDetermineSystem.cmake +++ b/Modules/CMakeDetermineSystem.cmake @@ -33,20 +33,32 @@ # find out on which system cmake runs if(CMAKE_HOST_UNIX) - find_program(CMAKE_UNAME uname /bin /usr/bin /usr/local/bin ) + find_program(CMAKE_UNAME NAMES uname PATHS /bin /usr/bin /usr/local/bin) if(CMAKE_UNAME) if(CMAKE_HOST_SYSTEM_NAME STREQUAL "AIX") - exec_program(${CMAKE_UNAME} ARGS -v OUTPUT_VARIABLE _CMAKE_HOST_SYSTEM_MAJOR_VERSION) - exec_program(${CMAKE_UNAME} ARGS -r OUTPUT_VARIABLE _CMAKE_HOST_SYSTEM_MINOR_VERSION) + execute_process(COMMAND ${CMAKE_UNAME} -v + OUTPUT_VARIABLE _CMAKE_HOST_SYSTEM_MAJOR_VERSION + OUTPUT_STRIP_TRAILING_WHITESPACE + ERROR_QUIET) + execute_process(COMMAND ${CMAKE_UNAME} -r + OUTPUT_VARIABLE _CMAKE_HOST_SYSTEM_MINOR_VERSION + OUTPUT_STRIP_TRAILING_WHITESPACE + ERROR_QUIET) set(CMAKE_HOST_SYSTEM_VERSION "${_CMAKE_HOST_SYSTEM_MAJOR_VERSION}.${_CMAKE_HOST_SYSTEM_MINOR_VERSION}") unset(_CMAKE_HOST_SYSTEM_MAJOR_VERSION) unset(_CMAKE_HOST_SYSTEM_MINOR_VERSION) else() - exec_program(${CMAKE_UNAME} ARGS -r OUTPUT_VARIABLE CMAKE_HOST_SYSTEM_VERSION) + execute_process(COMMAND ${CMAKE_UNAME} -r + OUTPUT_VARIABLE CMAKE_HOST_SYSTEM_VERSION + OUTPUT_STRIP_TRAILING_WHITESPACE + ERROR_QUIET) endif() if(CMAKE_HOST_SYSTEM_NAME MATCHES "Linux|CYGWIN.*|MSYS.*|^GNU$|Android") - exec_program(${CMAKE_UNAME} ARGS -m OUTPUT_VARIABLE CMAKE_HOST_SYSTEM_PROCESSOR - RETURN_VALUE val) + execute_process(COMMAND ${CMAKE_UNAME} -m + OUTPUT_VARIABLE CMAKE_HOST_SYSTEM_PROCESSOR + RESULT_VARIABLE val + OUTPUT_STRIP_TRAILING_WHITESPACE + ERROR_QUIET) elseif(CMAKE_HOST_SYSTEM_NAME MATCHES "Darwin") # If we are running on Apple Silicon, honor CMAKE_APPLE_SILICON_PROCESSOR. if(DEFINED CMAKE_APPLE_SILICON_PROCESSOR) @@ -74,8 +86,11 @@ if(CMAKE_HOST_UNIX) if(_CMAKE_APPLE_SILICON_PROCESSOR) set(CMAKE_HOST_SYSTEM_PROCESSOR "${_CMAKE_APPLE_SILICON_PROCESSOR}") else() - exec_program(${CMAKE_UNAME} ARGS -m OUTPUT_VARIABLE CMAKE_HOST_SYSTEM_PROCESSOR - RETURN_VALUE val) + execute_process(COMMAND ${CMAKE_UNAME} -m + OUTPUT_VARIABLE CMAKE_HOST_SYSTEM_PROCESSOR + RESULT_VARIABLE val + OUTPUT_STRIP_TRAILING_WHITESPACE + ERROR_QUIET) endif() unset(_CMAKE_APPLE_SILICON_PROCESSOR) if(CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL "Power Macintosh") @@ -83,14 +98,23 @@ if(CMAKE_HOST_UNIX) set(CMAKE_HOST_SYSTEM_PROCESSOR "powerpc") endif() elseif(CMAKE_HOST_SYSTEM_NAME MATCHES "OpenBSD") - exec_program(arch ARGS -s OUTPUT_VARIABLE CMAKE_HOST_SYSTEM_PROCESSOR - RETURN_VALUE val) + execute_process(COMMAND arch -s + OUTPUT_VARIABLE CMAKE_HOST_SYSTEM_PROCESSOR + RESULT_VARIABLE val + OUTPUT_STRIP_TRAILING_WHITESPACE + ERROR_QUIET) else() - exec_program(${CMAKE_UNAME} ARGS -p OUTPUT_VARIABLE CMAKE_HOST_SYSTEM_PROCESSOR - RETURN_VALUE val) + execute_process(COMMAND ${CMAKE_UNAME} -p + OUTPUT_VARIABLE CMAKE_HOST_SYSTEM_PROCESSOR + RESULT_VARIABLE val + OUTPUT_STRIP_TRAILING_WHITESPACE + ERROR_QUIET) if("${val}" GREATER 0) - exec_program(${CMAKE_UNAME} ARGS -m OUTPUT_VARIABLE CMAKE_HOST_SYSTEM_PROCESSOR - RETURN_VALUE val) + execute_process(COMMAND ${CMAKE_UNAME} -m + OUTPUT_VARIABLE CMAKE_HOST_SYSTEM_PROCESSOR + RESULT_VARIABLE val + OUTPUT_STRIP_TRAILING_WHITESPACE + ERROR_QUIET) endif() endif() # check the return of the last uname -m or -p @@ -128,7 +152,6 @@ if(CMAKE_TOOLCHAIN_FILE) set(CMAKE_TOOLCHAIN_FILE "${_INCLUDED_TOOLCHAIN_FILE}" CACHE FILEPATH "The CMake toolchain file" FORCE) else() message(FATAL_ERROR "Could not find toolchain file: ${CMAKE_TOOLCHAIN_FILE}") - set(CMAKE_TOOLCHAIN_FILE "NOTFOUND" CACHE FILEPATH "The CMake toolchain file" FORCE) endif() endif() @@ -173,13 +196,14 @@ endif() if(CMAKE_BINARY_DIR) # write entry to the log file if(PRESET_CMAKE_SYSTEM_NAME) - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log - "The target system is: ${CMAKE_SYSTEM_NAME} - ${CMAKE_SYSTEM_VERSION} - ${CMAKE_SYSTEM_PROCESSOR}\n") - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log - "The host system is: ${CMAKE_HOST_SYSTEM_NAME} - ${CMAKE_HOST_SYSTEM_VERSION} - ${CMAKE_HOST_SYSTEM_PROCESSOR}\n") + message(CONFIGURE_LOG + "The target system is: ${CMAKE_SYSTEM_NAME} - ${CMAKE_SYSTEM_VERSION} - ${CMAKE_SYSTEM_PROCESSOR}\n" + "The host system is: ${CMAKE_HOST_SYSTEM_NAME} - ${CMAKE_HOST_SYSTEM_VERSION} - ${CMAKE_HOST_SYSTEM_PROCESSOR}\n" + ) else() - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log - "The system is: ${CMAKE_SYSTEM_NAME} - ${CMAKE_SYSTEM_VERSION} - ${CMAKE_SYSTEM_PROCESSOR}\n") + message(CONFIGURE_LOG + "The system is: ${CMAKE_SYSTEM_NAME} - ${CMAKE_SYSTEM_VERSION} - ${CMAKE_SYSTEM_PROCESSOR}\n" + ) endif() # if a toolchain file is used, it needs to be included in the configured file, diff --git a/Modules/CMakeDetermineVSServicePack.cmake b/Modules/CMakeDetermineVSServicePack.cmake index 53868d2..0d360b5 100644 --- a/Modules/CMakeDetermineVSServicePack.cmake +++ b/Modules/CMakeDetermineVSServicePack.cmake @@ -105,8 +105,7 @@ function(_DetermineVSServicePack_CheckVersionWithTryCompile _SUCCESS_VAR _VERSI try_compile( _CompileResult - "${CMAKE_BINARY_DIR}" - "${CMAKE_BINARY_DIR}/return0.cc" + SOURCES "${CMAKE_BINARY_DIR}/return0.cc" OUTPUT_VARIABLE _output COPY_FILE "${CMAKE_BINARY_DIR}/return0.cc") @@ -128,8 +127,7 @@ function(_DetermineVSServicePack_CheckVersionWithTryRun _SUCCESS_VAR _VERSION_V try_run( _RunResult _CompileResult - "${CMAKE_BINARY_DIR}" - "${CMAKE_BINARY_DIR}/return0.cc" + SOURCES "${CMAKE_BINARY_DIR}/return0.cc" RUN_OUTPUT_VARIABLE _runoutput ) diff --git a/Modules/CMakeFindBinUtils.cmake b/Modules/CMakeFindBinUtils.cmake index a6bd0d1..2ac8879 100644 --- a/Modules/CMakeFindBinUtils.cmake +++ b/Modules/CMakeFindBinUtils.cmake @@ -170,7 +170,7 @@ else() if("${CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_ID}" STREQUAL Clang) if("x${CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_SIMULATE_ID}" STREQUAL "xMSVC") list(PREPEND _CMAKE_LINKER_NAMES "lld-link") - else() + elseif(NOT APPLE) list(PREPEND _CMAKE_LINKER_NAMES "ld.lld") endif() if(APPLE) diff --git a/Modules/CMakeFindDependencyMacro.cmake b/Modules/CMakeFindDependencyMacro.cmake index bcdfbeb..2c04abe 100644 --- a/Modules/CMakeFindDependencyMacro.cmake +++ b/Modules/CMakeFindDependencyMacro.cmake @@ -3,7 +3,7 @@ #[=======================================================================[.rst: CMakeFindDependencyMacro -------------------------- +------------------------ .. command:: find_dependency @@ -28,36 +28,70 @@ CMakeFindDependencyMacro The call to :command:`return` makes this macro unsuitable to call from :ref:`Find Modules`. + +Package Dependency Search Optimizations +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +If ``find_dependency`` is called with arguments identical to a previous +call in the same directory, perhaps due to diamond-shaped package +dependencies, the underlying call to :command:`find_package` is optimized +out. This optimization is important to support large package dependency +graphs while avoiding a combinatorial explosion of repeated searches. +However, the heuristic cannot account for ambient variables that +affect package behavior, such as ``<PackageName>_USE_STATIC_LIBS``, +offered by some packages. Therefore package configuration files should +avoid setting such variables before their calls to ``find_dependency``. + +.. versionchanged:: 3.15 + Previously, the underlying call to :command:`find_package` was always + optimized out if the package had already been found. CMake 3.15 + removed the optimization to support cases in which ``find_dependency`` + call arguments request different components. + +.. versionchanged:: 3.26 + The pre-3.15 optimization was restored, but with the above-described + heuristic to account for varying ``find_dependency`` call arguments. + #]=======================================================================] macro(find_dependency dep) - set(cmake_fd_quiet_arg) - if(${CMAKE_FIND_PACKAGE_NAME}_FIND_QUIETLY) - set(cmake_fd_quiet_arg QUIET) - endif() - set(cmake_fd_required_arg) - if(${CMAKE_FIND_PACKAGE_NAME}_FIND_REQUIRED) - set(cmake_fd_required_arg REQUIRED) - endif() + string(SHA256 cmake_fd_call_hash "${dep};${ARGN};${${CMAKE_FIND_PACKAGE_NAME}_FIND_REQUIRED}") + if(_CMAKE_${dep}_${cmake_fd_call_hash}_FOUND) + unset(cmake_fd_call_hash) + else() + list(APPEND _CMAKE_${dep}_HASH_STACK ${cmake_fd_call_hash}) + set(cmake_fd_quiet_arg) + if(${CMAKE_FIND_PACKAGE_NAME}_FIND_QUIETLY) + set(cmake_fd_quiet_arg QUIET) + endif() + set(cmake_fd_required_arg) + if(${CMAKE_FIND_PACKAGE_NAME}_FIND_REQUIRED) + set(cmake_fd_required_arg REQUIRED) + endif() - get_property(cmake_fd_alreadyTransitive GLOBAL PROPERTY - _CMAKE_${dep}_TRANSITIVE_DEPENDENCY - ) + get_property(cmake_fd_alreadyTransitive GLOBAL PROPERTY + _CMAKE_${dep}_TRANSITIVE_DEPENDENCY + ) - find_package(${dep} ${ARGN} - ${cmake_fd_quiet_arg} - ${cmake_fd_required_arg} - ) + find_package(${dep} ${ARGN} + ${cmake_fd_quiet_arg} + ${cmake_fd_required_arg} + ) + list(POP_BACK _CMAKE_${dep}_HASH_STACK cmake_fd_call_hash) + set("_CMAKE_${dep}_${cmake_fd_call_hash}_FOUND" "${${dep}_FOUND}") - if(NOT DEFINED cmake_fd_alreadyTransitive OR cmake_fd_alreadyTransitive) - set_property(GLOBAL PROPERTY _CMAKE_${dep}_TRANSITIVE_DEPENDENCY TRUE) - endif() + if(NOT DEFINED cmake_fd_alreadyTransitive OR cmake_fd_alreadyTransitive) + set_property(GLOBAL PROPERTY _CMAKE_${dep}_TRANSITIVE_DEPENDENCY TRUE) + endif() - if (NOT ${dep}_FOUND) - set(${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE "${CMAKE_FIND_PACKAGE_NAME} could not be found because dependency ${dep} could not be found.") - set(${CMAKE_FIND_PACKAGE_NAME}_FOUND False) - return() + unset(cmake_fd_alreadyTransitive) + unset(cmake_fd_call_hash) + unset(cmake_fd_quiet_arg) + unset(cmake_fd_required_arg) + if (NOT ${dep}_FOUND) + set(${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE "${CMAKE_FIND_PACKAGE_NAME} could not be found because dependency ${dep} could not be found.") + set(${CMAKE_FIND_PACKAGE_NAME}_FOUND False) + return() + endif() endif() - set(cmake_fd_required_arg) - set(cmake_fd_quiet_arg) endmacro() diff --git a/Modules/CMakeFindFrameworks.cmake b/Modules/CMakeFindFrameworks.cmake index 8906f48..1aa3929 100644 --- a/Modules/CMakeFindFrameworks.cmake +++ b/Modules/CMakeFindFrameworks.cmake @@ -17,12 +17,19 @@ if(NOT CMAKE_FIND_FRAMEWORKS_INCLUDED) macro(CMAKE_FIND_FRAMEWORKS fwk) set(${fwk}_FRAMEWORKS) if(APPLE) + # 'Frameworks' directory from Brew (Apple Silicon and Intel) + if(CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64") + set(_brew_framework_path /opt/homebrew/Frameworks) + else() + set(_brew_framework_path /usr/local/Frameworks) + endif() + file(TO_CMAKE_PATH "$ENV{CMAKE_FRAMEWORK_PATH}" _cmff_CMAKE_FRAMEWORK_PATH) set(_cmff_search_paths ${CMAKE_FRAMEWORK_PATH} ${_cmff_CMAKE_FRAMEWORK_PATH} ~/Library/Frameworks - /usr/local/Frameworks + ${_brew_framework_path} /Library/Frameworks /System/Library/Frameworks /Network/Library/Frameworks diff --git a/Modules/CMakeFindJavaCommon.cmake b/Modules/CMakeFindJavaCommon.cmake index 46b6280..c6e3348 100644 --- a/Modules/CMakeFindJavaCommon.cmake +++ b/Modules/CMakeFindJavaCommon.cmake @@ -19,7 +19,10 @@ else() set(_CMD_JAVA_HOME "") if(APPLE AND EXISTS /usr/libexec/java_home) execute_process(COMMAND /usr/libexec/java_home - OUTPUT_VARIABLE _CMD_JAVA_HOME OUTPUT_STRIP_TRAILING_WHITESPACE) + OUTPUT_VARIABLE _CMD_JAVA_HOME + OUTPUT_STRIP_TRAILING_WHITESPACE + ERROR_QUIET + ) endif() if(_CMD_JAVA_HOME AND IS_DIRECTORY "${_CMD_JAVA_HOME}") set(_JAVA_HOME "${_CMD_JAVA_HOME}") diff --git a/Modules/CMakeFortranCompiler.cmake.in b/Modules/CMakeFortranCompiler.cmake.in index 97f891e..f52ad02 100644 --- a/Modules/CMakeFortranCompiler.cmake.in +++ b/Modules/CMakeFortranCompiler.cmake.in @@ -25,7 +25,7 @@ set(CMAKE_Fortran_COMPILER_ENV_VAR "FC") set(CMAKE_Fortran_COMPILER_SUPPORTS_F90 @CMAKE_Fortran_COMPILER_SUPPORTS_F90@) set(CMAKE_Fortran_COMPILER_ID_RUN 1) -set(CMAKE_Fortran_SOURCE_FILE_EXTENSIONS f;F;fpp;FPP;f77;F77;f90;F90;for;For;FOR;f95;F95) +set(CMAKE_Fortran_SOURCE_FILE_EXTENSIONS f;F;fpp;FPP;f77;F77;f90;F90;for;For;FOR;f95;F95@CMAKE_Fortran_VENDOR_SOURCE_FILE_EXTENSIONS@) set(CMAKE_Fortran_IGNORE_EXTENSIONS h;H;o;O;obj;OBJ;def;DEF;rc;RC) set(CMAKE_Fortran_LINKER_PREFERENCE 20) if(UNIX) diff --git a/Modules/CMakeFortranCompilerId.F.in b/Modules/CMakeFortranCompilerId.F.in index 969c841..f5c2ab5 100644 --- a/Modules/CMakeFortranCompilerId.F.in +++ b/Modules/CMakeFortranCompilerId.F.in @@ -154,6 +154,13 @@ # if defined(__FLANG_PATCHLEVEL__) # define COMPILER_VERSION_PATCH DEC(__FLANG_PATCHLEVEL__) # endif +#elif defined(__flang__) + PRINT *, 'INFO:compiler[LLVMFlang]' +# define COMPILER_VERSION_MAJOR DEC(__flang_major__) +# define COMPILER_VERSION_MINOR DEC(__flang_minor__) +# if defined(__flang_patchlevel__) +# define COMPILER_VERSION_PATCH DEC(__flang_patchlevel__) +# endif #elif defined(_AIX) || defined(__AIX) || defined(__AIX__) || defined(__aix) || defined(__aix__) PRINT *, 'INFO:compiler[VisualAge]' #elif defined(__hpux) || defined(__hpux__) diff --git a/Modules/CMakeGenericSystem.cmake b/Modules/CMakeGenericSystem.cmake index 649b6f7..77c1780 100644 --- a/Modules/CMakeGenericSystem.cmake +++ b/Modules/CMakeGenericSystem.cmake @@ -24,12 +24,24 @@ set(CMAKE_DL_LIBS "dl") set(CMAKE_FIND_LIBRARY_PREFIXES "lib") set(CMAKE_FIND_LIBRARY_SUFFIXES ".so" ".a") -set(CMAKE_AUTOGEN_ORIGIN_DEPENDS ON) -set(CMAKE_AUTOMOC_COMPILER_PREDEFINES ON) +# Define feature "DEFAULT" as supported. This special feature generates the +# default option to link a library +# This feature is intended to be used in LINK_LIBRARY_OVERRIDE and +# LINK_LIBRARY_OVERRIDE_<LIBRARY> target properties +set(CMAKE_LINK_LIBRARY_USING_DEFAULT_SUPPORTED TRUE) + +if(NOT DEFINED CMAKE_AUTOGEN_ORIGIN_DEPENDS) + set(CMAKE_AUTOGEN_ORIGIN_DEPENDS ON) +endif() +if(NOT DEFINED CMAKE_AUTOMOC_COMPILER_PREDEFINES) + set(CMAKE_AUTOMOC_COMPILER_PREDEFINES ON) +endif() if(NOT DEFINED CMAKE_AUTOMOC_PATH_PREFIX) set(CMAKE_AUTOMOC_PATH_PREFIX OFF) endif() -set(CMAKE_AUTOMOC_MACRO_NAMES "Q_OBJECT" "Q_GADGET" "Q_NAMESPACE" "Q_NAMESPACE_EXPORT") +if(NOT DEFINED CMAKE_AUTOMOC_MACRO_NAMES) + set(CMAKE_AUTOMOC_MACRO_NAMES "Q_OBJECT" "Q_GADGET" "Q_NAMESPACE" "Q_NAMESPACE_EXPORT") +endif() # basically all general purpose OSs support shared libs set_property(GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS TRUE) @@ -41,11 +53,16 @@ set (CMAKE_SKIP_INSTALL_RPATH "NO" CACHE BOOL set(CMAKE_VERBOSE_MAKEFILE FALSE CACHE BOOL "If this value is on, makefiles will be generated without the .SILENT directive, and all commands will be echoed to the console during the make. This is useful for debugging only. With Visual Studio IDE projects all commands are done without /nologo.") +if(DEFINED ENV{CMAKE_COLOR_DIAGNOSTICS} AND NOT DEFINED CACHE{CMAKE_COLOR_DIAGNOSTICS}) + set(CMAKE_COLOR_DIAGNOSTICS $ENV{CMAKE_COLOR_DIAGNOSTICS} CACHE BOOL "Enable colored diagnostics throughout.") +endif() + if(CMAKE_GENERATOR MATCHES "Make") - set(CMAKE_COLOR_MAKEFILE ON CACHE BOOL - "Enable/Disable color output during build." - ) + if(NOT DEFINED CMAKE_COLOR_DIAGNOSTICS) + set(CMAKE_COLOR_MAKEFILE ON CACHE BOOL "Enable/Disable color output during build.") + endif() mark_as_advanced(CMAKE_COLOR_MAKEFILE) + if(DEFINED CMAKE_RULE_MESSAGES) set_property(GLOBAL PROPERTY RULE_MESSAGES ${CMAKE_RULE_MESSAGES}) endif() diff --git a/Modules/CMakeHIPInformation.cmake b/Modules/CMakeHIPInformation.cmake index 4c57677..33f8697 100644 --- a/Modules/CMakeHIPInformation.cmake +++ b/Modules/CMakeHIPInformation.cmake @@ -143,7 +143,7 @@ set(CMAKE_HIP_INFORMATION_LOADED 1) # Load the file and find the relevant HIP runtime. if(NOT DEFINED _CMAKE_HIP_DEVICE_RUNTIME_TARGET) set(hip-lang_DIR "${CMAKE_HIP_COMPILER_ROCM_ROOT}/lib/cmake/hip-lang") - find_package(hip-lang CONFIG QUIET NO_DEFAULT_PATH) + find_package(hip-lang CONFIG QUIET NO_DEFAULT_PATH REQUIRED) endif() if(DEFINED _CMAKE_HIP_DEVICE_RUNTIME_TARGET) list(APPEND CMAKE_HIP_RUNTIME_LIBRARIES_STATIC ${_CMAKE_HIP_DEVICE_RUNTIME_TARGET}) diff --git a/Modules/CMakeMSYSFindMake.cmake b/Modules/CMakeMSYSFindMake.cmake index 33b02c9..96fdb37 100644 --- a/Modules/CMakeMSYSFindMake.cmake +++ b/Modules/CMakeMSYSFindMake.cmake @@ -3,8 +3,13 @@ find_program(CMAKE_MAKE_PROGRAM make + REGISTRY_VIEW 32 PATHS - "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\MSYS-1.0_is1;Inno Setup: App Path]/bin" - "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\MinGW;InstallLocation]/bin" - c:/msys/1.0/bin /msys/1.0/bin) + # Typical install path for 32-bit MSYS2 (https://repo.msys2.org/distrib/msys2-i686-latest.sfx.exe) + "C:/msys32/usr" + # Typical install path for MINGW32 (https://sourceforge.net/projects/mingw) + "C:/mingw/msys" + # Git for Windows 32-bit (https://gitforwindows.org/) + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\GitForWindows;InstallPath]/usr") + mark_as_advanced(CMAKE_MAKE_PROGRAM) diff --git a/Modules/CMakePackageConfigHelpers.cmake b/Modules/CMakePackageConfigHelpers.cmake index 6f5702a..1dc850a 100644 --- a/Modules/CMakePackageConfigHelpers.cmake +++ b/Modules/CMakePackageConfigHelpers.cmake @@ -200,14 +200,16 @@ Example using both :command:`configure_package_config_file` and .. code-block:: cmake - set(INCLUDE_INSTALL_DIR include/ ... CACHE ) - set(LIB_INSTALL_DIR lib/ ... CACHE ) - set(SYSCONFIG_INSTALL_DIR etc/foo/ ... CACHE ) + include(GNUInstallDirs) + set(INCLUDE_INSTALL_DIR ${CMAKE_INSTALL_INCLUDEDIR}/Foo + CACHE PATH "Location of header files" ) + set(SYSCONFIG_INSTALL_DIR ${CMAKE_INSTALL_SYSCONFDIR}/foo + CACHE PATH "Location of configuration files" ) #... include(CMakePackageConfigHelpers) configure_package_config_file(FooConfig.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/FooConfig.cmake - INSTALL_DESTINATION ${LIB_INSTALL_DIR}/Foo/cmake + INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/Foo PATH_VARS INCLUDE_INSTALL_DIR SYSCONFIG_INSTALL_DIR) write_basic_package_version_file( ${CMAKE_CURRENT_BINARY_DIR}/FooConfigVersion.cmake @@ -215,7 +217,7 @@ Example using both :command:`configure_package_config_file` and COMPATIBILITY SameMajorVersion ) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/FooConfig.cmake ${CMAKE_CURRENT_BINARY_DIR}/FooConfigVersion.cmake - DESTINATION ${LIB_INSTALL_DIR}/Foo/cmake ) + DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/Foo ) ``FooConfig.cmake.in``: diff --git a/Modules/CMakeParseImplicitIncludeInfo.cmake b/Modules/CMakeParseImplicitIncludeInfo.cmake index 5c0eda2..1ebd887 100644 --- a/Modules/CMakeParseImplicitIncludeInfo.cmake +++ b/Modules/CMakeParseImplicitIncludeInfo.cmake @@ -233,8 +233,9 @@ function(cmake_parse_implicit_include_info text lang dir_var log_var state_var) get_filename_component(dir "${d}" ABSOLUTE) list(APPEND implicit_dirs "${dir}") string(APPEND log " collapse include dir [${d}] ==> [${dir}]\n") - elseif("${d}" MATCHES [[^\.\.[\/]\.\.[\/](.*)$]]) - # This relative path is deep enough to get out of the CMakeFiles/CMakeTmp + elseif("${d}" MATCHES [[^\.\.[\/]\.\.[\/]\.\.[\/](.*)$]]) + # This relative path is deep enough to get out of the + # CMakeFiles/CMakeScratch/<unique> # directory where the ABI check is done. Assume that the compiler has # computed this path adaptively based on the current working directory # such that the effective result is absolute. diff --git a/Modules/CMakeParseImplicitLinkInfo.cmake b/Modules/CMakeParseImplicitLinkInfo.cmake index 6bdefde..1773dc4 100644 --- a/Modules/CMakeParseImplicitLinkInfo.cmake +++ b/Modules/CMakeParseImplicitLinkInfo.cmake @@ -22,7 +22,7 @@ function(CMAKE_PARSE_IMPLICIT_LINK_INFO text lib_var dir_var fwk_var log_var obj set(log "") set(keywordArgs) - set(oneValueArgs COMPUTE_IMPLICIT_OBJECTS) + set(oneValueArgs COMPUTE_IMPLICIT_OBJECTS LANGUAGE) set(multiValueArgs ) cmake_parse_arguments(EXTRA_PARSE "${keywordArgs}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) @@ -76,6 +76,11 @@ function(CMAKE_PARSE_IMPLICIT_LINK_INFO text lib_var dir_var fwk_var log_var obj endif() endif() set(is_msvc 0) + if(EXTRA_PARSE_LANGUAGE AND + ("x${CMAKE_${EXTRA_PARSE_LANGUAGE}_ID}" STREQUAL "xMSVC" OR + "x${CMAKE_${EXTRA_PARSE_LANGUAGE}_SIMULATE_ID}" STREQUAL "xMSVC")) + set(is_msvc 1) + endif() set(search_static 0) if("${cmd}" MATCHES "${linker_regex}") string(APPEND log " link line: [${line}]\n") diff --git a/Modules/CMakePlatformId.h.in b/Modules/CMakePlatformId.h.in index 59195f8..32b7166 100644 --- a/Modules/CMakePlatformId.h.in +++ b/Modules/CMakePlatformId.h.in @@ -105,6 +105,9 @@ # define PLATFORM_ID "Integrity" # endif +# elif defined(_ADI_COMPILER) +# define PLATFORM_ID "ADSP" + #else /* unknown platform */ # define PLATFORM_ID @@ -233,6 +236,36 @@ # define ARCHITECTURE_ID "" # endif +# elif defined(__ADSPSHARC__) +# define ARCHITECTURE_ID "SHARC" + +# elif defined(__ADSPBLACKFIN__) +# define ARCHITECTURE_ID "Blackfin" + +#elif defined(__TASKING__) + +# if defined(__CTC__) || defined(__CPTC__) +# define ARCHITECTURE_ID "TriCore" + +# elif defined(__CMCS__) +# define ARCHITECTURE_ID "MCS" + +# elif defined(__CARM__) +# define ARCHITECTURE_ID "ARM" + +# elif defined(__CARC__) +# define ARCHITECTURE_ID "ARC" + +# elif defined(__C51__) +# define ARCHITECTURE_ID "8051" + +# elif defined(__CPCP__) +# define ARCHITECTURE_ID "PCP" + +# else +# define ARCHITECTURE_ID "" +# endif + #else # define ARCHITECTURE_ID #endif diff --git a/Modules/CMakePrintHelpers.cmake b/Modules/CMakePrintHelpers.cmake index 8c25a73..fb201dc 100644 --- a/Modules/CMakePrintHelpers.cmake +++ b/Modules/CMakePrintHelpers.cmake @@ -10,16 +10,19 @@ e.g. for debugging. :: - cmake_print_properties([TARGETS target1 .. targetN] - [SOURCES source1 .. sourceN] - [DIRECTORIES dir1 .. dirN] - [TESTS test1 .. testN] - [CACHE_ENTRIES entry1 .. entryN] - PROPERTIES prop1 .. propN ) + cmake_print_properties(<TARGETS [<target1> ...] | + SOURCES [<source1> ...] | + DIRECTORIES [<dir1> ...] | + TESTS [<test1> ...] | + CACHE_ENTRIES [<entry1> ...] > + PROPERTIES [<prop1> ...] ) This function prints the values of the properties of the given targets, source files, directories, tests or cache entries. Exactly one of the -scope keywords must be used. Example:: +scope keywords must be used. The scope keyword and its arguments must +come before the ``PROPERTIES`` keyword, in the arguments list. + +Example:: cmake_print_properties(TARGETS foo bar PROPERTIES LOCATION INTERFACE_INCLUDE_DIRECTORIES) @@ -56,17 +59,34 @@ endfunction() function(cmake_print_properties) set(options ) set(oneValueArgs ) - set(multiValueArgs TARGETS SOURCES TESTS DIRECTORIES CACHE_ENTRIES PROPERTIES ) + set(cpp_multiValueArgs PROPERTIES ) + set(cppmode_multiValueArgs TARGETS SOURCES TESTS DIRECTORIES CACHE_ENTRIES ) + + string(JOIN " " _mode_names ${cppmode_multiValueArgs}) + set(_missing_mode_message + "Mode keyword missing in cmake_print_properties() call, there must be exactly one of ${_mode_names}") - cmake_parse_arguments(CPP "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + cmake_parse_arguments( + CPP "${options}" "${oneValueArgs}" "${cpp_multiValueArgs}" ${ARGN}) - if(CPP_UNPARSED_ARGUMENTS) - message(FATAL_ERROR "Unknown keywords given to cmake_print_properties(): \"${CPP_UNPARSED_ARGUMENTS}\"") + if(NOT CPP_PROPERTIES) + message(FATAL_ERROR + "Required argument PROPERTIES missing in cmake_print_properties() call") return() endif() - if(NOT CPP_PROPERTIES) - message(FATAL_ERROR "Required argument PROPERTIES missing in cmake_print_properties() call") + if(NOT CPP_UNPARSED_ARGUMENTS) + message(FATAL_ERROR "${_missing_mode_message}") + return() + endif() + + cmake_parse_arguments( + CPPMODE "${options}" "${oneValueArgs}" "${cppmode_multiValueArgs}" + ${CPP_UNPARSED_ARGUMENTS}) + + if(CPPMODE_UNPARSED_ARGUMENTS) + message(FATAL_ERROR + "Unknown keywords given to cmake_print_properties(): \"${CPPMODE_UNPARSED_ARGUMENTS}\"") return() endif() @@ -74,32 +94,32 @@ function(cmake_print_properties) set(items) set(keyword) - if(CPP_TARGETS) - set(items ${CPP_TARGETS}) + if(CPPMODE_TARGETS) + set(items ${CPPMODE_TARGETS}) set(mode ${mode} TARGETS) set(keyword TARGET) endif() - if(CPP_SOURCES) - set(items ${CPP_SOURCES}) + if(CPPMODE_SOURCES) + set(items ${CPPMODE_SOURCES}) set(mode ${mode} SOURCES) set(keyword SOURCE) endif() - if(CPP_TESTS) - set(items ${CPP_TESTS}) + if(CPPMODE_TESTS) + set(items ${CPPMODE_TESTS}) set(mode ${mode} TESTS) set(keyword TEST) endif() - if(CPP_DIRECTORIES) - set(items ${CPP_DIRECTORIES}) + if(CPPMODE_DIRECTORIES) + set(items ${CPPMODE_DIRECTORIES}) set(mode ${mode} DIRECTORIES) set(keyword DIRECTORY) endif() - if(CPP_CACHE_ENTRIES) - set(items ${CPP_CACHE_ENTRIES}) + if(CPPMODE_CACHE_ENTRIES) + set(items ${CPPMODE_CACHE_ENTRIES}) set(mode ${mode} CACHE_ENTRIES) # This is a workaround for the fact that passing `CACHE` as an argument to # set() causes a cache variable to be set. @@ -108,13 +128,14 @@ function(cmake_print_properties) endif() if(NOT mode) - message(FATAL_ERROR "Mode keyword missing in cmake_print_properties() call, must be one of TARGETS SOURCES TESTS DIRECTORIES CACHE_ENTRIES PROPERTIES") + message(FATAL_ERROR "${_missing_mode_message}") return() endif() list(LENGTH mode modeLength) if("${modeLength}" GREATER 1) - message(FATAL_ERROR "Multiple mode keyword used in cmake_print_properties() call, it must be exactly one of TARGETS SOURCES TESTS DIRECTORIES CACHE_ENTRIES PROPERTIES") + message(FATAL_ERROR + "Multiple mode keywords used in cmake_print_properties() call, there must be exactly one of ${_mode_names}.") return() endif() @@ -124,8 +145,8 @@ function(cmake_print_properties) set(itemExists TRUE) if(keyword STREQUAL "TARGET") if(NOT TARGET ${item}) - set(itemExists FALSE) - string(APPEND msg "\n No such TARGET \"${item}\" !\n\n") + set(itemExists FALSE) + string(APPEND msg "\n No such TARGET \"${item}\" !\n\n") endif() endif() diff --git a/Modules/CMakeSwiftInformation.cmake b/Modules/CMakeSwiftInformation.cmake index ecad1d5..a75dfce 100644 --- a/Modules/CMakeSwiftInformation.cmake +++ b/Modules/CMakeSwiftInformation.cmake @@ -17,19 +17,20 @@ if(CMAKE_Swift_COMPILER_ID) include(Platform/${CMAKE_EFFECTIVE_SYSTEM_NAME}-${CMAKE_Swift_COMPILER_ID}-Swift OPTIONAL) endif() -set(CMAKE_EXE_EXPORTS_Swift_FLAG "-emit-module -emit-module-path <SWIFT_MODULE> ${CMAKE_Swift_IMPLIB_LINKER_FLAGS}") - set(CMAKE_INCLUDE_FLAG_Swift "-I ") -if(CMAKE_SYSTEM_NAME STREQUAL Darwin) + +# FIXME: Move compiler- and platform-specific flags to the above-included modules. +if(CMAKE_SYSTEM_NAME STREQUAL "Darwin" OR CMAKE_SYSTEM_NAME STREQUAL "iOS" + OR CMAKE_SYSTEM_NAME STREQUAL "tvOS" OR CMAKE_SYSTEM_NAME STREQUAL "watchOS") set(CMAKE_SHARED_LIBRARY_SONAME_Swift_FLAG "-Xlinker -install_name -Xlinker ") elseif(NOT CMAKE_SYSTEM_NAME STREQUAL Windows) set(CMAKE_SHARED_LIBRARY_SONAME_Swift_FLAG "-Xlinker -soname -Xlinker ") endif() - if(NOT CMAKE_SYSTEM_NAME STREQUAL Windows) set(CMAKE_EXECUTABLE_RUNTIME_Swift_FLAG "-Xlinker -rpath -Xlinker ") set(CMAKE_SHARED_LIBRARY_RUNTIME_Swift_FLAG "-Xlinker -rpath -Xlinker ") - if(CMAKE_SYSTEM_NAME STREQUAL Darwin) + if(CMAKE_SYSTEM_NAME STREQUAL "Darwin" OR CMAKE_SYSTEM_NAME STREQUAL "iOS" + OR CMAKE_SYSTEM_NAME STREQUAL "tvOS" OR CMAKE_SYSTEM_NAME STREQUAL "watchOS") set(CMAKE_EXECUTABLE_RUNTIME_Swift_FLAG_SEP "") set(CMAKE_SHARED_LIBRARY_RUNTIME_Swift_FLAG_SEP "") else() @@ -65,10 +66,22 @@ set(CMAKE_Swift_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDLL -libc MD) set(CMAKE_Swift_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDebug -libc MTd) set(CMAKE_Swift_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDebugDLL -libc MDd) -set(CMAKE_Swift_FLAGS_DEBUG_INIT "-g") -set(CMAKE_Swift_FLAGS_RELEASE_INIT "-O") -set(CMAKE_Swift_FLAGS_RELWITHDEBINFO_INIT "-O -g") -set(CMAKE_Swift_FLAGS_MINSIZEREL_INIT "-Osize") +if(CMAKE_GENERATOR STREQUAL "Xcode") + # Xcode has a separate Xcode project option (SWIFT_COMPILATION_MODE) used to set + # whether compiling with whole-module optimizations or incrementally. Setting + # these options here will have no effect when compiling with the built-in driver, + # and will explode violently, leaving build products in the source directory, when + # using the old swift driver. + set(CMAKE_Swift_FLAGS_DEBUG_INIT "-Onone -g") + set(CMAKE_Swift_FLAGS_RELEASE_INIT "-O") + set(CMAKE_Swift_FLAGS_RELWITHDEBINFO_INIT "-O -g") + set(CMAKE_Swift_FLAGS_MINSIZEREL_INIT "-Osize") +else() + set(CMAKE_Swift_FLAGS_DEBUG_INIT "-Onone -g -incremental") + set(CMAKE_Swift_FLAGS_RELEASE_INIT "-O -wmo") + set(CMAKE_Swift_FLAGS_RELWITHDEBINFO_INIT "-O -g -wmo") + set(CMAKE_Swift_FLAGS_MINSIZEREL_INIT "-Osize -wmo") +endif() if(CMAKE_EXECUTABLE_FORMAT STREQUAL "ELF") if(NOT DEFINED CMAKE_Swift_LINK_WHAT_YOU_USE_FLAG) @@ -91,7 +104,7 @@ if(NOT CMAKE_Swift_NUM_THREADS MATCHES "^[0-9]+$") endif() if(NOT CMAKE_Swift_CREATE_SHARED_LIBRARY) - set(CMAKE_Swift_CREATE_SHARED_LIBRARY "<CMAKE_Swift_COMPILER> -output-file-map <SWIFT_OUTPUT_FILE_MAP> -incremental -j ${CMAKE_Swift_NUM_THREADS} -emit-library -o <TARGET> -module-name <SWIFT_MODULE_NAME> -module-link-name <SWIFT_LIBRARY_NAME> -emit-module -emit-module-path <SWIFT_MODULE> -emit-dependencies <DEFINES> <FLAGS> <INCLUDES> <SWIFT_SOURCES> <LINK_FLAGS> <SONAME_FLAG> <TARGET_INSTALLNAME_DIR><TARGET_SONAME> ${CMAKE_Swift_IMPLIB_LINKER_FLAGS} <LINK_LIBRARIES>") + set(CMAKE_Swift_CREATE_SHARED_LIBRARY "<CMAKE_Swift_COMPILER> -j ${CMAKE_Swift_NUM_THREADS} -num-threads ${CMAKE_Swift_NUM_THREADS} -emit-library -o <TARGET> -module-name <SWIFT_MODULE_NAME> -module-link-name <SWIFT_LIBRARY_NAME> -emit-module -emit-module-path <SWIFT_MODULE> -emit-dependencies <DEFINES> <FLAGS> <INCLUDES> <SWIFT_SOURCES> <LINK_FLAGS> <SONAME_FLAG> <TARGET_INSTALLNAME_DIR><TARGET_SONAME> ${CMAKE_Swift_IMPLIB_LINKER_FLAGS} <LINK_LIBRARIES>") endif() if(NOT CMAKE_Swift_CREATE_SHARED_MODULE) @@ -99,11 +112,15 @@ if(NOT CMAKE_Swift_CREATE_SHARED_MODULE) endif() if(NOT CMAKE_Swift_LINK_EXECUTABLE) - set(CMAKE_Swift_LINK_EXECUTABLE "<CMAKE_Swift_COMPILER> -output-file-map <SWIFT_OUTPUT_FILE_MAP> -incremental -j ${CMAKE_Swift_NUM_THREADS} -emit-executable -o <TARGET> -emit-dependencies <DEFINES> <FLAGS> <INCLUDES> <SWIFT_SOURCES> <LINK_FLAGS> <LINK_LIBRARIES>") + set(CMAKE_Swift_LINK_EXECUTABLE "<CMAKE_Swift_COMPILER> -j ${CMAKE_Swift_NUM_THREADS} -num-threads ${CMAKE_Swift_NUM_THREADS} -emit-executable -o <TARGET> -emit-dependencies <DEFINES> <FLAGS> <INCLUDES> <SWIFT_SOURCES> <LINK_FLAGS> <LINK_LIBRARIES>") +endif() + +if(NOT CMAKE_Swift_LINK_EXECUTABLE_WITH_EXPORTS) + set(CMAKE_Swift_LINK_EXECUTABLE_WITH_EXPORTS "${CMAKE_Swift_LINK_EXECUTABLE} -emit-module -emit-module-path <SWIFT_MODULE> ${CMAKE_Swift_IMPLIB_LINKER_FLAGS}") endif() if(NOT CMAKE_Swift_CREATE_STATIC_LIBRARY) - set(CMAKE_Swift_CREATE_STATIC_LIBRARY "<CMAKE_Swift_COMPILER> -output-file-map <SWIFT_OUTPUT_FILE_MAP> -incremental -j ${CMAKE_Swift_NUM_THREADS} -emit-library -static -o <TARGET> -module-name <SWIFT_MODULE_NAME> -module-link-name <SWIFT_LIBRARY_NAME> -emit-module -emit-module-path <SWIFT_MODULE> -emit-dependencies <DEFINES> <FLAGS> <INCLUDES> <SWIFT_SOURCES> <LINK_FLAGS> <LINK_LIBRARIES>") + set(CMAKE_Swift_CREATE_STATIC_LIBRARY "<CMAKE_Swift_COMPILER> -j ${CMAKE_Swift_NUM_THREADS} -num-threads ${CMAKE_Swift_NUM_THREADS} -emit-library -static -o <TARGET> -module-name <SWIFT_MODULE_NAME> -module-link-name <SWIFT_LIBRARY_NAME> -emit-module -emit-module-path <SWIFT_MODULE> -emit-dependencies <DEFINES> <FLAGS> <INCLUDES> <SWIFT_SOURCES> <LINK_FLAGS> <LINK_LIBRARIES>") set(CMAKE_Swift_ARCHIVE_CREATE "<CMAKE_AR> crs <TARGET> <OBJECTS>") set(CMAKE_Swift_ARCHIVE_FINISH "") diff --git a/Modules/CMakeSystemSpecificInformation.cmake b/Modules/CMakeSystemSpecificInformation.cmake index 0ded568..b5dc8d3 100644 --- a/Modules/CMakeSystemSpecificInformation.cmake +++ b/Modules/CMakeSystemSpecificInformation.cmake @@ -16,7 +16,25 @@ set(UNIX ) set(CYGWIN ) set(MSYS ) set(WIN32 ) +set(BSD ) +set(LINUX ) +function(_cmake_record_install_prefix ) + set(_CMAKE_SYSTEM_PREFIX_PATH_INSTALL_PREFIX_VALUE "${CMAKE_INSTALL_PREFIX}" PARENT_SCOPE) + set(_CMAKE_SYSTEM_PREFIX_PATH_STAGING_PREFIX_VALUE "${CMAKE_STAGING_PREFIX}" PARENT_SCOPE) + set(icount 0) + set(scount 0) + foreach(value IN LISTS CMAKE_SYSTEM_PREFIX_PATH) + if(value STREQUAL CMAKE_INSTALL_PREFIX) + math(EXPR icount "${icount}+1") + endif() + if(value STREQUAL CMAKE_STAGING_PREFIX) + math(EXPR scount "${scount}+1") + endif() + endforeach() + set(_CMAKE_SYSTEM_PREFIX_PATH_INSTALL_PREFIX_COUNT "${icount}" PARENT_SCOPE) + set(_CMAKE_SYSTEM_PREFIX_PATH_STAGING_PREFIX_COUNT "${scount}" PARENT_SCOPE) +endfunction() # include Generic system information include(CMakeGenericSystem) diff --git a/Modules/CMakeTestASM_MARMASMCompiler.cmake b/Modules/CMakeTestASM_MARMASMCompiler.cmake new file mode 100644 index 0000000..a6de04c --- /dev/null +++ b/Modules/CMakeTestASM_MARMASMCompiler.cmake @@ -0,0 +1,13 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + + +# This file is used by EnableLanguage in cmGlobalGenerator to +# determine that the selected ASM_MARMASM "compiler" (should be marmasm or marmasm64) +# works. For assembler this can only check whether the compiler has been found, +# because otherwise there would have to be a separate assembler source file +# for each assembler on every architecture. + +set(ASM_DIALECT "_MARMASM") +include(CMakeTestASMCompiler) +set(ASM_DIALECT) diff --git a/Modules/CMakeTestCCompiler.cmake b/Modules/CMakeTestCCompiler.cmake index ae5aa27..58726db 100644 --- a/Modules/CMakeTestCCompiler.cmake +++ b/Modules/CMakeTestCCompiler.cmake @@ -38,7 +38,7 @@ endif() if(NOT CMAKE_C_COMPILER_WORKS) PrintTestCompilerStatus("C") __TestCompiler_setTryCompileTargetType() - file(WRITE ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/testCCompiler.c + string(CONCAT __TestCompiler_testCCompilerSource "#ifdef __cplusplus\n" "# error \"The CMAKE_C_COMPILER is set to a C++ compiler\"\n" "#endif\n" @@ -53,18 +53,16 @@ if(NOT CMAKE_C_COMPILER_WORKS) # Clear result from normal variable. unset(CMAKE_C_COMPILER_WORKS) # Puts test result in cache variable. - try_compile(CMAKE_C_COMPILER_WORKS ${CMAKE_BINARY_DIR} - ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/testCCompiler.c + try_compile(CMAKE_C_COMPILER_WORKS + SOURCE_FROM_VAR testCCompiler.c __TestCompiler_testCCompilerSource OUTPUT_VARIABLE __CMAKE_C_COMPILER_OUTPUT) + unset(__TestCompiler_testCCompilerSource) # Move result from cache to normal variable. set(CMAKE_C_COMPILER_WORKS ${CMAKE_C_COMPILER_WORKS}) unset(CMAKE_C_COMPILER_WORKS CACHE) __TestCompiler_restoreTryCompileTargetType() if(NOT CMAKE_C_COMPILER_WORKS) PrintTestCompilerResult(CHECK_FAIL "broken") - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log - "Determining if the C compiler works failed with " - "the following output:\n${__CMAKE_C_COMPILER_OUTPUT}\n\n") string(REPLACE "\n" "\n " _output "${__CMAKE_C_COMPILER_OUTPUT}") message(FATAL_ERROR "The C compiler\n \"${CMAKE_C_COMPILER}\"\n" "is not able to compile a simple test program.\nIt fails " @@ -72,9 +70,6 @@ if(NOT CMAKE_C_COMPILER_WORKS) "CMake will not be able to correctly generate this project.") endif() PrintTestCompilerResult(CHECK_PASS "works") - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log - "Determining if the C compiler works passed with " - "the following output:\n${__CMAKE_C_COMPILER_OUTPUT}\n\n") endif() # Try to identify the compiler features diff --git a/Modules/CMakeTestCSharpCompiler.cmake b/Modules/CMakeTestCSharpCompiler.cmake index adea250..9f4b99f 100644 --- a/Modules/CMakeTestCSharpCompiler.cmake +++ b/Modules/CMakeTestCSharpCompiler.cmake @@ -12,8 +12,6 @@ include(CMakeTestCompilerCommon) unset(CMAKE_CSharp_COMPILER_WORKS CACHE) -set(test_compile_file "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/testCSharpCompiler.cs") - # This file is used by EnableLanguage in cmGlobalGenerator to # determine that the selected C# compiler can actually compile # and link the most basic of programs. If not, a fatal error @@ -23,19 +21,21 @@ if(NOT CMAKE_CSharp_COMPILER_WORKS) # Don't call PrintTestCompilerStatus() because the "C#" we want to pass # as the LANG doesn't match with the variable name "CMAKE_CSharp_COMPILER" message(CHECK_START "Check for working C# compiler: ${CMAKE_CSharp_COMPILER}") - file(WRITE "${test_compile_file}" - "namespace Test {" - " public class CSharp {" - " static void Main(string[] args) {}" - " }" - "}" + string(CONCAT __TestCompiler_testCSharpCompilerSource + "namespace Test {\n" + " public class CSharp {\n" + " static void Main(string[] args) {}\n" + " }\n" + "}\n" ) # Clear result from normal variable. unset(CMAKE_CSharp_COMPILER_WORKS) # Puts test result in cache variable. - try_compile(CMAKE_CSharp_COMPILER_WORKS ${CMAKE_BINARY_DIR} "${test_compile_file}" + try_compile(CMAKE_CSharp_COMPILER_WORKS + SOURCE_FROM_VAR testCSharpCompiler.cs __TestCompiler_testCSharpCompilerSource OUTPUT_VARIABLE __CMAKE_CSharp_COMPILER_OUTPUT ) + unset(__TestCompiler_testCSharpCompilerSource) # Move result from cache to normal variable. set(CMAKE_CSharp_COMPILER_WORKS ${CMAKE_CSharp_COMPILER_WORKS}) unset(CMAKE_CSharp_COMPILER_WORKS CACHE) @@ -44,9 +44,6 @@ endif() if(NOT CMAKE_CSharp_COMPILER_WORKS) PrintTestCompilerResult(CHECK_FAIL "broken") - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log - "Determining if the C# compiler works failed with " - "the following output:\n${__CMAKE_CSharp_COMPILER_OUTPUT}\n\n") string(REPLACE "\n" "\n " _output "${__CMAKE_CSharp_COMPILER_OUTPUT}") message(FATAL_ERROR "The C# compiler\n \"${CMAKE_CSharp_COMPILER}\"\n" "is not able to compile a simple test program.\nIt fails " @@ -55,9 +52,6 @@ if(NOT CMAKE_CSharp_COMPILER_WORKS) else() if(CSharp_TEST_WAS_RUN) PrintTestCompilerResult(CHECK_PASS "works") - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log - "Determining if the C# compiler works passed with " - "the following output:\n${__CMAKE_CSharp_COMPILER_OUTPUT}\n\n") endif() # Re-configure to save learned information. diff --git a/Modules/CMakeTestCUDACompiler.cmake b/Modules/CMakeTestCUDACompiler.cmake index 25a3653..5779e4b 100644 --- a/Modules/CMakeTestCUDACompiler.cmake +++ b/Modules/CMakeTestCUDACompiler.cmake @@ -21,6 +21,52 @@ if(CMAKE_CUDA_ABI_COMPILED) # The compiler worked so skip dedicated test below. set(CMAKE_CUDA_COMPILER_WORKS TRUE) message(STATUS "Check for working CUDA compiler: ${CMAKE_CUDA_COMPILER} - skipped") + + # Run the test binary to detect the native architectures. + execute_process(COMMAND "${CMAKE_PLATFORM_INFO_DIR}/CMakeDetermineCompilerABI_CUDA.bin" + RESULT_VARIABLE _CUDA_ARCHS_RESULT + OUTPUT_VARIABLE _CUDA_ARCHS_OUTPUT + ERROR_VARIABLE _CUDA_ARCHS_OUTPUT + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + if(_CUDA_ARCHS_RESULT EQUAL 0) + if("$ENV{CMAKE_CUDA_ARCHITECTURES_NATIVE_CLAMP}") + # Undocumented hook used by CMake's CI. + # Clamp native architecture to version range supported by this CUDA. + list(GET CMAKE_CUDA_ARCHITECTURES_ALL 0 _CUDA_ARCH_MIN) + list(GET CMAKE_CUDA_ARCHITECTURES_ALL -1 _CUDA_ARCH_MAX) + set(CMAKE_CUDA_ARCHITECTURES_NATIVE "") + foreach(_CUDA_ARCH IN LISTS _CUDA_ARCHS_OUTPUT) + if(_CUDA_ARCH LESS _CUDA_ARCH_MIN) + set(_CUDA_ARCH "${_CUDA_ARCH_MIN}") + endif() + if(_CUDA_ARCH GREATER _CUDA_ARCH_MAX) + set(_CUDA_ARCH "${_CUDA_ARCH_MAX}") + endif() + list(APPEND CMAKE_CUDA_ARCHITECTURES_NATIVE ${_CUDA_ARCH}) + endforeach() + unset(_CUDA_ARCH) + unset(_CUDA_ARCH_MIN) + unset(_CUDA_ARCH_MAX) + else() + set(CMAKE_CUDA_ARCHITECTURES_NATIVE "${_CUDA_ARCHS_OUTPUT}") + endif() + list(REMOVE_DUPLICATES CMAKE_CUDA_ARCHITECTURES_NATIVE) + list(TRANSFORM CMAKE_CUDA_ARCHITECTURES_NATIVE APPEND "-real") + else() + if(NOT _CUDA_ARCHS_RESULT MATCHES "[0-9]+") + set(_CUDA_ARCHS_STATUS " (${_CUDA_ARCHS_RESULT})") + else() + set(_CUDA_ARCHS_STATUS "") + endif() + string(REPLACE "\n" "\n " _CUDA_ARCHS_OUTPUT " ${_CUDA_ARCHS_OUTPUT}") + message(CONFIGURE_LOG + "Detecting the CUDA native architecture(s) failed with " + "the following output:\n${_CUDA_ARCHS_OUTPUT}\n\n") + endif() + unset(_CUDA_ARCHS_EXE) + unset(_CUDA_ARCHS_RESULT) + unset(_CUDA_ARCHS_OUTPUT) endif() # This file is used by EnableLanguage in cmGlobalGenerator to @@ -30,7 +76,7 @@ endif() # any makefiles or projects. if(NOT CMAKE_CUDA_COMPILER_WORKS) PrintTestCompilerStatus("CUDA") - file(WRITE ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/main.cu + string(CONCAT __TestCompiler_testCudaCompilerSource "#ifndef __CUDACC__\n" "# error \"The CMAKE_CUDA_COMPILER is set to an invalid CUDA compiler\"\n" "#endif\n" @@ -40,18 +86,16 @@ if(NOT CMAKE_CUDA_COMPILER_WORKS) unset(CMAKE_CUDA_COMPILER_WORKS) # Puts test result in cache variable. - try_compile(CMAKE_CUDA_COMPILER_WORKS ${CMAKE_BINARY_DIR} - ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/main.cu + try_compile(CMAKE_CUDA_COMPILER_WORKS + SOURCE_FROM_VAR main.cu __TestCompiler_testCudaCompilerSource OUTPUT_VARIABLE __CMAKE_CUDA_COMPILER_OUTPUT) + unset(__TestCompiler_testCudaCompilerSource) # Move result from cache to normal variable. set(CMAKE_CUDA_COMPILER_WORKS ${CMAKE_CUDA_COMPILER_WORKS}) unset(CMAKE_CUDA_COMPILER_WORKS CACHE) if(NOT CMAKE_CUDA_COMPILER_WORKS) PrintTestCompilerResult(CHECK_FAIL "broken") - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log - "Determining if the CUDA compiler works failed with " - "the following output:\n${__CMAKE_CUDA_COMPILER_OUTPUT}\n\n") string(REPLACE "\n" "\n " _output "${__CMAKE_CUDA_COMPILER_OUTPUT}") message(FATAL_ERROR "The CUDA compiler\n \"${CMAKE_CUDA_COMPILER}\"\n" "is not able to compile a simple test program.\nIt fails " @@ -59,9 +103,6 @@ if(NOT CMAKE_CUDA_COMPILER_WORKS) "CMake will not be able to correctly generate this project.") endif() PrintTestCompilerResult(CHECK_PASS "works") - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log - "Determining if the CUDA compiler works passed with " - "the following output:\n${__CMAKE_CUDA_COMPILER_OUTPUT}\n\n") endif() # Try to identify the compiler features diff --git a/Modules/CMakeTestCXXCompiler.cmake b/Modules/CMakeTestCXXCompiler.cmake index bbe3533..e640ff9 100644 --- a/Modules/CMakeTestCXXCompiler.cmake +++ b/Modules/CMakeTestCXXCompiler.cmake @@ -38,7 +38,7 @@ endif() if(NOT CMAKE_CXX_COMPILER_WORKS) PrintTestCompilerStatus("CXX") __TestCompiler_setTryCompileTargetType() - file(WRITE ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/testCXXCompiler.cxx + string(CONCAT __TestCompiler_testCXXCompilerSource "#ifndef __cplusplus\n" "# error \"The CMAKE_CXX_COMPILER is set to a C compiler\"\n" "#endif\n" @@ -46,18 +46,16 @@ if(NOT CMAKE_CXX_COMPILER_WORKS) # Clear result from normal variable. unset(CMAKE_CXX_COMPILER_WORKS) # Puts test result in cache variable. - try_compile(CMAKE_CXX_COMPILER_WORKS ${CMAKE_BINARY_DIR} - ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/testCXXCompiler.cxx + try_compile(CMAKE_CXX_COMPILER_WORKS + SOURCE_FROM_VAR testCXXCompiler.cxx __TestCompiler_testCXXCompilerSource OUTPUT_VARIABLE __CMAKE_CXX_COMPILER_OUTPUT) + unset(__TestCompiler_testCXXCompilerSource) # Move result from cache to normal variable. set(CMAKE_CXX_COMPILER_WORKS ${CMAKE_CXX_COMPILER_WORKS}) unset(CMAKE_CXX_COMPILER_WORKS CACHE) __TestCompiler_restoreTryCompileTargetType() if(NOT CMAKE_CXX_COMPILER_WORKS) PrintTestCompilerResult(CHECK_FAIL "broken") - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log - "Determining if the CXX compiler works failed with " - "the following output:\n${__CMAKE_CXX_COMPILER_OUTPUT}\n\n") string(REPLACE "\n" "\n " _output "${__CMAKE_CXX_COMPILER_OUTPUT}") message(FATAL_ERROR "The C++ compiler\n \"${CMAKE_CXX_COMPILER}\"\n" "is not able to compile a simple test program.\nIt fails " @@ -65,9 +63,6 @@ if(NOT CMAKE_CXX_COMPILER_WORKS) "CMake will not be able to correctly generate this project.") endif() PrintTestCompilerResult(CHECK_PASS "works") - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log - "Determining if the CXX compiler works passed with " - "the following output:\n${__CMAKE_CXX_COMPILER_OUTPUT}\n\n") endif() # Try to identify the compiler features diff --git a/Modules/CMakeTestFortranCompiler.cmake b/Modules/CMakeTestFortranCompiler.cmake index 579f83f..1baa18d 100644 --- a/Modules/CMakeTestFortranCompiler.cmake +++ b/Modules/CMakeTestFortranCompiler.cmake @@ -38,7 +38,7 @@ endif() # any makefiles or projects. if(NOT CMAKE_Fortran_COMPILER_WORKS) PrintTestCompilerStatus("Fortran") - file(WRITE ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/testFortranCompiler.f " + set(__TestCompiler_testFortranCompilerSource " PROGRAM TESTFortran PRINT *, 'Hello' END @@ -46,17 +46,15 @@ if(NOT CMAKE_Fortran_COMPILER_WORKS) # Clear result from normal variable. unset(CMAKE_Fortran_COMPILER_WORKS) # Puts test result in cache variable. - try_compile(CMAKE_Fortran_COMPILER_WORKS ${CMAKE_BINARY_DIR} - ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/testFortranCompiler.f + try_compile(CMAKE_Fortran_COMPILER_WORKS + SOURCE_FROM_VAR testFortranCompiler.f __TestCompiler_testFortranCompilerSource OUTPUT_VARIABLE OUTPUT) + unset(__TestCompiler_testFortranCompilerSource) # Move result from cache to normal variable. set(CMAKE_Fortran_COMPILER_WORKS ${CMAKE_Fortran_COMPILER_WORKS}) unset(CMAKE_Fortran_COMPILER_WORKS CACHE) if(NOT CMAKE_Fortran_COMPILER_WORKS) PrintTestCompilerResult(CHECK_FAIL "broken") - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log - "Determining if the Fortran compiler works failed with " - "the following output:\n${OUTPUT}\n\n") string(REPLACE "\n" "\n " _output "${OUTPUT}") message(FATAL_ERROR "The Fortran compiler\n \"${CMAKE_Fortran_COMPILER}\"\n" "is not able to compile a simple test program.\nIt fails " @@ -64,33 +62,25 @@ if(NOT CMAKE_Fortran_COMPILER_WORKS) "CMake will not be able to correctly generate this project.") endif() PrintTestCompilerResult(CHECK_PASS "works") - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log - "Determining if the Fortran compiler works passed with " - "the following output:\n${OUTPUT}\n\n") endif() # Test for Fortran 90 support by using an f90-specific construct. if(NOT DEFINED CMAKE_Fortran_COMPILER_SUPPORTS_F90) message(CHECK_START "Checking whether ${CMAKE_Fortran_COMPILER} supports Fortran 90") - file(WRITE ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/testFortranCompilerF90.f90 " + set(__TestCompiler_testFortranCompilerSource " PROGRAM TESTFortran90 integer stop ; stop = 1 ; do while ( stop .eq. 0 ) ; end do END PROGRAM TESTFortran90 ") - try_compile(CMAKE_Fortran_COMPILER_SUPPORTS_F90 ${CMAKE_BINARY_DIR} - ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/testFortranCompilerF90.f90 + try_compile(CMAKE_Fortran_COMPILER_SUPPORTS_F90 + SOURCE_FROM_VAR testFortranCompilerF90.f90 __TestCompiler_testFortranCompilerF90Source OUTPUT_VARIABLE OUTPUT) + unset(__TestCompiler_testFortranCompilerF90Source) if(CMAKE_Fortran_COMPILER_SUPPORTS_F90) message(CHECK_PASS "yes") - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log - "Determining if the Fortran compiler supports Fortran 90 passed with " - "the following output:\n${OUTPUT}\n\n") set(CMAKE_Fortran_COMPILER_SUPPORTS_F90 1) else() message(CHECK_FAIL "no") - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log - "Determining if the Fortran compiler supports Fortran 90 failed with " - "the following output:\n${OUTPUT}\n\n") set(CMAKE_Fortran_COMPILER_SUPPORTS_F90 0) endif() unset(CMAKE_Fortran_COMPILER_SUPPORTS_F90 CACHE) diff --git a/Modules/CMakeTestHIPCompiler.cmake b/Modules/CMakeTestHIPCompiler.cmake index ecbfa7f..686f055 100644 --- a/Modules/CMakeTestHIPCompiler.cmake +++ b/Modules/CMakeTestHIPCompiler.cmake @@ -41,7 +41,7 @@ endif() if(NOT CMAKE_HIP_COMPILER_WORKS) PrintTestCompilerStatus("HIP") __TestCompiler_setTryCompileTargetType() - file(WRITE ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/testHIPCompiler.hip + string(CONCAT __TestCompiler_testHIPCompilerSource "#ifndef __HIP__\n" "# error \"The CMAKE_HIP_COMPILER is set to a C/CXX compiler\"\n" "#endif\n" @@ -49,18 +49,16 @@ if(NOT CMAKE_HIP_COMPILER_WORKS) # Clear result from normal variable. unset(CMAKE_HIP_COMPILER_WORKS) # Puts test result in cache variable. - try_compile(CMAKE_HIP_COMPILER_WORKS ${CMAKE_BINARY_DIR} - ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/testHIPCompiler.hip + try_compile(CMAKE_HIP_COMPILER_WORKS + SOURCE_FROM_VAR testHIPCompiler.hip __TestCompiler_testHIPCompilerSource OUTPUT_VARIABLE __CMAKE_HIP_COMPILER_OUTPUT) + unset(__TestCompiler_testHIPCompilerSource) # Move result from cache to normal variable. set(CMAKE_HIP_COMPILER_WORKS ${CMAKE_HIP_COMPILER_WORKS}) unset(CMAKE_HIP_COMPILER_WORKS CACHE) __TestCompiler_restoreTryCompileTargetType() if(NOT CMAKE_HIP_COMPILER_WORKS) PrintTestCompilerResult(CHECK_FAIL "broken") - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log - "Determining if the HIP compiler works failed with " - "the following output:\n${__CMAKE_HIP_COMPILER_OUTPUT}\n\n") string(REPLACE "\n" "\n " _output "${__CMAKE_HIP_COMPILER_OUTPUT}") message(FATAL_ERROR "The HIP compiler\n \"${CMAKE_HIP_COMPILER}\"\n" "is not able to compile a simple test program.\nIt fails " @@ -68,9 +66,6 @@ if(NOT CMAKE_HIP_COMPILER_WORKS) "CMake will not be able to correctly generate this project.") endif() PrintTestCompilerResult(CHECK_PASS "works") - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log - "Determining if the HIP compiler works passed with " - "the following output:\n${__CMAKE_HIP_COMPILER_OUTPUT}\n\n") endif() set(CMAKE_HIP_FLAGS "${__CMAKE_HIP_FLAGS}") diff --git a/Modules/CMakeTestOBJCCompiler.cmake b/Modules/CMakeTestOBJCCompiler.cmake index 20d1f8b..a36180b 100644 --- a/Modules/CMakeTestOBJCCompiler.cmake +++ b/Modules/CMakeTestOBJCCompiler.cmake @@ -38,7 +38,7 @@ endif() if(NOT CMAKE_OBJC_COMPILER_WORKS) PrintTestCompilerStatus("OBJC") __TestCompiler_setTryCompileTargetType() - file(WRITE ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/testOBJCCompiler.m + string(CONCAT __TestCompiler_testObjCCompilerSource "#ifdef __cplusplus\n" "# error \"The CMAKE_OBJC_COMPILER is set to a C++ compiler\"\n" "#endif\n" @@ -50,18 +50,16 @@ if(NOT CMAKE_OBJC_COMPILER_WORKS) # Clear result from normal variable. unset(CMAKE_OBJC_COMPILER_WORKS) # Puts test result in cache variable. - try_compile(CMAKE_OBJC_COMPILER_WORKS ${CMAKE_BINARY_DIR} - ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/testOBJCCompiler.m + try_compile(CMAKE_OBJC_COMPILER_WORKS + SOURCE_FROM_VAR testObjCCompiler.m __TestCompiler_testObjCCompilerSource OUTPUT_VARIABLE __CMAKE_OBJC_COMPILER_OUTPUT) + unset(__TestCompiler_testObjCCompilerSource) # Move result from cache to normal variable. set(CMAKE_OBJC_COMPILER_WORKS ${CMAKE_OBJC_COMPILER_WORKS}) unset(CMAKE_OBJC_COMPILER_WORKS CACHE) __TestCompiler_restoreTryCompileTargetType() if(NOT CMAKE_OBJC_COMPILER_WORKS) PrintTestCompilerResult(CHECK_FAIL "broken") - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log - "Determining if the Objective-C compiler works failed with " - "the following output:\n${__CMAKE_OBJC_COMPILER_OUTPUT}\n\n") string(REPLACE "\n" "\n " _output "${__CMAKE_OBJC_COMPILER_OUTPUT}") message(FATAL_ERROR "The Objective-C compiler\n \"${CMAKE_OBJC_COMPILER}\"\n" "is not able to compile a simple test program.\nIt fails " @@ -69,9 +67,6 @@ if(NOT CMAKE_OBJC_COMPILER_WORKS) "CMake will not be able to correctly generate this project.") endif() PrintTestCompilerResult(CHECK_PASS "works") - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log - "Determining if the Objective-C compiler works passed with " - "the following output:\n${__CMAKE_OBJC_COMPILER_OUTPUT}\n\n") endif() # Try to identify the compiler features diff --git a/Modules/CMakeTestOBJCXXCompiler.cmake b/Modules/CMakeTestOBJCXXCompiler.cmake index 4f7185f..f7935c7 100644 --- a/Modules/CMakeTestOBJCXXCompiler.cmake +++ b/Modules/CMakeTestOBJCXXCompiler.cmake @@ -38,7 +38,7 @@ endif() if(NOT CMAKE_OBJCXX_COMPILER_WORKS) PrintTestCompilerStatus("OBJCXX") __TestCompiler_setTryCompileTargetType() - file(WRITE ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/testOBJCXXCompiler.mm + string(CONCAT __TestCompiler_testObjCXXCompilerSource "#ifndef __cplusplus\n" "# error \"The CMAKE_OBJCXX_COMPILER is set to a C compiler\"\n" "#endif\n" @@ -49,18 +49,16 @@ if(NOT CMAKE_OBJCXX_COMPILER_WORKS) # Clear result from normal variable. unset(CMAKE_OBJCXX_COMPILER_WORKS) # Puts test result in cache variable. - try_compile(CMAKE_OBJCXX_COMPILER_WORKS ${CMAKE_BINARY_DIR} - ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/testOBJCXXCompiler.mm + try_compile(CMAKE_OBJCXX_COMPILER_WORKS + SOURCE_FROM_VAR testObjCXXCompiler.mm __TestCompiler_testObjCXXCompilerSource OUTPUT_VARIABLE __CMAKE_OBJCXX_COMPILER_OUTPUT) + unset(__TestCompiler_testObjCXXCompilerSource) # Move result from cache to normal variable. set(CMAKE_OBJCXX_COMPILER_WORKS ${CMAKE_OBJCXX_COMPILER_WORKS}) unset(CMAKE_OBJCXX_COMPILER_WORKS CACHE) __TestCompiler_restoreTryCompileTargetType() if(NOT CMAKE_OBJCXX_COMPILER_WORKS) PrintTestCompilerResult(CHECK_FAIL "broken") - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log - "Determining if the Objective-C++ compiler works failed with " - "the following output:\n${__CMAKE_OBJCXX_COMPILER_OUTPUT}\n\n") string(REPLACE "\n" "\n " _output "${__CMAKE_OBJCXX_COMPILER_OUTPUT}") message(FATAL_ERROR "The Objective-C++ compiler\n \"${CMAKE_OBJCXX_COMPILER}\"\n" "is not able to compile a simple test program.\nIt fails " @@ -68,9 +66,6 @@ if(NOT CMAKE_OBJCXX_COMPILER_WORKS) "CMake will not be able to correctly generate this project.") endif() PrintTestCompilerResult(CHECK_PASS "works") - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log - "Determining if the Objective-C++ compiler works passed with " - "the following output:\n${__CMAKE_OBJCXX_COMPILER_OUTPUT}\n\n") endif() # Try to identify the compiler features diff --git a/Modules/CMakeTestSwiftCompiler.cmake b/Modules/CMakeTestSwiftCompiler.cmake index 2f2546f..c7df912 100644 --- a/Modules/CMakeTestSwiftCompiler.cmake +++ b/Modules/CMakeTestSwiftCompiler.cmake @@ -21,13 +21,12 @@ unset(CMAKE_Swift_COMPILER_WORKS CACHE) # any makefiles or projects. if(NOT CMAKE_Swift_COMPILER_WORKS) PrintTestCompilerStatus("Swift") - file(WRITE ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/main.swift - "print(\"CMake\")\n") # Clear result from normal variable. unset(CMAKE_Swift_COMPILER_WORKS) # Puts test result in cache variable. - try_compile(CMAKE_Swift_COMPILER_WORKS ${CMAKE_BINARY_DIR} - ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/main.swift + set(__CMAKE_Swift_TEST_SOURCE "print(\"CMake\")\n") + try_compile(CMAKE_Swift_COMPILER_WORKS + SOURCE_FROM_VAR main.swift __CMAKE_Swift_TEST_SOURCE OUTPUT_VARIABLE __CMAKE_Swift_COMPILER_OUTPUT) # Move result from cache to normal variable. set(CMAKE_Swift_COMPILER_WORKS ${CMAKE_Swift_COMPILER_WORKS}) @@ -37,9 +36,6 @@ endif() if(NOT CMAKE_Swift_COMPILER_WORKS) PrintTestCompilerResult(CHECK_FAIL "broken") - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log - "Determining if the Swift compiler works failed with " - "the following output:\n${__CMAKE_Swift_COMPILER_OUTPUT}\n\n") string(REPLACE "\n" "\n " _output "${__CMAKE_Swift_COMPILER_OUTPUT}") message(FATAL_ERROR "The Swift compiler\n \"${CMAKE_Swift_COMPILER}\"\n" "is not able to compile a simple test program.\nIt fails " @@ -48,9 +44,6 @@ if(NOT CMAKE_Swift_COMPILER_WORKS) else() if(Swift_TEST_WAS_RUN) PrintTestCompilerResult(CHECK_PASS "works") - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log - "Determining if the Swift compiler works passed with " - "the following output:\n${__CMAKE_Swift_COMPILER_OUTPUT}\n\n") endif() # Unlike C and CXX we do not yet detect any information about the Swift ABI. @@ -64,4 +57,5 @@ else() include(${CMAKE_PLATFORM_INFO_DIR}/CMakeSwiftCompiler.cmake) endif() +unset(__CMAKE_Swift_TEST_SOURCE) unset(__CMAKE_Swift_COMPILER_OUTPUT) diff --git a/Modules/CPack.cmake b/Modules/CPack.cmake index 6650f7c..f9cf33f 100644 --- a/Modules/CPack.cmake +++ b/Modules/CPack.cmake @@ -53,9 +53,9 @@ Here's how it works: * :manual:`cpack <cpack(1)>` runs * it includes ``CPackConfig.cmake`` -* it iterates over the generators given by the ``-G`` command line option, - or if no such option was specified, over the list of generators given by - the :variable:`CPACK_GENERATOR` variable set in the ``CPackConfig.cmake`` +* it iterates over the generators given by the :option:`-G <cpack -G>` command + line option, or if no such option was specified, over the list of generators + given by the :variable:`CPACK_GENERATOR` variable set in the ``CPackConfig.cmake`` input file. * foreach generator, it then @@ -217,7 +217,8 @@ installers. The most commonly-used variables are: to the user by the produced installer (often with an explicit "Accept" button, for graphical installers) prior to installation. This license file is NOT added to the installed files but is used by some CPack generators - like NSIS. If you want to install a license file (may be the same as this + like NSIS. If you want to use UTF-8 characters, the file needs to be encoded + in UTF-8 BOM. If you want to install a license file (may be the same as this one) along with your project, you must add an appropriate CMake :command:`install` command in your ``CMakeLists.txt``. @@ -246,9 +247,9 @@ installers. The most commonly-used variables are: List of CPack generators to use. If not specified, CPack will create a set of options following the naming pattern :variable:`CPACK_BINARY_<GENNAME>` (e.g. ``CPACK_BINARY_NSIS``) allowing - the user to enable/disable individual generators. If the ``-G`` option is - given on the :manual:`cpack <cpack(1)>` command line, it will override this - variable and any ``CPACK_BINARY_<GENNAME>`` options. + the user to enable/disable individual generators. If the :option:`-G <cpack -G>` + option is given on the :manual:`cpack <cpack(1)>` command line, it will override + this variable and any ``CPACK_BINARY_<GENNAME>`` options. .. variable:: CPACK_OUTPUT_CONFIG_FILE @@ -261,7 +262,7 @@ installers. The most commonly-used variables are: Lists each of the executables and associated text label to be used to create Start Menu shortcuts. For example, setting this to the list ``ccmake;CMake`` will create a shortcut named "CMake" that will execute the - installed executable ``ccmake``. Not all CPack generators use it (at least + installed executable :program:`ccmake`. Not all CPack generators use it (at least NSIS, and WIX do). .. variable:: CPACK_STRIP_FILES @@ -304,14 +305,25 @@ installers. The most commonly-used variables are: By default ``CPACK_THREADS`` is set to ``1``. - Currently only ``xz`` compression *may* take advantage of multiple cores. - Other compression methods ignore this value and use only one thread. + The following compression methods may take advantage of multiple cores: + + ``xz`` + Supported if CMake is built with a ``liblzma`` that supports + parallel compression. + + .. versionadded:: 3.21 - .. versionadded:: 3.21 + Official CMake binaries available on ``cmake.org`` now ship + with a ``liblzma`` that supports parallel compression. + Older versions did not. - Official CMake binaries available on ``cmake.org`` now ship - with a ``liblzma`` that supports parallel compression. - Older versions did not. + ``zstd`` + .. versionadded:: 3.24 + + Supported if CMake is built with libarchive 3.6 or higher. + Official CMake binaries available on ``cmake.org`` support it. + + Other compression methods ignore this value and use only one thread. Variables for Source Package Generators ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -458,7 +470,35 @@ The following variables are for advanced uses of CPack: generates (when :variable:`CPACK_GENERATOR` is not set) a set of CMake options (see CMake :command:`option` command) which may then be used to select the CPack generator(s) to be used when building the ``package`` - target or when running :manual:`cpack <cpack(1)>` without the ``-G`` option. + target or when running :manual:`cpack <cpack(1)>` without the + :option:`-G <cpack -G>` option. + +.. variable:: CPACK_READELF_EXECUTABLE + + .. versionadded:: 3.25 + + Specify the ``readelf`` executable path used by CPack. + The default value will be ``CMAKE_READELF`` when set. Otherwise, + the default value will be empty and CPack will use :command:`find_program` + to determine the ``readelf`` path when needed. + +.. variable:: CPACK_OBJCOPY_EXECUTABLE + + .. versionadded:: 3.25 + + Specify the ``objcopy`` executable path used by CPack. + The default value will be ``CMAKE_OBJCOPY`` when set. Otherwise, + the default value will be empty and CPack will use :command:`find_program` + to determine the ``objcopy`` path when needed. + +.. variable:: CPACK_OBJDUMP_EXECUTABLE + + .. versionadded:: 3.25 + + Specify the ``objdump`` executable path used by CPack. + The default value will be ``CMAKE_OBJDUMP`` when set. Otherwise, + the default value will be empty and CPack will use :command:`find_program` + to determine the ``objdump`` path when needed. #]=======================================================================] @@ -579,6 +619,16 @@ _cpack_set_default(CPACK_RESOURCE_FILE_WELCOME _cpack_set_default(CPACK_MODULE_PATH "${CMAKE_MODULE_PATH}") +if(CMAKE_READELF) + _cpack_set_default(CPACK_READELF_EXECUTABLE "${CMAKE_READELF}") +endif() +if(CMAKE_OBJCOPY) + _cpack_set_default(CPACK_OBJCOPY_EXECUTABLE "${CMAKE_OBJCOPY}") +endif() +if(CMAKE_OBJDUMP) + _cpack_set_default(CPACK_OBJDUMP_EXECUTABLE "${CMAKE_OBJDUMP}") +endif() + # Set default directory creation permissions mode if(CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS) _cpack_set_default(CPACK_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS @@ -658,12 +708,10 @@ if(NOT CPACK_GENERATOR) if(APPLE) option(CPACK_BINARY_BUNDLE "Enable to build OSX bundles" OFF) option(CPACK_BINARY_DRAGNDROP "Enable to build OSX Drag And Drop package" OFF) - option(CPACK_BINARY_PACKAGEMAKER "Enable to build PackageMaker packages (deprecated)" OFF) option(CPACK_BINARY_PRODUCTBUILD "Enable to build productbuild packages" OFF) mark_as_advanced( CPACK_BINARY_BUNDLE CPACK_BINARY_DRAGNDROP - CPACK_BINARY_PACKAGEMAKER CPACK_BINARY_PRODUCTBUILD ) else() @@ -715,7 +763,6 @@ if(NOT CPACK_GENERATOR) cpack_optional_append(CPACK_GENERATOR CPACK_BINARY_IFW IFW) cpack_optional_append(CPACK_GENERATOR CPACK_BINARY_NSIS NSIS) cpack_optional_append(CPACK_GENERATOR CPACK_BINARY_NUGET NuGet) - cpack_optional_append(CPACK_GENERATOR CPACK_BINARY_PACKAGEMAKER PackageMaker) cpack_optional_append(CPACK_GENERATOR CPACK_BINARY_PRODUCTBUILD productbuild) cpack_optional_append(CPACK_GENERATOR CPACK_BINARY_RPM RPM) cpack_optional_append(CPACK_GENERATOR CPACK_BINARY_STGZ STGZ) @@ -806,8 +853,20 @@ _cpack_set_default(CPACK_NSIS_INSTALLER_ICON_CODE "") _cpack_set_default(CPACK_NSIS_INSTALLER_MUI_ICON_CODE "") # DragNDrop specific variables -if(CPACK_RESOURCE_FILE_LICENSE AND NOT CPACK_RESOURCE_FILE_LICENSE STREQUAL "${CMAKE_ROOT}/Templates/CPack.GenericLicense.txt") - _cpack_set_default(CPACK_DMG_SLA_USE_RESOURCE_FILE_LICENSE ON) +if(NOT DEFINED CPACK_DMG_SLA_USE_RESOURCE_FILE_LICENSE + AND CPACK_RESOURCE_FILE_LICENSE AND NOT CPACK_RESOURCE_FILE_LICENSE STREQUAL "${CMAKE_ROOT}/Templates/CPack.GenericLicense.txt") + cmake_policy(GET CMP0133 _CPack_CMP0133) + if(NOT "x${_CPack_CMP0133}x" STREQUAL "xNEWx") + if(NOT "x${_CPack_CMP0133}x" STREQUAL "xOLDx" AND CMAKE_POLICY_WARNING_CMP0133) + cmake_policy(GET_WARNING CMP0133 _CMP0133_warning) + message(AUTHOR_WARNING + "${_CMP0133_warning}\n" + "For compatibility, CMake will enable the SLA in the CPack DragNDrop Generator." + ) + endif() + _cpack_set_default(CPACK_DMG_SLA_USE_RESOURCE_FILE_LICENSE ON) + endif() + unset(_CPack_CMP0133) endif() # WiX specific variables diff --git a/Modules/CPackComponent.cmake b/Modules/CPackComponent.cmake index 1f8c38c..529f4e7 100644 --- a/Modules/CPackComponent.cmake +++ b/Modules/CPackComponent.cmake @@ -301,7 +301,7 @@ be built and installed on system using macOS 10.5 or later. The site argument is a URL where the archives for downloadable components will reside, e.g., -https://cmake.org/files/2.6.1/installer/ All of the archives +https://cmake.org/files/v3.25/ All of the archives produced by CPack should be uploaded to that location. UPLOAD_DIRECTORY is the local directory where CPack will create the @@ -327,32 +327,34 @@ OS X. if(NOT CPackComponent_CMake_INCLUDED) set(CPackComponent_CMake_INCLUDED 1) -# Macro that appends a SET command for the given variable name (var) -# to the macro named strvar, but only if the variable named "var" +# Function that appends a SET command for the given variable name (var) +# to the string named strvar, but only if the variable named "var" # has been defined. The string will eventually be appended to a CPack # configuration file. -macro(cpack_append_variable_set_command var strvar) +function(cpack_append_variable_set_command var strvar) if (DEFINED ${var}) string(APPEND ${strvar} "set(${var}") foreach(APPENDVAL ${${var}}) string(APPEND ${strvar} " ${APPENDVAL}") endforeach() string(APPEND ${strvar} ")\n") + set(${strvar} "${${strvar}}" PARENT_SCOPE) endif () -endmacro() +endfunction() -# Macro that appends a SET command for the given variable name (var) -# to the macro named strvar, but only if the variable named "var" +# Function that appends a SET command for the given variable name (var) +# to the string named strvar, but only if the variable named "var" # has been defined and is a string. The string will eventually be # appended to a CPack configuration file. -macro(cpack_append_string_variable_set_command var strvar) +function(cpack_append_string_variable_set_command var strvar) if (DEFINED ${var}) list(LENGTH ${var} CPACK_APP_VALUE_LEN) if(${CPACK_APP_VALUE_LEN} EQUAL 1) string(APPEND ${strvar} "set(${var} \"${${var}}\")\n") endif() + set(${strvar} "${${strvar}}" PARENT_SCOPE) endif () -endmacro() +endfunction() # Macro that appends a SET command for the given list variable name (var) # to the macro named strvar, but only if the variable named "var" diff --git a/Modules/CPackIFW.cmake b/Modules/CPackIFW.cmake index 003cf3f..d4e02f1 100644 --- a/Modules/CPackIFW.cmake +++ b/Modules/CPackIFW.cmake @@ -439,36 +439,57 @@ set(_CPACK_IFW_PREFIXES "QtIFW-") set(_CPACK_IFW_VERSIONS + "4.5.0" + "4.5" + "4.4.2" + "4.4.1" + "4.4.0" + "4.4" + "4.3.0" "4.3" + "4.2.0" "4.2" + "4.1.1" + "4.1.0" "4.1" + "4.0.1" + "4.0.0" "4.0" - "3.2" + "3.2.3" + "3.2.2" + "3.2.1" "3.2.0" - "3.1" + "3.2" + "3.1.1" "3.1.0" - "3.0" + "3.1" + "3.0.6" + "3.0.4" + "3.0.3" + "3.0.2" + "3.0.1" "3.0.0" - "2.3" + "3.0" "2.3.0" - "2.2" + "2.3" "2.2.0" - "2.1" + "2.2" "2.1.0" - "2.0" + "2.1" "2.0.5" "2.0.3" "2.0.2" "2.0.1" "2.0.0" - "1.6" + "2.0" "1.6.0" - "1.5" + "1.6" "1.5.0" - "1.4" + "1.5" "1.4.0" - "1.3" - "1.3.0") + "1.4" + "1.3.0" + "1.3") set(_CPACK_IFW_SUFFIXES "bin") foreach(_CPACK_IFW_PREFIX ${_CPACK_IFW_PREFIXES}) diff --git a/Modules/CTest.cmake b/Modules/CTest.cmake index 8f8ebb4..16283d6 100644 --- a/Modules/CTest.cmake +++ b/Modules/CTest.cmake @@ -33,7 +33,7 @@ file at the top of the project with content such as:: (the CDash server can provide the file to a project administrator who configures ``MyProject``). Settings in the config file are shared by both this ``CTest`` module and the :manual:`ctest(1)` command-line -:ref:`Dashboard Client` mode (``ctest -S``). +:ref:`Dashboard Client` mode (:option:`ctest -S`). While building a project for submission to CDash, CTest scans the build output for errors and warnings and reports them with surrounding diff --git a/Modules/CTestTargets.cmake b/Modules/CTestTargets.cmake index 838fbbf..b91b48e 100644 --- a/Modules/CTestTargets.cmake +++ b/Modules/CTestTargets.cmake @@ -86,7 +86,7 @@ if(NOT _CTEST_TARGETS_ADDED) # or "RUN_TESTS" target: if(CTEST_TEST_TARGET_ALIAS) add_custom_target(${CTEST_TEST_TARGET_ALIAS} - ${CMAKE_CTEST_COMMAND} ${__conf_types} + ${CMAKE_CTEST_COMMAND} ${CMAKE_CTEST_ARGUMENTS} ${__conf_types} USES_TERMINAL ) endif() diff --git a/Modules/CTestUseLaunchers.cmake b/Modules/CTestUseLaunchers.cmake index 23a206b..5c544f8 100644 --- a/Modules/CTestUseLaunchers.cmake +++ b/Modules/CTestUseLaunchers.cmake @@ -11,7 +11,7 @@ CTestUseLaunchers is automatically included when you include(CTest). However, it is split out into its own module file so projects can use the CTEST_USE_LAUNCHERS functionality independently. -To use launchers, set CTEST_USE_LAUNCHERS to ON in a ctest -S +To use launchers, set CTEST_USE_LAUNCHERS to ON in a :option:`ctest -S` dashboard script, and then also set it in the cache of the configured project. Both cmake and ctest need to know the value of it for the launchers to work properly. CMake needs to know in order to generate @@ -27,9 +27,12 @@ variable initialization only occurs if CTEST_USE_LAUNCHERS is not already defined. .. versionadded:: 3.8 - If CTEST_USE_LAUNCHERS is on in a ctest -S script + If CTEST_USE_LAUNCHERS is on in a :option:`ctest -S` script the ctest_configure command will add -DCTEST_USE_LAUNCHERS:BOOL=TRUE to the cmake command used to configure the project. + +.. TODO Use RST markup + #]=======================================================================] if(NOT DEFINED CTEST_USE_LAUNCHERS AND DEFINED ENV{CTEST_USE_LAUNCHERS_DEFAULT}) diff --git a/Modules/CUDA/architectures.cmake b/Modules/CUDA/architectures.cmake index fa3a5a1..7d6a6e0 100644 --- a/Modules/CUDA/architectures.cmake +++ b/Modules/CUDA/architectures.cmake @@ -17,7 +17,7 @@ if(CMAKE_CUDA_COMPILER_TOOLKIT_VERSION VERSION_GREATER_EQUAL 9.0) endif() list(REMOVE_ITEM CMAKE_CUDA_ARCHITECTURES_ALL 20 21) - list(REMOVE_ITEM CMAKE_CUDA_ARCHITECTURES_ALL_MAJOR 20 21) + list(REMOVE_ITEM CMAKE_CUDA_ARCHITECTURES_ALL_MAJOR 20) endif() if(CMAKE_CUDA_COMPILER_TOOLKIT_VERSION VERSION_GREATER_EQUAL 10.0 @@ -44,3 +44,26 @@ if(CMAKE_CUDA_COMPILER_TOOLKIT_VERSION VERSION_GREATER_EQUAL 11.4 AND (NOT CMAKE_CUDA_COMPILER_ID STREQUAL "Clang")) list(APPEND CMAKE_CUDA_ARCHITECTURES_ALL 87) endif() + +if(CMAKE_CUDA_COMPILER_TOOLKIT_VERSION VERSION_GREATER_EQUAL 11.8 + AND (NOT CMAKE_CUDA_COMPILER_ID STREQUAL "Clang")) + list(APPEND CMAKE_CUDA_ARCHITECTURES_ALL 89 90) + list(APPEND CMAKE_CUDA_ARCHITECTURES_ALL_MAJOR 90) +endif() + +if(CMAKE_CUDA_COMPILER_TOOLKIT_VERSION VERSION_GREATER_EQUAL 12.0 + AND (NOT CMAKE_CUDA_COMPILER_ID STREQUAL "Clang")) + list(REMOVE_ITEM CMAKE_CUDA_ARCHITECTURES_ALL 35 37) + list(REMOVE_ITEM CMAKE_CUDA_ARCHITECTURES_ALL_MAJOR 35) +endif() + +# only generate jit code for the newest arch for all/all-major +list(POP_BACK CMAKE_CUDA_ARCHITECTURES_ALL _latest_arch) +list(TRANSFORM CMAKE_CUDA_ARCHITECTURES_ALL APPEND "-real") +list(APPEND CMAKE_CUDA_ARCHITECTURES_ALL ${_latest_arch}) + +list(POP_BACK CMAKE_CUDA_ARCHITECTURES_ALL_MAJOR _latest_arch) +list(TRANSFORM CMAKE_CUDA_ARCHITECTURES_ALL_MAJOR APPEND "-real") +list(APPEND CMAKE_CUDA_ARCHITECTURES_ALL_MAJOR ${_latest_arch}) + +unset(_latest_arch) diff --git a/Modules/CheckCXXSymbolExists.cmake b/Modules/CheckCXXSymbolExists.cmake index 7b13c3a..1fa0898 100644 --- a/Modules/CheckCXXSymbolExists.cmake +++ b/Modules/CheckCXXSymbolExists.cmake @@ -74,5 +74,5 @@ include_guard(GLOBAL) include(CheckSymbolExists) macro(CHECK_CXX_SYMBOL_EXISTS SYMBOL FILES VARIABLE) - __CHECK_SYMBOL_EXISTS_IMPL("${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckSymbolExists.cxx" "${SYMBOL}" "${FILES}" "${VARIABLE}" ) + __CHECK_SYMBOL_EXISTS_IMPL(CheckSymbolExists.cxx "${SYMBOL}" "${FILES}" "${VARIABLE}" ) endmacro() diff --git a/Modules/CheckFortranFunctionExists.cmake b/Modules/CheckFortranFunctionExists.cmake index 8f1ca9d..4e5a246 100644 --- a/Modules/CheckFortranFunctionExists.cmake +++ b/Modules/CheckFortranFunctionExists.cmake @@ -58,8 +58,7 @@ macro(CHECK_FORTRAN_FUNCTION_EXISTS FUNCTION VARIABLE) else() set(CHECK_FUNCTION_EXISTS_ADD_LIBRARIES) endif() - file(WRITE - ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/testFortranCompiler.f + set(__CheckFunction_testFortranCompilerSource " program TESTFortran external ${FUNCTION} @@ -68,24 +67,17 @@ macro(CHECK_FORTRAN_FUNCTION_EXISTS FUNCTION VARIABLE) " ) try_compile(${VARIABLE} - ${CMAKE_BINARY_DIR} - ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/testFortranCompiler.f + SOURCE_FROM_VAR testFortranCompiler.f __CheckFunction_testFortranCompilerSource ${CHECK_FUNCTION_EXISTS_ADD_LINK_OPTIONS} ${CHECK_FUNCTION_EXISTS_ADD_LIBRARIES} - OUTPUT_VARIABLE OUTPUT ) + unset(__CheckFunction_testFortranCompilerSource) if(${VARIABLE}) set(${VARIABLE} 1 CACHE INTERNAL "Have Fortran function ${FUNCTION}") message(CHECK_PASS "found") - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log - "Determining if the Fortran ${FUNCTION} exists passed with the following output:\n" - "${OUTPUT}\n\n") else() message(CHECK_FAIL "not found") set(${VARIABLE} "" CACHE INTERNAL "Have Fortran function ${FUNCTION}") - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log - "Determining if the Fortran ${FUNCTION} exists failed with the following output:\n" - "${OUTPUT}\n\n") endif() endif() endmacro() diff --git a/Modules/CheckFortranSourceCompiles.cmake b/Modules/CheckFortranSourceCompiles.cmake index e134329..8dcc1d5 100644 --- a/Modules/CheckFortranSourceCompiles.cmake +++ b/Modules/CheckFortranSourceCompiles.cmake @@ -19,18 +19,22 @@ Check if given Fortran source compiles and links into an executable. ) Checks that the source supplied in ``<code>`` can be compiled as a Fortran - source file and linked as an executable. The ``<code>`` must be a Fortran program - containing at least an ``end`` statement--for example: + source file and linked as an executable. The ``<code>`` must be a Fortran + ``program``. .. code-block:: cmake - check_fortran_source_compiles("character :: b; error stop b; end" F2018ESTOPOK SRC_EXT F90) + check_fortran_source_compiles("program test + error stop + end program" + HAVE_ERROR_STOP + SRC_EXT .F90) This command can help avoid costly build processes when a compiler lacks support for a necessary feature, or a particular vendor library is not compatible with the Fortran compiler version being used. This generate-time check may advise the user of such before the main build process. See also the - :command:`check_fortran_source_runs` command to actually run the compiled code. + :command:`check_fortran_source_runs` command to run the compiled code. The result will be stored in the internal cache variable ``<resultVar>``, with a boolean true value for success and boolean diff --git a/Modules/CheckFortranSourceRuns.cmake b/Modules/CheckFortranSourceRuns.cmake index 28f713f..985c765 100644 --- a/Modules/CheckFortranSourceRuns.cmake +++ b/Modules/CheckFortranSourceRuns.cmake @@ -18,12 +18,16 @@ subsequently be run. [SRC_EXT <extension>]) Check that the source supplied in ``<code>`` can be compiled as a Fortran source - file, linked as an executable and then run. The ``<code>`` must be a Fortran program - containing at least an ``end`` statement--for example: + file, linked as an executable and then run. The ``<code>`` must be a Fortran + ``program``. .. code-block:: cmake - check_fortran_source_runs("real :: x[*]; call co_sum(x); end" F2018coarrayOK) + check_fortran_source_runs("program test + real :: x[*] + call co_sum(x) + end program" + HAVE_COARRAY) This command can help avoid costly build processes when a compiler lacks support for a necessary feature, or a particular vendor library is not compatible with diff --git a/Modules/CheckFunctionExists.cmake b/Modules/CheckFunctionExists.cmake index 9efa132..e2939ed 100644 --- a/Modules/CheckFunctionExists.cmake +++ b/Modules/CheckFunctionExists.cmake @@ -81,23 +81,21 @@ macro(CHECK_FUNCTION_EXISTS FUNCTION VARIABLE) endif() if(CMAKE_C_COMPILER_LOADED) - set(_cfe_source ${CMAKE_ROOT}/Modules/CheckFunctionExists.c) + set(_cfe_source CheckFunctionExists.c) elseif(CMAKE_CXX_COMPILER_LOADED) - set(_cfe_source ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CheckFunctionExists/CheckFunctionExists.cxx) - configure_file(${CMAKE_ROOT}/Modules/CheckFunctionExists.c "${_cfe_source}" COPYONLY) + set(_cfe_source CheckFunctionExists.cxx) else() message(FATAL_ERROR "CHECK_FUNCTION_EXISTS needs either C or CXX language enabled") endif() try_compile(${VARIABLE} - ${CMAKE_BINARY_DIR} - ${_cfe_source} + SOURCE_FROM_FILE "${_cfe_source}" "${CMAKE_ROOT}/Modules/CheckFunctionExists.c" COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS} ${CHECK_FUNCTION_EXISTS_ADD_LINK_OPTIONS} ${CHECK_FUNCTION_EXISTS_ADD_LIBRARIES} CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_FUNCTION_DEFINITIONS} "${CHECK_FUNCTION_EXISTS_ADD_INCLUDES}" - OUTPUT_VARIABLE OUTPUT) + ) unset(_cfe_source) if(${VARIABLE}) @@ -105,17 +103,11 @@ macro(CHECK_FUNCTION_EXISTS FUNCTION VARIABLE) if(NOT CMAKE_REQUIRED_QUIET) message(CHECK_PASS "found") endif() - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log - "Determining if the function ${FUNCTION} exists passed with the following output:\n" - "${OUTPUT}\n\n") else() if(NOT CMAKE_REQUIRED_QUIET) message(CHECK_FAIL "not found") endif() set(${VARIABLE} "" CACHE INTERNAL "Have function ${FUNCTION}") - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log - "Determining if the function ${FUNCTION} exists failed with the following output:\n" - "${OUTPUT}\n\n") endif() endif() endmacro() diff --git a/Modules/CheckIPOSupported.cmake b/Modules/CheckIPOSupported.cmake index 0bc3c92..de682b7 100644 --- a/Modules/CheckIPOSupported.cmake +++ b/Modules/CheckIPOSupported.cmake @@ -36,6 +36,11 @@ module will return error in this case. See policy :policy:`CMP0069` for details. .. versionadded:: 3.13 Add support for Visual Studio generators. +.. versionadded:: 3.24 + The check uses the caller's :variable:`CMAKE_<LANG>_FLAGS` + and :variable:`CMAKE_<LANG>_FLAGS_<CONFIG>` values. + See policy :policy:`CMP0138`. + Examples ^^^^^^^^ @@ -71,6 +76,23 @@ endmacro() # Run IPO/LTO test macro(_ipo_run_language_check language) + set(_C_ext "c") + set(_CXX_ext "cpp") + set(_Fortran_ext "f") + string(COMPARE EQUAL "${language}" "CUDA" is_cuda) + + set(ext ${_${language}_ext}) + if(NOT "${ext}" STREQUAL "") + set(copy_sources foo.${ext} main.${ext}) + elseif(is_cuda) + if(_CMAKE_CUDA_IPO_SUPPORTED_BY_CMAKE) + set("${X_RESULT}" YES PARENT_SCOPE) + endif() + return() + else() + message(FATAL_ERROR "Language not supported") + endif() + set(testdir "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/_CMakeLTOTest-${language}") file(REMOVE_RECURSE "${testdir}") @@ -95,20 +117,6 @@ macro(_ipo_run_language_check language) @ONLY ) - string(COMPARE EQUAL "${language}" "C" is_c) - string(COMPARE EQUAL "${language}" "CXX" is_cxx) - string(COMPARE EQUAL "${language}" "Fortran" is_fortran) - - if(is_c) - set(copy_sources foo.c main.c) - elseif(is_cxx) - set(copy_sources foo.cpp main.cpp) - elseif(is_fortran) - set(copy_sources foo.f main.f) - else() - message(FATAL_ERROR "Language not supported") - endif() - foreach(x ${copy_sources}) configure_file( "${try_compile_src}/${x}" @@ -117,23 +125,31 @@ macro(_ipo_run_language_check language) ) endforeach() + if(ipo_CMP0138 STREQUAL "NEW") + set(CMAKE_TRY_COMPILE_CONFIGURATION Debug) + set(_CMAKE_LANG_FLAGS + "-DCMAKE_${language}_FLAGS:STRING=${CMAKE_${language}_FLAGS}" + "-DCMAKE_${language}_FLAGS_DEBUG:STRING=${CMAKE_${language}_FLAGS_DEBUG}" + ) + else() + set(_CMAKE_LANG_FLAGS "") + endif() + try_compile( _IPO_LANGUAGE_CHECK_RESULT - "${bindir}" - "${srcdir}" - "${TRY_COMPILE_PROJECT_NAME}" + PROJECT "${TRY_COMPILE_PROJECT_NAME}" + SOURCE_DIR "${srcdir}" + BINARY_DIR "${bindir}" CMAKE_FLAGS "-DCMAKE_VERBOSE_MAKEFILE=ON" "-DCMAKE_INTERPROCEDURAL_OPTIMIZATION=ON" + ${_CMAKE_LANG_FLAGS} OUTPUT_VARIABLE output ) set(_IPO_LANGUAGE_CHECK_RESULT "${_IPO_LANGUAGE_CHECK_RESULT}") unset(_IPO_LANGUAGE_CHECK_RESULT CACHE) if(NOT _IPO_LANGUAGE_CHECK_RESULT) - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log - "${language} compiler IPO check failed with the following output:\n" - "${output}\n") _ipo_not_supported("check failed to compile") if(X_OUTPUT) set("${X_OUTPUT}" "${output}" PARENT_SCOPE) @@ -155,6 +171,11 @@ function(check_ipo_supported) message(FATAL_ERROR "Policy CMP0069 set to OLD") endif() + # Save policy setting for condition in _ipo_run_language_check. + cmake_policy(GET CMP0138 ipo_CMP0138 + PARENT_SCOPE # undocumented, do not use outside of CMake + ) + set(optional) set(one RESULT OUTPUT) set(multiple LANGUAGES) @@ -193,6 +214,11 @@ function(check_ipo_supported) list(APPEND languages "C") endif() + list(FIND enabled_languages "CUDA" result) + if(NOT result EQUAL -1) + list(APPEND languages "CUDA") + endif() + list(FIND enabled_languages "Fortran" result) if(NOT result EQUAL -1) list(APPEND languages "Fortran") @@ -201,7 +227,7 @@ function(check_ipo_supported) string(COMPARE EQUAL "${languages}" "" no_languages) if(no_languages) _ipo_not_supported( - "no C/CXX/Fortran languages found in ENABLED_LANGUAGES global property" + "no C/CXX/CUDA/Fortran languages found in ENABLED_LANGUAGES global property" ) return() endif() @@ -209,7 +235,7 @@ function(check_ipo_supported) set(languages "${X_LANGUAGES}") set(unsupported_languages "${languages}") - list(REMOVE_ITEM unsupported_languages "C" "CXX" "Fortran") + list(REMOVE_ITEM unsupported_languages "C" "CXX" "CUDA" "Fortran") string(COMPARE NOTEQUAL "${unsupported_languages}" "" has_unsupported) if(has_unsupported) _ipo_not_supported( diff --git a/Modules/CheckIncludeFile.cmake b/Modules/CheckIncludeFile.cmake index 71ddde7..5771307 100644 --- a/Modules/CheckIncludeFile.cmake +++ b/Modules/CheckIncludeFile.cmake @@ -54,8 +54,8 @@ macro(CHECK_INCLUDE_FILE INCLUDE VARIABLE) endif() set(MACRO_CHECK_INCLUDE_FILE_FLAGS ${CMAKE_REQUIRED_FLAGS}) set(CHECK_INCLUDE_FILE_VAR ${INCLUDE}) - configure_file(${CMAKE_ROOT}/Modules/CheckIncludeFile.c.in - ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckIncludeFile.c) + file(READ ${CMAKE_ROOT}/Modules/CheckIncludeFile.c.in _CIF_SOURCE_CONTENT) + string(CONFIGURE "${_CIF_SOURCE_CONTENT}" _CIF_SOURCE_CONTENT) if(NOT CMAKE_REQUIRED_QUIET) message(CHECK_START "Looking for ${INCLUDE}") endif() @@ -93,15 +93,14 @@ macro(CHECK_INCLUDE_FILE INCLUDE VARIABLE) endif() try_compile(${VARIABLE} - ${CMAKE_BINARY_DIR} - ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckIncludeFile.c + SOURCE_FROM_VAR CheckIncludeFile.c _CIF_SOURCE_CONTENT COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS} ${_CIF_LINK_OPTIONS} ${_CIF_LINK_LIBRARIES} CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_INCLUDE_FILE_FLAGS} "${CHECK_INCLUDE_FILE_C_INCLUDE_DIRS}" - OUTPUT_VARIABLE OUTPUT) + ) unset(_CIF_LINK_OPTIONS) unset(_CIF_LINK_LIBRARIES) @@ -114,19 +113,11 @@ macro(CHECK_INCLUDE_FILE INCLUDE VARIABLE) message(CHECK_PASS "found") endif() set(${VARIABLE} 1 CACHE INTERNAL "Have include ${INCLUDE}") - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log - "Determining if the include file ${INCLUDE} " - "exists passed with the following output:\n" - "${OUTPUT}\n\n") else() if(NOT CMAKE_REQUIRED_QUIET) message(CHECK_FAIL "not found") endif() set(${VARIABLE} "" CACHE INTERNAL "Have include ${INCLUDE}") - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log - "Determining if the include file ${INCLUDE} " - "exists failed with the following output:\n" - "${OUTPUT}\n\n") endif() endif() endmacro() diff --git a/Modules/CheckIncludeFileCXX.cmake b/Modules/CheckIncludeFileCXX.cmake index 953224e..d27b485 100644 --- a/Modules/CheckIncludeFileCXX.cmake +++ b/Modules/CheckIncludeFileCXX.cmake @@ -53,8 +53,8 @@ macro(CHECK_INCLUDE_FILE_CXX INCLUDE VARIABLE) endif() set(MACRO_CHECK_INCLUDE_FILE_FLAGS ${CMAKE_REQUIRED_FLAGS}) set(CHECK_INCLUDE_FILE_VAR ${INCLUDE}) - configure_file(${CMAKE_ROOT}/Modules/CheckIncludeFile.cxx.in - ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckIncludeFile.cxx) + file(READ ${CMAKE_ROOT}/Modules/CheckIncludeFile.cxx.in _CIF_SOURCE_CONTENT) + string(CONFIGURE "${_CIF_SOURCE_CONTENT}" _CIF_SOURCE_CONTENT) if(NOT CMAKE_REQUIRED_QUIET) message(CHECK_START "Looking for C++ include ${INCLUDE}") endif() @@ -92,15 +92,14 @@ macro(CHECK_INCLUDE_FILE_CXX INCLUDE VARIABLE) endif() try_compile(${VARIABLE} - ${CMAKE_BINARY_DIR} - ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckIncludeFile.cxx + SOURCE_FROM_VAR CheckIncludeFile.cxx _CIF_SOURCE_CONTENT COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS} ${_CIF_LINK_OPTIONS} ${_CIF_LINK_LIBRARIES} CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_INCLUDE_FILE_FLAGS} "${CHECK_INCLUDE_FILE_CXX_INCLUDE_DIRS}" - OUTPUT_VARIABLE OUTPUT) + ) unset(_CIF_LINK_OPTIONS) unset(_CIF_LINK_LIBRARIES) @@ -113,19 +112,11 @@ macro(CHECK_INCLUDE_FILE_CXX INCLUDE VARIABLE) message(CHECK_PASS "found") endif() set(${VARIABLE} 1 CACHE INTERNAL "Have include ${INCLUDE}") - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log - "Determining if the include file ${INCLUDE} " - "exists passed with the following output:\n" - "${OUTPUT}\n\n") else() if(NOT CMAKE_REQUIRED_QUIET) message(CHECK_FAIL "not found") endif() set(${VARIABLE} "" CACHE INTERNAL "Have include ${INCLUDE}") - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log - "Determining if the include file ${INCLUDE} " - "exists failed with the following output:\n" - "${OUTPUT}\n\n") endif() endif() endmacro() diff --git a/Modules/CheckIncludeFiles.cmake b/Modules/CheckIncludeFiles.cmake index 1800ca8..2f50c61 100644 --- a/Modules/CheckIncludeFiles.cmake +++ b/Modules/CheckIncludeFiles.cmake @@ -52,7 +52,7 @@ include_guard(GLOBAL) macro(CHECK_INCLUDE_FILES INCLUDE VARIABLE) if(NOT DEFINED "${VARIABLE}") - set(CMAKE_CONFIGURABLE_FILE_CONTENT "/* */\n") + set(_src_content "/* */\n") if("x${ARGN}" STREQUAL "x") if(CMAKE_C_COMPILER_LOADED) @@ -70,10 +70,11 @@ macro(CHECK_INCLUDE_FILES INCLUDE VARIABLE) message(FATAL_ERROR "Unknown arguments:\n ${ARGN}\n") endif() + string(MAKE_C_IDENTIFIER ${VARIABLE} _variable_escaped) if(_lang STREQUAL "C") - set(src ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CheckIncludeFiles/${VARIABLE}.c) + set(src ${_variable_escaped}.c) elseif(_lang STREQUAL "CXX") - set(src ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CheckIncludeFiles/${VARIABLE}.cpp) + set(src ${_variable_escaped}.cpp) else() message(FATAL_ERROR "Unknown language:\n ${_lang}\nSupported languages: C, CXX.\n") endif() @@ -86,13 +87,11 @@ macro(CHECK_INCLUDE_FILES INCLUDE VARIABLE) set(CHECK_INCLUDE_FILES_CONTENT "/* */\n") set(MACRO_CHECK_INCLUDE_FILES_FLAGS ${CMAKE_REQUIRED_FLAGS}) foreach(FILE ${INCLUDE}) - string(APPEND CMAKE_CONFIGURABLE_FILE_CONTENT + string(APPEND _src_content "#include <${FILE}>\n") endforeach() - string(APPEND CMAKE_CONFIGURABLE_FILE_CONTENT + string(APPEND _src_content "\n\nint main(void){return 0;}\n") - configure_file("${CMAKE_ROOT}/Modules/CMakeConfigurableFile.in" - "${src}" @ONLY) set(_INCLUDE ${INCLUDE}) # remove empty elements if("${_INCLUDE}" MATCHES "^([^;]+);.+;([^;]+)$") @@ -136,15 +135,14 @@ macro(CHECK_INCLUDE_FILES INCLUDE VARIABLE) message(CHECK_START "Looking for ${_description}") endif() try_compile(${VARIABLE} - ${CMAKE_BINARY_DIR} - ${src} + SOURCE_FROM_VAR "${src}" _src_content COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS} ${_CIF_LINK_OPTIONS} ${_CIF_LINK_LIBRARIES} CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_INCLUDE_FILES_FLAGS} "${CHECK_INCLUDE_FILES_INCLUDE_DIRS}" - OUTPUT_VARIABLE OUTPUT) + ) unset(_CIF_LINK_OPTIONS) unset(_CIF_LINK_LIBRARIES) if(${VARIABLE}) @@ -152,19 +150,11 @@ macro(CHECK_INCLUDE_FILES INCLUDE VARIABLE) message(CHECK_PASS "found") endif() set(${VARIABLE} 1 CACHE INTERNAL "Have include ${INCLUDE}") - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log - "Determining if files ${INCLUDE} " - "exist passed with the following output:\n" - "${OUTPUT}\n\n") else() if(NOT CMAKE_REQUIRED_QUIET) message(CHECK_FAIL "not found") endif() set(${VARIABLE} "" CACHE INTERNAL "Have includes ${INCLUDE}") - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log - "Determining if files ${INCLUDE} " - "exist failed with the following output:\n" - "${OUTPUT}\nSource:\n${CMAKE_CONFIGURABLE_FILE_CONTENT}\n") endif() endif() endmacro() diff --git a/Modules/CheckLanguage.cmake b/Modules/CheckLanguage.cmake index 52f707c..2e56a19 100644 --- a/Modules/CheckLanguage.cmake +++ b/Modules/CheckLanguage.cmake @@ -90,14 +90,14 @@ file(WRITE \"\${CMAKE_CURRENT_BINARY_DIR}/result.cmake\" ) include(${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/Check${lang}/result.cmake OPTIONAL) if(CMAKE_${lang}_COMPILER AND "${_cl_result}" STREQUAL "0") - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log + message(CONFIGURE_LOG "${_desc} passed with the following output:\n" "${_cl_output}\n") set(_CHECK_COMPILER_STATUS CHECK_PASS) else() set(CMAKE_${lang}_COMPILER NOTFOUND) set(_CHECK_COMPILER_STATUS CHECK_FAIL) - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log + message(CONFIGURE_LOG "${_desc} failed with the following output:\n" "${_cl_output}\n") endif() diff --git a/Modules/CheckLibraryExists.cmake b/Modules/CheckLibraryExists.cmake index 804e0cb..5f1a914 100644 --- a/Modules/CheckLibraryExists.cmake +++ b/Modules/CheckLibraryExists.cmake @@ -61,24 +61,22 @@ macro(CHECK_LIBRARY_EXISTS LIBRARY FUNCTION LOCATION VARIABLE) endif() if(CMAKE_C_COMPILER_LOADED) - set(_cle_source ${CMAKE_ROOT}/Modules/CheckFunctionExists.c) + set(_cle_source CheckFunctionExists.c) elseif(CMAKE_CXX_COMPILER_LOADED) - set(_cle_source ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CheckLibraryExists/CheckFunctionExists.cxx) - configure_file(${CMAKE_ROOT}/Modules/CheckFunctionExists.c "${_cle_source}" COPYONLY) + set(_cle_source CheckFunctionExists.cxx) else() message(FATAL_ERROR "CHECK_FUNCTION_EXISTS needs either C or CXX language enabled") endif() try_compile(${VARIABLE} - ${CMAKE_BINARY_DIR} - ${_cle_source} + SOURCE_FROM_FILE "${_cle_source}" "${CMAKE_ROOT}/Modules/CheckFunctionExists.c" COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS} ${CHECK_LIBRARY_EXISTS_LINK_OPTIONS} LINK_LIBRARIES ${CHECK_LIBRARY_EXISTS_LIBRARIES} CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_LIBRARY_EXISTS_DEFINITION} -DLINK_DIRECTORIES:STRING=${LOCATION} - OUTPUT_VARIABLE OUTPUT) + ) unset(_cle_source) if(${VARIABLE}) @@ -86,19 +84,11 @@ macro(CHECK_LIBRARY_EXISTS LIBRARY FUNCTION LOCATION VARIABLE) message(CHECK_PASS "found") endif() set(${VARIABLE} 1 CACHE INTERNAL "Have library ${LIBRARY}") - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log - "Determining if the function ${FUNCTION} exists in the ${LIBRARY} " - "passed with the following output:\n" - "${OUTPUT}\n\n") else() if(NOT CMAKE_REQUIRED_QUIET) message(CHECK_FAIL "not found") endif() set(${VARIABLE} "" CACHE INTERNAL "Have library ${LIBRARY}") - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log - "Determining if the function ${FUNCTION} exists in the ${LIBRARY} " - "failed with the following output:\n" - "${OUTPUT}\n\n") endif() endif() endmacro() diff --git a/Modules/CheckPrototypeDefinition.cmake b/Modules/CheckPrototypeDefinition.cmake index d29c5e8..3d53b93 100644 --- a/Modules/CheckPrototypeDefinition.cmake +++ b/Modules/CheckPrototypeDefinition.cmake @@ -94,37 +94,28 @@ function(check_prototype_definition _FUNCTION _PROTOTYPE _RETURN _HEADER _VARIAB set(CHECK_PROTOTYPE_DEFINITION_PROTO ${_PROTOTYPE}) set(CHECK_PROTOTYPE_DEFINITION_RETURN ${_RETURN}) - configure_file("${__check_proto_def_dir}/CheckPrototypeDefinition.c.in" - "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckPrototypeDefinition.c" @ONLY) - - file(READ ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckPrototypeDefinition.c _SOURCE) + file(READ ${__check_proto_def_dir}/CheckPrototypeDefinition.c.in _SOURCE) + string(CONFIGURE "${_SOURCE}" _SOURCE @ONLY) try_compile(${_VARIABLE} - ${CMAKE_BINARY_DIR} - ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckPrototypeDefinition.c + SOURCE_FROM_VAR CheckPrototypeDefinition.c _SOURCE COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS} ${CHECK_PROTOTYPE_DEFINITION_LINK_OPTIONS} ${CHECK_PROTOTYPE_DEFINITION_LIBS} CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${CHECK_PROTOTYPE_DEFINITION_FLAGS} "${CMAKE_SYMBOL_EXISTS_INCLUDES}" - OUTPUT_VARIABLE OUTPUT) + ) if (${_VARIABLE}) set(${_VARIABLE} 1 CACHE INTERNAL "Have correct prototype for ${_FUNCTION}") if(NOT CMAKE_REQUIRED_QUIET) message(CHECK_PASS "True") endif() - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log - "Determining if the prototype ${_FUNCTION} exists for ${_VARIABLE} passed with the following output:\n" - "${OUTPUT}\n\n") else () if(NOT CMAKE_REQUIRED_QUIET) message(CHECK_FAIL "False") endif() set(${_VARIABLE} 0 CACHE INTERNAL "Have correct prototype for ${_FUNCTION}") - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log - "Determining if the prototype ${_FUNCTION} exists for ${_VARIABLE} failed with the following output:\n" - "${OUTPUT}\n\n${_SOURCE}\n\n") endif () endif() diff --git a/Modules/CheckSourceCompiles.cmake b/Modules/CheckSourceCompiles.cmake index ad74c3c..9788798 100644 --- a/Modules/CheckSourceCompiles.cmake +++ b/Modules/CheckSourceCompiles.cmake @@ -19,17 +19,34 @@ Check if given source compiles and links into an executable. [SRC_EXT <extension>]) Check that the source supplied in ``<code>`` can be compiled as a source - file for the requested language and linked as an executable (so it must - contain at least a ``main()`` function). The result will be stored in the - internal cache variable specified by ``<resultVar>``, with a boolean true - value for success and boolean false for failure. If ``FAIL_REGEX`` is - provided, then failure is determined by checking if anything in the output - matches any of the specified regular expressions. + file for the requested language and linked as an executable. The result + will be stored in the internal cache variable specified by ``<resultVar>``, + with a boolean true value for success and boolean false for failure. If + ``FAIL_REGEX`` is provided, then failure is determined by checking if + anything in the compiler output matches any of the specified regular + expressions. By default, the test source file will be given a file extension that matches the requested language. The ``SRC_EXT`` option can be used to override this with ``.<extension>`` instead. + The ``<code>`` must contain a valid main program. For example: + + .. code-block:: cmake + + check_source_compiles(C + "#include <stdlib.h> + #include <stdnoreturn.h> + noreturn void f(){ exit(0); } + int main(void) { f(); return 1; }" + HAVE_NORETURN) + + check_source_compiles(Fortran + "program test + error stop + end program" + HAVE_ERROR_STOP) + The underlying check is performed by the :command:`try_compile` command. The compile and link commands can be influenced by setting any of the following variables prior to calling ``check_source_compiles()``: @@ -73,7 +90,6 @@ Check if given source compiles and links into an executable. #]=======================================================================] - include_guard(GLOBAL) include(Internal/CheckSourceCompiles) diff --git a/Modules/CheckSourceRuns.cmake b/Modules/CheckSourceRuns.cmake index 8f1cf01..e2fa579 100644 --- a/Modules/CheckSourceRuns.cmake +++ b/Modules/CheckSourceRuns.cmake @@ -20,22 +20,40 @@ subsequently be run. Check that the source supplied in ``<code>`` can be compiled as a source file for the requested language, linked as an executable and then run. - The ``<code>`` must contain at least a ``main()`` function. If the ``<code>`` - could be built and run successfully, the internal cache variable specified by - ``<resultVar>`` will be set to 1, otherwise it will be set to an value that - evaluates to boolean false (e.g. an empty string or an error message). + If the ``<code>`` could be built and run successfully, the internal cache variable + specified by ``<resultVar>`` will be set to 1, otherwise it will be set to + a value that evaluates to boolean false (e.g. an empty string or an error + message). By default, the test source file will be given a file extension that matches the requested language. The ``SRC_EXT`` option can be used to override this with ``.<extension>`` instead. + The ``<code>`` must contain a valid main program. For example: + + .. code-block:: cmake + + check_source_runs(C + "#include <stdlib.h> + #include <stdnoreturn.h> + noreturn void f(){ exit(0); } + int main(void) { f(); return 1; }" + HAVE_NORETURN) + + check_source_runs(Fortran + "program test + real :: x[*] + call co_sum(x) + end program" + HAVE_COARRAY) + The underlying check is performed by the :command:`try_run` command. The compile and link commands can be influenced by setting any of the following - variables prior to calling ``check_objc_source_runs()``: + variables prior to calling ``check_source_runs()``: ``CMAKE_REQUIRED_FLAGS`` Additional flags to pass to the compiler. Note that the contents of - :variable:`CMAKE_OBJC_FLAGS <CMAKE_<LANG>_FLAGS>` and its associated + :variable:`CMAKE_<LANG>_FLAGS <CMAKE_<LANG>_FLAGS>` and its associated configuration-specific variable are automatically added to the compiler command before the contents of ``CMAKE_REQUIRED_FLAGS``. diff --git a/Modules/CheckSymbolExists.cmake b/Modules/CheckSymbolExists.cmake index a7139af..c4a1574 100644 --- a/Modules/CheckSymbolExists.cmake +++ b/Modules/CheckSymbolExists.cmake @@ -68,11 +68,11 @@ cmake_policy(SET CMP0054 NEW) # if() quoted variables not dereferenced macro(CHECK_SYMBOL_EXISTS SYMBOL FILES VARIABLE) if(CMAKE_C_COMPILER_LOADED) __CHECK_SYMBOL_EXISTS_FILTER_FLAGS(C) - __CHECK_SYMBOL_EXISTS_IMPL("${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckSymbolExists.c" "${SYMBOL}" "${FILES}" "${VARIABLE}" ) + __CHECK_SYMBOL_EXISTS_IMPL(CheckSymbolExists.c "${SYMBOL}" "${FILES}" "${VARIABLE}" ) __CHECK_SYMBOL_EXISTS_RESTORE_FLAGS(C) elseif(CMAKE_CXX_COMPILER_LOADED) __CHECK_SYMBOL_EXISTS_FILTER_FLAGS(CXX) - __CHECK_SYMBOL_EXISTS_IMPL("${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckSymbolExists.cxx" "${SYMBOL}" "${FILES}" "${VARIABLE}" ) + __CHECK_SYMBOL_EXISTS_IMPL(CheckSymbolExists.cxx "${SYMBOL}" "${FILES}" "${VARIABLE}" ) __CHECK_SYMBOL_EXISTS_RESTORE_FLAGS(CXX) else() message(FATAL_ERROR "CHECK_SYMBOL_EXISTS needs either C or CXX language enabled") @@ -92,7 +92,7 @@ endmacro() macro(__CHECK_SYMBOL_EXISTS_IMPL SOURCEFILE SYMBOL FILES VARIABLE) if(NOT DEFINED "${VARIABLE}" OR "x${${VARIABLE}}" STREQUAL "x${VARIABLE}") - set(CMAKE_CONFIGURABLE_FILE_CONTENT "/* */\n") + set(_CSE_SOURCE "/* */\n") set(MACRO_CHECK_SYMBOL_EXISTS_FLAGS ${CMAKE_REQUIRED_FLAGS}) if(CMAKE_REQUIRED_LINK_OPTIONS) set(CHECK_SYMBOL_EXISTS_LINK_OPTIONS @@ -113,17 +113,17 @@ macro(__CHECK_SYMBOL_EXISTS_IMPL SOURCEFILE SYMBOL FILES VARIABLE) set(CMAKE_SYMBOL_EXISTS_INCLUDES) endif() foreach(FILE ${FILES}) - string(APPEND CMAKE_CONFIGURABLE_FILE_CONTENT + string(APPEND _CSE_SOURCE "#include <${FILE}>\n") endforeach() - string(APPEND CMAKE_CONFIGURABLE_FILE_CONTENT " + string(APPEND _CSE_SOURCE " int main(int argc, char** argv) { (void)argv;") set(_CSE_CHECK_NON_MACRO "return ((int*)(&${SYMBOL}))[argc];") if("${SYMBOL}" MATCHES "^[a-zA-Z_][a-zA-Z0-9_]*$") # The SYMBOL has a legal macro name. Test whether it exists as a macro. - string(APPEND CMAKE_CONFIGURABLE_FILE_CONTENT " + string(APPEND _CSE_SOURCE " #ifndef ${SYMBOL} ${_CSE_CHECK_NON_MACRO} #else @@ -132,51 +132,37 @@ int main(int argc, char** argv) #endif") else() # The SYMBOL cannot be a macro (e.g., a template function). - string(APPEND CMAKE_CONFIGURABLE_FILE_CONTENT " + string(APPEND _CSE_SOURCE " ${_CSE_CHECK_NON_MACRO}") endif() - string(APPEND CMAKE_CONFIGURABLE_FILE_CONTENT " -}") + string(APPEND _CSE_SOURCE " +}\n") unset(_CSE_CHECK_NON_MACRO) - configure_file("${CMAKE_ROOT}/Modules/CMakeConfigurableFile.in" - "${SOURCEFILE}" @ONLY) - if(NOT CMAKE_REQUIRED_QUIET) message(CHECK_START "Looking for ${SYMBOL}") endif() try_compile(${VARIABLE} - ${CMAKE_BINARY_DIR} - "${SOURCEFILE}" + SOURCE_FROM_VAR "${SOURCEFILE}" _CSE_SOURCE COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS} ${CHECK_SYMBOL_EXISTS_LINK_OPTIONS} ${CHECK_SYMBOL_EXISTS_LIBS} CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_SYMBOL_EXISTS_FLAGS} "${CMAKE_SYMBOL_EXISTS_INCLUDES}" - OUTPUT_VARIABLE OUTPUT) + ) if(${VARIABLE}) if(NOT CMAKE_REQUIRED_QUIET) message(CHECK_PASS "found") endif() set(${VARIABLE} 1 CACHE INTERNAL "Have symbol ${SYMBOL}") - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log - "Determining if the ${SYMBOL} " - "exist passed with the following output:\n" - "${OUTPUT}\nFile ${SOURCEFILE}:\n" - "${CMAKE_CONFIGURABLE_FILE_CONTENT}\n") else() if(NOT CMAKE_REQUIRED_QUIET) message(CHECK_FAIL "not found") endif() set(${VARIABLE} "" CACHE INTERNAL "Have symbol ${SYMBOL}") - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log - "Determining if the ${SYMBOL} " - "exist failed with the following output:\n" - "${OUTPUT}\nFile ${SOURCEFILE}:\n" - "${CMAKE_CONFIGURABLE_FILE_CONTENT}\n") endif() - unset(CMAKE_CONFIGURABLE_FILE_CONTENT) + unset(_CSE_SOURCE) endif() endmacro() diff --git a/Modules/CheckTypeSize.cmake b/Modules/CheckTypeSize.cmake index 602170c..579d189 100644 --- a/Modules/CheckTypeSize.cmake +++ b/Modules/CheckTypeSize.cmake @@ -103,10 +103,11 @@ function(__check_type_size_impl type var map builtin language) endif() # Perform language check + string(MAKE_C_IDENTIFIER ${var} _var_escaped) if(language STREQUAL "C") - set(src ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CheckTypeSize/${var}.c) + set(src ${_var_escaped}.c) elseif(language STREQUAL "CXX") - set(src ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CheckTypeSize/${var}.cpp) + set(src ${_var_escaped}.cpp) else() message(FATAL_ERROR "Unknown language:\n ${language}\nSupported languages: C, CXX.\n") endif() @@ -142,15 +143,15 @@ function(__check_type_size_impl type var map builtin language) # Perform the check. set(bin ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CheckTypeSize/${var}.bin) - configure_file(${__check_type_size_dir}/CheckTypeSize.c.in ${src} @ONLY) - try_compile(HAVE_${var} ${CMAKE_BINARY_DIR} ${src} + file(READ ${__check_type_size_dir}/CheckTypeSize.c.in src_content) + string(CONFIGURE "${src_content}" src_content @ONLY) + try_compile(HAVE_${var} SOURCE_FROM_VAR "${src}" src_content COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS} LINK_OPTIONS ${CMAKE_REQUIRED_LINK_OPTIONS} LINK_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} CMAKE_FLAGS "-DCOMPILE_DEFINITIONS:STRING=${CMAKE_REQUIRED_FLAGS}" "-DINCLUDE_DIRECTORIES:STRING=${CMAKE_REQUIRED_INCLUDES}" - OUTPUT_VARIABLE output COPY_FILE ${bin} ) @@ -201,17 +202,12 @@ function(__check_type_size_impl type var map builtin language) if(NOT CMAKE_REQUIRED_QUIET) message(CHECK_PASS "done") endif() - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log - "Determining size of ${type} passed with the following output:\n${output}\n\n") set(${var} "${${var}}" CACHE INTERNAL "CHECK_TYPE_SIZE: sizeof(${type})") else() # The check failed to compile. if(NOT CMAKE_REQUIRED_QUIET) message(CHECK_FAIL "failed") endif() - file(READ ${src} content) - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log - "Determining size of ${type} failed with the following output:\n${output}\n${src}:\n${content}\n\n") set(${var} "" CACHE INTERNAL "CHECK_TYPE_SIZE: ${type} unknown") file(REMOVE ${map}) endif() diff --git a/Modules/CheckVariableExists.cmake b/Modules/CheckVariableExists.cmake index 7420124..3a7a431 100644 --- a/Modules/CheckVariableExists.cmake +++ b/Modules/CheckVariableExists.cmake @@ -62,29 +62,22 @@ macro(CHECK_VARIABLE_EXISTS VAR VARIABLE) set(CHECK_VARIABLE_EXISTS_ADD_LIBRARIES) endif() try_compile(${VARIABLE} - ${CMAKE_BINARY_DIR} - ${CMAKE_ROOT}/Modules/CheckVariableExists.c + SOURCES ${CMAKE_ROOT}/Modules/CheckVariableExists.c COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS} ${CHECK_VARIABLE_EXISTS_ADD_LINK_OPTIONS} ${CHECK_VARIABLE_EXISTS_ADD_LIBRARIES} CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_VARIABLE_DEFINITIONS} - OUTPUT_VARIABLE OUTPUT) + ) if(${VARIABLE}) set(${VARIABLE} 1 CACHE INTERNAL "Have variable ${VAR}") if(NOT CMAKE_REQUIRED_QUIET) message(CHECK_PASS "found") endif() - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log - "Determining if the variable ${VAR} exists passed with the following output:\n" - "${OUTPUT}\n\n") else() set(${VARIABLE} "" CACHE INTERNAL "Have variable ${VAR}") if(NOT CMAKE_REQUIRED_QUIET) message(CHECK_FAIL "not found") endif() - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log - "Determining if the variable ${VAR} exists failed with the following output:\n" - "${OUTPUT}\n\n") endif() endif() endmacro() diff --git a/Modules/Compiler/ADSP-C.cmake b/Modules/Compiler/ADSP-C.cmake new file mode 100644 index 0000000..cef3fb1 --- /dev/null +++ b/Modules/Compiler/ADSP-C.cmake @@ -0,0 +1,11 @@ +include(Compiler/CMakeCommonCompilerMacros) +include(Compiler/ADSP) + +__compiler_adsp(C) + +set(CMAKE_C90_STANDARD_COMPILE_OPTION -c89) +set(CMAKE_C90_STANDARD__HAS_FULL_SUPPORT ON) + +set(CMAKE_C99_STANDARD__HAS_FULL_SUPPORT ON) + +__compiler_check_default_language_standard(C 8.0.0.0 99) diff --git a/Modules/Compiler/ADSP-CXX.cmake b/Modules/Compiler/ADSP-CXX.cmake new file mode 100644 index 0000000..b01cab1 --- /dev/null +++ b/Modules/Compiler/ADSP-CXX.cmake @@ -0,0 +1,16 @@ +include(Compiler/CMakeCommonCompilerMacros) +include(Compiler/ADSP) + +__compiler_adsp(CXX) + +set(CMAKE_CXX98_STANDARD_COMPILE_OPTION -c++) +set(CMAKE_CXX98_EXTENSION_COMPILE_OPTION -g++) +set(CMAKE_CXX98_STANDARD__HAS_FULL_SUPPORT ON) + +if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 8.3.0.0) + set(CMAKE_CXX11_STANDARD_COMPILE_OPTION -c++11) + set(CMAKE_CXX11_EXTENSION_COMPILE_OPTION -c++11 -g++) + set(CMAKE_CXX11_STANDARD__HAS_FULL_SUPPORT ON) +endif() + +__compiler_check_default_language_standard(CXX 8.0.0.0 98) diff --git a/Modules/Compiler/ADSP-DetermineCompiler.cmake b/Modules/Compiler/ADSP-DetermineCompiler.cmake index 0340f69..96c88f9 100644 --- a/Modules/Compiler/ADSP-DetermineCompiler.cmake +++ b/Modules/Compiler/ADSP-DetermineCompiler.cmake @@ -1,10 +1,11 @@ -set(_compiler_id_pp_test "defined(__VISUALDSPVERSION__) || defined(__ADSPBLACKFIN__) || defined(__ADSPTS__) || defined(__ADSP21000__)") +set(_compiler_id_pp_test "defined(_ADI_COMPILER)") set(_compiler_id_version_compute " -#if defined(__VISUALDSPVERSION__) - /* __VISUALDSPVERSION__ = 0xVVRRPP00 */ -# define @PREFIX@COMPILER_VERSION_MAJOR @MACRO_HEX@(__VISUALDSPVERSION__>>24) -# define @PREFIX@COMPILER_VERSION_MINOR @MACRO_HEX@(__VISUALDSPVERSION__>>16 & 0xFF) -# define @PREFIX@COMPILER_VERSION_PATCH @MACRO_HEX@(__VISUALDSPVERSION__>>8 & 0xFF) +#if defined(__VERSIONNUM__) + /* __VERSIONNUM__ = 0xVVRRPPTT */ +# define @PREFIX@COMPILER_VERSION_MAJOR @MACRO_DEC@(__VERSIONNUM__ >> 24 & 0xFF) +# define @PREFIX@COMPILER_VERSION_MINOR @MACRO_DEC@(__VERSIONNUM__ >> 16 & 0xFF) +# define @PREFIX@COMPILER_VERSION_PATCH @MACRO_DEC@(__VERSIONNUM__ >> 8 & 0xFF) +# define @PREFIX@COMPILER_VERSION_TWEAK @MACRO_DEC@(__VERSIONNUM__ & 0xFF) #endif") diff --git a/Modules/Compiler/ADSP.cmake b/Modules/Compiler/ADSP.cmake new file mode 100644 index 0000000..62566a0 --- /dev/null +++ b/Modules/Compiler/ADSP.cmake @@ -0,0 +1,26 @@ +include_guard() + +set(CMAKE_EXECUTABLE_SUFFIX ".dxe") + +macro(__compiler_adsp lang) + set(CMAKE_${lang}_OUTPUT_EXTENSION ".doj") + + set(CMAKE_${lang}_LINKER_WRAPPER_FLAG "-flags-link" " ") + set(CMAKE_${lang}_LINKER_WRAPPER_FLAG_SEP ",") + + set(_CMAKE_${lang}_ADSP_FLAGS "-proc=${CMAKE_ADSP_PROCESSOR}") + + set(CMAKE_${lang}_COMPILE_OBJECT + "<CMAKE_${lang}_COMPILER> ${_CMAKE_${lang}_ADSP_FLAGS} <DEFINES> <INCLUDES> <FLAGS> -o <OBJECT> -c <SOURCE>") + + set(CMAKE_${lang}_CREATE_STATIC_LIBRARY + "<CMAKE_${lang}_COMPILER> ${_CMAKE_${lang}_ADSP_FLAGS} -build-lib -o <TARGET> <CMAKE_${lang}_LINK_FLAGS> <OBJECTS>") + + set(CMAKE_${lang}_LINK_EXECUTABLE + "<CMAKE_${lang}_COMPILER> ${_CMAKE_${lang}_ADSP_FLAGS} <FLAGS> <CMAKE_${lang}_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>") + + unset(_CMAKE_${lang}_ADSP_FLAGS) + + set(CMAKE_${lang}_CREATE_SHARED_LIBRARY) + set(CMAKE_${lang}_CREATE_MODULE_LIBRARY) +endmacro() diff --git a/Modules/Compiler/Clang-CUDA.cmake b/Modules/Compiler/Clang-CUDA.cmake index 219897e..d9929f1 100644 --- a/Modules/Compiler/Clang-CUDA.cmake +++ b/Modules/Compiler/Clang-CUDA.cmake @@ -35,6 +35,10 @@ set(CMAKE_CUDA_RUNTIME_LIBRARY_LINK_OPTIONS_STATIC "cudadevrt;cudart_static") set(CMAKE_CUDA_RUNTIME_LIBRARY_LINK_OPTIONS_SHARED "cudadevrt;cudart") set(CMAKE_CUDA_RUNTIME_LIBRARY_LINK_OPTIONS_NONE "") +# Clang doesn't support CUDA device LTO +set(_CMAKE_CUDA_IPO_SUPPORTED_BY_CMAKE NO) +set(_CMAKE_CUDA_IPO_MAY_BE_SUPPORTED_BY_COMPILER NO) + if(UNIX) list(APPEND CMAKE_CUDA_RUNTIME_LIBRARY_LINK_OPTIONS_STATIC "rt" "pthread" "dl") endif() diff --git a/Modules/Compiler/Clang-FindBinUtils.cmake b/Modules/Compiler/Clang-FindBinUtils.cmake index 125ae78..daf0371 100644 --- a/Modules/Compiler/Clang-FindBinUtils.cmake +++ b/Modules/Compiler/Clang-FindBinUtils.cmake @@ -43,3 +43,14 @@ find_program(CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_RANLIB NAMES DOC "Generate index for LLVM archive" ) mark_as_advanced(CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_RANLIB) + +# clang-scan-deps +find_program(CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_CLANG_SCAN_DEPS NAMES + "${_CMAKE_TOOLCHAIN_PREFIX}clang-scan-deps-${__version_x_y}" + "${_CMAKE_TOOLCHAIN_PREFIX}clang-scan-deps-${__version_x}" + "${_CMAKE_TOOLCHAIN_PREFIX}clang-scan-deps" + HINTS ${__clang_hints} + NO_CMAKE_PATH NO_CMAKE_ENVIRONMENT_PATH + DOC "`clang-scan-deps` dependency scanner" +) +mark_as_advanced(CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_CLANG_SCAN_DEPS) diff --git a/Modules/Compiler/Clang.cmake b/Modules/Compiler/Clang.cmake index f885eb0..6c544fd 100644 --- a/Modules/Compiler/Clang.cmake +++ b/Modules/Compiler/Clang.cmake @@ -44,7 +44,7 @@ else() set(CMAKE_${lang}_LINKER_WRAPPER_FLAG "-Xlinker" " ") set(CMAKE_${lang}_LINKER_WRAPPER_FLAG_SEP) - if(CMAKE_${lang}_COMPILER_TARGET) + if(CMAKE_${lang}_COMPILER_TARGET AND "${lang}" STREQUAL "CXX") if(CMAKE_${lang}_COMPILER_VERSION VERSION_LESS 3.4.0) list(APPEND CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND "-target" "${CMAKE_${lang}_COMPILER_TARGET}") else() @@ -114,6 +114,12 @@ else() endif() set(CMAKE_${lang}_COMPILE_OPTIONS_USE_PCH -Xclang -include-pch -Xclang <PCH_FILE> -Xclang -include -Xclang <PCH_HEADER>) set(CMAKE_${lang}_COMPILE_OPTIONS_CREATE_PCH -Xclang -emit-pch -Xclang -include -Xclang <PCH_HEADER> -x ${__pch_header_${lang}}) + + # '-fcolor-diagnostics' introduced since Clang 2.6 + if(CMAKE_${lang}_COMPILER_VERSION VERSION_GREATER_EQUAL 2.6) + set(CMAKE_${lang}_COMPILE_OPTIONS_COLOR_DIAGNOSTICS "-fcolor-diagnostics") + set(CMAKE_${lang}_COMPILE_OPTIONS_COLOR_DIAGNOSTICS_OFF "-fno-color-diagnostics") + endif() endmacro() endif() @@ -249,6 +255,7 @@ macro(__compiler_clang_cxx_standards lang) cxx_std_17 cxx_std_20 cxx_std_23 + cxx_std_26 ) _record_compiler_features(${lang} "" CMAKE_${lang}_COMPILE_FEATURES) endmacro() diff --git a/Modules/Compiler/Fujitsu.cmake b/Modules/Compiler/Fujitsu.cmake index 78495cb..55c2aa4 100644 --- a/Modules/Compiler/Fujitsu.cmake +++ b/Modules/Compiler/Fujitsu.cmake @@ -11,6 +11,7 @@ include(Compiler/CMakeCommonCompilerMacros) macro(__compiler_fujitsu lang) set(CMAKE_${lang}_VERBOSE_FLAG "-###") + set(CMAKE_${lang}_COMPILE_OPTIONS_WARNING_AS_ERROR "-cwno") # Initial configuration flags string(APPEND CMAKE_${lang}_FLAGS_INIT " ") diff --git a/Modules/Compiler/GNU.cmake b/Modules/Compiler/GNU.cmake index 928e726..5930e37 100644 --- a/Modules/Compiler/GNU.cmake +++ b/Modules/Compiler/GNU.cmake @@ -18,6 +18,7 @@ set(__pch_header_OBJCXX "objective-c++-header") macro(__compiler_gnu lang) # Feature flags. set(CMAKE_${lang}_VERBOSE_FLAG "-v") + set(CMAKE_${lang}_COMPILE_OPTIONS_WARNING_AS_ERROR "-Werror") set(CMAKE_${lang}_COMPILE_OPTIONS_PIC "-fPIC") set (_CMAKE_${lang}_PIE_MAY_BE_SUPPORTED_BY_LINKER NO) if(NOT CMAKE_${lang}_COMPILER_VERSION VERSION_LESS 3.4) @@ -71,7 +72,25 @@ macro(__compiler_gnu lang) # * https://gcc.gnu.org/onlinedocs/gcc-4.5.4/gcc/Option-Summary.html (yes) if(NOT CMAKE_${lang}_COMPILER_VERSION VERSION_LESS 4.5) set(_CMAKE_${lang}_IPO_MAY_BE_SUPPORTED_BY_COMPILER YES) - set(__lto_flags -flto) + + set(__lto_flags "") + + # '-flto=auto' introduced since GCC 10.1: + # * https://gcc.gnu.org/onlinedocs/gcc-9.5.0/gcc/Optimize-Options.html#Optimize-Options (no) + # * https://gcc.gnu.org/onlinedocs/gcc-10.1.0/gcc/Optimize-Options.html#Optimize-Options (yes) + # Since GCC 12.1, the abundance of a parameter produces a warning if compiling multiple targets. + # FIXME: What version of GCC for Windows added support for -flto=auto? 10.3 does not have it. + if(NOT CMAKE_${lang}_COMPILER_VERSION VERSION_LESS 11.0) + list(APPEND __lto_flags -flto=auto) + elseif(NOT CMAKE_${lang}_COMPILER_VERSION VERSION_LESS 10.1) + if (CMAKE_HOST_WIN32) + list(APPEND __lto_flags -flto=1) + else() + list(APPEND __lto_flags -flto=auto) + endif() + else() + list(APPEND __lto_flags -flto) + endif() if(NOT CMAKE_${lang}_COMPILER_VERSION VERSION_LESS 4.7) # '-ffat-lto-objects' introduced since GCC 4.7: @@ -102,13 +121,15 @@ macro(__compiler_gnu lang) ) endif() - set(CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND "${CMAKE_${lang}_COMPILER}") - if(CMAKE_${lang}_COMPILER_ARG1) - separate_arguments(_COMPILER_ARGS NATIVE_COMMAND "${CMAKE_${lang}_COMPILER_ARG1}") - list(APPEND CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND ${_COMPILER_ARGS}) - unset(_COMPILER_ARGS) + if("${lang}" STREQUAL "CXX") + set(CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND "${CMAKE_${lang}_COMPILER}") + if(CMAKE_${lang}_COMPILER_ARG1) + separate_arguments(_COMPILER_ARGS NATIVE_COMMAND "${CMAKE_${lang}_COMPILER_ARG1}") + list(APPEND CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND ${_COMPILER_ARGS}) + unset(_COMPILER_ARGS) + endif() + list(APPEND CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND "-dM" "-E" "-c" "${CMAKE_ROOT}/Modules/CMakeCXXCompilerABI.cpp") endif() - list(APPEND CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND "-dM" "-E" "-c" "${CMAKE_ROOT}/Modules/CMakeCXXCompilerABI.cpp") if(NOT "x${lang}" STREQUAL "xFortran") set(CMAKE_PCH_EXTENSION .gch) @@ -119,4 +140,11 @@ macro(__compiler_gnu lang) set(CMAKE_${lang}_COMPILE_OPTIONS_USE_PCH -include <PCH_HEADER>) set(CMAKE_${lang}_COMPILE_OPTIONS_CREATE_PCH -x ${__pch_header_${lang}} -include <PCH_HEADER>) endif() + + # '-fdiagnostics-color=always' introduced since GCC 4.9 + # https://gcc.gnu.org/gcc-4.9/changes.html + if(CMAKE_${lang}_COMPILER_VERSION VERSION_GREATER_EQUAL 4.9) + set(CMAKE_${lang}_COMPILE_OPTIONS_COLOR_DIAGNOSTICS "-fdiagnostics-color=always") + set(CMAKE_${lang}_COMPILE_OPTIONS_COLOR_DIAGNOSTICS_OFF "-fno-diagnostics-color") + endif() endmacro() diff --git a/Modules/Compiler/IAR-CXX.cmake b/Modules/Compiler/IAR-CXX.cmake index 6c15735..3f0ef1f 100644 --- a/Modules/Compiler/IAR-CXX.cmake +++ b/Modules/Compiler/IAR-CXX.cmake @@ -22,9 +22,9 @@ if(NOT CMAKE_IAR_CXX_FLAG) set(_CMAKE_IAR_MODERNCXX_LIST 14 17) if(${CMAKE_CXX_STANDARD_COMPUTED_DEFAULT} IN_LIST _CMAKE_IAR_MODERNCXX_LIST OR ("${CMAKE_CXX_COMPILER_ARCHITECTURE_ID}" STREQUAL "ARM" AND ${CMAKE_CXX_STANDARD_COMPUTED_DEFAULT} EQUAL 98)) - string(PREPEND CMAKE_CXX_FLAGS "--c++ ") + set(CMAKE_IAR_CXX_FLAG --c++) else() - string(PREPEND CMAKE_CXX_FLAGS "--eec++ ") + set(CMAKE_IAR_CXX_FLAG --eec++) endif() unset(_CMAKE_IAR_MODERNCXX_LIST) diff --git a/Modules/Compiler/IAR.cmake b/Modules/Compiler/IAR.cmake index 53456f5..7908f96 100644 --- a/Modules/Compiler/IAR.cmake +++ b/Modules/Compiler/IAR.cmake @@ -8,54 +8,48 @@ # include_guard() -macro(__compiler_iar_ilink lang) - set(CMAKE_EXECUTABLE_SUFFIX ".elf") - set(CMAKE_${lang}_OUTPUT_EXTENSION ".o") - if (${lang} STREQUAL "C" OR ${lang} STREQUAL "CXX") +macro(__compiler_iar_common lang) + if (${lang} MATCHES "^(C|CXX)$") set(CMAKE_${lang}_COMPILE_OBJECT "<CMAKE_${lang}_COMPILER> ${CMAKE_IAR_${lang}_FLAG} --silent <SOURCE> <DEFINES> <INCLUDES> <FLAGS> -o <OBJECT>") set(CMAKE_${lang}_CREATE_PREPROCESSED_SOURCE "<CMAKE_${lang}_COMPILER> ${CMAKE_IAR_${lang}_FLAG} --silent <SOURCE> <DEFINES> <INCLUDES> <FLAGS> --preprocess=cnl <PREPROCESSED_SOURCE>") set(CMAKE_${lang}_CREATE_ASSEMBLY_SOURCE "<CMAKE_${lang}_COMPILER> ${CMAKE_IAR_${lang}_FLAG} --silent <SOURCE> <DEFINES> <INCLUDES> <FLAGS> -lAH <ASSEMBLY_SOURCE> -o <OBJECT>.dummy") - set(CMAKE_${lang}_RESPONSE_FILE_LINK_FLAG "-f ") set(CMAKE_DEPFILE_FLAGS_${lang} "--dependencies=ns <DEP_FILE>") string(APPEND CMAKE_${lang}_FLAGS_INIT " ") string(APPEND CMAKE_${lang}_FLAGS_DEBUG_INIT " -r") - string(APPEND CMAKE_${lang}_FLAGS_MINSIZEREL_INIT " -Ohz -DNDEBUG") string(APPEND CMAKE_${lang}_FLAGS_RELEASE_INIT " -Oh -DNDEBUG") + string(APPEND CMAKE_${lang}_FLAGS_MINSIZEREL_INIT " -Ohz -DNDEBUG") string(APPEND CMAKE_${lang}_FLAGS_RELWITHDEBINFO_INIT " -Oh -r -DNDEBUG") endif() + set(CMAKE_${lang}_RESPONSE_FILE_FLAG "-f ") + set(CMAKE_${lang}_RESPONSE_FILE_LINK_FLAG "-f ") + + set(CMAKE_${lang}_ARCHIVE_FINISH "") +endmacro() + +macro(__compiler_iar_ilink lang) + set(CMAKE_EXECUTABLE_SUFFIX ".elf") + set(CMAKE_${lang}_OUTPUT_EXTENSION ".o") + + __compiler_iar_common(${lang}) + set(CMAKE_${lang}_LINK_EXECUTABLE "<CMAKE_LINKER> --silent <OBJECTS> <CMAKE_${lang}_LINK_FLAGS> <LINK_FLAGS> <LINK_LIBRARIES> -o <TARGET>") set(CMAKE_${lang}_CREATE_STATIC_LIBRARY "<CMAKE_AR> <TARGET> --create <LINK_FLAGS> <OBJECTS>") set(CMAKE_${lang}_ARCHIVE_CREATE "<CMAKE_AR> <TARGET> --create <LINK_FLAGS> <OBJECTS>") set(CMAKE_${lang}_ARCHIVE_APPEND "<CMAKE_AR> <TARGET> --replace <LINK_FLAGS> <OBJECTS>") - set(CMAKE_${lang}_ARCHIVE_FINISH "") endmacro() macro(__compiler_iar_xlink lang) set(CMAKE_EXECUTABLE_SUFFIX ".bin") - if (${lang} STREQUAL "C" OR ${lang} STREQUAL "CXX") - - set(CMAKE_${lang}_COMPILE_OBJECT "<CMAKE_${lang}_COMPILER> ${CMAKE_IAR_${lang}_FLAG} --silent <SOURCE> <DEFINES> <INCLUDES> <FLAGS> -o <OBJECT>") - set(CMAKE_${lang}_CREATE_PREPROCESSED_SOURCE "<CMAKE_${lang}_COMPILER> ${CMAKE_IAR_${lang}_FLAG} --silent <SOURCE> <DEFINES> <INCLUDES> <FLAGS> --preprocess=cnl <PREPROCESSED_SOURCE>") - set(CMAKE_${lang}_CREATE_ASSEMBLY_SOURCE "<CMAKE_${lang}_COMPILER> ${CMAKE_IAR_${lang}_FLAG} --silent <SOURCE> <DEFINES> <INCLUDES> <FLAGS> -lAH <ASSEMBLY_SOURCE> -o <OBJECT>.dummy") - - set(CMAKE_${lang}_RESPONSE_FILE_LINK_FLAG "-f ") - set(CMAKE_DEPFILE_FLAGS_${lang} "--dependencies=ns <DEP_FILE>") - string(APPEND CMAKE_${lang}_FLAGS_INIT " ") - string(APPEND CMAKE_${lang}_FLAGS_DEBUG_INIT " -r") - string(APPEND CMAKE_${lang}_FLAGS_MINSIZEREL_INIT " -Ohz -DNDEBUG") - string(APPEND CMAKE_${lang}_FLAGS_RELEASE_INIT " -Oh -DNDEBUG") - string(APPEND CMAKE_${lang}_FLAGS_RELWITHDEBINFO_INIT " -Oh -r -DNDEBUG") - endif() + __compiler_iar_common(${lang}) set(CMAKE_${lang}_LINK_EXECUTABLE "<CMAKE_LINKER> -S <OBJECTS> <CMAKE_${lang}_LINK_FLAGS> <LINK_FLAGS> <LINK_LIBRARIES> -o <TARGET>") set(CMAKE_${lang}_CREATE_STATIC_LIBRARY "<CMAKE_AR> <TARGET> <LINK_FLAGS> <OBJECTS>") set(CMAKE_${lang}_ARCHIVE_CREATE "<CMAKE_AR> <TARGET> <LINK_FLAGS> <OBJECTS>") set(CMAKE_${lang}_ARCHIVE_APPEND "") - set(CMAKE_${lang}_ARCHIVE_FINISH "") set(CMAKE_LIBRARY_PATH_FLAG "-I") endmacro() diff --git a/Modules/Compiler/IBMClang.cmake b/Modules/Compiler/IBMClang.cmake index 9ed7658..a9d760f 100644 --- a/Modules/Compiler/IBMClang.cmake +++ b/Modules/Compiler/IBMClang.cmake @@ -36,7 +36,7 @@ macro(__compiler_ibmclang lang) set(CMAKE_${lang}_LINKER_WRAPPER_FLAG "-Xlinker" " ") set(CMAKE_${lang}_LINKER_WRAPPER_FLAG_SEP) - if(CMAKE_${lang}_COMPILER_TARGET) + if(CMAKE_${lang}_COMPILER_TARGET AND "${lang}" STREQUAL "CXX") list(APPEND CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND "--target=${CMAKE_${lang}_COMPILER_TARGET}") endif() @@ -66,7 +66,9 @@ macro(__compiler_ibmclang lang) "\"${__ranlib}\" <TARGET>" ) - list(APPEND CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND "-dM" "-E" "-c" "${CMAKE_ROOT}/Modules/CMakeCXXCompilerABI.cpp") + if("${lang}" STREQUAL "CXX") + list(APPEND CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND "-dM" "-E" "-c" "${CMAKE_ROOT}/Modules/CMakeCXXCompilerABI.cpp") + endif() set(CMAKE_PCH_EXTENSION .pch) diff --git a/Modules/Compiler/Intel.cmake b/Modules/Compiler/Intel.cmake index 9a760c8..317cfc7 100644 --- a/Modules/Compiler/Intel.cmake +++ b/Modules/Compiler/Intel.cmake @@ -13,6 +13,11 @@ include(Compiler/CMakeCommonCompilerMacros) if(CMAKE_HOST_WIN32) # MSVC-like macro(__compiler_intel lang) + if("x${lang}" STREQUAL "xFortran") + set(CMAKE_${lang}_COMPILE_OPTIONS_WARNING_AS_ERROR "-warn:errors") + else() + set(CMAKE_${lang}_COMPILE_OPTIONS_WARNING_AS_ERROR "-Werror-all") + endif() endmacro() else() # GNU-like @@ -25,15 +30,19 @@ else() string(APPEND CMAKE_${lang}_FLAGS_RELEASE_INIT " -O3") string(APPEND CMAKE_${lang}_FLAGS_RELWITHDEBINFO_INIT " -O2 -g") - set(CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND "${CMAKE_${lang}_COMPILER}") - if(CMAKE_${lang}_COMPILER_ARG1) - separate_arguments(_COMPILER_ARGS NATIVE_COMMAND "${CMAKE_${lang}_COMPILER_ARG1}") - list(APPEND CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND ${_COMPILER_ARGS}) - unset(_COMPILER_ARGS) + if("${lang}" STREQUAL "CXX") + set(CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND "${CMAKE_${lang}_COMPILER}") + if(CMAKE_${lang}_COMPILER_ARG1) + separate_arguments(_COMPILER_ARGS NATIVE_COMMAND "${CMAKE_${lang}_COMPILER_ARG1}") + list(APPEND CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND ${_COMPILER_ARGS}) + unset(_COMPILER_ARGS) + endif() + list(APPEND CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND "-QdM" "-P" "-Za" "${CMAKE_ROOT}/Modules/CMakeCXXCompilerABI.cpp") endif() - list(APPEND CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND "-QdM" "-P" "-Za" "${CMAKE_ROOT}/Modules/CMakeCXXCompilerABI.cpp") - if(NOT "x${lang}" STREQUAL "xFortran") + if("x${lang}" STREQUAL "xFortran") + set(CMAKE_${lang}_COMPILE_OPTIONS_WARNING_AS_ERROR "-warn" "errors") + else() # Precompile Headers set(CMAKE_PCH_EXTENSION .pchi) set(CMAKE_LINK_PCH ON) @@ -41,6 +50,9 @@ else() set(CMAKE_${lang}_COMPILE_OPTIONS_INVALID_PCH -Winvalid-pch) set(CMAKE_${lang}_COMPILE_OPTIONS_USE_PCH -Wno-pch-messages -pch-use <PCH_FILE> -include <PCH_HEADER>) set(CMAKE_${lang}_COMPILE_OPTIONS_CREATE_PCH -Wno-pch-messages -pch-create <PCH_FILE> -include <PCH_HEADER>) + + # COMPILE_WARNING_AS_ERROR + set(CMAKE_${lang}_COMPILE_OPTIONS_WARNING_AS_ERROR "-Werror-all") endif() endmacro() endif() diff --git a/Modules/Compiler/IntelLLVM-C.cmake b/Modules/Compiler/IntelLLVM-C.cmake index d7346f6..3a81154 100644 --- a/Modules/Compiler/IntelLLVM-C.cmake +++ b/Modules/Compiler/IntelLLVM-C.cmake @@ -41,6 +41,9 @@ if(NOT "x${CMAKE_C_SIMULATE_ID}" STREQUAL "xMSVC") set(CMAKE_C17_STANDARD_COMPILE_OPTION "-std=c17") set(CMAKE_C17_EXTENSION_COMPILE_OPTION "-std=gnu17") + + set(CMAKE_C23_STANDARD_COMPILE_OPTION "-std=c2x") + set(CMAKE_C23_EXTENSION_COMPILE_OPTION "-std=gnu2x") else() # clang-cl doesn't have any of these set(CMAKE_C90_STANDARD_COMPILE_OPTION "") @@ -54,6 +57,9 @@ else() set(CMAKE_C17_STANDARD_COMPILE_OPTION "") set(CMAKE_C17_EXTENSION_COMPILE_OPTION "") + + set(CMAKE_C23_STANDARD_COMPILE_OPTION "") + set(CMAKE_C23_EXTENSION_COMPILE_OPTION "") endif() __compiler_check_default_language_standard(C 2020 17) diff --git a/Modules/Compiler/IntelLLVM-CXX.cmake b/Modules/Compiler/IntelLLVM-CXX.cmake index cae1f11..45b723f 100644 --- a/Modules/Compiler/IntelLLVM-CXX.cmake +++ b/Modules/Compiler/IntelLLVM-CXX.cmake @@ -46,21 +46,27 @@ if(NOT "x${CMAKE_CXX_SIMULATE_ID}" STREQUAL "xMSVC") set(CMAKE_CXX20_STANDARD_COMPILE_OPTION "-std=c++20") set(CMAKE_CXX20_EXTENSION_COMPILE_OPTION "-std=gnu++20") + + set(CMAKE_CXX23_STANDARD_COMPILE_OPTION "-std=c++2b") + set(CMAKE_CXX23_EXTENSION_COMPILE_OPTION "-std=gnu++2b") else() set(CMAKE_CXX98_STANDARD_COMPILE_OPTION "") set(CMAKE_CXX98_EXTENSION_COMPILE_OPTION "") - set(CMAKE_CXX11_STANDARD_COMPILE_OPTION "-Qstd=c++11") - set(CMAKE_CXX11_EXTENSION_COMPILE_OPTION "-Qstd=c++11") + set(CMAKE_CXX11_STANDARD_COMPILE_OPTION "") + set(CMAKE_CXX11_EXTENSION_COMPILE_OPTION "") + + set(CMAKE_CXX14_STANDARD_COMPILE_OPTION "-Qstd:c++14") + set(CMAKE_CXX14_EXTENSION_COMPILE_OPTION "-Qstd:c++14") - set(CMAKE_CXX14_STANDARD_COMPILE_OPTION "-Qstd=c++14") - set(CMAKE_CXX14_EXTENSION_COMPILE_OPTION "-Qstd=c++14") + set(CMAKE_CXX17_STANDARD_COMPILE_OPTION "-Qstd:c++17") + set(CMAKE_CXX17_EXTENSION_COMPILE_OPTION "-Qstd:c++17") - set(CMAKE_CXX17_STANDARD_COMPILE_OPTION "-Qstd=c++17") - set(CMAKE_CXX17_EXTENSION_COMPILE_OPTION "-Qstd=c++17") + set(CMAKE_CXX20_STANDARD_COMPILE_OPTION "-Qstd:c++20") + set(CMAKE_CXX20_EXTENSION_COMPILE_OPTION "-Qstd:c++20") - set(CMAKE_CXX20_STANDARD_COMPILE_OPTION "-Qstd=c++20") - set(CMAKE_CXX20_EXTENSION_COMPILE_OPTION "-Qstd=c++20") + set(CMAKE_CXX23_STANDARD_COMPILE_OPTION "-Qstd:c++2b") + set(CMAKE_CXX23_EXTENSION_COMPILE_OPTION "-Qstd:c++2b") endif() __compiler_check_default_language_standard(CXX 2020 14) diff --git a/Modules/Compiler/IntelLLVM-FindBinUtils.cmake b/Modules/Compiler/IntelLLVM-FindBinUtils.cmake new file mode 100644 index 0000000..c5b1ee6 --- /dev/null +++ b/Modules/Compiler/IntelLLVM-FindBinUtils.cmake @@ -0,0 +1,45 @@ +if(NOT DEFINED _CMAKE_PROCESSING_LANGUAGE OR _CMAKE_PROCESSING_LANGUAGE STREQUAL "") + message(FATAL_ERROR "Internal error: _CMAKE_PROCESSING_LANGUAGE is not set") +endif() + +# Ubuntu: +# * /usr/bin/llvm-ar-9 +# * /usr/bin/llvm-ranlib-9 +string(REGEX MATCH "^([0-9]+)" __version_x + "${CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_VERSION}") + +# Debian: +# * /usr/bin/llvm-ar-4.0 +# * /usr/bin/llvm-ranlib-4.0 +string(REGEX MATCH "^([0-9]+\\.[0-9]+)" __version_x_y + "${CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_VERSION}") + +# Try to find tools in the IntelLLVM Clang tools directory +get_filename_component(__intel_llvm_hint_1 "${CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER}" DIRECTORY) +get_filename_component(__intel_llvm_hint_1 "${__intel_llvm_hint_1}/../bin-llvm" REALPATH) + +get_filename_component(__intel_llvm_hint_2 "${CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER}" DIRECTORY) + +set(__intel_llvm_hints ${__intel_llvm_hint_1} ${__intel_llvm_hint_2}) + +# http://manpages.ubuntu.com/manpages/precise/en/man1/llvm-ar.1.html +find_program(CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_AR NAMES + "${_CMAKE_TOOLCHAIN_PREFIX}llvm-ar-${__version_x_y}" + "${_CMAKE_TOOLCHAIN_PREFIX}llvm-ar-${__version_x}" + "${_CMAKE_TOOLCHAIN_PREFIX}llvm-ar" + HINTS ${__intel_llvm_hints} + NO_CMAKE_PATH NO_CMAKE_ENVIRONMENT_PATH + DOC "LLVM archiver" +) +mark_as_advanced(CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_AR) + +# http://manpages.ubuntu.com/manpages/precise/en/man1/llvm-ranlib.1.html +find_program(CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_RANLIB NAMES + "${_CMAKE_TOOLCHAIN_PREFIX}llvm-ranlib-${__version_x_y}" + "${_CMAKE_TOOLCHAIN_PREFIX}llvm-ranlib-${__version_x}" + "${_CMAKE_TOOLCHAIN_PREFIX}llvm-ranlib" + HINTS ${__intel_llvm_hints} + NO_CMAKE_PATH NO_CMAKE_ENVIRONMENT_PATH + DOC "Generate index for LLVM archive" +) +mark_as_advanced(CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_RANLIB) diff --git a/Modules/Compiler/IntelLLVM.cmake b/Modules/Compiler/IntelLLVM.cmake index 14b7ad8..e256c8f 100644 --- a/Modules/Compiler/IntelLLVM.cmake +++ b/Modules/Compiler/IntelLLVM.cmake @@ -15,12 +15,27 @@ set(__pch_header_CXX "c++-header") set(__pch_header_OBJC "objective-c-header") set(__pch_header_OBJCXX "objective-c++-header") +# Variables that are common across front-end variants +macro(__compiler_intel_llvm_common lang) + set(_CMAKE_${lang}_IPO_SUPPORTED_BY_CMAKE YES) + set(_CMAKE_${lang}_IPO_MAY_BE_SUPPORTED_BY_COMPILER YES) + set(CMAKE_${lang}_ARCHIVE_CREATE_IPO "\"${CMAKE_${lang}_COMPILER_AR}\" cr <TARGET> <LINK_FLAGS> <OBJECTS>") + set(CMAKE_${lang}_ARCHIVE_APPEND_IPO "\"${CMAKE_${lang}_COMPILER_AR}\" r <TARGET> <LINK_FLAGS> <OBJECTS>") + set(CMAKE_${lang}_ARCHIVE_FINISH_IPO "\"${CMAKE_${lang}_COMPILER_RANLIB}\" <TARGET>") +endmacro() + if(CMAKE_HOST_WIN32) # MSVC-like macro(__compiler_intel_llvm lang) - if(NOT "x${lang}" STREQUAL "xFortran") + if("x${lang}" STREQUAL "xFortran") + set(CMAKE_${lang}_COMPILE_OPTIONS_WARNING_AS_ERROR "-warn:errors") + else() set(CMAKE_${lang}_COMPILE_OPTIONS_INVALID_PCH -Winvalid-pch) + set(CMAKE_${lang}_COMPILE_OPTIONS_WARNING_AS_ERROR "-WX") endif() + __compiler_intel_llvm_common(${lang}) + set(CMAKE_${lang}_COMPILE_OPTIONS_IPO "-Qipo") + set(CMAKE_${lang}_LINK_OPTIONS_IPO "-Qipo") endmacro() else() # GNU-like @@ -58,28 +73,29 @@ else() set(CMAKE_${lang}_LINKER_WRAPPER_FLAG "-Xlinker" " ") set(CMAKE_${lang}_LINKER_WRAPPER_FLAG_SEP) - set(_CMAKE_${lang}_IPO_SUPPORTED_BY_CMAKE YES) - set(_CMAKE_${lang}_IPO_MAY_BE_SUPPORTED_BY_COMPILER YES) - set(CMAKE_${lang}_COMPILE_OPTIONS_IPO "-flto=thin") - set(CMAKE_${lang}_ARCHIVE_CREATE_IPO "\"${CMAKE_${lang}_COMPILER_AR}\" cr <TARGET> <LINK_FLAGS> <OBJECTS>") - set(CMAKE_${lang}_ARCHIVE_APPEND_IPO "\"${CMAKE_${lang}_COMPILER_AR}\" r <TARGET> <LINK_FLAGS> <OBJECTS>") - set(CMAKE_${lang}_ARCHIVE_FINISH_IPO "\"${CMAKE_${lang}_COMPILER_RANLIB}\" <TARGET>") + __compiler_intel_llvm_common(${lang}) + set(CMAKE_${lang}_COMPILE_OPTIONS_IPO "-ipo") + set(CMAKE_${lang}_LINK_OPTIONS_IPO "-ipo") set(CMAKE_${lang}_CREATE_PREPROCESSED_SOURCE "<CMAKE_${lang}_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>") set(CMAKE_${lang}_CREATE_ASSEMBLY_SOURCE "<CMAKE_${lang}_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -S <SOURCE> -o <ASSEMBLY_SOURCE>") - set(CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND "${CMAKE_${lang}_COMPILER}") - if(CMAKE_${lang}_COMPILER_ARG1) - separate_arguments(_COMPILER_ARGS NATIVE_COMMAND "${CMAKE_${lang}_COMPILER_ARG1}") - list(APPEND CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND ${_COMPILER_ARGS}) - unset(_COMPILER_ARGS) - endif() - list(APPEND CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND "-dM" "-E" "-c" "${CMAKE_ROOT}/Modules/CMakeCXXCompilerABI.cpp") - if(CMAKE_${lang}_COMPILER_TARGET) - list(APPEND CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND "--target=${CMAKE_${lang}_COMPILER_TARGET}") + if("${lang}" STREQUAL "CXX") + set(CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND "${CMAKE_${lang}_COMPILER}") + if(CMAKE_${lang}_COMPILER_ARG1) + separate_arguments(_COMPILER_ARGS NATIVE_COMMAND "${CMAKE_${lang}_COMPILER_ARG1}") + list(APPEND CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND ${_COMPILER_ARGS}) + unset(_COMPILER_ARGS) + endif() + list(APPEND CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND "-dM" "-E" "-c" "${CMAKE_ROOT}/Modules/CMakeCXXCompilerABI.cpp") + if(CMAKE_${lang}_COMPILER_TARGET) + list(APPEND CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND "--target=${CMAKE_${lang}_COMPILER_TARGET}") + endif() endif() - if(NOT "x${lang}" STREQUAL "xFortran") + if("x${lang}" STREQUAL "xFortran") + set(CMAKE_${lang}_COMPILE_OPTIONS_WARNING_AS_ERROR "-warn" "errors") + else() # Precompile Headers set(CMAKE_PCH_EXTENSION .pch) set(CMAKE_PCH_PROLOGUE "#pragma clang system_header") @@ -87,6 +103,9 @@ else() set(CMAKE_${lang}_COMPILE_OPTIONS_INVALID_PCH -Winvalid-pch) set(CMAKE_${lang}_COMPILE_OPTIONS_USE_PCH -Xclang -include-pch -Xclang <PCH_FILE> -Xclang -include -Xclang <PCH_HEADER>) set(CMAKE_${lang}_COMPILE_OPTIONS_CREATE_PCH -Xclang -emit-pch -Xclang -include -Xclang <PCH_HEADER> -x ${__pch_header_${lang}}) + + # COMPILE_WARNING_AS_ERROR + set(CMAKE_${lang}_COMPILE_OPTIONS_WARNING_AS_ERROR "-Werror") endif() endmacro() endif() diff --git a/Modules/Compiler/LCC-C-DetermineCompiler.cmake b/Modules/Compiler/LCC-C-DetermineCompiler.cmake index 2ce92fe..3f46210 100644 --- a/Modules/Compiler/LCC-C-DetermineCompiler.cmake +++ b/Modules/Compiler/LCC-C-DetermineCompiler.cmake @@ -2,10 +2,8 @@ set(_compiler_id_pp_test "defined(__LCC__) && (defined(__GNUC__) || defined(__GNUG__) || defined(__MCST__))") set(_compiler_id_version_compute " -# define @PREFIX@COMPILER_VERSION_MAJOR @MACRO_DEC@(1) -# if defined(__LCC__) -# define @PREFIX@COMPILER_VERSION_MINOR @MACRO_DEC@(__LCC__- 100) -# endif +# define @PREFIX@COMPILER_VERSION_MAJOR @MACRO_DEC@(__LCC__ / 100) +# define @PREFIX@COMPILER_VERSION_MINOR @MACRO_DEC@(__LCC__ % 100) # if defined(__LCC_MINOR__) # define @PREFIX@COMPILER_VERSION_PATCH @MACRO_DEC@(__LCC_MINOR__) # endif diff --git a/Modules/Compiler/LCC-CXX-DetermineCompiler.cmake b/Modules/Compiler/LCC-CXX-DetermineCompiler.cmake index 2ce92fe..3f46210 100644 --- a/Modules/Compiler/LCC-CXX-DetermineCompiler.cmake +++ b/Modules/Compiler/LCC-CXX-DetermineCompiler.cmake @@ -2,10 +2,8 @@ set(_compiler_id_pp_test "defined(__LCC__) && (defined(__GNUC__) || defined(__GNUG__) || defined(__MCST__))") set(_compiler_id_version_compute " -# define @PREFIX@COMPILER_VERSION_MAJOR @MACRO_DEC@(1) -# if defined(__LCC__) -# define @PREFIX@COMPILER_VERSION_MINOR @MACRO_DEC@(__LCC__- 100) -# endif +# define @PREFIX@COMPILER_VERSION_MAJOR @MACRO_DEC@(__LCC__ / 100) +# define @PREFIX@COMPILER_VERSION_MINOR @MACRO_DEC@(__LCC__ % 100) # if defined(__LCC_MINOR__) # define @PREFIX@COMPILER_VERSION_PATCH @MACRO_DEC@(__LCC_MINOR__) # endif diff --git a/Modules/Compiler/LCC.cmake b/Modules/Compiler/LCC.cmake index 8353ab6..f8c2084 100644 --- a/Modules/Compiler/LCC.cmake +++ b/Modules/Compiler/LCC.cmake @@ -18,6 +18,7 @@ set(__pch_header_OBJCXX "objective-c++-header") macro(__compiler_lcc lang) # Feature flags. set(CMAKE_${lang}_VERBOSE_FLAG "-v") + set(CMAKE_${lang}_COMPILE_OPTIONS_WARNING_AS_ERROR "-Werror") set(CMAKE_${lang}_COMPILE_OPTIONS_PIC "-fPIC") set (_CMAKE_${lang}_PIE_MAY_BE_SUPPORTED_BY_LINKER NO) set(CMAKE_${lang}_COMPILE_OPTIONS_PIE "-fPIE") @@ -75,13 +76,15 @@ macro(__compiler_lcc lang) "\"${CMAKE_${lang}_COMPILER_RANLIB}\" <TARGET>" ) - set(CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND "${CMAKE_${lang}_COMPILER}") - if(CMAKE_${lang}_COMPILER_ARG1) - separate_arguments(_COMPILER_ARGS NATIVE_COMMAND "${CMAKE_${lang}_COMPILER_ARG1}") - list(APPEND CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND ${_COMPILER_ARGS}) - unset(_COMPILER_ARGS) + if("${lang}" STREQUAL "CXX") + set(CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND "${CMAKE_${lang}_COMPILER}") + if(CMAKE_${lang}_COMPILER_ARG1) + separate_arguments(_COMPILER_ARGS NATIVE_COMMAND "${CMAKE_${lang}_COMPILER_ARG1}") + list(APPEND CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND ${_COMPILER_ARGS}) + unset(_COMPILER_ARGS) + endif() + list(APPEND CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND "-dM" "-E" "-c" "${CMAKE_ROOT}/Modules/CMakeCXXCompilerABI.cpp") endif() - list(APPEND CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND "-dM" "-E" "-c" "${CMAKE_ROOT}/Modules/CMakeCXXCompilerABI.cpp") if(NOT "x${lang}" STREQUAL "xFortran") set(CMAKE_PCH_EXTENSION .gch) diff --git a/Modules/Compiler/LLVMFlang-Fortran.cmake b/Modules/Compiler/LLVMFlang-Fortran.cmake new file mode 100644 index 0000000..9e72b06 --- /dev/null +++ b/Modules/Compiler/LLVMFlang-Fortran.cmake @@ -0,0 +1,16 @@ +set(CMAKE_Fortran_VERBOSE_FLAG "-v") + +set(CMAKE_Fortran_SUBMODULE_SEP "-") +set(CMAKE_Fortran_SUBMODULE_EXT ".mod") + +set(CMAKE_Fortran_PREPROCESS_SOURCE + "<CMAKE_Fortran_COMPILER> -cpp <DEFINES> <INCLUDES> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>") + +set(CMAKE_Fortran_FORMAT_FIXED_FLAG "-ffixed-form") +set(CMAKE_Fortran_FORMAT_FREE_FLAG "-ffree-form") + +set(CMAKE_Fortran_MODDIR_FLAG "-module-dir") + +set(CMAKE_Fortran_COMPILE_OPTIONS_PREPROCESS_ON "-cpp") +set(CMAKE_Fortran_COMPILE_OPTIONS_PREPROCESS_OFF "-nocpp") +set(CMAKE_Fortran_POSTPROCESS_FLAG "-ffixed-line-length-72") diff --git a/Modules/Compiler/MSVC-C.cmake b/Modules/Compiler/MSVC-C.cmake index df3691c..6bf6b4e 100644 --- a/Modules/Compiler/MSVC-C.cmake +++ b/Modules/Compiler/MSVC-C.cmake @@ -1,6 +1,9 @@ # Distributed under the OSI-approved BSD 3-Clause License. See accompanying # file Copyright.txt or https://cmake.org/licensing for details. +include(Compiler/MSVC) +__compiler_msvc(C) + include(Compiler/CMakeCommonCompilerMacros) if(CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 19.27) @@ -67,16 +70,3 @@ else() endif() set(CMAKE_C_COMPILE_OPTIONS_EXPLICIT_LANGUAGE -TC) -set(CMAKE_C_CLANG_TIDY_DRIVER_MODE "cl") -set(CMAKE_C_INCLUDE_WHAT_YOU_USE_DRIVER_MODE "cl") - -# /JMC "Just My Code" is only supported by MSVC 19.05 onward. -if (CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 19.05) - set(CMAKE_C_COMPILE_OPTIONS_JMC "-JMC") -endif() - -# The `/external:I` flag was made non-experimental in 19.29.30036.3. -if (CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 19.29.30036.3) - set(CMAKE_INCLUDE_SYSTEM_FLAG_C "-external:I") - set(_CMAKE_INCLUDE_SYSTEM_FLAG_C_WARNING "-external:W0 ") -endif () diff --git a/Modules/Compiler/MSVC-CXX.cmake b/Modules/Compiler/MSVC-CXX.cmake index 17cbc3c..10a9073 100644 --- a/Modules/Compiler/MSVC-CXX.cmake +++ b/Modules/Compiler/MSVC-CXX.cmake @@ -1,10 +1,10 @@ # Distributed under the OSI-approved BSD 3-Clause License. See accompanying # file Copyright.txt or https://cmake.org/licensing for details. -include(Compiler/CMakeCommonCompilerMacros) +include(Compiler/MSVC) +__compiler_msvc(CXX) -set(CMAKE_CXX_CLANG_TIDY_DRIVER_MODE "cl") -set(CMAKE_CXX_INCLUDE_WHAT_YOU_USE_DRIVER_MODE "cl") +include(Compiler/CMakeCommonCompilerMacros) if ((CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 19.0.24215.1 AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 19.10) OR @@ -72,18 +72,19 @@ elseif (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 16.0) cxx_std_17 cxx_std_20 cxx_std_23 + cxx_std_26 ) _record_compiler_features(CXX "" CMAKE_CXX_COMPILE_FEATURES) endmacro() endif() -# /JMC "Just My Code" is only supported by MSVC 19.05 onward. -if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 19.05) - set(CMAKE_CXX_COMPILE_OPTIONS_JMC "-JMC") -endif() - -# The `/external:I` flag was made non-experimental in 19.29.30036.3. -if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 19.29.30036.3) - set(CMAKE_INCLUDE_SYSTEM_FLAG_CXX "-external:I") - set(_CMAKE_INCLUDE_SYSTEM_FLAG_CXX_WARNING "-external:W0 ") +if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL "19.34") + string(CONCAT CMAKE_EXPERIMENTAL_CXX_SCANDEP_SOURCE + "<CMAKE_CXX_COMPILER> <DEFINES> <INCLUDES> <FLAGS> <SOURCE> -nologo -TP" + " -showIncludes" + " -scanDependencies <DYNDEP_FILE>" + " -Fo<OBJECT>") + set(CMAKE_EXPERIMENTAL_CXX_SCANDEP_DEPFILE_FORMAT "msvc") + set(CMAKE_EXPERIMENTAL_CXX_MODULE_MAP_FORMAT "msvc") + set(CMAKE_EXPERIMENTAL_CXX_MODULE_MAP_FLAG "@<MODULE_MAP_FILE>") endif () diff --git a/Modules/Compiler/MSVC.cmake b/Modules/Compiler/MSVC.cmake new file mode 100644 index 0000000..154b657 --- /dev/null +++ b/Modules/Compiler/MSVC.cmake @@ -0,0 +1,25 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + +# This module is shared by multiple languages; use include blocker. +if(__COMPILER_MSVC) + return() +endif() +set(__COMPILER_MSVC 1) + +macro(__compiler_msvc lang) + set(CMAKE_${lang}_CLANG_TIDY_DRIVER_MODE "cl") + set(CMAKE_${lang}_INCLUDE_WHAT_YOU_USE_DRIVER_MODE "cl") + set(CMAKE_${lang}_COMPILE_OPTIONS_WARNING_AS_ERROR "-WX") + + # /JMC "Just My Code" is only supported by MSVC 19.05 onward. + if (CMAKE_${lang}_COMPILER_VERSION VERSION_GREATER_EQUAL 19.05) + set(CMAKE_${lang}_COMPILE_OPTIONS_JMC "-JMC") + endif() + + # The `/external:I` flag was made non-experimental in 19.29.30036.3. + if (CMAKE_${lang}_COMPILER_VERSION VERSION_GREATER_EQUAL 19.29.30036.3) + set(CMAKE_INCLUDE_SYSTEM_FLAG_${lang} "-external:I") + set(_CMAKE_INCLUDE_SYSTEM_FLAG_${lang}_WARNING "-external:W0 ") + endif () +endmacro() diff --git a/Modules/Compiler/NAG-Fortran.cmake b/Modules/Compiler/NAG-Fortran.cmake index a65fd2c..b946cfd 100644 --- a/Modules/Compiler/NAG-Fortran.cmake +++ b/Modules/Compiler/NAG-Fortran.cmake @@ -14,7 +14,7 @@ if(NOT CMAKE_Fortran_COMPILER_WORKS AND NOT CMAKE_Fortran_COMPILER_FORCED) string(REGEX REPLACE "/[^/]*$" "" _nag_dir "${_nag_obj}") string(REGEX REPLACE "([][+.*()^])" "\\\\\\1" _nag_regex "${_nag_dir}") set(CMAKE_Fortran_IMPLICIT_OBJECT_REGEX "^${_nag_regex}/") - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log + message(CONFIGURE_LOG "Detecting NAG Fortran directory with -dryrun found\n" " object: ${_nag_obj}\n" " directory: ${_nag_dir}\n" @@ -22,7 +22,7 @@ if(NOT CMAKE_Fortran_COMPILER_WORKS AND NOT CMAKE_Fortran_COMPILER_FORCED) "from output:\n${_dryrun}\n\n") message(CHECK_PASS "${_nag_dir}") else() - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log + message(CONFIGURE_LOG "Detecting NAG Fortran directory with -dryrun failed:\n${_dryrun}\n\n") message(CHECK_FAIL "failed") endif() diff --git a/Modules/Compiler/NVHPC.cmake b/Modules/Compiler/NVHPC.cmake index b51bb43..474ac80 100644 --- a/Modules/Compiler/NVHPC.cmake +++ b/Modules/Compiler/NVHPC.cmake @@ -13,4 +13,5 @@ include(Compiler/PGI) macro(__compiler_nvhpc lang) # Logic specific to NVHPC. set(CMAKE_INCLUDE_SYSTEM_FLAG_${lang} "-isystem ") + set(CMAKE_${lang}_COMPILE_OPTIONS_WARNING_AS_ERROR "-Werror" "all-warnings") endmacro() diff --git a/Modules/Compiler/NVIDIA-CUDA.cmake b/Modules/Compiler/NVIDIA-CUDA.cmake index 2f12b43..0823954 100644 --- a/Modules/Compiler/NVIDIA-CUDA.cmake +++ b/Modules/Compiler/NVIDIA-CUDA.cmake @@ -30,6 +30,11 @@ if(CMAKE_CUDA_HOST_COMPILER AND NOT CMAKE_GENERATOR MATCHES "Visual Studio") endif() if (CMAKE_CUDA_COMPILER_VERSION VERSION_GREATER_EQUAL 10.2.89) + # Starting in 10.2, nvcc supported treating all warnings as errors + set(CMAKE_CUDA_COMPILE_OPTIONS_WARNING_AS_ERROR "-Werror" "all-warnings") +endif() + +if (CMAKE_CUDA_COMPILER_VERSION VERSION_GREATER_EQUAL 10.2.89) # The -MD flag was only added to nvcc in 10.2 so # before that we had to invoke the compiler twice # to get header dependency information @@ -43,6 +48,13 @@ if((NOT DEFINED CMAKE_DEPENDS_USE_COMPILER OR CMAKE_DEPENDS_USE_COMPILER) set(CMAKE_CUDA_DEPENDS_USE_COMPILER TRUE) endif() +if(CMAKE_CUDA_COMPILER_VERSION VERSION_GREATER_EQUAL 11.2) + set(_CMAKE_CUDA_IPO_SUPPORTED_BY_CMAKE YES) + set(_CMAKE_CUDA_IPO_MAY_BE_SUPPORTED_BY_COMPILER YES) + + set(CMAKE_CUDA_DEVICE_LINK_OPTIONS_IPO " -dlto") +endif() + if(NOT "x${CMAKE_CUDA_SIMULATE_ID}" STREQUAL "xMSVC") set(CMAKE_CUDA_COMPILE_OPTIONS_PIE -Xcompiler=-fPIE) set(CMAKE_CUDA_COMPILE_OPTIONS_PIC -Xcompiler=-fPIC) @@ -56,8 +68,9 @@ if(NOT "x${CMAKE_CUDA_SIMULATE_ID}" STREQUAL "xMSVC") string(APPEND CMAKE_CUDA_FLAGS_MINSIZEREL_INIT " -O1 -DNDEBUG") string(APPEND CMAKE_CUDA_FLAGS_RELWITHDEBINFO_INIT " -O2 -g -DNDEBUG") endif() + set(CMAKE_SHARED_LIBRARY_CREATE_CUDA_FLAGS -shared) -set(CMAKE_INCLUDE_SYSTEM_FLAG_CUDA -isystem=) +set(CMAKE_INCLUDE_SYSTEM_FLAG_CUDA "-isystem ") if (CMAKE_CUDA_SIMULATE_ID STREQUAL "GNU") set(CMAKE_CUDA_LINKER_WRAPPER_FLAG "-Wl,") @@ -106,6 +119,13 @@ if("x${CMAKE_CUDA_SIMULATE_ID}" STREQUAL "xMSVC") endif() endif() + if (NOT CMAKE_CUDA_COMPILER_VERSION VERSION_LESS 12.0) + if(CMAKE_CUDA_SIMULATE_VERSION VERSION_GREATER_EQUAL 19.11.25505) + set(CMAKE_CUDA20_STANDARD_COMPILE_OPTION "-std=c++20") + set(CMAKE_CUDA20_EXTENSION_COMPILE_OPTION "-std=c++20") + endif() + endif() + else() set(CMAKE_CUDA03_STANDARD_COMPILE_OPTION "") set(CMAKE_CUDA03_EXTENSION_COMPILE_OPTION "") @@ -125,17 +145,26 @@ else() set(CMAKE_CUDA17_EXTENSION_COMPILE_OPTION "-std=c++17") endif() -endif() + if (NOT CMAKE_CUDA_COMPILER_VERSION VERSION_LESS 12.0) + set(CMAKE_CUDA20_STANDARD_COMPILE_OPTION "-std=c++20") + set(CMAKE_CUDA20_EXTENSION_COMPILE_OPTION "-std=c++20") + endif() -# FIXME: investigate use of --options-file. -# Tell Makefile generator that nvcc does not support @<rspfile> syntax. -set(CMAKE_CUDA_USE_RESPONSE_FILE_FOR_INCLUDES 0) -set(CMAKE_CUDA_USE_RESPONSE_FILE_FOR_LIBRARIES 0) -set(CMAKE_CUDA_USE_RESPONSE_FILE_FOR_OBJECTS 0) +endif() if (CMAKE_CUDA_COMPILER_VERSION VERSION_GREATER_EQUAL "9.0") set(CMAKE_CUDA_RESPONSE_FILE_DEVICE_LINK_FLAG "--options-file ") set(CMAKE_CUDA_RESPONSE_FILE_FLAG "--options-file ") endif() +if (CMAKE_CUDA_COMPILER_VERSION VERSION_GREATER_EQUAL "11.0") + set(CMAKE_CUDA_USE_RESPONSE_FILE_FOR_INCLUDES 1) + set(CMAKE_CUDA_USE_RESPONSE_FILE_FOR_LIBRARIES 1) + set(CMAKE_CUDA_USE_RESPONSE_FILE_FOR_OBJECTS 1) +else() + set(CMAKE_CUDA_USE_RESPONSE_FILE_FOR_INCLUDES 0) + set(CMAKE_CUDA_USE_RESPONSE_FILE_FOR_LIBRARIES 0) + set(CMAKE_CUDA_USE_RESPONSE_FILE_FOR_OBJECTS 0) +endif() + __compiler_check_default_language_standard(CUDA 6.0 03) diff --git a/Modules/Compiler/QCC.cmake b/Modules/Compiler/QCC.cmake index 7fbfd10..b720dc1 100644 --- a/Modules/Compiler/QCC.cmake +++ b/Modules/Compiler/QCC.cmake @@ -22,13 +22,15 @@ macro(__compiler_qcc lang) set(_CMAKE_${lang}_IPO_SUPPORTED_BY_CMAKE NO) set(_CMAKE_${lang}_IPO_MAY_BE_SUPPORTED_BY_COMPILER NO) - set(CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND "${CMAKE_${lang}_COMPILER}") - if(CMAKE_${lang}_COMPILER_ARG1) - separate_arguments(_COMPILER_ARGS NATIVE_COMMAND "${CMAKE_${lang}_COMPILER_ARG1}") - list(APPEND CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND ${_COMPILER_ARGS}) - unset(_COMPILER_ARGS) + if("${lang}" STREQUAL "CXX") + set(CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND "${CMAKE_${lang}_COMPILER}") + if(CMAKE_${lang}_COMPILER_ARG1) + separate_arguments(_COMPILER_ARGS NATIVE_COMMAND "${CMAKE_${lang}_COMPILER_ARG1}") + list(APPEND CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND ${_COMPILER_ARGS}) + unset(_COMPILER_ARGS) + endif() + list(APPEND CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND "-Wp,-dM" "-E" "-c" "${CMAKE_ROOT}/Modules/CMakeCXXCompilerABI.cpp") endif() - list(APPEND CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND "-Wp,-dM" "-E" "-c" "${CMAKE_ROOT}/Modules/CMakeCXXCompilerABI.cpp") unset(CMAKE_${lang}_COMPILE_OPTIONS_IPO) unset(CMAKE_${lang}_ARCHIVE_CREATE_IPO) diff --git a/Modules/Compiler/SunPro-ASM.cmake b/Modules/Compiler/SunPro-ASM.cmake index 0d67400..fc0f2fa 100644 --- a/Modules/Compiler/SunPro-ASM.cmake +++ b/Modules/Compiler/SunPro-ASM.cmake @@ -1,3 +1,6 @@ +include(Compiler/SunPro) +__compiler_sunpro(ASM) + set(CMAKE_ASM_SOURCE_FILE_EXTENSIONS s ) set(CMAKE_ASM_VERBOSE_FLAG "-#") diff --git a/Modules/Compiler/SunPro-C.cmake b/Modules/Compiler/SunPro-C.cmake index c98656f..b06719d 100644 --- a/Modules/Compiler/SunPro-C.cmake +++ b/Modules/Compiler/SunPro-C.cmake @@ -2,6 +2,7 @@ # file Copyright.txt or https://cmake.org/licensing for details. include(Compiler/SunPro) +__compiler_sunpro(C) set(CMAKE_C_VERBOSE_FLAG "-#") @@ -33,8 +34,13 @@ foreach(type SHARED_LIBRARY SHARED_MODULE EXE) set(CMAKE_${type}_LINK_DYNAMIC_C_FLAGS "-Bdynamic") endforeach() -set(CMAKE_C_LINKER_WRAPPER_FLAG "-Qoption" "ld" " ") -set(CMAKE_C_LINKER_WRAPPER_FLAG_SEP ",") +if (CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL "5.12") + set(CMAKE_C_LINKER_WRAPPER_FLAG "-Qoption" "ld" " ") + set(CMAKE_C_LINKER_WRAPPER_FLAG_SEP ",") +else() + set(CMAKE_C_LINKER_WRAPPER_FLAG "-Wl,") + set(CMAKE_C_LINKER_WRAPPER_FLAG_SEP ",") +endif() if (CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 5.13) set(CMAKE_C90_STANDARD_COMPILE_OPTION "-std=c89") diff --git a/Modules/Compiler/SunPro-CXX.cmake b/Modules/Compiler/SunPro-CXX.cmake index aa8a9c5..f835f2d 100644 --- a/Modules/Compiler/SunPro-CXX.cmake +++ b/Modules/Compiler/SunPro-CXX.cmake @@ -2,6 +2,7 @@ # file Copyright.txt or https://cmake.org/licensing for details. include(Compiler/SunPro) +__compiler_sunpro(CXX) set(CMAKE_CXX_VERBOSE_FLAG "-v") diff --git a/Modules/Compiler/SunPro-Fortran.cmake b/Modules/Compiler/SunPro-Fortran.cmake index 0ba5015..d336980 100644 --- a/Modules/Compiler/SunPro-Fortran.cmake +++ b/Modules/Compiler/SunPro-Fortran.cmake @@ -1,3 +1,6 @@ +include(Compiler/SunPro) +__compiler_sunpro(Fortran) + set(CMAKE_Fortran_VERBOSE_FLAG "-v") set(CMAKE_Fortran_FORMAT_FIXED_FLAG "-fixed") set(CMAKE_Fortran_FORMAT_FREE_FLAG "-free") diff --git a/Modules/Compiler/SunPro.cmake b/Modules/Compiler/SunPro.cmake index 52da39a..331cdfc 100644 --- a/Modules/Compiler/SunPro.cmake +++ b/Modules/Compiler/SunPro.cmake @@ -8,3 +8,7 @@ endif() set(__COMPILER_SUNPRO 1) include(Compiler/CMakeCommonCompilerMacros) + +macro(__compiler_sunpro lang) + set(CMAKE_${lang}_COMPILE_OPTIONS_WARNING_AS_ERROR "-errwarn=%all") +endmacro() diff --git a/Modules/Compiler/TI.cmake b/Modules/Compiler/TI.cmake index 0f9ded3..6cb115b 100644 --- a/Modules/Compiler/TI.cmake +++ b/Modules/Compiler/TI.cmake @@ -15,6 +15,7 @@ set(__COMPILER_TI_SOURCE_FLAG_CXX "--cpp_file") set(__COMPILER_TI_SOURCE_FLAG_ASM "--asm_file") macro(__compiler_ti lang) + set(CMAKE_${lang}_COMPILE_OPTIONS_WARNING_AS_ERROR "--emit_warnings_as_errors") set(CMAKE_${lang}_RESPONSE_FILE_FLAG "--cmd_file=") # Using --cmd_file flag is not possible after the --run_linker flag. # By using a whitespace only the filename is used without flag. diff --git a/Modules/Compiler/Tasking-ASM.cmake b/Modules/Compiler/Tasking-ASM.cmake new file mode 100644 index 0000000..19bce19 --- /dev/null +++ b/Modules/Compiler/Tasking-ASM.cmake @@ -0,0 +1,7 @@ +include(Compiler/Tasking) + +set(CMAKE_ASM_OUTPUT_EXTENSION ".o") +set(CMAKE_ASM_OUTPUT_EXTENSION_REPLACE 1) + +set(CMAKE_ASM_COMPILE_OBJECT "<CMAKE_ASM_COMPILER> <INCLUDES> <FLAGS> -o <OBJECT> <SOURCE>") +set(CMAKE_ASM_SOURCE_FILE_EXTENSIONS S;s;asm;msa) diff --git a/Modules/Compiler/Tasking-C.cmake b/Modules/Compiler/Tasking-C.cmake new file mode 100644 index 0000000..0ea3cd2 --- /dev/null +++ b/Modules/Compiler/Tasking-C.cmake @@ -0,0 +1,47 @@ +include(Compiler/Tasking) +__compiler_tasking(C) + +set(CMAKE_C90_STANDARD_COMPILE_OPTION "--iso=90" "--strict") +set(CMAKE_C90_EXTENSION_COMPILE_OPTION "--iso=90" " ") + +set(CMAKE_C99_STANDARD_COMPILE_OPTION "--iso=99" "--strict") +set(CMAKE_C99_EXTENSION_COMPILE_OPTION "--iso=99" " ") + +set(CMAKE_C11_STANDARD_COMPILE_OPTION "--iso=11" "--strict") +set(CMAKE_C11_EXTENSION_COMPILE_OPTION "--iso=11" " ") + +if(CMAKE_C_COMPILER_ARCHITECTURE_ID STREQUAL "TriCore") + if(CMAKE_TASKING_TOOLSET STREQUAL "SmartCode") + __compiler_check_default_language_standard(C 10.1 11) + else() + __compiler_check_default_language_standard(C 6.3 11) + endif() +elseif(CMAKE_C_COMPILER_ARCHITECTURE_ID STREQUAL "ARM") + if(CMAKE_TASKING_TOOLSET STREQUAL "SmartCode") + __compiler_check_default_language_standard(C 10.1 11) + elseif(CMAKE_TASKING_TOOLSET STREQUAL "TriCore") + __compiler_check_default_language_standard(C 6.3 11) + else() + __compiler_check_default_language_standard(C 6.0 11) + endif() +elseif(CMAKE_C_COMPILER_ARCHITECTURE_ID STREQUAL "MCS") + if(CMAKE_TASKING_TOOLSET STREQUAL "SmartCode") + __compiler_check_default_language_standard(C 10.1 11) + elseif(CMAKE_TASKING_TOOLSET STREQUAL "TriCore") + __compiler_check_default_language_standard(C 6.3 11) + else() + __compiler_check_default_language_standard(C 3.3 11) + endif() +elseif(CMAKE_C_COMPILER_ARCHITECTURE_ID STREQUAL "ARC") + __compiler_check_default_language_standard(C 10.1 11) +elseif(CMAKE_C_COMPILER_ARCHITECTURE_ID STREQUAL "8051") + if(CMAKE_TASKING_TOOLSET STREQUAL "SmartCode") + __compiler_check_default_language_standard(C 10.1 11) + elseif(CMAKE_TASKING_TOOLSET STREQUAL "TriCore") + __compiler_check_default_language_standard(C 6.3 11) + else() + __compiler_check_default_language_standard(C 7.2 89) + endif() +elseif(CMAKE_C_COMPILER_ARCHITECTURE_ID STREQUAL "PCP") + __compiler_check_default_language_standard(C 6.3 11) +endif() diff --git a/Modules/Compiler/Tasking-CXX.cmake b/Modules/Compiler/Tasking-CXX.cmake new file mode 100644 index 0000000..635104c --- /dev/null +++ b/Modules/Compiler/Tasking-CXX.cmake @@ -0,0 +1,31 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. +include(Compiler/Tasking) +__compiler_tasking(CXX) + +set(CMAKE_CXX98_STANDARD_COMPILE_OPTION "--c++=03" "--strict") +set(CMAKE_CXX98_EXTENSION_COMPILE_OPTION "--iso=03" " ") + +set(CMAKE_CXX11_STANDARD_COMPILE_OPTION "--c++=11" "--strict") +set(CMAKE_CXX11_EXTENSION_COMPILE_OPTION "--c++=11" " ") + +set(CMAKE_CXX14_STANDARD_COMPILE_OPTION "--c++=14" "--strict") +set(CMAKE_CXX14_EXTENSION_COMPILE_OPTION "--c++=14" " ") + +if(CMAKE_CXX_COMPILER_ARCHITECTURE_ID STREQUAL "TriCore") + if(CMAKE_TASKING_TOOLSET STREQUAL "SmartCode") + __compiler_check_default_language_standard(CXX 10.1 14) + else() + __compiler_check_default_language_standard(CXX 6.3 14) + endif() +elseif(CMAKE_CXX_COMPILER_ARCHITECTURE_ID STREQUAL "ARM") + if(CMAKE_TASKING_TOOLSET STREQUAL "SmartCode") + __compiler_check_default_language_standard(CXX 10.1 14) + elseif(CMAKE_TASKING_TOOLSET STREQUAL "TriCore") + __compiler_check_default_language_standard(CXX 6.3 14) + else() + __compiler_check_default_language_standard(CXX 6.0 14) + endif() +else() + message(FATAL_ERROR "CXX is not supported with the ${CMAKE_CXX_COMPILER_ARCHITECTURE_ID} architecture.") +endif() diff --git a/Modules/Compiler/Tasking-DetermineCompiler.cmake b/Modules/Compiler/Tasking-DetermineCompiler.cmake new file mode 100644 index 0000000..a40be19 --- /dev/null +++ b/Modules/Compiler/Tasking-DetermineCompiler.cmake @@ -0,0 +1,10 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. +set(_compiler_id_pp_test "defined(__TASKING__)") + +set(_compiler_id_version_compute " + # define @PREFIX@COMPILER_VERSION_MAJOR @MACRO_DEC@(__VERSION__/1000) + # define @PREFIX@COMPILER_VERSION_MINOR @MACRO_DEC@(__VERSION__ % 100)") + +string(APPEND _compiler_id_version_compute " +# define @PREFIX@COMPILER_VERSION_INTERNAL @MACRO_DEC@(__VERSION__)") diff --git a/Modules/Compiler/Tasking-FindBinUtils.cmake b/Modules/Compiler/Tasking-FindBinUtils.cmake new file mode 100644 index 0000000..eab31d7 --- /dev/null +++ b/Modules/Compiler/Tasking-FindBinUtils.cmake @@ -0,0 +1,18 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + +# Find the archiver for the compiler architecture, which is always in the same +# directory as the compiler. +if(NOT DEFINED _CMAKE_PROCESSING_LANGUAGE OR _CMAKE_PROCESSING_LANGUAGE STREQUAL "") + message(FATAL_ERROR "Internal error: _CMAKE_PROCESSING_LANGUAGE is not set") +endif() + +get_filename_component(__tasking_hints "${CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER}" DIRECTORY) + +find_program(CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_AR + NAMES artc ararm armcs ar51 ararc arpcp + HINTS ${__tasking_hints} + NO_CMAKE_PATH NO_CMAKE_ENVIRONMENT_PATH + DOC "Tasking Archiver" +) +mark_as_advanced(CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_AR) diff --git a/Modules/Compiler/Tasking.cmake b/Modules/Compiler/Tasking.cmake new file mode 100644 index 0000000..82622fa --- /dev/null +++ b/Modules/Compiler/Tasking.cmake @@ -0,0 +1,56 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + +# This module is shared by multiple languages; use include blocker. +if(_Tasking_CMAKE_LOADED) + return() +endif() +set(_Tasking_CMAKE_LOADED TRUE) +include(Compiler/CMakeCommonCompilerMacros) + +set(CMAKE_EXECUTABLE_SUFFIX ".elf") +set(CMAKE_STATIC_LIBRARY_SUFFIX ".a") +set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY) + +set_property(GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS FALSE) +set(BUILD_SHARED_LIBS FALSE CACHE BOOL "") +set(CMAKE_FIND_LIBRARY_SUFFIXES ".a") +set(CMAKE_LINK_SEARCH_START_STATIC TRUE) + +if(NOT CMAKE_TASKING_TOOLSET) + set(CMAKE_TASKING_TOOLSET "Standalone") +endif() + +macro(__compiler_tasking lang) + + set(CMAKE_${lang}_VERBOSE_FLAG "-v") + set(CMAKE_${lang}_COMPILE_OPTIONS_PIC "--pic") + set(CMAKE_${lang}_LINKER_WRAPPER_FLAG "-Wl" " ") + set(CMAKE_${lang}_RESPONSE_FILE_LINK_FLAG "-f ") + set(CMAKE_DEPFILE_FLAGS_${lang} "--dep-file=<DEP_FILE>") + set(CMAKE_${lang}_COMPILE_OPTIONS_WARNING_AS_ERROR "--warning-as-errors") + + string(APPEND CMAKE_${lang}_FLAGS_INIT " ") + string(APPEND CMAKE_${lang}_FLAGS_DEBUG_INIT " -O0 -g") + string(APPEND CMAKE_${lang}_FLAGS_MINSIZEREL_INIT " -O2 -t4 -DNDEBUG") + string(APPEND CMAKE_${lang}_FLAGS_RELEASE_INIT " -O2 -t2 -DNDEBUG") + string(APPEND CMAKE_${lang}_FLAGS_RELWITHDEBINFO_INIT " -O2 -t2 -g -DNDEBUG") + + set(CMAKE_${lang}_ARCHIVE_CREATE "\"${CMAKE_${lang}_COMPILER_AR}\" -r <TARGET> <OBJECTS>") + set(CMAKE_${lang}_ARCHIVE_APPEND "\"${CMAKE_${lang}_COMPILER_AR}\" -r <TARGET> <OBJECTS>") + set(CMAKE_${lang}_ARCHIVE_FINISH "") + + set(CMAKE_${lang}_CREATE_ASSEMBLY_SOURCE "<CMAKE_${lang}_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -cs <SOURCE> -o <ASSEMBLY_SOURCE>") + set(CMAKE_${lang}_CREATE_PREPROCESSED_SOURCE "<CMAKE_${lang}_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -Ep <SOURCE> > <PREPROCESSED_SOURCE>") + + if("${lang}" STREQUAL "CXX") + set(CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND "${CMAKE_${lang}_COMPILER}") + if(CMAKE_${lang}_COMPILER_ARG1) + separate_arguments(_COMPILER_ARGS NATIVE_COMMAND "${CMAKE_${lang}_COMPILER_ARG1}") + list(APPEND CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND ${_COMPILER_ARGS}) + unset(_COMPILER_ARGS) + endif() + list(APPEND CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND "-Ep" "${CMAKE_ROOT}/Modules/CMakeCXXCompilerABI.cpp") + endif() + +endmacro() diff --git a/Modules/Compiler/XL.cmake b/Modules/Compiler/XL.cmake index 8b9d4a9..844fcfd 100644 --- a/Modules/Compiler/XL.cmake +++ b/Modules/Compiler/XL.cmake @@ -15,6 +15,7 @@ macro(__compiler_xl lang) set(CMAKE_${lang}_VERBOSE_FLAG "-V") set(CMAKE_${lang}_COMPILE_OPTIONS_PIC "-qpic") set(CMAKE_${lang}_COMPILE_OPTIONS_PIE "-qpic") + set(CMAKE_${lang}_COMPILE_OPTIONS_WARNING_AS_ERROR "-qhalt=i") set(CMAKE_${lang}_RESPONSE_FILE_FLAG "-qoptfile=") set(CMAKE_${lang}_RESPONSE_FILE_LINK_FLAG "-qoptfile=") diff --git a/Modules/Compiler/XLClang.cmake b/Modules/Compiler/XLClang.cmake index cdf0fdc..8c3e5e9 100644 --- a/Modules/Compiler/XLClang.cmake +++ b/Modules/Compiler/XLClang.cmake @@ -17,6 +17,7 @@ macro(__compiler_xlclang lang) set(CMAKE_${lang}_VERBOSE_FLAG "-V") set(CMAKE_${lang}_COMPILE_OPTIONS_PIC "-fPIC") set(CMAKE_${lang}_COMPILE_OPTIONS_PIE "-fPIC") + set(CMAKE_${lang}_COMPILE_OPTIONS_WARNING_AS_ERROR "-Werror") set(CMAKE_${lang}_RESPONSE_FILE_FLAG "@") set(CMAKE_${lang}_RESPONSE_FILE_LINK_FLAG "@") endmacro() diff --git a/Modules/CompilerId/Xcode-3.pbxproj.in b/Modules/CompilerId/Xcode-3.pbxproj.in index 43e8cc8..543c6a9 100644 --- a/Modules/CompilerId/Xcode-3.pbxproj.in +++ b/Modules/CompilerId/Xcode-3.pbxproj.in @@ -83,6 +83,7 @@ buildSettings = { CODE_SIGNING_REQUIRED = NO; CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)"; + GENERATE_INFOPLIST_FILE = YES; SYMROOT = .; @id_archs@ @id_arch_active@ diff --git a/Modules/ExternalData.cmake b/Modules/ExternalData.cmake index 189374b..6826c7b 100644 --- a/Modules/ExternalData.cmake +++ b/Modules/ExternalData.cmake @@ -945,7 +945,7 @@ function(_ExternalData_link_or_copy src dst) file(CREATE_LINK "${tgt}" "${tmp}" RESULT result COPY_ON_ERROR SYMBOLIC) else() # Create a copy. - file(COPY_FILE "${src}" "${tmp}" RESULT result) + file(COPY_FILE "${src}" "${tmp}" RESULT result INPUT_MAY_BE_RECENT) endif() if(result) file(REMOVE "${tmp}") diff --git a/Modules/ExternalProject.cmake b/Modules/ExternalProject.cmake index cb62c99..b34a35b 100644 --- a/Modules/ExternalProject.cmake +++ b/Modules/ExternalProject.cmake @@ -170,6 +170,19 @@ External Project Definition the default name is generally suitable and is not normally used outside of code internal to the ``ExternalProject`` module. + ``DOWNLOAD_EXTRACT_TIMESTAMP <bool>`` + .. versionadded:: 3.24 + + When specified with a true value, the timestamps of the extracted + files will match those in the archive. When false, the timestamps of + the extracted files will reflect the time at which the extraction + was performed. If the download URL changes, timestamps based off + those in the archive can result in dependent targets not being rebuilt + when they potentially should have been. Therefore, unless the file + timestamps are significant to the project in some way, use a false + value for this option. If ``DOWNLOAD_EXTRACT_TIMESTAMP`` is not given, + the default is false. See policy :policy:`CMP0135`. + ``DOWNLOAD_NO_EXTRACT <bool>`` .. versionadded:: 3.6 @@ -231,9 +244,9 @@ External Project Definition .. versionadded:: 3.11 Specify whether the ``.netrc`` file is to be used for operation. - If this option is not specified, the value of the :variable:`CMAKE_NETRC` - variable will be used instead (see :command:`file(DOWNLOAD)`) - Valid levels are: + If this option is not specified, the value of the + :variable:`CMAKE_NETRC` variable will be used instead + (see :command:`file(DOWNLOAD)`). Valid levels are: ``IGNORED`` The ``.netrc`` file is ignored. @@ -288,6 +301,9 @@ External Project Definition If ``GIT_SHALLOW`` is enabled then ``GIT_TAG`` works only with branch names and tags. A commit hash is not allowed. + Note that if not provided, ``GIT_TAG`` defaults to ``master``, not the + default Git branch name. + ``GIT_REMOTE_NAME <name>`` The optional name of the remote. If this option is not specified, it defaults to ``origin``. @@ -353,6 +369,10 @@ External Project Definition When ``GIT_REMOTE_UPDATE_STRATEGY`` is not present, this is the default strategy unless the default has been overridden with ``CMAKE_EP_GIT_REMOTE_UPDATE_STRATEGY`` (see below). + Note that if the branch specified in ``GIT_TAG`` is different to + the upstream branch currently being tracked, it is not safe to + perform a rebase. In that situation, ``REBASE`` will silently be + treated as ``CHECKOUT`` instead. ``REBASE_CHECKOUT`` Same as ``REBASE`` except if the rebase fails, an annotated tag will @@ -369,8 +389,9 @@ External Project Definition override the default strategy. This variable should not be set by a project, it is intended for the user to set. It is primarily intended for use in continuous integration scripts to ensure that when history - is rewritten on a remote branch, the build doesn't end up with unintended - changes or failed builds resulting from conflicts during rebase operations. + is rewritten on a remote branch, the build doesn't end up with + unintended changes or failed builds resulting from conflicts during + rebase operations. *Subversion* ``SVN_REPOSITORY <url>`` @@ -504,13 +525,14 @@ External Project Definition option without the ``CMAKE_GENERATOR`` option. ``CMAKE_ARGS <arg>...`` - The specified arguments are passed to the ``cmake`` command line. They - can be any argument the ``cmake`` command understands, not just cache - values defined by ``-D...`` arguments (see also + The specified arguments are passed to the :program:`cmake` command line. + They can be any argument the :program:`cmake` command understands, not just + cache values defined by ``-D...`` arguments (see also :manual:`CMake Options <cmake(1)>`). .. versionadded:: 3.3 - Arguments may use :manual:`generator expressions <cmake-generator-expressions(7)>`. + Arguments may use + :manual:`generator expressions <cmake-generator-expressions(7)>`. ``CMAKE_CACHE_ARGS <arg>...`` This is an alternate way of specifying cache variables where command line @@ -521,7 +543,8 @@ External Project Definition using the :manual:`cmake -C <cmake(1)>` command line option. .. versionadded:: 3.3 - Arguments may use :manual:`generator expressions <cmake-generator-expressions(7)>`. + Arguments may use + :manual:`generator expressions <cmake-generator-expressions(7)>`. ``CMAKE_CACHE_DEFAULT_ARGS <arg>...`` .. versionadded:: 3.2 @@ -534,7 +557,7 @@ External Project Definition build directory or re-uses previous build contents. .. versionadded:: 3.15 - If the CMake generator is the ``Green Hills MULTI`` and not overridden then + If the CMake generator is the ``Green Hills MULTI`` and not overridden, the original project's settings for the GHS toolset and target system customization cache variables are propagated into the external project. @@ -588,9 +611,9 @@ External Project Definition supported). If this option is not given, the default build command will be chosen to integrate with the main build in the most appropriate way (e.g. using recursive ``make`` for Makefile generators or - ``cmake --build`` if the project uses a CMake build). This option can be - specified with an empty string as the command to make the build step do - nothing. + :option:`cmake --build` if the project uses a CMake build). This option + can be specified with an empty string as the command to make the build + step do nothing. ``BUILD_IN_SOURCE <bool>`` When this option is enabled, the build will be done directly within the @@ -614,8 +637,11 @@ External Project Definition Specifies files that will be generated by the build command but which might or might not have their modification time updated by subsequent - builds. These ultimately get passed through as ``BYPRODUCTS`` to the - build step's own underlying call to :command:`add_custom_command`. + builds. This may also be required to explicitly declare dependencies + when using the :generator:`Ninja` generator. + These ultimately get passed through as ``BYPRODUCTS`` to the + build step's own underlying call to :command:`add_custom_command`, which + has additional documentation. **Install Step Options:** If the configure step assumed the external project uses CMake as its build @@ -638,6 +664,17 @@ External Project Definition supported). Passing an empty string as the ``<cmd>`` makes the install step do nothing. + ``INSTALL_BYPRODUCTS <file>...`` + .. versionadded:: 3.26 + + Specifies files that will be generated by the install command but which + might or might not have their modification time updated by subsequent + installs. This may also be required to explicitly declare dependencies + when using the :generator:`Ninja` generator. + These ultimately get passed through as ``BYPRODUCTS`` to the + install step's own underlying call to :command:`add_custom_command`, which + has additional documentation. + .. 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 @@ -920,9 +957,12 @@ control needed to implement such step-level capabilities. .. versionadded:: 3.2 Files that will be generated by this custom step but which might or might - not have their modification time updated by subsequent builds. This list of + not have their modification time updated by subsequent builds. + This may also be required to explicitly declare dependencies + when using the :generator:`Ninja` generator. This list of files will ultimately be passed through as the ``BYPRODUCTS`` option to the - :command:`add_custom_command` used to implement the custom step internally. + :command:`add_custom_command` used to implement the custom step internally, + which has additional documentation. ``ALWAYS <bool>`` When enabled, this option specifies that the custom step should always be @@ -1000,9 +1040,9 @@ control needed to implement such step-level capabilities. .. versionadded:: 3.19 If :policy:`CMP0114` is set to ``NEW``, step targets are fully responsible - for holding the custom commands implementing their steps. The primary target - created by ``ExternalProject_Add`` depends on the step targets, and the - step targets depend on each other. The target-level dependencies match + for holding the custom commands implementing their steps. The primary + target created by ``ExternalProject_Add`` depends on the step targets, and + the step targets depend on each other. The target-level dependencies match the file-level dependencies used by the custom commands for each step. The targets for steps created with :command:`ExternalProject_Add_Step`'s ``INDEPENDENT`` option do not depend on the external targets specified @@ -1014,16 +1054,16 @@ control needed to implement such step-level capabilities. * A deprecated ``NO_DEPENDS`` option may be specified immediately after the ``<name>`` and before the first step. - If the ``NO_DEPENDS`` option is specified, the step target will not depend on - the dependencies of the external project (i.e. on any dependencies of the + If the ``NO_DEPENDS`` option is specified, the step target will not depend + on the dependencies of the external project (i.e. on any dependencies of the ``<name>`` custom target created by :command:`ExternalProject_Add`). This is - usually safe for the ``download``, ``update`` and ``patch`` steps, since they - do not typically require that the dependencies are updated and built. Using - ``NO_DEPENDS`` for any of the other pre-defined steps, however, may break - parallel builds. Only use ``NO_DEPENDS`` where it is certain that the named - steps genuinely do not have dependencies. For custom steps, consider whether - or not the custom commands require the dependencies to be configured, built - and installed. + usually safe for the ``download``, ``update`` and ``patch`` steps, since + they do not typically require that the dependencies are updated and built. + Using ``NO_DEPENDS`` for any of the other pre-defined steps, however, may + break parallel builds. Only use ``NO_DEPENDS`` where it is certain that the + named steps genuinely do not have dependencies. For custom steps, consider + whether or not the custom commands require the dependencies to be + configured, built and installed. * The ``INDEPENDENT_STEP_TARGETS`` option for :command:`ExternalProject_Add`, or the ``EP_INDEPENDENT_STEP_TARGETS`` directory property, tells the @@ -1173,7 +1213,13 @@ macro(_ep_get_hash_regex out_var) set(${out_var} "^(${${out_var}})=([0-9A-Fa-f]+)$") endmacro() -function(_ep_parse_arguments f keywords name ns args) +function(_ep_parse_arguments + f + keywords + name + ns + args +) # Transfer the arguments to this function into target properties for the # new custom target we just added so that we can set up all the build steps # correctly based on target properties. @@ -1189,7 +1235,8 @@ function(_ep_parse_arguments f keywords name ns args) set(is_value 1) if(arg MATCHES "^[A-Z][A-Z0-9_][A-Z0-9_]+$" AND - NOT (("x${arg}x" STREQUAL "x${key}x") AND ("x${key}x" STREQUAL "xCOMMANDx")) AND + NOT (("x${arg}x" STREQUAL "x${key}x") AND + ("x${key}x" STREQUAL "xCOMMANDx")) AND NOT arg MATCHES "^(TRUE|FALSE)$") if(arg IN_LIST keywords) set(is_value 0) @@ -1212,7 +1259,9 @@ function(_ep_parse_arguments f keywords name ns args) endif() else() # Missing Keyword - message(AUTHOR_WARNING "value '${arg}' with no previous keyword in ${f}") + message(AUTHOR_WARNING + "value '${arg}' with no previous keyword in ${f}" + ) endif() else() set(key "${arg}") @@ -1221,63 +1270,31 @@ function(_ep_parse_arguments f keywords name ns args) endfunction() -define_property(DIRECTORY PROPERTY "EP_BASE" INHERITED - BRIEF_DOCS "Base directory for External Project storage." - FULL_DOCS - "See documentation of the ExternalProject_Add() function in the " - "ExternalProject module." - ) - -define_property(DIRECTORY PROPERTY "EP_PREFIX" INHERITED - BRIEF_DOCS "Top prefix for External Project storage." - FULL_DOCS - "See documentation of the ExternalProject_Add() function in the " - "ExternalProject module." - ) - -define_property(DIRECTORY PROPERTY "EP_STEP_TARGETS" INHERITED - BRIEF_DOCS - "List of ExternalProject steps that automatically get corresponding targets" - FULL_DOCS - "These targets will be dependent on the main target dependencies. " - "See documentation of the ExternalProject_Add_StepTargets() function in the " - "ExternalProject module." - ) - -define_property(DIRECTORY PROPERTY "EP_INDEPENDENT_STEP_TARGETS" INHERITED - BRIEF_DOCS - "List of ExternalProject steps that automatically get corresponding targets" - FULL_DOCS - "These targets will not be dependent on the main target dependencies. " - "See documentation of the ExternalProject_Add_StepTargets() function in the " - "ExternalProject module." - ) - -define_property(DIRECTORY PROPERTY "EP_UPDATE_DISCONNECTED" INHERITED - BRIEF_DOCS "Never update automatically from the remote repo." - FULL_DOCS - "See documentation of the ExternalProject_Add() function in the " - "ExternalProject module." - ) +define_property(DIRECTORY PROPERTY "EP_BASE" INHERITED) +define_property(DIRECTORY PROPERTY "EP_PREFIX" INHERITED) +define_property(DIRECTORY PROPERTY "EP_STEP_TARGETS" INHERITED) +define_property(DIRECTORY PROPERTY "EP_INDEPENDENT_STEP_TARGETS" INHERITED) +define_property(DIRECTORY PROPERTY "EP_UPDATE_DISCONNECTED" INHERITED) function(_ep_write_gitclone_script - script_filename - source_dir - git_EXECUTABLE - git_repository - git_tag - git_remote_name - init_submodules - git_submodules_recurse - git_submodules - git_shallow - git_progress - git_config - src_name - work_dir - gitclone_infofile - gitclone_stampfile - tls_verify) + script_filename + source_dir + git_EXECUTABLE + git_repository + git_tag + git_remote_name + init_submodules + git_submodules_recurse + git_submodules + git_shallow + git_progress + git_config + src_name + work_dir + gitclone_infofile + gitclone_stampfile + tls_verify +) if(NOT GIT_VERSION_STRING VERSION_LESS 1.8.5) # Use `git checkout <tree-ish> --` to avoid ambiguity with a local path. @@ -1292,7 +1309,8 @@ function(_ep_write_gitclone_script message(FATAL_ERROR "Tag for git checkout should not be empty.") endif() - if(GIT_VERSION_STRING VERSION_LESS 2.20 OR 2.21 VERSION_LESS_EQUAL GIT_VERSION_STRING) + if(GIT_VERSION_STRING VERSION_LESS 2.20 OR + 2.21 VERSION_LESS_EQUAL GIT_VERSION_STRING) set(git_clone_options "--no-checkout") else() set(git_clone_options) @@ -1320,7 +1338,8 @@ function(_ep_write_gitclone_script # disable cert checking if explicitly told not to do it if(NOT "x${tls_verify}" STREQUAL "x" AND NOT tls_verify) set(git_options - -c http.sslVerify=false) + -c http.sslVerify=false + ) endif() string (REPLACE ";" " " git_options "${git_options}") @@ -1332,15 +1351,16 @@ function(_ep_write_gitclone_script endfunction() function(_ep_write_hgclone_script - script_filename - source_dir - hg_EXECUTABLE - hg_repository - hg_tag - src_name - work_dir - hgclone_infofile - hgclone_stampfile) + script_filename + source_dir + hg_EXECUTABLE + hg_repository + hg_tag + src_name + work_dir + hgclone_infofile + hgclone_stampfile +) if("${hg_tag}" STREQUAL "") message(FATAL_ERROR "Tag for hg checkout should not be empty.") @@ -1355,16 +1375,17 @@ endfunction() function(_ep_write_gitupdate_script - script_filename - git_EXECUTABLE - git_tag - git_remote_name - init_submodules - git_submodules_recurse - git_submodules - git_repository - work_dir - git_update_strategy) + script_filename + git_EXECUTABLE + git_tag + git_remote_name + init_submodules + git_submodules_recurse + git_submodules + git_repository + work_dir + git_update_strategy +) if("${git_tag}" STREQUAL "") message(FATAL_ERROR "Tag for git checkout should not be empty.") @@ -1386,20 +1407,20 @@ function(_ep_write_gitupdate_script endfunction() function(_ep_write_downloadfile_script - script_filename - REMOTE - LOCAL - timeout - inactivity_timeout - no_progress - hash - tls_verify - tls_cainfo - userpwd - http_headers - netrc - netrc_file) - + script_filename + REMOTE + LOCAL + timeout + inactivity_timeout + no_progress + hash + tls_verify + tls_cainfo + userpwd + http_headers + netrc + netrc_file +) if(timeout) set(TIMEOUT_ARGS TIMEOUT ${timeout}) set(TIMEOUT_MSG "${timeout} seconds") @@ -1482,9 +1503,8 @@ function(_ep_write_downloadfile_script set(HTTP_HEADERS_ARGS "") if(NOT http_headers STREQUAL "") foreach(header ${http_headers}) - set( - HTTP_HEADERS_ARGS - "HTTPHEADER \"${header}\"\n ${HTTP_HEADERS_ARGS}" + string(PREPEND HTTP_HEADERS_ARGS + "HTTPHEADER \"${header}\"\n " ) endforeach() endif() @@ -1502,13 +1522,17 @@ function(_ep_write_downloadfile_script # * USERPWD_ARGS # * HTTP_HEADERS_ARGS configure_file( - "${CMAKE_CURRENT_FUNCTION_LIST_DIR}/ExternalProject/download.cmake.in" - "${script_filename}" - @ONLY + "${CMAKE_CURRENT_FUNCTION_LIST_DIR}/ExternalProject/download.cmake.in" + "${script_filename}" + @ONLY ) endfunction() -function(_ep_write_verifyfile_script script_filename LOCAL hash) +function(_ep_write_verifyfile_script + script_filename + LOCAL + hash +) _ep_get_hash_regex(_ep_hash_regex) if("${hash}" MATCHES "${_ep_hash_regex}") set(ALGO "${CMAKE_MATCH_1}") @@ -1523,17 +1547,23 @@ function(_ep_write_verifyfile_script script_filename LOCAL hash) # * EXPECT_VALUE # * LOCAL configure_file( - "${CMAKE_CURRENT_FUNCTION_LIST_DIR}/ExternalProject/verify.cmake.in" - "${script_filename}" - @ONLY + "${CMAKE_CURRENT_FUNCTION_LIST_DIR}/ExternalProject/verify.cmake.in" + "${script_filename}" + @ONLY ) endfunction() -function(_ep_write_extractfile_script script_filename name filename directory) +function(_ep_write_extractfile_script + script_filename + name + filename + directory options +) set(args "") - if(filename MATCHES "(\\.|=)(7z|tar\\.bz2|tar\\.gz|tar\\.xz|tbz2|tgz|txz|zip)$") + if(filename MATCHES + "(\\.|=)(7z|tar\\.bz2|tar\\.gz|tar\\.xz|tbz2|tgz|txz|zip)$") set(args xfz) endif() @@ -1542,8 +1572,10 @@ function(_ep_write_extractfile_script script_filename name filename directory) endif() if(args STREQUAL "") - message(SEND_ERROR "error: do not know how to extract '${filename}' -- known types are .7z, .tar, .tar.bz2, .tar.gz, .tar.xz, .tbz2, .tgz, .txz and .zip") - return() + message(FATAL_ERROR + "Do not know how to extract '${filename}' -- known types are: " + ".7z, .tar, .tar.bz2, .tar.gz, .tar.xz, .tbz2, .tgz, .txz and .zip" + ) endif() configure_file( @@ -1587,7 +1619,8 @@ function(_ep_set_directories name) get_property(have_binary_dir TARGET ${name} PROPERTY _EP_BINARY_DIR SET) if(have_binary_dir) message(FATAL_ERROR - "External project ${name} has both BINARY_DIR and BUILD_IN_SOURCE!") + "External project ${name} has both BINARY_DIR and BUILD_IN_SOURCE!" + ) endif() endif() set(top "${CMAKE_CURRENT_BINARY_DIR}") @@ -1623,7 +1656,8 @@ function(_ep_set_directories name) set_property(TARGET ${name} PROPERTY _EP_SOURCE_SUBDIR "") elseif(IS_ABSOLUTE "${source_subdir}") message(FATAL_ERROR - "External project ${name} has non-relative SOURCE_SUBDIR!") + "External project ${name} has non-relative SOURCE_SUBDIR!" + ) else() # Prefix with a slash so that when appended to the source directory, it # behaves as expected. @@ -1633,9 +1667,13 @@ function(_ep_set_directories name) if(build_in_source) get_property(source_dir TARGET ${name} PROPERTY _EP_SOURCE_DIR) if(source_subdir) - set_property(TARGET ${name} PROPERTY _EP_BINARY_DIR "${source_dir}/${source_subdir}") + set_property(TARGET ${name} PROPERTY + _EP_BINARY_DIR "${source_dir}/${source_subdir}" + ) else() - set_property(TARGET ${name} PROPERTY _EP_BINARY_DIR "${source_dir}") + set_property(TARGET ${name} PROPERTY + _EP_BINARY_DIR "${source_dir}" + ) endif() endif() @@ -1663,7 +1701,16 @@ macro(_ep_replace_location_tags target_name) set(vars ${ARGN}) foreach(var ${vars}) if(${var}) - foreach(dir SOURCE_DIR SOURCE_SUBDIR BINARY_DIR INSTALL_DIR TMP_DIR DOWNLOAD_DIR DOWNLOADED_FILE LOG_DIR) + foreach(dir + SOURCE_DIR + SOURCE_SUBDIR + BINARY_DIR + INSTALL_DIR + TMP_DIR + DOWNLOAD_DIR + DOWNLOADED_FILE + LOG_DIR + ) get_property(val TARGET ${target_name} PROPERTY _EP_${dir}) string(REPLACE "<${dir}>" "${val}" ${var} "${${var}}") endforeach() @@ -1672,7 +1719,11 @@ macro(_ep_replace_location_tags target_name) endmacro() -function(_ep_command_line_to_initial_cache var args force) +function(_ep_command_line_to_initial_cache + var + args + force +) set(script_initial_cache "") set(regex "^([^:]+):([^=]+)=(.*)$") set(setArg "") @@ -1685,7 +1736,9 @@ function(_ep_command_line_to_initial_cache var args force) set(line "${CMAKE_MATCH_1}") if(NOT "${setArg}" STREQUAL "") # This is required to build up lists in variables, or complete an entry - string(APPEND setArg "${accumulator}\" CACHE ${type} \"Initial cache\" ${forceArg})") + string(APPEND setArg + "${accumulator}\" CACHE ${type} \"Initial cache\" ${forceArg})" + ) string(APPEND script_initial_cache "\n${setArg}") set(accumulator "") set(setArg "") @@ -1705,14 +1758,20 @@ function(_ep_command_line_to_initial_cache var args force) endforeach() # Catch the final line of the args if(NOT "${setArg}" STREQUAL "") - string(APPEND setArg "${accumulator}\" CACHE ${type} \"Initial cache\" ${forceArg})") + string(APPEND setArg + "${accumulator}\" CACHE ${type} \"Initial cache\" ${forceArg})" + ) string(APPEND script_initial_cache "\n${setArg}") endif() set(${var} ${script_initial_cache} PARENT_SCOPE) endfunction() -function(_ep_write_initial_cache target_name script_filename script_initial_cache) +function(_ep_write_initial_cache + target_name + script_filename + script_initial_cache +) # Write out values into an initial cache, that will be passed to CMake with -C # Replace location tags. _ep_replace_location_tags(${target_name} script_initial_cache) @@ -1740,7 +1799,10 @@ function(ExternalProject_Get_Property name) endfunction() -function(_ep_get_configure_command_id name cfg_cmd_id_var) +function(_ep_get_configure_command_id + name + cfg_cmd_id_var +) get_target_property(cmd ${name} _EP_CONFIGURE_COMMAND) if(cmd STREQUAL "") @@ -1766,7 +1828,11 @@ function(_ep_get_configure_command_id name cfg_cmd_id_var) endfunction() -function(_ep_get_build_command name step cmd_var) +function(_ep_get_build_command + name + step + cmd_var +) set(cmd "") set(args) _ep_get_configure_command_id(${name} cfg_cmd_id) @@ -1804,8 +1870,10 @@ function(_ep_get_build_command name step cmd_var) # BUILD_COMMAND to change the default command instead, but for # compatibility honor the value. set(config ${CMAKE_CFG_INTDIR}) - message(AUTHOR_WARNING "CMAKE_CFG_INTDIR should not be set by project code.\n" - "To get a non-default build command, use the BUILD_COMMAND option.") + message(AUTHOR_WARNING + "CMAKE_CFG_INTDIR should not be set by project code.\n" + "To get a non-default build command, use the BUILD_COMMAND option." + ) else() set(config $<CONFIG>) endif() @@ -1853,7 +1921,11 @@ function(_ep_get_build_command name step cmd_var) set(${cmd_var} "${cmd}" PARENT_SCOPE) endfunction() -function(_ep_write_log_script name step cmd_var) +function(_ep_write_log_script + name + step + cmd_var +) ExternalProject_Get_Property(${name} log_dir) ExternalProject_Get_Property(${name} stamp_dir) set(command "${${cmd_var}}") @@ -1920,15 +1992,29 @@ endif() endif() endforeach() string(APPEND code "set(command \"${cmd}\")${code_execute_process}") - file(GENERATE OUTPUT "${stamp_dir}/${name}-${step}-$<CONFIG>-impl.cmake" CONTENT "${code}") - set(command ${CMAKE_COMMAND} "-Dmake=\${make}" "-Dconfig=\${config}" -P ${stamp_dir}/${name}-${step}-$<CONFIG>-impl.cmake) + file(GENERATE + OUTPUT "${stamp_dir}/${name}-${step}-$<CONFIG>-impl.cmake" + CONTENT "${code}" + ) + set(command + ${CMAKE_COMMAND} + "-Dmake=\${make}" + "-Dconfig=\${config}" + -P ${stamp_dir}/${name}-${step}-$<CONFIG>-impl.cmake + ) endif() # Wrap the command in a script to log output to files. set(script ${stamp_dir}/${name}-${step}-$<CONFIG>.cmake) set(logbase ${log_dir}/${name}-${step}) - get_property(log_merged TARGET ${name} PROPERTY _EP_LOG_MERGED_STDOUTERR) - get_property(log_output_on_failure TARGET ${name} PROPERTY _EP_LOG_OUTPUT_ON_FAILURE) + get_property(log_merged + TARGET ${name} + PROPERTY _EP_LOG_MERGED_STDOUTERR + ) + get_property(log_output_on_failure + TARGET ${name} + PROPERTY _EP_LOG_OUTPUT_ON_FAILURE + ) if (log_merged) set(stdout_log "${logbase}.log") set(stderr_log "${logbase}.log") @@ -1949,7 +2035,7 @@ execute_process( RESULT_VARIABLE result OUTPUT_FILE \"\${stdout_log}\" ERROR_FILE \"\${stderr_log}\" - ) +) macro(read_up_to_max_size log_file output_var) file(SIZE \${log_file} determined_size) set(max_size 10240) @@ -1998,44 +2084,55 @@ endif() set(${cmd_var} "${command}" PARENT_SCOPE) endfunction() -# This module used to use "/${CMAKE_CFG_INTDIR}" directly and produced -# makefiles with "/./" in paths for custom command dependencies. Which -# resulted in problems with parallel make -j invocations. -# -# This function was added so that the suffix (search below for ${cfgdir}) is -# only set to "/${CMAKE_CFG_INTDIR}" when ${CMAKE_CFG_INTDIR} is not going to -# be "." (multi-configuration build systems like Visual Studio and Xcode...) -# -function(_ep_get_configuration_subdir_suffix suffix_var) +# On multi-config generators, provide a placeholder for a per-config subdir. +# On single-config generators, this is empty. +function(_ep_get_configuration_subdir_genex suffix_var) set(suffix "") get_property(_isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) if(_isMultiConfig) - set(suffix "/${CMAKE_CFG_INTDIR}") + if(CMAKE_GENERATOR STREQUAL "Xcode") + # The Xcode generator does not support per-config sources, + # so use the underlying build system's placeholder instead. + set(suffix "/${CMAKE_CFG_INTDIR}") + else() + set(suffix "/$<CONFIG>") + endif() endif() set(${suffix_var} "${suffix}" PARENT_SCOPE) endfunction() -function(_ep_get_step_stampfile name step stampfile_var) +function(_ep_get_step_stampfile + name + step + stampfile_var +) ExternalProject_Get_Property(${name} stamp_dir) - _ep_get_configuration_subdir_suffix(cfgdir) + _ep_get_configuration_subdir_genex(cfgdir) set(stampfile "${stamp_dir}${cfgdir}/${name}-${step}") set(${stampfile_var} "${stampfile}" PARENT_SCOPE) endfunction() -function(_ep_get_complete_stampfile name stampfile_var) +function(_ep_get_complete_stampfile + name + stampfile_var +) set(cmf_dir ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles) - _ep_get_configuration_subdir_suffix(cfgdir) + _ep_get_configuration_subdir_genex(cfgdir) set(stampfile "${cmf_dir}${cfgdir}/${name}-complete") set(${stampfile_var} ${stampfile} PARENT_SCOPE) endfunction() -function(_ep_step_add_target name step no_deps) +function(_ep_step_add_target + name + step + no_deps +) if(TARGET ${name}-${step}) return() endif() @@ -2047,16 +2144,20 @@ function(_ep_step_add_target name step no_deps) # we need CMP0113 NEW behavior. cmake_policy(SET CMP0113 NEW) endif() - add_custom_target(${name}-${step} - DEPENDS ${stamp_file}) + add_custom_target(${name}-${step} DEPENDS ${stamp_file}) cmake_policy(POP) - set_property(TARGET ${name}-${step} PROPERTY _EP_IS_EXTERNAL_PROJECT_STEP 1) - set_property(TARGET ${name}-${step} PROPERTY LABELS ${name}) - set_property(TARGET ${name}-${step} PROPERTY FOLDER "ExternalProjectTargets/${name}") + set_target_properties(${name}-${step} PROPERTIES + _EP_IS_EXTERNAL_PROJECT_STEP 1 + LABELS "${name}" + FOLDER "ExternalProjectTargets/${name}" + ) if(cmp0114 STREQUAL "NEW") # Add target-level dependencies for the step. - get_property(exclude_from_main TARGET ${name} PROPERTY _EP_${step}_EXCLUDE_FROM_MAIN) + get_property(exclude_from_main + TARGET ${name} + PROPERTY _EP_${step}_EXCLUDE_FROM_MAIN + ) if(NOT exclude_from_main) add_dependencies(${name} ${name}-${step}) endif() @@ -2066,7 +2167,9 @@ function(_ep_step_add_target name step no_deps) get_property(independent TARGET ${name} PROPERTY _EP_${step}_INDEPENDENT) else() if(no_deps AND "${step}" MATCHES "^(configure|build|install|test)$") - message(AUTHOR_WARNING "Using NO_DEPENDS for \"${step}\" step might break parallel builds") + message(AUTHOR_WARNING + "Using NO_DEPENDS for \"${step}\" step might break parallel builds" + ) endif() set(independent ${no_deps}) endif() @@ -2081,12 +2184,25 @@ function(_ep_step_add_target name step no_deps) endfunction() -function(_ep_step_add_target_dependencies name step node) - get_property(dependees TARGET ${name} PROPERTY _EP_${node}_INTERNAL_DEPENDEES) +function(_ep_step_add_target_dependencies + name + step + node +) + get_property(dependees + TARGET ${name} + PROPERTY _EP_${node}_INTERNAL_DEPENDEES + ) list(REMOVE_DUPLICATES dependees) foreach(dependee IN LISTS dependees) - get_property(exclude_from_main TARGET ${name} PROPERTY _EP_${step}_EXCLUDE_FROM_MAIN) - get_property(dependee_dependers TARGET ${name} PROPERTY _EP_${dependee}_INTERNAL_DEPENDERS) + get_property(exclude_from_main + TARGET ${name} + PROPERTY _EP_${step}_EXCLUDE_FROM_MAIN + ) + get_property(dependee_dependers + TARGET ${name} + PROPERTY _EP_${dependee}_INTERNAL_DEPENDERS + ) if(exclude_from_main OR dependee_dependers MATCHES ";") # The step on which our step target depends itself has # dependents in multiple targes. It needs a step target too @@ -2103,8 +2219,15 @@ function(_ep_step_add_target_dependencies name step node) endfunction() -function(_ep_step_add_target_dependents name step node) - get_property(dependers TARGET ${name} PROPERTY _EP_${node}_INTERNAL_DEPENDERS) +function(_ep_step_add_target_dependents + name + step + node +) + get_property(dependers + TARGET ${name} + PROPERTY _EP_${node}_INTERNAL_DEPENDERS + ) list(REMOVE_DUPLICATES dependers) foreach(depender IN LISTS dependers) if(TARGET ${name}-${depender}) @@ -2131,7 +2254,7 @@ function(ExternalProject_Add_StepTargets name) "The 'NO_DEPENDS' option is no longer allowed. " "It has been superseded by the per-step 'INDEPENDENT' option. " "See policy CMP0114." - ) + ) endif() elseif(cmp0114 STREQUAL "") cmake_policy(GET_WARNING CMP0114 _cmp0114_warning) @@ -2139,11 +2262,11 @@ function(ExternalProject_Add_StepTargets name) "ExternalProject target '${name}' would depend on the targets for " "step(s) '${steps}' under policy CMP0114, but this is being left out " "for compatibility since the policy is not set." - ) + ) if(no_deps) - string(APPEND _cmp0114_warning - " Also, the NO_DEPENDS option is deprecated in favor of policy CMP0114." - ) + string(APPEND _cmp0114_warning " " + "Also, the NO_DEPENDS option is deprecated in favor of policy CMP0114." + ) endif() message(AUTHOR_WARNING "${_cmp0114_warning}") endif() @@ -2172,38 +2295,60 @@ function(ExternalProject_Add_Step name step) LOG USES_TERMINAL ) - _ep_parse_arguments(ExternalProject_Add_Step "${keywords}" - ${name} _EP_${step}_ "${ARGN}") + _ep_parse_arguments( + ExternalProject_Add_Step + "${keywords}" + ${name} + _EP_${step}_ + "${ARGN}" + ) - get_property(independent TARGET ${name} PROPERTY _EP_${step}_INDEPENDENT) + get_property(independent + TARGET ${name} + PROPERTY _EP_${step}_INDEPENDENT + ) if(independent STREQUAL "") set(independent FALSE) - set_property(TARGET ${name} PROPERTY _EP_${step}_INDEPENDENT "${independent}") + set_property(TARGET ${name} PROPERTY + _EP_${step}_INDEPENDENT "${independent}" + ) endif() - get_property(exclude_from_main TARGET ${name} PROPERTY _EP_${step}_EXCLUDE_FROM_MAIN) + get_property(exclude_from_main + TARGET ${name} + PROPERTY _EP_${step}_EXCLUDE_FROM_MAIN + ) if(NOT exclude_from_main) add_custom_command(APPEND OUTPUT ${complete_stamp_file} DEPENDS ${stamp_file} - ) + ) endif() # Steps depending on this step. get_property(dependers TARGET ${name} PROPERTY _EP_${step}_DEPENDERS) - set_property(TARGET ${name} APPEND PROPERTY _EP_${step}_INTERNAL_DEPENDERS ${dependers}) + set_property(TARGET ${name} APPEND PROPERTY + _EP_${step}_INTERNAL_DEPENDERS ${dependers} + ) foreach(depender IN LISTS dependers) - set_property(TARGET ${name} APPEND PROPERTY _EP_${depender}_INTERNAL_DEPENDEES ${step}) + set_property(TARGET ${name} APPEND PROPERTY + _EP_${depender}_INTERNAL_DEPENDEES ${step} + ) _ep_get_step_stampfile(${name} ${depender} depender_stamp_file) add_custom_command(APPEND OUTPUT ${depender_stamp_file} DEPENDS ${stamp_file} - ) + ) if(cmp0114 STREQUAL "NEW" AND NOT independent) - get_property(dep_independent TARGET ${name} PROPERTY _EP_${depender}_INDEPENDENT) + get_property(dep_independent + TARGET ${name} + PROPERTY _EP_${depender}_INDEPENDENT + ) if(dep_independent) - message(FATAL_ERROR "ExternalProject '${name}' step '${depender}' is marked INDEPENDENT " - "but depends on step '${step}' that is not marked INDEPENDENT.") + message(FATAL_ERROR + "ExternalProject '${name}' step '${depender}' is marked INDEPENDENT " + "but depends on step '${step}' that is not marked INDEPENDENT." + ) endif() endif() endforeach() @@ -2216,16 +2361,25 @@ function(ExternalProject_Add_Step name step) # Dependencies on steps. get_property(dependees TARGET ${name} PROPERTY _EP_${step}_DEPENDEES) - set_property(TARGET ${name} APPEND PROPERTY _EP_${step}_INTERNAL_DEPENDEES ${dependees}) + set_property(TARGET ${name} APPEND PROPERTY + _EP_${step}_INTERNAL_DEPENDEES ${dependees} + ) foreach(dependee IN LISTS dependees) - set_property(TARGET ${name} APPEND PROPERTY _EP_${dependee}_INTERNAL_DEPENDERS ${step}) + set_property(TARGET ${name} APPEND PROPERTY + _EP_${dependee}_INTERNAL_DEPENDERS ${step} + ) _ep_get_step_stampfile(${name} ${dependee} dependee_stamp_file) list(APPEND depends ${dependee_stamp_file}) if(cmp0114 STREQUAL "NEW" AND independent) - get_property(dep_independent TARGET ${name} PROPERTY _EP_${dependee}_INDEPENDENT) + get_property(dep_independent + TARGET ${name} + PROPERTY _EP_${dependee}_INDEPENDENT + ) if(NOT dep_independent) - message(FATAL_ERROR "ExternalProject '${name}' step '${step}' is marked INDEPENDENT " - "but depends on step '${dependee}' that is not marked INDEPENDENT.") + message(FATAL_ERROR + "ExternalProject '${name}' step '${step}' is marked INDEPENDENT " + "but depends on step '${dependee}' that is not marked INDEPENDENT." + ) endif() endif() endforeach() @@ -2237,25 +2391,47 @@ function(ExternalProject_Add_Step name step) else() set(comment "No ${step} step for '${name}'") endif() - get_property(work_dir TARGET ${name} PROPERTY _EP_${step}_WORKING_DIRECTORY) + get_property(work_dir + TARGET ${name} + PROPERTY _EP_${step}_WORKING_DIRECTORY + ) # Replace list separators. - get_property(sep TARGET ${name} PROPERTY _EP_LIST_SEPARATOR) + get_property(sep + TARGET ${name} + PROPERTY _EP_LIST_SEPARATOR + ) if(sep AND command) string(REPLACE "${sep}" "\\;" command "${command}") endif() # Replace location tags. - _ep_replace_location_tags(${name} comment command work_dir byproducts) + _ep_replace_location_tags( + ${name} + comment + command + work_dir + byproducts + ) # Custom comment? - get_property(comment_set TARGET ${name} PROPERTY _EP_${step}_COMMENT SET) + get_property(comment_set + TARGET ${name} + PROPERTY _EP_${step}_COMMENT + SET + ) if(comment_set) - get_property(comment TARGET ${name} PROPERTY _EP_${step}_COMMENT) + get_property(comment + TARGET ${name} + PROPERTY _EP_${step}_COMMENT + ) endif() # Uses terminal? - get_property(uses_terminal TARGET ${name} PROPERTY _EP_${step}_USES_TERMINAL) + get_property(uses_terminal + TARGET ${name} + PROPERTY _EP_${step}_USES_TERMINAL + ) if(uses_terminal) set(uses_terminal USES_TERMINAL) else() @@ -2263,18 +2439,30 @@ function(ExternalProject_Add_Step name step) endif() # Run every time? - get_property(always TARGET ${name} PROPERTY _EP_${step}_ALWAYS) + get_property(always + TARGET ${name} + PROPERTY _EP_${step}_ALWAYS + ) if(always) - set_property(SOURCE ${stamp_file} PROPERTY SYMBOLIC 1) set(touch) + # Mark stamp files for all configs as SYMBOLIC since we do not create them. # Remove any existing stamp in case the option changed in an existing tree. get_property(_isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) if(_isMultiConfig) + _ep_get_configuration_subdir_genex(cfgdir) foreach(cfg ${CMAKE_CONFIGURATION_TYPES}) - string(REPLACE "/${CMAKE_CFG_INTDIR}" "/${cfg}" stamp_file_config "${stamp_file}") + string(REPLACE "${cfgdir}" "/${cfg}" + stamp_file_config "${stamp_file}" + ) + set_property(SOURCE ${stamp_file_config} PROPERTY SYMBOLIC 1) file(REMOVE ${stamp_file_config}) endforeach() + if(CMAKE_GENERATOR STREQUAL "Xcode") + # See Xcode case in _ep_get_configuration_subdir_genex. + set_property(SOURCE ${stamp_file} PROPERTY SYMBOLIC 1) + endif() else() + set_property(SOURCE ${stamp_file} PROPERTY SYMBOLIC 1) file(REMOVE ${stamp_file}) endif() else() @@ -2316,9 +2504,15 @@ function(ExternalProject_Add_Step name step) set_property(TARGET ${name} APPEND PROPERTY _EP_STEPS ${step}) # Add custom "step target"? - get_property(step_targets TARGET ${name} PROPERTY _EP_STEP_TARGETS) + get_property(step_targets + TARGET ${name} + PROPERTY _EP_STEP_TARGETS + ) if(NOT step_targets) - get_property(step_targets DIRECTORY PROPERTY EP_STEP_TARGETS) + get_property(step_targets + DIRECTORY + PROPERTY EP_STEP_TARGETS + ) endif() foreach(st ${step_targets}) if("${st}" STREQUAL "${step}") @@ -2327,31 +2521,43 @@ function(ExternalProject_Add_Step name step) endif() endforeach() - get_property(independent_step_targets TARGET ${name} PROPERTY _EP_INDEPENDENT_STEP_TARGETS) + get_property(independent_step_targets + TARGET ${name} PROPERTY + _EP_INDEPENDENT_STEP_TARGETS + ) if(NOT independent_step_targets) - get_property(independent_step_targets DIRECTORY PROPERTY EP_INDEPENDENT_STEP_TARGETS) + get_property(independent_step_targets + DIRECTORY + PROPERTY EP_INDEPENDENT_STEP_TARGETS + ) endif() if(cmp0114 STREQUAL "NEW") if(independent_step_targets) message(FATAL_ERROR - "ExternalProject '${name}' option 'INDEPENDENT_STEP_TARGETS' is set to\n" - " ${independent_step_targets}\n" + "ExternalProject '${name}' option 'INDEPENDENT_STEP_TARGETS' is set to" + "\n ${independent_step_targets}\n" "but the option is no longer allowed. " "It has been superseded by the per-step 'INDEPENDENT' option. " "See policy CMP0114." - ) + ) endif() else() if(independent_step_targets AND cmp0114 STREQUAL "") - get_property(warned TARGET ${name} PROPERTY _EP_CMP0114_WARNED_INDEPENDENT_STEP_TARGETS) + get_property(warned + TARGET ${name} + PROPERTY _EP_CMP0114_WARNED_INDEPENDENT_STEP_TARGETS + ) if(NOT warned) - set_property(TARGET ${name} PROPERTY _EP_CMP0114_WARNED_INDEPENDENT_STEP_TARGETS 1) + set_property(TARGET ${name} PROPERTY + _EP_CMP0114_WARNED_INDEPENDENT_STEP_TARGETS 1 + ) cmake_policy(GET_WARNING CMP0114 _cmp0114_warning) - string(APPEND _cmp0114_warning "\n" - "ExternalProject '${name}' option INDEPENDENT_STEP_TARGETS is set to\n" - " ${independent_step_targets}\n" + string(APPEND _cmp0114_warning + "\n" + "ExternalProject '${name}' option INDEPENDENT_STEP_TARGETS is set to" + "\n ${independent_step_targets}\n" "but the option is deprecated in favor of policy CMP0114." - ) + ) message(AUTHOR_WARNING "${_cmp0114_warning}") endif() endif() @@ -2370,33 +2576,51 @@ function(ExternalProject_Add_StepDependencies name step) # Sanity checks on "name" and "step". if(NOT TARGET ${name}) - message(FATAL_ERROR "Cannot find target \"${name}\". Perhaps it has not yet been created using ExternalProject_Add.") + message(FATAL_ERROR + "Cannot find target \"${name}\". Perhaps it has not yet been created " + "using ExternalProject_Add." + ) endif() get_property(type TARGET ${name} PROPERTY TYPE) if(NOT type STREQUAL "UTILITY") - message(FATAL_ERROR "Target \"${name}\" was not generated by ExternalProject_Add.") + message(FATAL_ERROR + "Target \"${name}\" was not generated by ExternalProject_Add." + ) endif() get_property(is_ep TARGET ${name} PROPERTY _EP_IS_EXTERNAL_PROJECT) if(NOT is_ep) - message(FATAL_ERROR "Target \"${name}\" was not generated by ExternalProject_Add.") + message(FATAL_ERROR + "Target \"${name}\" was not generated by ExternalProject_Add." + ) endif() get_property(steps TARGET ${name} PROPERTY _EP_STEPS) list(FIND steps ${step} is_step) if(is_step LESS 0) - message(FATAL_ERROR "External project \"${name}\" does not have a step \"${step}\".") + message(FATAL_ERROR + "External project \"${name}\" does not have a step \"${step}\"." + ) endif() if(TARGET ${name}-${step}) get_property(type TARGET ${name}-${step} PROPERTY TYPE) if(NOT type STREQUAL "UTILITY") - message(FATAL_ERROR "Target \"${name}-${step}\" was not generated by ExternalProject_Add_StepTargets.") + message(FATAL_ERROR + "Target \"${name}-${step}\" was not generated by " + "ExternalProject_Add_StepTargets." + ) endif() - get_property(is_ep_step TARGET ${name}-${step} PROPERTY _EP_IS_EXTERNAL_PROJECT_STEP) + get_property(is_ep_step + TARGET ${name}-${step} + PROPERTY _EP_IS_EXTERNAL_PROJECT_STEP + ) if(NOT is_ep_step) - message(FATAL_ERROR "Target \"${name}-${step}\" was not generated by ExternalProject_Add_StepTargets.") + message(FATAL_ERROR + "Target \"${name}-${step}\" was not generated by " + "ExternalProject_Add_StepTargets." + ) endif() endif() @@ -2406,7 +2630,8 @@ function(ExternalProject_Add_StepDependencies name step) foreach(dep ${dependencies}) add_custom_command(APPEND OUTPUT ${stamp_file} - DEPENDS ${dep}) + DEPENDS ${dep} + ) if(TARGET ${name}-${step}) foreach(dep ${dependencies}) add_dependencies(${name}-${step} ${dep}) @@ -2420,7 +2645,7 @@ endfunction() function(_ep_add_mkdir_command name) ExternalProject_Get_Property(${name} tmp_dir) set(script_filename "${tmp_dir}/${name}-mkdirs.cmake") - _ep_get_configuration_subdir_suffix(cfgdir) + _ep_get_configuration_subdir_genex(cfgdir) ExternalProject_Add_Step(${name} mkdir INDEPENDENT TRUE @@ -2440,14 +2665,21 @@ function(_ep_is_dir_empty dir empty_var) endfunction() function(_ep_get_git_submodules_recurse git_submodules_recurse) - # Checks for GIT_SUBMODULES_RECURSE property - # Default is ON, which sets git_submodules_recurse output variable to "--recursive" - # Otherwise, the output variable is set to an empty value "" - get_property(git_submodules_recurse_set TARGET ${name} PROPERTY _EP_GIT_SUBMODULES_RECURSE SET) + # Checks for GIT_SUBMODULES_RECURSE property. Default is ON, which sets + # git_submodules_recurse output variable to "--recursive". Otherwise, the + # output variable is set to an empty value "". + get_property(git_submodules_recurse_set + TARGET ${name} + PROPERTY _EP_GIT_SUBMODULES_RECURSE + SET + ) if(NOT git_submodules_recurse_set) set(recurseFlag "--recursive") else() - get_property(git_submodules_recurse_value TARGET ${name} PROPERTY _EP_GIT_SUBMODULES_RECURSE) + get_property(git_submodules_recurse_value + TARGET ${name} + PROPERTY _EP_GIT_SUBMODULES_RECURSE + ) if(git_submodules_recurse_value) set(recurseFlag "--recursive") else() @@ -2458,13 +2690,21 @@ function(_ep_get_git_submodules_recurse git_submodules_recurse) # The git submodule update '--recursive' flag requires git >= v1.6.5 if(recurseFlag AND GIT_VERSION_STRING VERSION_LESS 1.6.5) - message(FATAL_ERROR "error: git version 1.6.5 or later required for --recursive flag with 'git submodule ...': GIT_VERSION_STRING='${GIT_VERSION_STRING}'") + message(FATAL_ERROR + "git version 1.6.5 or later required for --recursive flag with " + "'git submodule ...': GIT_VERSION_STRING='${GIT_VERSION_STRING}'" + ) endif() endfunction() function(_ep_add_download_command name) - ExternalProject_Get_Property(${name} source_dir stamp_dir download_dir tmp_dir) + ExternalProject_Get_Property(${name} + source_dir + stamp_dir + download_dir + tmp_dir + ) get_property(cmd_set TARGET ${name} PROPERTY _EP_DOWNLOAD_COMMAND SET) get_property(cmd TARGET ${name} PROPERTY _EP_DOWNLOAD_COMMAND) @@ -2502,7 +2742,14 @@ function(_ep_add_download_command name) get_filename_component(src_name "${source_dir}" NAME) get_filename_component(work_dir "${source_dir}" PATH) set(comment "Performing download step (CVS checkout) for '${name}'") - set(cmd ${CVS_EXECUTABLE} -d ${cvs_repository} -q co ${cvs_tag} -d ${src_name} ${cvs_module}) + set(cmd + ${CVS_EXECUTABLE} + -d ${cvs_repository} + -q + co ${cvs_tag} + -d ${src_name} + ${cvs_module} + ) elseif(svn_repository) set(method svn) @@ -2515,6 +2762,15 @@ function(_ep_add_download_command name) get_property(svn_username TARGET ${name} PROPERTY _EP_SVN_USERNAME) get_property(svn_password TARGET ${name} PROPERTY _EP_SVN_PASSWORD) get_property(svn_trust_cert TARGET ${name} PROPERTY _EP_SVN_TRUST_CERT) + get_property(uses_terminal + TARGET ${name} + PROPERTY _EP_USES_TERMINAL_DOWNLOAD + ) + if(uses_terminal) + set(svn_interactive_args "") + else() + set(svn_interactive_args "--non-interactive") + endif() get_filename_component(src_name "${source_dir}" NAME) get_filename_component(work_dir "${source_dir}" PATH) @@ -2529,8 +2785,16 @@ function(_ep_add_download_command name) if(svn_trust_cert) set(svn_trust_cert_args --trust-server-cert) endif() - set(cmd ${Subversion_SVN_EXECUTABLE} co ${svn_repository} ${svn_revision} - --non-interactive ${svn_trust_cert_args} ${svn_user_pw_args} ${src_name}) + set(cmd + ${Subversion_SVN_EXECUTABLE} + co + ${svn_repository} + ${svn_revision} + ${svn_interactive_args} + ${svn_trust_cert_args} + ${svn_user_pw_args} + ${src_name} + ) elseif(git_repository) set(method git) @@ -2551,7 +2815,10 @@ function(_ep_add_download_command name) endif() set(git_init_submodules TRUE) - get_property(git_submodules_set TARGET ${name} PROPERTY _EP_GIT_SUBMODULES SET) + get_property(git_submodules_set + TARGET ${name} + PROPERTY _EP_GIT_SUBMODULES SET + ) if(git_submodules_set) get_property(git_submodules TARGET ${name} PROPERTY _EP_GIT_SUBMODULES) if(git_submodules STREQUAL "" AND _EP_CMP0097 STREQUAL "NEW") @@ -2600,10 +2867,25 @@ CMP0097=${_EP_CMP0097} # create a cmake script to invoke as download command. # The script will delete the source directory and then call git clone. # - _ep_write_gitclone_script(${tmp_dir}/${name}-gitclone.cmake ${source_dir} - ${GIT_EXECUTABLE} ${git_repository} ${git_tag} ${git_remote_name} ${git_init_submodules} "${git_submodules_recurse}" "${git_submodules}" "${git_shallow}" "${git_progress}" "${git_config}" ${src_name} ${work_dir} - ${stamp_dir}/${name}-gitinfo.txt ${stamp_dir}/${name}-gitclone-lastrun.txt "${tls_verify}" - ) + _ep_write_gitclone_script( + ${tmp_dir}/${name}-gitclone.cmake + ${source_dir} + ${GIT_EXECUTABLE} + ${git_repository} + ${git_tag} + ${git_remote_name} + ${git_init_submodules} + "${git_submodules_recurse}" + "${git_submodules}" + "${git_shallow}" + "${git_progress}" + "${git_config}" + ${src_name} + ${work_dir} + ${stamp_dir}/${name}-gitinfo.txt + ${stamp_dir}/${name}-gitclone-lastrun.txt + "${tls_verify}" + ) set(comment "Performing download step (git clone) for '${name}'") set(cmd ${CMAKE_COMMAND} -P ${tmp_dir}/${name}-gitclone.cmake) @@ -2634,10 +2916,17 @@ CMP0097=${_EP_CMP0097} # create a cmake script to invoke as download command. # The script will delete the source directory and then call hg clone. # - _ep_write_hgclone_script(${tmp_dir}/${name}-hgclone.cmake ${source_dir} - ${HG_EXECUTABLE} ${hg_repository} ${hg_tag} ${src_name} ${work_dir} - ${stamp_dir}/${name}-hginfo.txt ${stamp_dir}/${name}-hgclone-lastrun.txt - ) + _ep_write_hgclone_script( + ${tmp_dir}/${name}-hgclone.cmake + ${source_dir} + ${HG_EXECUTABLE} + ${hg_repository} + ${hg_tag} + ${src_name} + ${work_dir} + ${stamp_dir}/${name}-hginfo.txt + ${stamp_dir}/${name}-hgclone-lastrun.txt + ) set(comment "Performing download step (hg clone) for '${name}'") set(cmd ${CMAKE_COMMAND} -P ${tmp_dir}/${name}-hgclone.cmake) @@ -2649,13 +2938,21 @@ CMP0097=${_EP_CMP0097} if(hash AND NOT "${hash}" MATCHES "${_ep_hash_regex}") _ep_get_hash_algos(_ep_hash_algos) list(JOIN _ep_hash_algos "|" _ep_hash_algos) - message(FATAL_ERROR "URL_HASH is set to\n ${hash}\n" - "but must be ALGO=value where ALGO is\n ${_ep_hash_algos}\n" - "and value is a hex string.") + message(FATAL_ERROR + "URL_HASH is set to\n" + " ${hash}\n" + "but must be ALGO=value where ALGO is\n" + " ${_ep_hash_algos}\n" + "and value is a hex string." + ) endif() get_property(md5 TARGET ${name} PROPERTY _EP_URL_MD5) if(md5 AND NOT "MD5=${md5}" MATCHES "${_ep_hash_regex}") - message(FATAL_ERROR "URL_MD5 is set to\n ${md5}\nbut must be a hex string.") + message(FATAL_ERROR + "URL_MD5 is set to\n" + " ${md5}\n" + "but must be a hex string." + ) endif() if(md5 AND NOT hash) set(hash "MD5=${md5}") @@ -2669,7 +2966,9 @@ hash=${hash} if(NOT "${url_list_length}" STREQUAL "1") foreach(entry ${url}) if(NOT "${entry}" MATCHES "^[a-z]+://") - message(FATAL_ERROR "At least one entry of URL is a path (invalid in a list)") + message(FATAL_ERROR + "At least one entry of URL is a path (invalid in a list)" + ) endif() endforeach() if("x${fname}" STREQUAL "x") @@ -2680,17 +2979,23 @@ hash=${hash} if(IS_DIRECTORY "${url}") get_filename_component(abs_dir "${url}" ABSOLUTE) set(comment "Performing download step (DIR copy) for '${name}'") - set(cmd ${CMAKE_COMMAND} -E rm -rf ${source_dir} - COMMAND ${CMAKE_COMMAND} -E copy_directory ${abs_dir} ${source_dir}) + set(cmd + ${CMAKE_COMMAND} -E rm -rf ${source_dir} + COMMAND ${CMAKE_COMMAND} -E copy_directory ${abs_dir} ${source_dir} + ) else() - get_property(no_extract TARGET "${name}" PROPERTY _EP_DOWNLOAD_NO_EXTRACT) + get_property(no_extract + TARGET "${name}" + PROPERTY _EP_DOWNLOAD_NO_EXTRACT + ) string(APPEND extra_repo_info "no_extract=${no_extract}\n") if("${url}" MATCHES "^[a-z]+://") # TODO: Should download and extraction be different steps? if("x${fname}" STREQUAL "x") set(fname "${url}") endif() - if("${fname}" MATCHES [[([^/\?#]+(\.|=)(7z|tar|tar\.bz2|tar\.gz|tar\.xz|tbz2|tgz|txz|zip))([/?#].*)?$]]) + set(ext_regex [[7z|tar|tar\.bz2|tar\.gz|tar\.xz|tbz2|tgz|txz|zip]]) + if("${fname}" MATCHES "([^/\\?#]+(\\.|=)(${ext_regex}))([/?#].*)?$") set(fname "${CMAKE_MATCH_1}") elseif(no_extract) get_filename_component(fname "${fname}" NAME) @@ -2705,8 +3010,14 @@ hash=${hash} string(REPLACE ";" "-" fname "${fname}") set(file ${download_dir}/${fname}) get_property(timeout TARGET ${name} PROPERTY _EP_TIMEOUT) - get_property(inactivity_timeout TARGET ${name} PROPERTY _EP_INACTIVITY_TIMEOUT) - get_property(no_progress TARGET ${name} PROPERTY _EP_DOWNLOAD_NO_PROGRESS) + get_property(inactivity_timeout + TARGET ${name} + PROPERTY _EP_INACTIVITY_TIMEOUT + ) + get_property(no_progress + TARGET ${name} + PROPERTY _EP_DOWNLOAD_NO_PROGRESS + ) get_property(tls_verify TARGET ${name} PROPERTY _EP_TLS_VERIFY) get_property(tls_cainfo TARGET ${name} PROPERTY _EP_TLS_CAINFO) get_property(netrc TARGET ${name} PROPERTY _EP_NETRC) @@ -2730,15 +3041,18 @@ hash=${hash} "${netrc}" "${netrc_file}" ) - set(cmd ${CMAKE_COMMAND} -P "${download_script}" - COMMAND) + set(cmd + ${CMAKE_COMMAND} -P "${download_script}" + COMMAND + ) if (no_extract) set(steps "download and verify") else () set(steps "download, verify and extract") endif () set(comment "Performing download step (${steps}) for '${name}'") - file(WRITE "${stamp_dir}/verify-${name}.cmake" "") # already verified by 'download_script' + # already verified by 'download_script' + file(WRITE "${stamp_dir}/verify-${name}.cmake" "") # Rather than adding everything to the RepositoryInfo.txt file, it is # more robust to just depend on the download script. That way, we will @@ -2759,23 +3073,62 @@ hash=${hash} ) endif() list(APPEND cmd ${CMAKE_COMMAND} -P ${stamp_dir}/verify-${name}.cmake) - if (NOT no_extract) + get_target_property(extract_timestamp ${name} + _EP_DOWNLOAD_EXTRACT_TIMESTAMP + ) + if(no_extract) + if(NOT extract_timestamp STREQUAL "extract_timestamp-NOTFOUND") + message(FATAL_ERROR + "Cannot specify DOWNLOAD_EXTRACT_TIMESTAMP when using " + "DOWNLOAD_NO_EXTRACT TRUE" + ) + endif() + set_property(TARGET ${name} PROPERTY _EP_DOWNLOADED_FILE ${file}) + else() + if(extract_timestamp STREQUAL "extract_timestamp-NOTFOUND") + # Default depends on policy CMP0135 + if(_EP_CMP0135 STREQUAL "") + message(AUTHOR_WARNING + "The DOWNLOAD_EXTRACT_TIMESTAMP option was not given and policy " + "CMP0135 is not set. The policy's OLD behavior will be used. " + "When using a URL download, the timestamps of extracted files " + "should preferably be that of the time of extraction, otherwise " + "code that depends on the extracted contents might not be " + "rebuilt if the URL changes. The OLD behavior preserves the " + "timestamps from the archive instead, but this is usually not " + "what you want. Update your project to the NEW behavior or " + "specify the DOWNLOAD_EXTRACT_TIMESTAMP option with a value of " + "true to avoid this robustness issue." + ) + set(extract_timestamp TRUE) + elseif(_EP_CMP0135 STREQUAL "NEW") + set(extract_timestamp FALSE) + else() + set(extract_timestamp TRUE) + endif() + endif() + if(extract_timestamp) + set(options "") + else() + set(options "--touch") + endif() _ep_write_extractfile_script( "${stamp_dir}/extract-${name}.cmake" "${name}" "${file}" "${source_dir}" + "${options}" + ) + list(APPEND cmd + COMMAND ${CMAKE_COMMAND} -P ${stamp_dir}/extract-${name}.cmake ) - list(APPEND cmd COMMAND ${CMAKE_COMMAND} -P ${stamp_dir}/extract-${name}.cmake) - else () - set_property(TARGET ${name} PROPERTY _EP_DOWNLOADED_FILE ${file}) endif () endif() else() set(method source_dir) _ep_is_dir_empty("${source_dir}" empty) if(${empty}) - message(SEND_ERROR + message(FATAL_ERROR "No download info given for '${name}' and its source directory:\n" " ${source_dir}\n" "is not an existing non-empty directory. Please specify one of:\n" @@ -2786,7 +3139,7 @@ hash=${hash} " * SVN_REPOSITORY\n" " * HG_REPOSITORY\n" " * CVS_REPOSITORY and CVS_MODULE" - ) + ) endif() endif() @@ -2801,15 +3154,20 @@ hash=${hash} @ONLY ) - get_property(log TARGET ${name} PROPERTY _EP_LOG_DOWNLOAD) + get_property(log + TARGET ${name} + PROPERTY _EP_LOG_DOWNLOAD + ) if(log) set(log LOG 1) else() set(log "") endif() - get_property(uses_terminal TARGET ${name} PROPERTY - _EP_USES_TERMINAL_DOWNLOAD) + get_property(uses_terminal + TARGET ${name} + PROPERTY _EP_USES_TERMINAL_DOWNLOAD + ) if(uses_terminal) set(uses_terminal USES_TERMINAL 1) else() @@ -2830,16 +3188,26 @@ hash=${hash} DEPENDEES mkdir ${log} ${uses_terminal} - )" + )" ) endfunction() function(_ep_get_update_disconnected var name) - get_property(update_disconnected_set TARGET ${name} PROPERTY _EP_UPDATE_DISCONNECTED SET) + get_property(update_disconnected_set + TARGET ${name} + PROPERTY _EP_UPDATE_DISCONNECTED + SET + ) if(update_disconnected_set) - get_property(update_disconnected TARGET ${name} PROPERTY _EP_UPDATE_DISCONNECTED) + get_property(update_disconnected + TARGET ${name} + PROPERTY _EP_UPDATE_DISCONNECTED + ) else() - get_property(update_disconnected DIRECTORY PROPERTY EP_UPDATE_DISCONNECTED) + get_property(update_disconnected + DIRECTORY + PROPERTY EP_UPDATE_DISCONNECTED + ) endif() set(${var} "${update_disconnected}" PARENT_SCOPE) endfunction() @@ -2884,6 +3252,12 @@ function(_ep_add_update_command name) get_property(svn_username TARGET ${name} PROPERTY _EP_SVN_USERNAME) get_property(svn_password TARGET ${name} PROPERTY _EP_SVN_PASSWORD) get_property(svn_trust_cert TARGET ${name} PROPERTY _EP_SVN_TRUST_CERT) + get_property(uses_terminal TARGET ${name} PROPERTY _EP_USES_TERMINAL_UPDATE) + if(uses_terminal) + set(svn_interactive_args "") + else() + set(svn_interactive_args "--non-interactive") + endif() set(svn_user_pw_args "") if(DEFINED svn_username) set(svn_user_pw_args ${svn_user_pw_args} "--username=${svn_username}") @@ -2894,8 +3268,14 @@ function(_ep_add_update_command name) if(svn_trust_cert) set(svn_trust_cert_args --trust-server-cert) endif() - set(cmd ${Subversion_SVN_EXECUTABLE} up ${svn_revision} - --non-interactive ${svn_trust_cert_args} ${svn_user_pw_args}) + set(cmd + ${Subversion_SVN_EXECUTABLE} + up + ${svn_revision} + ${svn_interactive_args} + ${svn_trust_cert_args} + ${svn_user_pw_args} + ) set(always 1) elseif(git_repository) # FetchContent gives us these directly, so don't try to recompute them @@ -2908,25 +3288,43 @@ function(_ep_add_update_command name) endif() set(work_dir ${source_dir}) set(comment "Performing update step for '${name}'") - get_property(git_tag TARGET ${name} PROPERTY _EP_GIT_TAG) + + get_property(git_tag + TARGET ${name} + PROPERTY _EP_GIT_TAG + ) if(NOT git_tag) set(git_tag "master") endif() - get_property(git_remote_name TARGET ${name} PROPERTY _EP_GIT_REMOTE_NAME) + + get_property(git_remote_name + TARGET ${name} + PROPERTY _EP_GIT_REMOTE_NAME + ) if(NOT git_remote_name) set(git_remote_name "origin") endif() set(git_init_submodules TRUE) - get_property(git_submodules_set TARGET ${name} PROPERTY _EP_GIT_SUBMODULES SET) + get_property(git_submodules_set + TARGET ${name} + PROPERTY _EP_GIT_SUBMODULES + SET + ) if(git_submodules_set) - get_property(git_submodules TARGET ${name} PROPERTY _EP_GIT_SUBMODULES) + get_property(git_submodules + TARGET ${name} + PROPERTY _EP_GIT_SUBMODULES + ) if(git_submodules STREQUAL "" AND _EP_CMP0097 STREQUAL "NEW") set(git_init_submodules FALSE) endif() endif() - get_property(git_update_strategy TARGET ${name} PROPERTY _EP_GIT_REMOTE_UPDATE_STRATEGY) + get_property(git_update_strategy + TARGET ${name} + PROPERTY _EP_GIT_REMOTE_UPDATE_STRATEGY + ) if(NOT git_update_strategy) set(git_update_strategy "${CMAKE_EP_GIT_REMOTE_UPDATE_STRATEGY}") endif() @@ -2935,7 +3333,10 @@ function(_ep_add_update_command name) endif() set(strategies CHECKOUT REBASE REBASE_CHECKOUT) if(NOT git_update_strategy IN_LIST strategies) - message(FATAL_ERROR "'${git_update_strategy}' is not one of the supported strategies: ${strategies}") + message(FATAL_ERROR + "'${git_update_strategy}' is not one of the supported strategies: " + "${strategies}" + ) endif() _ep_get_git_submodules_recurse(git_submodules_recurse) @@ -2960,32 +3361,48 @@ function(_ep_add_update_command name) endif() set(work_dir ${source_dir}) set(comment "Performing update step (hg pull) for '${name}'") - get_property(hg_tag TARGET ${name} PROPERTY _EP_HG_TAG) + + get_property(hg_tag + TARGET ${name} + PROPERTY _EP_HG_TAG + ) if(NOT hg_tag) set(hg_tag "tip") endif() + if("${HG_VERSION_STRING}" STREQUAL "2.1") - message(WARNING "Mercurial 2.1 does not distinguish an empty pull from a failed pull: - http://mercurial.selenic.com/wiki/UpgradeNotes#A2.1.1:_revert_pull_return_code_change.2C_compile_issue_on_OS_X + set(notesAnchor + "#A2.1.1:_revert_pull_return_code_change.2C_compile_issue_on_OS_X" + ) + message(WARNING +"Mercurial 2.1 does not distinguish an empty pull from a failed pull: + http://mercurial.selenic.com/wiki/UpgradeNotes${notesAnchor} http://thread.gmane.org/gmane.comp.version-control.mercurial.devel/47656 Update to Mercurial >= 2.1.1. ") endif() - set(cmd ${HG_EXECUTABLE} pull + + set(cmd + ${HG_EXECUTABLE} pull COMMAND ${HG_EXECUTABLE} update ${hg_tag} - ) + ) set(always 1) endif() - get_property(log TARGET ${name} PROPERTY _EP_LOG_UPDATE) + get_property(log + TARGET ${name} + PROPERTY _EP_LOG_UPDATE + ) if(log) set(log LOG 1) else() set(log "") endif() - get_property(uses_terminal TARGET ${name} PROPERTY - _EP_USES_TERMINAL_UPDATE) + get_property(uses_terminal + TARGET ${name} + PROPERTY _EP_USES_TERMINAL_UPDATE + ) if(uses_terminal) set(uses_terminal USES_TERMINAL 1) else() @@ -3007,7 +3424,7 @@ Update to Mercurial >= 2.1.1. DEPENDEES download ${log} ${uses_terminal} - )" + )" ) endfunction() @@ -3025,14 +3442,20 @@ function(_ep_add_patch_command name) set(work_dir ${source_dir}) endif() - get_property(log TARGET ${name} PROPERTY _EP_LOG_PATCH) + get_property(log + TARGET ${name} + PROPERTY _EP_LOG_PATCH + ) if(log) set(log LOG 1) else() set(log "") endif() - get_property(uses_terminal TARGET ${name} PROPERTY _EP_USES_TERMINAL_PATCH) + get_property(uses_terminal + TARGET ${name} + PROPERTY _EP_USES_TERMINAL_PATCH + ) if(uses_terminal) set(uses_terminal USES_TERMINAL 1) else() @@ -3058,18 +3481,27 @@ function(_ep_add_patch_command name) DEPENDEES \${patch_dep} ${log} ${uses_terminal} - )" + )" ) endfunction() function(_ep_get_file_deps var name) set(file_deps) - get_property(deps TARGET ${name} PROPERTY _EP_DEPENDS) + get_property(deps + TARGET ${name} + PROPERTY _EP_DEPENDS + ) foreach(dep IN LISTS deps) - get_property(dep_type TARGET ${dep} PROPERTY TYPE) + get_property(dep_type + TARGET ${dep} + PROPERTY TYPE + ) if(dep_type STREQUAL "UTILITY") - get_property(is_ep TARGET ${dep} PROPERTY _EP_IS_EXTERNAL_PROJECT) + get_property(is_ep + TARGET ${dep} + PROPERTY _EP_IS_EXTERNAL_PROJECT + ) if(is_ep) _ep_get_step_stampfile(${dep} "done" done_stamp_file) list(APPEND file_deps ${done_stamp_file}) @@ -3081,9 +3513,16 @@ function(_ep_get_file_deps var name) endfunction() function(_ep_extract_configure_command var name) - get_property(cmd_set TARGET ${name} PROPERTY _EP_CONFIGURE_COMMAND SET) + get_property(cmd_set + TARGET ${name} + PROPERTY _EP_CONFIGURE_COMMAND + SET + ) if(cmd_set) - get_property(cmd TARGET ${name} PROPERTY _EP_CONFIGURE_COMMAND) + get_property(cmd + TARGET ${name} + PROPERTY _EP_CONFIGURE_COMMAND + ) else() get_target_property(cmake_command ${name} _EP_CMAKE_COMMAND) if(cmake_command) @@ -3092,13 +3531,22 @@ function(_ep_extract_configure_command var name) set(cmd "${CMAKE_COMMAND}") endif() - get_property(cmake_args TARGET ${name} PROPERTY _EP_CMAKE_ARGS) + get_property(cmake_args + TARGET ${name} + PROPERTY _EP_CMAKE_ARGS + ) list(APPEND cmd ${cmake_args}) # If there are any CMAKE_CACHE_ARGS or CMAKE_CACHE_DEFAULT_ARGS, # write an initial cache and use it - get_property(cmake_cache_args TARGET ${name} PROPERTY _EP_CMAKE_CACHE_ARGS) - get_property(cmake_cache_default_args TARGET ${name} PROPERTY _EP_CMAKE_CACHE_DEFAULT_ARGS) + get_property(cmake_cache_args + TARGET ${name} + PROPERTY _EP_CMAKE_CACHE_ARGS + ) + get_property(cmake_cache_default_args + TARGET ${name} + PROPERTY _EP_CMAKE_CACHE_DEFAULT_ARGS + ) set(has_cmake_cache_args 0) if(NOT "${cmake_cache_args}" STREQUAL "") @@ -3110,10 +3558,18 @@ function(_ep_extract_configure_command var name) set(has_cmake_cache_default_args 1) endif() - get_target_property(cmake_generator ${name} _EP_CMAKE_GENERATOR) - get_target_property(cmake_generator_instance ${name} _EP_CMAKE_GENERATOR_INSTANCE) - get_target_property(cmake_generator_platform ${name} _EP_CMAKE_GENERATOR_PLATFORM) - get_target_property(cmake_generator_toolset ${name} _EP_CMAKE_GENERATOR_TOOLSET) + get_target_property(cmake_generator ${name} + _EP_CMAKE_GENERATOR + ) + get_target_property(cmake_generator_instance ${name} + _EP_CMAKE_GENERATOR_INSTANCE + ) + get_target_property(cmake_generator_platform ${name} + _EP_CMAKE_GENERATOR_PLATFORM + ) + get_target_property(cmake_generator_toolset ${name} + _EP_CMAKE_GENERATOR_TOOLSET + ) if(cmake_generator) list(APPEND cmd "-G${cmake_generator}") if(cmake_generator_platform) @@ -3123,7 +3579,9 @@ function(_ep_extract_configure_command var name) list(APPEND cmd "-T${cmake_generator_toolset}") endif() if(cmake_generator_instance) - list(APPEND cmd "-DCMAKE_GENERATOR_INSTANCE:INTERNAL=${cmake_generator_instance}") + list(APPEND cmd + "-DCMAKE_GENERATOR_INSTANCE:INTERNAL=${cmake_generator_instance}" + ) endif() else() if(CMAKE_EXTRA_GENERATOR) @@ -3132,52 +3590,75 @@ function(_ep_extract_configure_command var name) list(APPEND cmd "-G${CMAKE_GENERATOR}") if("${CMAKE_GENERATOR}" MATCHES "Green Hills MULTI") set(has_cmake_cache_default_args 1) - set(cmake_cache_default_args ${cmake_cache_default_args} + list(APPEND cmake_cache_default_args "-DGHS_TARGET_PLATFORM:STRING=${GHS_TARGET_PLATFORM}" "-DGHS_PRIMARY_TARGET:STRING=${GHS_PRIMARY_TARGET}" "-DGHS_TOOLSET_ROOT:STRING=${GHS_TOOLSET_ROOT}" "-DGHS_OS_ROOT:STRING=${GHS_OS_ROOT}" "-DGHS_OS_DIR:STRING=${GHS_OS_DIR}" - "-DGHS_BSP_NAME:STRING=${GHS_BSP_NAME}") + "-DGHS_BSP_NAME:STRING=${GHS_BSP_NAME}" + ) endif() endif() if(cmake_generator_platform) - message(FATAL_ERROR "Option CMAKE_GENERATOR_PLATFORM not allowed without CMAKE_GENERATOR.") + message(FATAL_ERROR + "Option CMAKE_GENERATOR_PLATFORM not allowed without " + "CMAKE_GENERATOR." + ) endif() if(CMAKE_GENERATOR_PLATFORM) list(APPEND cmd "-A${CMAKE_GENERATOR_PLATFORM}") endif() if(cmake_generator_toolset) - message(FATAL_ERROR "Option CMAKE_GENERATOR_TOOLSET not allowed without CMAKE_GENERATOR.") + message(FATAL_ERROR + "Option CMAKE_GENERATOR_TOOLSET not allowed without CMAKE_GENERATOR." + ) endif() if(CMAKE_GENERATOR_TOOLSET) list(APPEND cmd "-T${CMAKE_GENERATOR_TOOLSET}") endif() if(cmake_generator_instance) - message(FATAL_ERROR "Option CMAKE_GENERATOR_INSTANCE not allowed without CMAKE_GENERATOR.") + message(FATAL_ERROR + "Option CMAKE_GENERATOR_INSTANCE not allowed without CMAKE_GENERATOR." + ) endif() if(CMAKE_GENERATOR_INSTANCE) - list(APPEND cmd "-DCMAKE_GENERATOR_INSTANCE:INTERNAL=${CMAKE_GENERATOR_INSTANCE}") + list(APPEND cmd + "-DCMAKE_GENERATOR_INSTANCE:INTERNAL=${CMAKE_GENERATOR_INSTANCE}" + ) endif() endif() if(has_cmake_cache_args OR has_cmake_cache_default_args) set(_ep_cache_args_script "<TMP_DIR>/${name}-cache-$<CONFIG>.cmake") if(has_cmake_cache_args) - _ep_command_line_to_initial_cache(script_initial_cache_force "${cmake_cache_args}" 1) + _ep_command_line_to_initial_cache( + script_initial_cache_force + "${cmake_cache_args}" + 1 + ) endif() if(has_cmake_cache_default_args) - _ep_command_line_to_initial_cache(script_initial_cache_default "${cmake_cache_default_args}" 0) + _ep_command_line_to_initial_cache( + script_initial_cache_default + "${cmake_cache_default_args}" + 0 + ) endif() - _ep_write_initial_cache(${name} "${_ep_cache_args_script}" "${script_initial_cache_force}${script_initial_cache_default}") + _ep_write_initial_cache( + ${name} + "${_ep_cache_args_script}" + "${script_initial_cache_force}${script_initial_cache_default}" + ) list(APPEND cmd "-C${_ep_cache_args_script}") _ep_replace_location_tags(${name} _ep_cache_args_script) set(_ep_cache_args_script "${_ep_cache_args_script}" - PARENT_SCOPE) + PARENT_SCOPE + ) endif() - list(APPEND cmd "<SOURCE_DIR><SOURCE_SUBDIR>") + list(APPEND cmd -S "<SOURCE_DIR><SOURCE_SUBDIR>" -B "<BINARY_DIR>") endif() set("${var}" "${cmd}" PARENT_SCOPE) @@ -3188,8 +3669,10 @@ function(_ep_add_configure_command name) ExternalProject_Get_Property(${name} binary_dir tmp_dir) set(file_deps) - get_property(configure_handled_by_build TARGET ${name} - PROPERTY _EP_CONFIGURE_HANDLED_BY_BUILD) + get_property(configure_handled_by_build + TARGET ${name} + PROPERTY _EP_CONFIGURE_HANDLED_BY_BUILD + ) if(NOT configure_handled_by_build) # Depend on other external projects (file-level) _ep_get_file_deps(file_deps ${name}) @@ -3209,15 +3692,20 @@ function(_ep_add_configure_command name) list(APPEND file_deps ${tmp_dir}/${name}-cfgcmd.txt) list(APPEND file_deps ${_ep_cache_args_script}) - get_property(log TARGET ${name} PROPERTY _EP_LOG_CONFIGURE) + get_property(log + TARGET ${name} + PROPERTY _EP_LOG_CONFIGURE + ) if(log) set(log LOG 1) else() set(log "") endif() - get_property(uses_terminal TARGET ${name} PROPERTY - _EP_USES_TERMINAL_CONFIGURE) + get_property(uses_terminal + TARGET ${name} + PROPERTY _EP_USES_TERMINAL_CONFIGURE + ) if(uses_terminal) set(uses_terminal USES_TERMINAL 1) else() @@ -3237,7 +3725,7 @@ function(_ep_add_configure_command name) DEPENDS \${file_deps} ${log} ${uses_terminal} - )" + )" ) endfunction() @@ -3246,43 +3734,63 @@ function(_ep_add_build_command name) ExternalProject_Get_Property(${name} binary_dir) set(file_deps) - get_property(configure_handled_by_build TARGET ${name} - PROPERTY _EP_CONFIGURE_HANDLED_BY_BUILD) + get_property(configure_handled_by_build + TARGET ${name} + PROPERTY _EP_CONFIGURE_HANDLED_BY_BUILD + ) if(configure_handled_by_build) # Depend on other external projects (file-level) _ep_get_file_deps(file_deps ${name}) endif() - get_property(cmd_set TARGET ${name} PROPERTY _EP_BUILD_COMMAND SET) + get_property(cmd_set + TARGET ${name} + PROPERTY _EP_BUILD_COMMAND + SET + ) if(cmd_set) - get_property(cmd TARGET ${name} PROPERTY _EP_BUILD_COMMAND) + get_property(cmd + TARGET ${name} + PROPERTY _EP_BUILD_COMMAND + ) else() _ep_get_build_command(${name} BUILD cmd) endif() - get_property(log TARGET ${name} PROPERTY _EP_LOG_BUILD) + get_property(log + TARGET ${name} + PROPERTY _EP_LOG_BUILD + ) if(log) set(log LOG 1) else() set(log "") endif() - get_property(uses_terminal TARGET ${name} PROPERTY - _EP_USES_TERMINAL_BUILD) + get_property(uses_terminal + TARGET ${name} + PROPERTY _EP_USES_TERMINAL_BUILD + ) if(uses_terminal) set(uses_terminal USES_TERMINAL 1) else() set(uses_terminal "") endif() - get_property(build_always TARGET ${name} PROPERTY _EP_BUILD_ALWAYS) + get_property(build_always + TARGET ${name} + PROPERTY _EP_BUILD_ALWAYS + ) if(build_always) set(always 1) else() set(always 0) endif() - get_property(build_byproducts TARGET ${name} PROPERTY _EP_BUILD_BYPRODUCTS) + get_property(build_byproducts + TARGET ${name} + PROPERTY _EP_BUILD_BYPRODUCTS + ) set(__cmdQuoted) foreach(__item IN LISTS cmd) @@ -3299,7 +3807,7 @@ function(_ep_add_build_command name) ALWAYS \${always} ${log} ${uses_terminal} - )" + )" ) endfunction() @@ -3307,28 +3815,58 @@ endfunction() function(_ep_add_install_command name) ExternalProject_Get_Property(${name} binary_dir) - get_property(cmd_set TARGET ${name} PROPERTY _EP_INSTALL_COMMAND SET) + get_property(cmd_set + TARGET ${name} + PROPERTY _EP_INSTALL_COMMAND + SET + ) if(cmd_set) - get_property(cmd TARGET ${name} PROPERTY _EP_INSTALL_COMMAND) + get_property(cmd + TARGET ${name} + PROPERTY _EP_INSTALL_COMMAND + ) else() _ep_get_build_command(${name} INSTALL cmd) endif() - get_property(log TARGET ${name} PROPERTY _EP_LOG_INSTALL) + get_property(log + TARGET ${name} + PROPERTY _EP_LOG_INSTALL + ) if(log) set(log LOG 1) else() set(log "") endif() - get_property(uses_terminal TARGET ${name} PROPERTY - _EP_USES_TERMINAL_INSTALL) + get_property(uses_terminal + TARGET ${name} + PROPERTY _EP_USES_TERMINAL_INSTALL + ) if(uses_terminal) set(uses_terminal USES_TERMINAL 1) else() set(uses_terminal "") endif() + # With BUILD_ALWAYS+BUILD_BYPRODUCTS, Ninja restats the + # build step outputs and may not consider this step to + # be out-of-date. Explicitly mark it out-of-date too. + get_property(build_always + TARGET ${name} + PROPERTY _EP_BUILD_ALWAYS + ) + if(build_always) + set(always 1) + else() + set(always 0) + endif() + + get_property(install_byproducts + TARGET ${name} + PROPERTY _EP_INSTALL_BYPRODUCTS + ) + set(__cmdQuoted) foreach(__item IN LISTS cmd) string(APPEND __cmdQuoted " [==[${__item}]==]") @@ -3337,11 +3875,13 @@ function(_ep_add_install_command name) ExternalProject_Add_Step(${name} install INDEPENDENT FALSE COMMAND ${__cmdQuoted} + BYPRODUCTS \${install_byproducts} WORKING_DIRECTORY \${binary_dir} DEPENDEES build + ALWAYS \${always} ${log} ${uses_terminal} - )" + )" ) endfunction() @@ -3359,7 +3899,10 @@ function(_ep_add_test_command name) # if(cmd_set OR before OR after OR exclude) if(cmd_set) - get_property(cmd TARGET ${name} PROPERTY _EP_TEST_COMMAND) + get_property(cmd + TARGET ${name} + PROPERTY _EP_TEST_COMMAND + ) else() _ep_get_build_command(${name} TEST cmd) endif() @@ -3382,15 +3925,20 @@ function(_ep_add_test_command name) set(exclude_args "") endif() - get_property(log TARGET ${name} PROPERTY _EP_LOG_TEST) + get_property(log + TARGET ${name} + PROPERTY _EP_LOG_TEST + ) if(log) set(log LOG 1) else() set(log "") endif() - get_property(uses_terminal TARGET ${name} PROPERTY - _EP_USES_TERMINAL_TEST) + get_property(uses_terminal + TARGET ${name} + PROPERTY _EP_USES_TERMINAL_TEST + ) if(uses_terminal) set(uses_terminal USES_TERMINAL 1) else() @@ -3411,7 +3959,7 @@ function(_ep_add_test_command name) ${exclude_args} ${log} ${uses_terminal} - )" + )" ) endif() endfunction() @@ -3420,11 +3968,12 @@ endfunction() function(ExternalProject_Add name) cmake_policy(GET CMP0097 _EP_CMP0097 PARENT_SCOPE # undocumented, do not use outside of CMake - ) + ) cmake_policy(GET CMP0114 cmp0114 PARENT_SCOPE # undocumented, do not use outside of CMake - ) - if(CMAKE_XCODE_BUILD_SYSTEM VERSION_GREATER_EQUAL 12 AND NOT cmp0114 STREQUAL "NEW") + ) + if(CMAKE_XCODE_BUILD_SYSTEM VERSION_GREATER_EQUAL 12 AND + NOT cmp0114 STREQUAL "NEW") message(AUTHOR_WARNING "Policy CMP0114 is not set to NEW. " "In order to support the Xcode \"new build system\", " @@ -3433,11 +3982,14 @@ function(ExternalProject_Add name) "Since CMake is generating for the Xcode \"new build system\", " "ExternalProject_Add will use policy CMP0114's NEW behavior anyway, " "but the generated build system may not match what the project intends." - ) + ) set(cmp0114 "NEW") endif() + cmake_policy(GET CMP0135 _EP_CMP0135 + PARENT_SCOPE # undocumented, do not use outside of CMake + ) - _ep_get_configuration_subdir_suffix(cfgdir) + _ep_get_configuration_subdir_genex(cfgdir) # Add a custom target for the external project. set(cmf_dir ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles) @@ -3454,11 +4006,12 @@ function(ExternalProject_Add name) # argument was passed, we explicitly set it for the target. add_custom_target(${name} ALL DEPENDS ${complete_stamp_file}) cmake_policy(POP) - set_property(TARGET ${name} PROPERTY _EP_IS_EXTERNAL_PROJECT 1) - set_property(TARGET ${name} PROPERTY LABELS ${name}) - set_property(TARGET ${name} PROPERTY FOLDER "ExternalProjectTargets/${name}") - - set_property(TARGET ${name} PROPERTY _EP_CMP0114 "${cmp0114}") + set_target_properties(${name} PROPERTIES + _EP_IS_EXTERNAL_PROJECT 1 + LABELS ${name} + FOLDER "ExternalProjectTargets/${name}" + _EP_CMP0114 "${cmp0114}" + ) set(keywords # @@ -3481,6 +4034,7 @@ function(ExternalProject_Add name) URL_HASH URL_MD5 DOWNLOAD_NAME + DOWNLOAD_EXTRACT_TIMESTAMP DOWNLOAD_NO_EXTRACT DOWNLOAD_NO_PROGRESS TIMEOUT @@ -3549,6 +4103,7 @@ function(ExternalProject_Add name) # Install step options # INSTALL_COMMAND + INSTALL_BYPRODUCTS # # Test step options # @@ -3590,13 +4145,22 @@ function(ExternalProject_Add name) # LIST_SEPARATOR ) - _ep_parse_arguments(ExternalProject_Add "${keywords}" ${name} _EP_ "${ARGN}") + _ep_parse_arguments( + ExternalProject_Add + "${keywords}" + ${name} + _EP_ + "${ARGN}" + ) _ep_set_directories(${name}) _ep_get_step_stampfile(${name} "done" done_stamp_file) _ep_get_step_stampfile(${name} "install" install_stamp_file) # Set the EXCLUDE_FROM_ALL target property if required. - get_property(exclude_from_all TARGET ${name} PROPERTY _EP_EXCLUDE_FROM_ALL) + get_property(exclude_from_all + TARGET ${name} + PROPERTY _EP_EXCLUDE_FROM_ALL + ) if(exclude_from_all) set_property(TARGET ${name} PROPERTY EXCLUDE_FROM_ALL TRUE) endif() @@ -3623,11 +4187,13 @@ function(ExternalProject_Add name) COMMAND ${CMAKE_COMMAND} -E touch ${done_stamp_file} DEPENDS ${install_stamp_file} VERBATIM - ) - + ) # Depend on other external projects (target-level). - get_property(deps TARGET ${name} PROPERTY _EP_DEPENDS) + get_property(deps + TARGET ${name} + PROPERTY _EP_DEPENDS + ) foreach(arg IN LISTS deps) add_dependencies(${name} ${arg}) endforeach() diff --git a/Modules/ExternalProject/extractfile.cmake.in b/Modules/ExternalProject/extractfile.cmake.in index d7f5756..984565b 100644 --- a/Modules/ExternalProject/extractfile.cmake.in +++ b/Modules/ExternalProject/extractfile.cmake.in @@ -29,7 +29,7 @@ file(MAKE_DIRECTORY "${ut_dir}") # Extract it: # message(STATUS "extracting... [tar @args@]") -execute_process(COMMAND ${CMAKE_COMMAND} -E tar @args@ ${filename} +execute_process(COMMAND ${CMAKE_COMMAND} -E tar @args@ ${filename} @options@ WORKING_DIRECTORY ${ut_dir} RESULT_VARIABLE rv ) diff --git a/Modules/ExternalProject/gitupdate.cmake.in b/Modules/ExternalProject/gitupdate.cmake.in index 0de2372..50f0167 100644 --- a/Modules/ExternalProject/gitupdate.cmake.in +++ b/Modules/ExternalProject/gitupdate.cmake.in @@ -5,7 +5,7 @@ cmake_minimum_required(VERSION 3.5) function(get_hash_for_ref ref out_var err_var) execute_process( - COMMAND "@git_EXECUTABLE@" rev-parse "${ref}^0" + COMMAND "@git_EXECUTABLE@" --git-dir=.git rev-parse "${ref}^0" WORKING_DIRECTORY "@work_dir@" RESULT_VARIABLE error_code OUTPUT_VARIABLE ref_hash @@ -27,7 +27,7 @@ endif() execute_process( - COMMAND "@git_EXECUTABLE@" show-ref "@git_tag@" + COMMAND "@git_EXECUTABLE@" --git-dir=.git show-ref "@git_tag@" WORKING_DIRECTORY "@work_dir@" OUTPUT_VARIABLE show_ref_output ) @@ -95,7 +95,7 @@ endif() if(fetch_required) message(VERBOSE "Fetching latest from the remote @git_remote_name@") execute_process( - COMMAND "@git_EXECUTABLE@" fetch --tags --force "@git_remote_name@" + COMMAND "@git_EXECUTABLE@" --git-dir=.git fetch --tags --force "@git_remote_name@" WORKING_DIRECTORY "@work_dir@" COMMAND_ERROR_IS_FATAL ANY ) @@ -112,7 +112,7 @@ if(git_update_strategy MATCHES "^REBASE(_CHECKOUT)?$") # We can't if we aren't already on a branch and we shouldn't if that local # branch isn't tracking the one we want to checkout. execute_process( - COMMAND "@git_EXECUTABLE@" symbolic-ref -q HEAD + COMMAND "@git_EXECUTABLE@" --git-dir=.git symbolic-ref -q HEAD WORKING_DIRECTORY "@work_dir@" OUTPUT_VARIABLE current_branch OUTPUT_STRIP_TRAILING_WHITESPACE @@ -128,7 +128,7 @@ if(git_update_strategy MATCHES "^REBASE(_CHECKOUT)?$") else() execute_process( - COMMAND "@git_EXECUTABLE@" for-each-ref "--format='%(upstream:short)'" "${current_branch}" + COMMAND "@git_EXECUTABLE@" --git-dir=.git for-each-ref "--format=%(upstream:short)" "${current_branch}" WORKING_DIRECTORY "@work_dir@" OUTPUT_VARIABLE upstream_branch OUTPUT_STRIP_TRAILING_WHITESPACE @@ -151,7 +151,7 @@ endif() # Check if stash is needed execute_process( - COMMAND "@git_EXECUTABLE@" status --porcelain + COMMAND "@git_EXECUTABLE@" --git-dir=.git status --porcelain WORKING_DIRECTORY "@work_dir@" RESULT_VARIABLE error_code OUTPUT_VARIABLE repo_status @@ -165,7 +165,7 @@ string(LENGTH "${repo_status}" need_stash) # rebase or checkout without losing those changes permanently if(need_stash) execute_process( - COMMAND "@git_EXECUTABLE@" stash save @git_stash_save_options@ + COMMAND "@git_EXECUTABLE@" --git-dir=.git stash save @git_stash_save_options@ WORKING_DIRECTORY "@work_dir@" COMMAND_ERROR_IS_FATAL ANY ) @@ -173,13 +173,13 @@ endif() if(git_update_strategy STREQUAL "CHECKOUT") execute_process( - COMMAND "@git_EXECUTABLE@" checkout "${checkout_name}" + COMMAND "@git_EXECUTABLE@" --git-dir=.git checkout "${checkout_name}" WORKING_DIRECTORY "@work_dir@" COMMAND_ERROR_IS_FATAL ANY ) else() execute_process( - COMMAND "@git_EXECUTABLE@" rebase "${checkout_name}" + COMMAND "@git_EXECUTABLE@" --git-dir=.git rebase "${checkout_name}" WORKING_DIRECTORY "@work_dir@" RESULT_VARIABLE error_code OUTPUT_VARIABLE rebase_output @@ -188,7 +188,7 @@ else() if(error_code) # Rebase failed, undo the rebase attempt before continuing execute_process( - COMMAND "@git_EXECUTABLE@" rebase --abort + COMMAND "@git_EXECUTABLE@" --git-dir=.git rebase --abort WORKING_DIRECTORY "@work_dir@" ) @@ -196,7 +196,7 @@ else() # Not allowed to do a checkout as a fallback, so cannot proceed if(need_stash) execute_process( - COMMAND "@git_EXECUTABLE@" stash pop --index --quiet + COMMAND "@git_EXECUTABLE@" --git-dir=.git stash pop --index --quiet WORKING_DIRECTORY "@work_dir@" ) endif() @@ -218,7 +218,7 @@ else() message(WARNING "Rebase failed, output has been saved to ${error_log_file}" "\nFalling back to checkout, previous commit tagged as ${tag_name}") execute_process( - COMMAND "@git_EXECUTABLE@" tag -a + COMMAND "@git_EXECUTABLE@" --git-dir=.git tag -a -m "ExternalProject attempting to move from here to ${checkout_name}" ${tag_name} WORKING_DIRECTORY "@work_dir@" @@ -226,7 +226,7 @@ else() ) execute_process( - COMMAND "@git_EXECUTABLE@" checkout "${checkout_name}" + COMMAND "@git_EXECUTABLE@" --git-dir=.git checkout "${checkout_name}" WORKING_DIRECTORY "@work_dir@" COMMAND_ERROR_IS_FATAL ANY ) @@ -236,29 +236,29 @@ endif() if(need_stash) # Put back the stashed changes execute_process( - COMMAND "@git_EXECUTABLE@" stash pop --index --quiet + COMMAND "@git_EXECUTABLE@" --git-dir=.git stash pop --index --quiet WORKING_DIRECTORY "@work_dir@" RESULT_VARIABLE error_code ) if(error_code) # Stash pop --index failed: Try again dropping the index execute_process( - COMMAND "@git_EXECUTABLE@" reset --hard --quiet + COMMAND "@git_EXECUTABLE@" --git-dir=.git reset --hard --quiet WORKING_DIRECTORY "@work_dir@" ) execute_process( - COMMAND "@git_EXECUTABLE@" stash pop --quiet + COMMAND "@git_EXECUTABLE@" --git-dir=.git stash pop --quiet WORKING_DIRECTORY "@work_dir@" RESULT_VARIABLE error_code ) if(error_code) # Stash pop failed: Restore previous state. execute_process( - COMMAND "@git_EXECUTABLE@" reset --hard --quiet ${head_sha} + COMMAND "@git_EXECUTABLE@" --git-dir=.git reset --hard --quiet ${head_sha} WORKING_DIRECTORY "@work_dir@" ) execute_process( - COMMAND "@git_EXECUTABLE@" stash pop --index --quiet + COMMAND "@git_EXECUTABLE@" --git-dir=.git stash pop --index --quiet WORKING_DIRECTORY "@work_dir@" ) message(FATAL_ERROR "\nFailed to unstash changes in: '@work_dir@'." @@ -270,7 +270,7 @@ endif() set(init_submodules "@init_submodules@") if(init_submodules) execute_process( - COMMAND "@git_EXECUTABLE@" submodule update @git_submodules_recurse@ --init @git_submodules@ + COMMAND "@git_EXECUTABLE@" --git-dir=.git submodule update @git_submodules_recurse@ --init @git_submodules@ WORKING_DIRECTORY "@work_dir@" COMMAND_ERROR_IS_FATAL ANY ) diff --git a/Modules/FetchContent.cmake b/Modules/FetchContent.cmake index 7e14756..8afb9bc 100644 --- a/Modules/FetchContent.cmake +++ b/Modules/FetchContent.cmake @@ -11,6 +11,12 @@ FetchContent .. contents:: +.. note:: The :guide:`Using Dependencies Guide` provides a high-level + introduction to this general topic. It provides a broader overview of + where the ``FetchContent`` module fits into the bigger picture, + including its relationship to the :command:`find_package` command. + The guide is recommended pre-reading before moving on to the details below. + Overview ^^^^^^^^ @@ -102,7 +108,13 @@ Commands .. code-block:: cmake - FetchContent_Declare(<name> <contentOptions>...) + FetchContent_Declare( + <name> + <contentOptions>... + [SYSTEM] + [OVERRIDE_FIND_PACKAGE | + FIND_PACKAGE_ARGS args...] + ) The ``FetchContent_Declare()`` function records the options that describe how to populate the specified content. If such details have already @@ -169,6 +181,65 @@ Commands they do for :command:`ExternalProject_Add`. Previously, these variables were ignored by the ``FetchContent`` module. + .. versionadded:: 3.24 + + ``FIND_PACKAGE_ARGS`` + This option is for scenarios where the + :command:`FetchContent_MakeAvailable` command may first try a call to + :command:`find_package` to satisfy the dependency for ``<name>``. + By default, such a call would be simply ``find_package(<name>)``, but + ``FIND_PACKAGE_ARGS`` can be used to provide additional arguments to be + appended after the ``<name>``. ``FIND_PACKAGE_ARGS`` can also be given + with nothing after it, which indicates that :command:`find_package` can + still be called if :variable:`FETCHCONTENT_TRY_FIND_PACKAGE_MODE` is + set to ``OPT_IN`` or is not set. + + Everything after the ``FIND_PACKAGE_ARGS`` keyword is appended to the + :command:`find_package` call, so all other ``<contentOptions>`` must + come before the ``FIND_PACKAGE_ARGS`` keyword. If the + :variable:`CMAKE_FIND_PACKAGE_TARGETS_GLOBAL` variable is set to true + at the time ``FetchContent_Declare()`` is called, a ``GLOBAL`` keyword + will be appended to the :command:`find_package` arguments if it was + not already specified. It will also be appended if + ``FIND_PACKAGE_ARGS`` was not given, but + :variable:`FETCHCONTENT_TRY_FIND_PACKAGE_MODE` was set to ``ALWAYS``. + + ``OVERRIDE_FIND_PACKAGE`` cannot be used when ``FIND_PACKAGE_ARGS`` is + given. + + :ref:`dependency_providers` discusses another way that + :command:`FetchContent_MakeAvailable` calls can be redirected. + ``FIND_PACKAGE_ARGS`` is intended for project control, whereas + dependency providers allow users to override project behavior. + + ``OVERRIDE_FIND_PACKAGE`` + When a ``FetchContent_Declare(<name> ...)`` call includes this option, + subsequent calls to ``find_package(<name> ...)`` will ensure that + ``FetchContent_MakeAvailable(<name>)`` has been called, then use the + config package files in the :variable:`CMAKE_FIND_PACKAGE_REDIRECTS_DIR` + directory (which are usually created by ``FetchContent_MakeAvailable()``). + This effectively makes :command:`FetchContent_MakeAvailable` override + :command:`find_package` for the named dependency, allowing the former to + satisfy the package requirements of the latter. ``FIND_PACKAGE_ARGS`` + cannot be used when ``OVERRIDE_FIND_PACKAGE`` is given. + + If a :ref:`dependency provider <dependency_providers>` has been set + and the project calls :command:`find_package` for the ``<name>`` + dependency, ``OVERRIDE_FIND_PACKAGE`` will not prevent the provider + from seeing that call. Dependency providers always have the opportunity + to intercept any direct call to :command:`find_package`, except if that + call contains the ``BYPASS_PROVIDER`` option. + + .. versionadded:: 3.25 + + ``SYSTEM`` + If the ``SYSTEM`` argument is provided, the :prop_dir:`SYSTEM` directory + property of a subdirectory added by + :command:`FetchContent_MakeAvailable` will be set to true. This will + affect non-imported targets created as part of that command. + See the :prop_tgt:`SYSTEM` target property documentation for a more + detailed discussion of the effects. + .. command:: FetchContent_MakeAvailable .. versionadded:: 3.14 @@ -177,9 +248,45 @@ Commands FetchContent_MakeAvailable(<name1> [<name2>...]) - This command ensures that each of the named dependencies are populated and - potentially added to the build by the time it returns. It iterates over - the list, and for each dependency, the following logic is applied: + This command ensures that each of the named dependencies are made available + to the project by the time it returns. There must have been a call to + :command:`FetchContent_Declare` for each dependency, and the first such call + will control how that dependency will be made available, as described below. + + If ``<lowercaseName>_SOURCE_DIR`` is not set: + + * .. versionadded:: 3.24 + + If a :ref:`dependency provider <dependency_providers>` is set, call the + provider's command with ``FETCHCONTENT_MAKEAVAILABLE_SERIAL`` as the + first argument, followed by the arguments of the first call to + :command:`FetchContent_Declare` for ``<name>``. If ``SOURCE_DIR`` or + ``BINARY_DIR`` were not part of the original declared arguments, they + will be added with their default values. + If :variable:`FETCHCONTENT_TRY_FIND_PACKAGE_MODE` was set to ``NEVER`` + when the details were declared, any ``FIND_PACKAGE_ARGS`` will be + omitted. The ``OVERRIDE_FIND_PACKAGE`` keyword is also always omitted. + If the provider fulfilled the request, ``FetchContent_MakeAvailable()`` + will consider that dependency handled, skip the remaining steps below + and move on to the next dependency in the list. + + * .. versionadded:: 3.24 + + If permitted, :command:`find_package(<name> [<args>...]) <find_package>` + will be called, where ``<args>...`` may be provided by the + ``FIND_PACKAGE_ARGS`` option in :command:`FetchContent_Declare`. + The value of the :variable:`FETCHCONTENT_TRY_FIND_PACKAGE_MODE` variable + at the time :command:`FetchContent_Declare` was called determines whether + ``FetchContent_MakeAvailable()`` can call :command:`find_package`. + If the :variable:`CMAKE_FIND_PACKAGE_TARGETS_GLOBAL` variable is set to + true when ``FetchContent_MakeAvailable()`` is called, it still affects + any imported targets created when that in turn calls + :command:`find_package`, even if that variable was false when the + corresponding details were declared. + + If the dependency was not satisfied by a provider or a + :command:`find_package` call, ``FetchContent_MakeAvailable()`` then uses + the following logic to make the dependency available: * If the dependency has already been populated earlier in this run, set the ``<lowercaseName>_POPULATED``, ``<lowercaseName>_SOURCE_DIR`` and @@ -194,6 +301,40 @@ Commands the declared details and use content provided at the specified location instead. + * .. versionadded:: 3.24 + + Ensure the :variable:`CMAKE_FIND_PACKAGE_REDIRECTS_DIR` directory + contains a ``<lowercaseName>-config.cmake`` and a + ``<lowercaseName>-config-version.cmake`` file (or equivalently + ``<name>Config.cmake`` and ``<name>ConfigVersion.cmake``). + The directory that the :variable:`CMAKE_FIND_PACKAGE_REDIRECTS_DIR` + variable points to is cleared at the start of every CMake run. + If no config file exists when :command:`FetchContent_Populate` returns, + a minimal one will be written which :command:`includes <include>` any + ``<lowercaseName>-extra.cmake`` or ``<name>Extra.cmake`` file with the + ``OPTIONAL`` flag (so the files can be missing and won't generate a + warning). Similarly, if no config version file exists, a very simple + one will be written which sets ``PACKAGE_VERSION_COMPATIBLE`` and + ``PACKAGE_VERSION_EXACT`` to true. This ensures all future calls to + :command:`find_package()` for the dependency will use the redirected + config file, regardless of any version requirements. + CMake cannot automatically determine an arbitrary dependency's version, + so it cannot set ``PACKAGE_VERSION``. + When a dependency is pulled in via :command:`add_subdirectory` in the + next step, it may choose to overwrite the generated config version file + in :variable:`CMAKE_FIND_PACKAGE_REDIRECTS_DIR` with one that also sets + ``PACKAGE_VERSION``. + The dependency may also write a ``<lowercaseName>-extra.cmake`` or + ``<name>Extra.cmake`` file to perform custom processing or define any + variables that their normal (installed) package config file would + otherwise usually define (many projects don't do any custom processing + or set any variables and therefore have no need to do this). + If required, the main project can write these files instead if the + dependency project doesn't do so. This allows the main project to + add missing details from older dependencies that haven't or can't be + updated to support this functionality. + See `Integrating With find_package()`_ for examples. + * If the top directory of the populated content contains a ``CMakeLists.txt`` file, call :command:`add_subdirectory` to add it to the main build. It is not an error for there to be no ``CMakeLists.txt`` file, which @@ -212,6 +353,11 @@ Commands adding a project that contains a ``CMakeLists.txt`` file in its top directory. + .. versionadded:: 3.25 + If the ``SYSTEM`` keyword was included in the call to + :command:`FetchContent_Declare`, the ``SYSTEM`` keyword will be + added to the :command:`add_subdirectory` command as well. + Projects should aim to declare the details of all dependencies they might use before they call ``FetchContent_MakeAvailable()`` for any of them. This ensures that if any of the dependencies are also sub-dependencies of @@ -237,6 +383,18 @@ Commands FetchContent_Declare(other ...) FetchContent_MakeAvailable(uses_other other) + Note that :variable:`CMAKE_VERIFY_INTERFACE_HEADER_SETS` is explicitly set + to false upon entry to ``FetchContent_MakeAvailable()``, and is restored to + its original value before the command returns. Developers typically only + want to verify header sets from the main project, not those from any + dependencies. This local manipulation of the + :variable:`CMAKE_VERIFY_INTERFACE_HEADER_SETS` variable provides that + intuitive behavior. You can use variables like + :variable:`CMAKE_PROJECT_INCLUDE` or + :variable:`CMAKE_PROJECT_<PROJECT-NAME>_INCLUDE` to turn verification back + on for all or some dependencies. You can also set the + :prop_tgt:`VERIFY_INTERFACE_HEADER_SETS` property of individual targets. + .. command:: FetchContent_Populate .. note:: @@ -389,7 +547,7 @@ Commands When using saved content details, a call to :command:`FetchContent_MakeAvailable` or :command:`FetchContent_Populate` records information in global properties which can be queried at any time. - This information includes the source and binary directories associated with + This information may include the source and binary directories associated with the content and also whether or not the content population has been processed during the current configure run. @@ -409,6 +567,8 @@ Commands set the same variables as a call to :command:`FetchContent_MakeAvailable(name) <FetchContent_MakeAvailable>` or :command:`FetchContent_Populate(name) <FetchContent_Populate>`. + Note that the ``SOURCE_DIR`` and ``BINARY_DIR`` values can be empty if the + call is fulfilled by a :ref:`dependency provider <dependency_providers>`. This command is rarely needed when using :command:`FetchContent_MakeAvailable`. It is more commonly used as part of @@ -432,13 +592,42 @@ Commands add_subdirectory(${depname_SOURCE_DIR} ${depname_BINARY_DIR}) endif() +.. command:: FetchContent_SetPopulated + + .. versionadded:: 3.24 + + .. note:: + This command should only be called by + :ref:`dependency providers <dependency_providers>`. Calling it in any + other context is unsupported and future CMake versions may halt with a + fatal error in such cases. + + .. code-block:: cmake + + FetchContent_SetPopulated( + <name> + [SOURCE_DIR <srcDir>] + [BINARY_DIR <binDir>] + ) + + If a provider command fulfills a ``FETCHCONTENT_MAKEAVAILABLE_SERIAL`` + request, it must call this function before returning. The ``SOURCE_DIR`` + and ``BINARY_DIR`` arguments can be used to specify the values that + :command:`FetchContent_GetProperties` should return for its corresponding + arguments. Only provide ``SOURCE_DIR`` and ``BINARY_DIR`` if they have + the same meaning as if they had been populated by the built-in + :command:`FetchContent_MakeAvailable` implementation. + + Variables ^^^^^^^^^ A number of cache variables can influence the behavior where details from a :command:`FetchContent_Declare` call are used to populate content. -The variables are all intended for the developer to customize behavior and -should not normally be set by the project. + +.. note:: + All of these variables are intended for the developer to customize behavior. + They should not normally be set by the project. .. variable:: FETCHCONTENT_BASE_DIR @@ -481,8 +670,53 @@ should not normally be set by the project. This can speed up the configure stage, but not as much as :variable:`FETCHCONTENT_FULLY_DISCONNECTED`. It is ``OFF`` by default. -In addition to the above cache variables, the following cache variables are -also defined for each content name: +.. variable:: FETCHCONTENT_TRY_FIND_PACKAGE_MODE + + .. versionadded:: 3.24 + + This variable modifies the details that :command:`FetchContent_Declare` + records for a given dependency. While it ultimately controls the behavior + of :command:`FetchContent_MakeAvailable`, it is the variable's value when + :command:`FetchContent_Declare` is called that gets used. It makes no + difference what the variable is set to when + :command:`FetchContent_MakeAvailable` is called. Since the variable should + only be set by the user and not by projects directly, it will typically have + the same value throughout anyway, so this distinction is not usually + noticeable. + + ``FETCHCONTENT_TRY_FIND_PACKAGE_MODE`` ultimately controls whether + :command:`FetchContent_MakeAvailable` is allowed to call + :command:`find_package` to satisfy a dependency. The variable can be set + to one of the following values: + + ``OPT_IN`` + :command:`FetchContent_MakeAvailable` will only call + :command:`find_package` if the :command:`FetchContent_Declare` call + included a ``FIND_PACKAGE_ARGS`` keyword. This is also the default + behavior if ``FETCHCONTENT_TRY_FIND_PACKAGE_MODE`` is not set. + + ``ALWAYS`` + :command:`find_package` can be called by + :command:`FetchContent_MakeAvailable` regardless of whether the + :command:`FetchContent_Declare` call included a ``FIND_PACKAGE_ARGS`` + keyword or not. If no ``FIND_PACKAGE_ARGS`` keyword was given, the + behavior will be as though ``FIND_PACKAGE_ARGS`` had been provided, + with no additional arguments after it. + + ``NEVER`` + :command:`FetchContent_MakeAvailable` will not call + :command:`find_package`. Any ``FIND_PACKAGE_ARGS`` given to the + :command:`FetchContent_Declare` call will be ignored. + + As a special case, if the :variable:`FETCHCONTENT_SOURCE_DIR_<uppercaseName>` + variable has a non-empty value for a dependency, it is assumed that the + user is overriding all other methods of making that dependency available. + ``FETCHCONTENT_TRY_FIND_PACKAGE_MODE`` will have no effect on that + dependency and :command:`FetchContent_MakeAvailable` will not try to call + :command:`find_package` for it. + +In addition to the above, the following variables are also defined for each +content name: .. variable:: FETCHCONTENT_SOURCE_DIR_<uppercaseName> @@ -511,6 +745,9 @@ also defined for each content name: Examples ^^^^^^^^ +Typical Case +"""""""""""" + This first fairly straightforward example ensures that some popular testing frameworks are available to the main build: @@ -525,18 +762,148 @@ frameworks are available to the main build: FetchContent_Declare( Catch2 GIT_REPOSITORY https://github.com/catchorg/Catch2.git - GIT_TAG de6fe184a9ac1a06895cdd1c9b437f0a0bdf14ad # v2.13.4 + GIT_TAG 605a34765aa5d5ecbf476b4598a862ada971b0cc # v3.0.1 ) # After the following call, the CMake targets defined by googletest and # Catch2 will be available to the rest of the build FetchContent_MakeAvailable(googletest Catch2) +.. _FetchContent-find_package-integration-examples: + +Integrating With find_package() +""""""""""""""""""""""""""""""" + +For the previous example, if the user wanted to try to find ``googletest`` +and ``Catch2`` via :command:`find_package` first before trying to download +and build them from source, they could set the +:variable:`FETCHCONTENT_TRY_FIND_PACKAGE_MODE` variable to ``ALWAYS``. +This would also affect any other calls to :command:`FetchContent_Declare` +throughout the project, which might not be acceptable. The behavior can be +enabled for just these two dependencies instead by adding ``FIND_PACKAGE_ARGS`` +to the declared details and leaving +:variable:`FETCHCONTENT_TRY_FIND_PACKAGE_MODE` unset, or set to ``OPT_IN``: + +.. code-block:: cmake + + include(FetchContent) + FetchContent_Declare( + googletest + GIT_REPOSITORY https://github.com/google/googletest.git + GIT_TAG 703bd9caab50b139428cea1aaff9974ebee5742e # release-1.10.0 + FIND_PACKAGE_ARGS NAMES GTest + ) + FetchContent_Declare( + Catch2 + GIT_REPOSITORY https://github.com/catchorg/Catch2.git + GIT_TAG 605a34765aa5d5ecbf476b4598a862ada971b0cc # v3.0.1 + FIND_PACKAGE_ARGS + ) + + # This will try calling find_package() first for both dependencies + FetchContent_MakeAvailable(googletest Catch2) + +For ``Catch2``, no additional arguments to :command:`find_package` are needed, +so no additional arguments are provided after the ``FIND_PACKAGE_ARGS`` +keyword. For ``googletest``, its package is more commonly called ``GTest``, +so arguments are added to support it being found by that name. + +If the user wanted to disable :command:`FetchContent_MakeAvailable` from +calling :command:`find_package` for any dependency, even if it provided +``FIND_PACKAGE_ARGS`` in its declared details, they could set +:variable:`FETCHCONTENT_TRY_FIND_PACKAGE_MODE` to ``NEVER``. + +If the project wanted to indicate that these two dependencies should be +downloaded and built from source and that :command:`find_package` calls +should be redirected to use the built dependencies, the +``OVERRIDE_FIND_PACKAGE`` option should be used when declaring the content +details: + +.. code-block:: cmake + + include(FetchContent) + FetchContent_Declare( + googletest + GIT_REPOSITORY https://github.com/google/googletest.git + GIT_TAG 703bd9caab50b139428cea1aaff9974ebee5742e # release-1.10.0 + OVERRIDE_FIND_PACKAGE + ) + FetchContent_Declare( + Catch2 + GIT_REPOSITORY https://github.com/catchorg/Catch2.git + GIT_TAG 605a34765aa5d5ecbf476b4598a862ada971b0cc # v3.0.1 + OVERRIDE_FIND_PACKAGE + ) + + # The following will automatically forward through to FetchContent_MakeAvailable() + find_package(googletest) + find_package(Catch2) + +CMake provides a FindGTest module which defines some variables that older +projects may use instead of linking to the imported targets. To support +those cases, we can provide an extra file. In keeping with the +"first to define, wins" philosophy of ``FetchContent``, we only write out +that file if something else hasn't already done so. + +.. code-block:: cmake + + FetchContent_MakeAvailable(googletest) + + if(NOT EXISTS ${CMAKE_FIND_PACKAGE_REDIRECTS_DIR}/googletest-extra.cmake AND + NOT EXISTS ${CMAKE_FIND_PACKAGE_REDIRECTS_DIR}/googletestExtra.cmake) + file(WRITE ${CMAKE_FIND_PACKAGE_REDIRECTS_DIR}/googletest-extra.cmake + [=[ + if("${GTEST_LIBRARIES}" STREQUAL "" AND TARGET GTest::gtest) + set(GTEST_LIBRARIES GTest::gtest) + endif() + if("${GTEST_MAIN_LIBRARIES}" STREQUAL "" AND TARGET GTest::gtest_main) + set(GTEST_MAIN_LIBRARIES GTest::gtest_main) + endif() + if("${GTEST_BOTH_LIBRARIES}" STREQUAL "") + set(GTEST_BOTH_LIBRARIES ${GTEST_LIBRARIES} ${GTEST_MAIN_LIBRARIES}) + endif() + ]=]) + endif() + +Projects will also likely be using ``find_package(GTest)`` rather than +``find_package(googletest)``, but it is possible to make use of the +:variable:`CMAKE_FIND_PACKAGE_REDIRECTS_DIR` area to pull in the latter as +a dependency of the former. This is likely to be sufficient to satisfy +a typical ``find_package(GTest)`` call. + +.. code-block:: cmake + + FetchContent_MakeAvailable(googletest) + + if(NOT EXISTS ${CMAKE_FIND_PACKAGE_REDIRECTS_DIR}/gtest-config.cmake AND + NOT EXISTS ${CMAKE_FIND_PACKAGE_REDIRECTS_DIR}/GTestConfig.cmake) + file(WRITE ${CMAKE_FIND_PACKAGE_REDIRECTS_DIR}/gtest-config.cmake + [=[ + include(CMakeFindDependencyMacro) + find_dependency(googletest) + ]=]) + endif() + + if(NOT EXISTS ${CMAKE_FIND_PACKAGE_REDIRECTS_DIR}/gtest-config-version.cmake AND + NOT EXISTS ${CMAKE_FIND_PACKAGE_REDIRECTS_DIR}/GTestConfigVersion.cmake) + file(WRITE ${CMAKE_FIND_PACKAGE_REDIRECTS_DIR}/gtest-config-version.cmake + [=[ + include(${CMAKE_FIND_PACKAGE_REDIRECTS_DIR}/googletest-config-version.cmake OPTIONAL) + if(NOT PACKAGE_VERSION_COMPATIBLE) + include(${CMAKE_FIND_PACKAGE_REDIRECTS_DIR}/googletestConfigVersion.cmake OPTIONAL) + endif() + ]=]) + endif() + +Overriding Where To Find CMakeLists.txt +""""""""""""""""""""""""""""""""""""""" + If the sub-project's ``CMakeLists.txt`` file is not at the top level of its source tree, the ``SOURCE_SUBDIR`` option can be used to tell ``FetchContent`` -where to find it. The following example shows how to use that option and +where to find it. The following example shows how to use that option, and it also sets a variable which is meaningful to the subproject before pulling -it into the main build: +it into the main build (set as an ``INTERNAL`` cache variable to avoid +problems with policy :policy:`CMP0077`): .. code-block:: cmake @@ -547,9 +914,12 @@ it into the main build: GIT_TAG ae50d9b9902526efd6c7a1907d09739f959c6297 # v3.15.0 SOURCE_SUBDIR cmake ) - set(protobuf_BUILD_TESTS OFF) + set(protobuf_BUILD_TESTS OFF CACHE INTERNAL "") FetchContent_MakeAvailable(protobuf) +Complex Dependency Hierarchies +"""""""""""""""""""""""""""""" + In more complex project hierarchies, the dependency relationships can be more complicated. Consider a hierarchy where ``projA`` is the top level project and it depends directly on projects ``projB`` and ``projC``. Both ``projB`` and @@ -558,9 +928,8 @@ it depends directly on projects ``projB`` and ``projC``. Both ``projB`` and that all five projects are available on a company git server. The ``CMakeLists.txt`` of each project might have sections like the following: -*projA*: - .. code-block:: cmake + :caption: *projA* include(FetchContent) FetchContent_Declare( @@ -587,9 +956,9 @@ that all five projects are available on a company git server. The # Order is important, see notes in the discussion further below FetchContent_MakeAvailable(projD projB projC) -*projB*: .. code-block:: cmake + :caption: *projB* include(FetchContent) FetchContent_Declare( @@ -605,9 +974,9 @@ that all five projects are available on a company git server. The FetchContent_MakeAvailable(projD projE) -*projC*: .. code-block:: cmake + :caption: *projC* include(FetchContent) FetchContent_Declare( @@ -647,6 +1016,8 @@ A few key points should be noted in the above: child projects. This saves repeating the same thing at each level of the project hierarchy unnecessarily. +Populating Content Without Adding It To The Build +""""""""""""""""""""""""""""""""""""""""""""""""" Projects don't always need to add the populated content to the build. Sometimes the project just wants to make the downloaded content available at @@ -680,17 +1051,19 @@ directory. The :variable:`CMAKE_TOOLCHAIN_FILE` variable is not used until the :command:`project` command is reached, at which point CMake looks for the named toolchain file relative to the build directory. Because the tarball has already been downloaded and unpacked by then, the toolchain file will be in -place, even the very first time that ``cmake`` is run in the build directory. +place, even the very first time that :program:`cmake` is run in the build directory. + +Populating Content In CMake Script Mode +""""""""""""""""""""""""""""""""""""""" -Lastly, the following example demonstrates how one might download and unpack a +This last example demonstrates how one might download and unpack a firmware tarball using CMake's :manual:`script mode <cmake(1)>`. The call to :command:`FetchContent_Populate` specifies all the content details and the unpacked firmware will be placed in a ``firmware`` directory below the current working directory. -*getFirmware.cmake*: - .. code-block:: cmake + :caption: :file:`getFirmware.cmake` # NOTE: Intended to be run in script mode with cmake -P include(FetchContent) @@ -722,19 +1095,89 @@ current working directory. function(__FetchContent_declareDetails contentName) string(TOLOWER ${contentName} contentNameLower) - set(propertyName "_FetchContent_${contentNameLower}_savedDetails") - get_property(alreadyDefined GLOBAL PROPERTY ${propertyName} DEFINED) - if(NOT alreadyDefined) - define_property(GLOBAL PROPERTY ${propertyName} - BRIEF_DOCS "Internal implementation detail of FetchContent_Populate()" - FULL_DOCS "Details used by FetchContent_Populate() for ${contentName}" + set(savedDetailsPropertyName "_FetchContent_${contentNameLower}_savedDetails") + get_property(alreadyDefined GLOBAL PROPERTY ${savedDetailsPropertyName} DEFINED) + if(alreadyDefined) + return() + endif() + + if("${FETCHCONTENT_TRY_FIND_PACKAGE_MODE}" STREQUAL "ALWAYS") + set(__tryFindPackage TRUE) + set(__tryFindPackageAllowed TRUE) + elseif("${FETCHCONTENT_TRY_FIND_PACKAGE_MODE}" STREQUAL "NEVER") + set(__tryFindPackage FALSE) + set(__tryFindPackageAllowed FALSE) + elseif("${FETCHCONTENT_TRY_FIND_PACKAGE_MODE}" STREQUAL "OPT_IN" OR + NOT DEFINED FETCHCONTENT_TRY_FIND_PACKAGE_MODE) + set(__tryFindPackage FALSE) + set(__tryFindPackageAllowed TRUE) + else() + message(FATAL_ERROR + "Unsupported value for FETCHCONTENT_TRY_FIND_PACKAGE_MODE: " + "${FETCHCONTENT_TRY_FIND_PACKAGE_MODE}" ) - set(__cmdArgs) - foreach(__item IN LISTS ARGN) - string(APPEND __cmdArgs " [==[${__item}]==]") - endforeach() + endif() + + set(__cmdArgs) + set(__findPackageArgs) + set(__sawQuietKeyword NO) + set(__sawGlobalKeyword NO) + foreach(__item IN LISTS ARGN) + if(DEFINED __findPackageArgs) + # All remaining args are for find_package() + string(APPEND __findPackageArgs " [==[${__item}]==]") + if(__item STREQUAL "QUIET") + set(__sawQuietKeyword YES) + elseif(__item STREQUAL "GLOBAL") + set(__sawGlobalKeyword YES) + endif() + continue() + endif() + + # Still processing non-find_package() args + if(__item STREQUAL "FIND_PACKAGE_ARGS") + if(__tryFindPackageAllowed) + set(__tryFindPackage TRUE) + endif() + # All arguments after this keyword are for find_package(). Define the + # variable but with an empty value initially. This allows us to check + # at the start of the loop whether to store remaining items in this + # variable or not. Note that there could be no more args, which is still + # a valid case because we automatically provide ${contentName} as the + # package name and there may not need to be any further arguments. + set(__findPackageArgs "") + continue() # Don't store this item + elseif(__item STREQUAL "OVERRIDE_FIND_PACKAGE") + set(__tryFindPackageAllowed FALSE) + # Define a separate dedicated property for find_package() to check + # in its implementation. This will be a placeholder until FetchContent + # actually does the population. After that, we will have created a + # stand-in config file that find_package() will pick up instead. + set(propertyName "_FetchContent_${contentNameLower}_override_find_package") + define_property(GLOBAL PROPERTY ${propertyName}) + set_property(GLOBAL PROPERTY ${propertyName} TRUE) + endif() + + string(APPEND __cmdArgs " [==[${__item}]==]") + endforeach() + + define_property(GLOBAL PROPERTY ${savedDetailsPropertyName}) + cmake_language(EVAL CODE + "set_property(GLOBAL PROPERTY ${savedDetailsPropertyName} ${__cmdArgs})" + ) + + if(__tryFindPackage AND __tryFindPackageAllowed) + set(propertyName "_FetchContent_${contentNameLower}_find_package_args") + define_property(GLOBAL PROPERTY ${propertyName}) + if(NOT __sawQuietKeyword) + list(INSERT __findPackageArgs 0 QUIET) + endif() + if(CMAKE_FIND_PACKAGE_TARGETS_GLOBAL AND NOT __sawGlobalKeyword) + list(APPEND __findPackageArgs GLOBAL) + endif() cmake_language(EVAL CODE - "set_property(GLOBAL PROPERTY ${propertyName} ${__cmdArgs})") + "set_property(GLOBAL PROPERTY ${propertyName} ${__findPackageArgs})" + ) endif() endfunction() @@ -763,15 +1206,42 @@ endfunction() # SOURCE_DIR and BUILD_DIR. function(FetchContent_Declare contentName) - set(options "") - set(oneValueArgs SVN_REPOSITORY) - set(multiValueArgs "") + # Always check this even if we won't save these details. + # This helps projects catch errors earlier. + # Avoid using if(... IN_LIST ...) so we don't have to alter policy settings + list(FIND ARGN OVERRIDE_FIND_PACKAGE index_OVERRIDE_FIND_PACKAGE) + list(FIND ARGN FIND_PACKAGE_ARGS index_FIND_PACKAGE_ARGS) + if(index_OVERRIDE_FIND_PACKAGE GREATER_EQUAL 0 AND + index_FIND_PACKAGE_ARGS GREATER_EQUAL 0) + message(FATAL_ERROR + "Cannot specify both OVERRIDE_FIND_PACKAGE and FIND_PACKAGE_ARGS " + "when declaring details for ${contentName}" + ) + endif() - cmake_parse_arguments(PARSE_ARGV 1 ARG - "${options}" "${oneValueArgs}" "${multiValueArgs}") + # Because we are only looking for a subset of the supported keywords, we + # cannot check for multi-value arguments with this method. We will have to + # handle the URL keyword differently. + set(oneValueArgs + SVN_REPOSITORY + DOWNLOAD_NO_EXTRACT + DOWNLOAD_EXTRACT_TIMESTAMP + BINARY_DIR + SOURCE_DIR + ) + + cmake_parse_arguments(PARSE_ARGV 1 ARG "" "${oneValueArgs}" "") + + string(TOLOWER ${contentName} contentNameLower) + + if(NOT ARG_BINARY_DIR) + set(ARG_BINARY_DIR "${FETCHCONTENT_BASE_DIR}/${contentNameLower}-build") + endif() + + if(NOT ARG_SOURCE_DIR) + set(ARG_SOURCE_DIR "${FETCHCONTENT_BASE_DIR}/${contentNameLower}-src") + endif() - unset(srcDirSuffix) - unset(svnRepoArgs) if(ARG_SVN_REPOSITORY) # Add a hash of the svn repository URL to the source dir. This works # around the problem where if the URL changes, the download would @@ -781,25 +1251,69 @@ function(FetchContent_Declare contentName) # problem on windows due to path length limits). string(SHA1 urlSHA ${ARG_SVN_REPOSITORY}) string(SUBSTRING ${urlSHA} 0 7 urlSHA) - set(srcDirSuffix "-${urlSHA}") - set(svnRepoArgs SVN_REPOSITORY ${ARG_SVN_REPOSITORY}) + string(APPEND ARG_SOURCE_DIR "-${urlSHA}") endif() - string(TOLOWER ${contentName} contentNameLower) + # The ExternalProject_Add() call in the sub-build won't see the CMP0135 + # policy setting of our caller. Work out if that policy will be needed and + # explicitly set the relevant option if not already provided. The condition + # here is essentially an abbreviated version of the logic in + # ExternalProject's _ep_add_download_command() function. + if(NOT ARG_DOWNLOAD_NO_EXTRACT AND + NOT DEFINED ARG_DOWNLOAD_EXTRACT_TIMESTAMP) + list(FIND ARGN URL urlIndex) + if(urlIndex GREATER_EQUAL 0) + math(EXPR urlIndex "${urlIndex} + 1") + list(LENGTH ARGN numArgs) + if(urlIndex GREATER_EQUAL numArgs) + message(FATAL_ERROR + "URL keyword needs to be followed by at least one URL" + ) + endif() + # If we have multiple URLs, none of them are allowed to be local paths. + # Therefore, we can test just the first URL, and if it is non-local, so + # will be the others if there are more. + list(GET ARGN ${urlIndex} firstUrl) + if(NOT IS_DIRECTORY "${firstUrl}") + cmake_policy(GET CMP0135 _FETCHCONTENT_CMP0135 + PARENT_SCOPE # undocumented, do not use outside of CMake + ) + if(_FETCHCONTENT_CMP0135 STREQUAL "") + message(AUTHOR_WARNING + "The DOWNLOAD_EXTRACT_TIMESTAMP option was not given and policy " + "CMP0135 is not set. The policy's OLD behavior will be used. " + "When using a URL download, the timestamps of extracted files " + "should preferably be that of the time of extraction, otherwise " + "code that depends on the extracted contents might not be " + "rebuilt if the URL changes. The OLD behavior preserves the " + "timestamps from the archive instead, but this is usually not " + "what you want. Update your project to the NEW behavior or " + "specify the DOWNLOAD_EXTRACT_TIMESTAMP option with a value of " + "true to avoid this robustness issue." + ) + set(ARG_DOWNLOAD_EXTRACT_TIMESTAMP TRUE) + elseif(_FETCHCONTENT_CMP0135 STREQUAL "NEW") + set(ARG_DOWNLOAD_EXTRACT_TIMESTAMP FALSE) + else() + set(ARG_DOWNLOAD_EXTRACT_TIMESTAMP TRUE) + endif() + endif() + endif() + endif() + + # Add back in the keyword args we pulled out and potentially tweaked/added + foreach(key IN LISTS oneValueArgs) + if(DEFINED ARG_${key}) + list(PREPEND ARG_UNPARSED_ARGUMENTS ${key} "${ARG_${key}}") + endif() + endforeach() set(__argsQuoted) foreach(__item IN LISTS ARG_UNPARSED_ARGUMENTS) string(APPEND __argsQuoted " [==[${__item}]==]") endforeach() - cmake_language(EVAL CODE " - __FetchContent_declareDetails( - ${contentNameLower} - SOURCE_DIR \"${FETCHCONTENT_BASE_DIR}/${contentNameLower}-src${srcDirSuffix}\" - BINARY_DIR \"${FETCHCONTENT_BASE_DIR}/${contentNameLower}-build\" - \${svnRepoArgs} - # List these last so they can override things we set above - ${__argsQuoted} - )" + cmake_language(EVAL CODE + "__FetchContent_declareDetails(${contentNameLower} ${__argsQuoted})" ) endfunction() @@ -810,35 +1324,43 @@ endfunction() # The setter also records the source and binary dirs used. #======================================================================= -# Internal use, projects must not call this directly. It is -# intended for use by the FetchContent_Populate() function to -# record when FetchContent_Populate() is called for a particular -# content name. -function(__FetchContent_setPopulated contentName sourceDir binaryDir) +# Semi-internal use. Projects must not call this directly. Dependency +# providers must call it if they satisfy a request made with the +# FETCHCONTENT_MAKEAVAILABLE_SERIAL method (that is the only permitted +# place to call it outside of the FetchContent module). +function(FetchContent_SetPopulated contentName) + + cmake_parse_arguments(PARSE_ARGV 1 arg + "" + "SOURCE_DIR;BINARY_DIR" + "" + ) + if(NOT "${arg_UNPARSED_ARGUMENTS}" STREQUAL "") + message(FATAL_ERROR "Unsupported arguments: ${arg_UNPARSED_ARGUMENTS}") + endif() string(TOLOWER ${contentName} contentNameLower) set(prefix "_FetchContent_${contentNameLower}") set(propertyName "${prefix}_sourceDir") - define_property(GLOBAL PROPERTY ${propertyName} - BRIEF_DOCS "Internal implementation detail of FetchContent_Populate()" - FULL_DOCS "Details used by FetchContent_Populate() for ${contentName}" - ) - set_property(GLOBAL PROPERTY ${propertyName} ${sourceDir}) + define_property(GLOBAL PROPERTY ${propertyName}) + if("${arg_SOURCE_DIR}" STREQUAL "") + # Don't discard a previously provided SOURCE_DIR + get_property(arg_SOURCE_DIR GLOBAL PROPERTY ${propertyName}) + endif() + set_property(GLOBAL PROPERTY ${propertyName} "${arg_SOURCE_DIR}") set(propertyName "${prefix}_binaryDir") - define_property(GLOBAL PROPERTY ${propertyName} - BRIEF_DOCS "Internal implementation detail of FetchContent_Populate()" - FULL_DOCS "Details used by FetchContent_Populate() for ${contentName}" - ) - set_property(GLOBAL PROPERTY ${propertyName} ${binaryDir}) + define_property(GLOBAL PROPERTY ${propertyName}) + if("${arg_BINARY_DIR}" STREQUAL "") + # Don't discard a previously provided BINARY_DIR + get_property(arg_BINARY_DIR GLOBAL PROPERTY ${propertyName}) + endif() + set_property(GLOBAL PROPERTY ${propertyName} "${arg_BINARY_DIR}") set(propertyName "${prefix}_populated") - define_property(GLOBAL PROPERTY ${propertyName} - BRIEF_DOCS "Internal implementation detail of FetchContent_Populate()" - FULL_DOCS "Details used by FetchContent_Populate() for ${contentName}" - ) - set_property(GLOBAL PROPERTY ${propertyName} True) + define_property(GLOBAL PROPERTY ${propertyName}) + set_property(GLOBAL PROPERTY ${propertyName} TRUE) endfunction() @@ -908,6 +1430,9 @@ function(__FetchContent_directPopulate contentName) set(options QUIET + # SYSTEM has no meaning for ExternalProject, it is only used by us in + # FetchContent_MakeAvailable(). We need to parse and discard it here. + SYSTEM ) set(oneValueArgs SUBBUILD_DIR @@ -1016,6 +1541,14 @@ ExternalProject_Add_Step(${contentName}-populate copyfile list(APPEND subCMakeOpts "-DCMAKE_MAKE_PROGRAM:FILEPATH=${CMAKE_MAKE_PROGRAM}") endif() + # Override the sub-build's configuration types for multi-config generators. + # This ensures we are not affected by any custom setting from the project + # and can always request a known configuration further below. + get_property(is_multi_config GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) + if(is_multi_config) + list(APPEND subCMakeOpts "-DCMAKE_CONFIGURATION_TYPES:STRING=Debug") + endif() + else() # Likely we've been invoked via CMake's script mode where no # generator is set (and hence CMAKE_MAKE_PROGRAM could not be @@ -1060,7 +1593,8 @@ set_property(GLOBAL PROPERTY _CMAKE_FindGit_GIT_EXECUTABLE_VERSION # If we've already previously done these steps, they will not cause # anything to be updated, so extra rebuilds of the project won't occur. # Make sure to pass through CMAKE_MAKE_PROGRAM in case the main project - # has this set to something not findable on the PATH. + # has this set to something not findable on the PATH. We also ensured above + # that the Debug config will be defined for multi-config generators. configure_file("${CMAKE_CURRENT_FUNCTION_LIST_DIR}/FetchContent/CMakeLists.cmake.in" "${ARG_SUBBUILD_DIR}/CMakeLists.txt") execute_process( @@ -1076,7 +1610,7 @@ set_property(GLOBAL PROPERTY _CMAKE_FindGit_GIT_EXECUTABLE_VERSION message(FATAL_ERROR "CMake step for ${contentName} failed: ${result}") endif() execute_process( - COMMAND ${CMAKE_COMMAND} --build . + COMMAND ${CMAKE_COMMAND} --build . --config Debug RESULT_VARIABLE result ${outputOptions} WORKING_DIRECTORY "${ARG_SUBBUILD_DIR}" @@ -1134,7 +1668,16 @@ function(FetchContent_Populate contentName) # populated this content before in case the caller forgot to check. FetchContent_GetProperties(${contentName}) if(${contentNameLower}_POPULATED) - message(FATAL_ERROR "Content ${contentName} already populated in ${${contentNameLower}_SOURCE_DIR}") + if("${${contentNameLower}_SOURCE_DIR}" STREQUAL "") + message(FATAL_ERROR + "Content ${contentName} already populated by find_package() or a " + "dependency provider" + ) + else() + message(FATAL_ERROR + "Content ${contentName} already populated in ${${contentNameLower}_SOURCE_DIR}" + ) + endif() endif() __FetchContent_getSavedDetails(${contentName} contentDetails) @@ -1212,7 +1755,9 @@ function(FetchContent_Populate contentName) set(__detailsQuoted) foreach(__item IN LISTS contentDetails) - string(APPEND __detailsQuoted " [==[${__item}]==]") + if(NOT __item STREQUAL "OVERRIDE_FIND_PACKAGE") + string(APPEND __detailsQuoted " [==[${__item}]==]") + endif() endforeach() cmake_language(EVAL CODE " __FetchContent_directPopulate( @@ -1230,10 +1775,10 @@ function(FetchContent_Populate contentName) ) endif() - __FetchContent_setPopulated( + FetchContent_SetPopulated( ${contentName} - ${${contentNameLower}_SOURCE_DIR} - ${${contentNameLower}_BINARY_DIR} + SOURCE_DIR "${${contentNameLower}_SOURCE_DIR}" + BINARY_DIR "${${contentNameLower}_BINARY_DIR}" ) # Pass variables back to the caller. The variables passed back here @@ -1245,6 +1790,55 @@ function(FetchContent_Populate contentName) endfunction() +function(__FetchContent_setupFindPackageRedirection contentName) + + __FetchContent_getSavedDetails(${contentName} contentDetails) + + string(TOLOWER ${contentName} contentNameLower) + get_property(wantFindPackage GLOBAL PROPERTY + _FetchContent_${contentNameLower}_find_package_args + DEFINED + ) + + # Avoid using if(... IN_LIST ...) so we don't have to alter policy settings + list(FIND contentDetails OVERRIDE_FIND_PACKAGE indexResult) + if(NOT wantFindPackage AND indexResult EQUAL -1) + # No find_package() redirection allowed + return() + endif() + + # We write out dep-config.cmake and dep-config-version.cmake file name + # forms here because they are forced to lowercase. FetchContent + # dependency names are case-insensitive, but find_package() config files + # are only case-insensitive for the -config and -config-version forms, + # not the Config and ConfigVersion forms. + set(inFileDir ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/FetchContent) + set(configFilePrefix1 "${CMAKE_FIND_PACKAGE_REDIRECTS_DIR}/${contentName}Config") + set(configFilePrefix2 "${CMAKE_FIND_PACKAGE_REDIRECTS_DIR}/${contentNameLower}-config") + if(NOT EXISTS "${configFilePrefix1}.cmake" AND + NOT EXISTS "${configFilePrefix2}.cmake") + configure_file(${inFileDir}/package-config.cmake.in + "${configFilePrefix2}.cmake" @ONLY + ) + endif() + if(NOT EXISTS "${configFilePrefix1}Version.cmake" AND + NOT EXISTS "${configFilePrefix2}-version.cmake") + configure_file(${inFileDir}/package-config-version.cmake.in + "${configFilePrefix2}-version.cmake" @ONLY + ) + endif() + + # Now that we've created the redirected package config files, prevent + # find_package() from delegating to FetchContent and let it find these + # config files through its normal processing. + set(propertyName "${prefix}_override_find_package") + set(GLOBAL PROPERTY ${propertyName} FALSE) + set(${contentName}_DIR "${CMAKE_FIND_PACKAGE_REDIRECTS_DIR}" + CACHE INTERNAL "Redirected by FetchContent" + ) + +endfunction() + # Arguments are assumed to be the names of dependencies that have been # declared previously and should be populated. It is not an error if # any of them have already been populated (they will just be skipped in @@ -1253,11 +1847,134 @@ endfunction() # calls will be available to the caller. macro(FetchContent_MakeAvailable) + # We must append an item, even if the variable is unset, so prefix its value. + # We will strip that prefix when we pop the value at the end of the macro. + list(APPEND __cmake_fcCurrentVarsStack + "__fcprefix__${CMAKE_VERIFY_INTERFACE_HEADER_SETS}" + ) + set(CMAKE_VERIFY_INTERFACE_HEADER_SETS FALSE) + + get_property(__cmake_providerCommand GLOBAL PROPERTY + __FETCHCONTENT_MAKEAVAILABLE_SERIAL_PROVIDER + ) foreach(__cmake_contentName IN ITEMS ${ARGV}) string(TOLOWER ${__cmake_contentName} __cmake_contentNameLower) + + # If user specified FETCHCONTENT_SOURCE_DIR_... for this dependency, that + # overrides everything else and we shouldn't try to use find_package() or + # a dependency provider. + string(TOUPPER ${__cmake_contentName} __cmake_contentNameUpper) + if("${FETCHCONTENT_SOURCE_DIR_${__cmake_contentNameUpper}}" STREQUAL "") + # Dependency provider gets first opportunity, but prevent infinite + # recursion if we are called again for the same thing + if(NOT "${__cmake_providerCommand}" STREQUAL "" AND + NOT DEFINED __cmake_fcProvider_${__cmake_contentNameLower}) + message(VERBOSE + "Trying FETCHCONTENT_MAKEAVAILABLE_SERIAL dependency provider for " + "${__cmake_contentName}" + ) + # It's still valid if there are no saved details. The project may have + # been written to assume a dependency provider is always set and will + # provide dependencies without having any declared details for them. + __FetchContent_getSavedDetails(${__cmake_contentName} __cmake_contentDetails) + set(__cmake_providerArgs + "FETCHCONTENT_MAKEAVAILABLE_SERIAL" + "${__cmake_contentName}" + ) + # Empty arguments must be preserved because of things like + # GIT_SUBMODULES (see CMP0097) + foreach(__cmake_item IN LISTS __cmake_contentDetails) + string(APPEND __cmake_providerArgs " [==[${__cmake_item}]==]") + endforeach() + + # This property might be defined but empty. As long as it is defined, + # find_package() can be called. + get_property(__cmake_addfpargs GLOBAL PROPERTY + _FetchContent_${contentNameLower}_find_package_args + DEFINED + ) + if(__cmake_addfpargs) + get_property(__cmake_fpargs GLOBAL PROPERTY + _FetchContent_${contentNameLower}_find_package_args + ) + string(APPEND __cmake_providerArgs " FIND_PACKAGE_ARGS") + foreach(__cmake_item IN LISTS __cmake_fpargs) + string(APPEND __cmake_providerArgs " [==[${__cmake_item}]==]") + endforeach() + endif() + + # Calling the provider could lead to FetchContent_MakeAvailable() being + # called for a nested dependency. That nested call may occur in the + # current variable scope. We have to save and restore the variables we + # need preserved. + list(APPEND __cmake_fcCurrentVarsStack + ${__cmake_contentName} + ${__cmake_contentNameLower} + ) + + set(__cmake_fcProvider_${__cmake_contentNameLower} YES) + cmake_language(EVAL CODE "${__cmake_providerCommand}(${__cmake_providerArgs})") + + list(POP_BACK __cmake_fcCurrentVarsStack + __cmake_contentNameLower + __cmake_contentName + ) + + unset(__cmake_fcProvider_${__cmake_contentNameLower}) + unset(__cmake_providerArgs) + unset(__cmake_addfpargs) + unset(__cmake_fpargs) + unset(__cmake_item) + unset(__cmake_contentDetails) + + FetchContent_GetProperties(${__cmake_contentName}) + if(${__cmake_contentNameLower}_POPULATED) + continue() + endif() + endif() + + # Check if we've been asked to try find_package() first, even if we + # have already populated this dependency. If we previously tried to + # use find_package() for this and it succeeded, those things might + # no longer be in scope, so we have to do it again. + get_property(__cmake_haveFpArgs GLOBAL PROPERTY + _FetchContent_${__cmake_contentNameLower}_find_package_args DEFINED + ) + if(__cmake_haveFpArgs) + unset(__cmake_haveFpArgs) + message(VERBOSE "Trying find_package(${__cmake_contentName} ...) before FetchContent") + get_property(__cmake_fpArgs GLOBAL PROPERTY + _FetchContent_${__cmake_contentNameLower}_find_package_args + ) + + # This call could lead to FetchContent_MakeAvailable() being called for + # a nested dependency and it may occur in the current variable scope. + # We have to save/restore the variables we need to preserve. + list(APPEND __cmake_fcCurrentNameStack + ${__cmake_contentName} + ${__cmake_contentNameLower} + ) + find_package(${__cmake_contentName} ${__cmake_fpArgs}) + list(POP_BACK __cmake_fcCurrentNameStack + __cmake_contentNameLower + __cmake_contentName + ) + unset(__cmake_fpArgs) + + if(${__cmake_contentName}_FOUND) + FetchContent_SetPopulated(${__cmake_contentName}) + FetchContent_GetProperties(${__cmake_contentName}) + continue() + endif() + endif() + else() + unset(__cmake_haveFpArgs) + endif() + FetchContent_GetProperties(${__cmake_contentName}) if(NOT ${__cmake_contentNameLower}_POPULATED) FetchContent_Populate(${__cmake_contentName}) + __FetchContent_setupFindPackageRedirection(${__cmake_contentName}) # Only try to call add_subdirectory() if the populated content # can be treated that way. Protecting the call with the check @@ -1273,23 +1990,37 @@ macro(FetchContent_MakeAvailable) if("${__cmake_contentDetails}" STREQUAL "") message(FATAL_ERROR "No details have been set for content: ${__cmake_contentName}") endif() - cmake_parse_arguments(__cmake_arg "" "SOURCE_SUBDIR" "" ${__cmake_contentDetails}) + cmake_parse_arguments(__cmake_arg "SYSTEM" "SOURCE_SUBDIR" "" ${__cmake_contentDetails}) if(NOT "${__cmake_arg_SOURCE_SUBDIR}" STREQUAL "") string(APPEND __cmake_srcdir "/${__cmake_arg_SOURCE_SUBDIR}") endif() if(EXISTS ${__cmake_srcdir}/CMakeLists.txt) - add_subdirectory(${__cmake_srcdir} ${${__cmake_contentNameLower}_BINARY_DIR}) + if (__cmake_arg_SYSTEM) + add_subdirectory(${__cmake_srcdir} ${${__cmake_contentNameLower}_BINARY_DIR} SYSTEM) + else() + add_subdirectory(${__cmake_srcdir} ${${__cmake_contentNameLower}_BINARY_DIR}) + endif() endif() unset(__cmake_srcdir) + unset(__cmake_contentDetails) + unset(__cmake_arg_SOURCE_SUBDIR) endif() endforeach() + # Prefix will be "__fcprefix__" + list(POP_BACK __cmake_fcCurrentVarsStack __cmake_original_verify_setting) + string(SUBSTRING "${__cmake_original_verify_setting}" + 12 -1 __cmake_original_verify_setting + ) + set(CMAKE_VERIFY_INTERFACE_HEADER_SETS ${__cmake_original_verify_setting}) + # clear local variables to prevent leaking into the caller's scope unset(__cmake_contentName) unset(__cmake_contentNameLower) - unset(__cmake_contentDetails) - unset(__cmake_arg_SOURCE_SUBDIR) + unset(__cmake_contentNameUpper) + unset(__cmake_providerCommand) + unset(__cmake_original_verify_setting) endmacro() diff --git a/Modules/FetchContent/package-config-version.cmake.in b/Modules/FetchContent/package-config-version.cmake.in new file mode 100644 index 0000000..9fcade7 --- /dev/null +++ b/Modules/FetchContent/package-config-version.cmake.in @@ -0,0 +1,8 @@ +# Automatically generated by CMake's FetchContent module. +# Do not edit this file, it will be regenerated every time CMake runs. + +# Version not available, assuming it is compatible. We must also say it is an +# exact match to ensure find_package() calls with the EXACT keyword still get +# redirected. +set(PACKAGE_VERSION_COMPATIBLE TRUE) +set(PACKAGE_VERSION_EXACT TRUE) diff --git a/Modules/FetchContent/package-config.cmake.in b/Modules/FetchContent/package-config.cmake.in new file mode 100644 index 0000000..c3b64c9 --- /dev/null +++ b/Modules/FetchContent/package-config.cmake.in @@ -0,0 +1,11 @@ +# Automatically generated by CMake's FetchContent module. +# Do not edit this file, it will be regenerated every time CMake runs. + +# Projects or the dependencies themselves can provide the following files. +# The files should define any additional commands or variables that the +# dependency would normally provide but which won't be available globally +# if the dependency is brought into the build via FetchContent instead. +# For dependencies that only provide imported targets and no commands, +# these typically won't be needed. +include("${CMAKE_CURRENT_LIST_DIR}/@contentNameLower@-extra.cmake" OPTIONAL) +include("${CMAKE_CURRENT_LIST_DIR}/@contentName@Extra.cmake" OPTIONAL) diff --git a/Modules/FindAVIFile.cmake b/Modules/FindAVIFile.cmake index 9655440..d63b707 100644 --- a/Modules/FindAVIFile.cmake +++ b/Modules/FindAVIFile.cmake @@ -7,7 +7,7 @@ FindAVIFile Locate AVIFILE library and include paths -AVIFILE (http://avifile.sourceforge.net/) is a set of libraries for +AVIFILE (https://avifile.sourceforge.net/) is a set of libraries for i386 machines to use various AVI codecs. Support is limited beyond Linux. Windows provides native AVI support, and so doesn't need this library. This module defines diff --git a/Modules/FindBLAS.cmake b/Modules/FindBLAS.cmake index e3bf8f9..7af1017 100644 --- a/Modules/FindBLAS.cmake +++ b/Modules/FindBLAS.cmake @@ -12,7 +12,7 @@ This module finds an installed Fortran library that implements the At least one of the ``C``, ``CXX``, or ``Fortran`` languages must be enabled. -.. _`BLAS linear-algebra interface`: http://www.netlib.org/blas/ +.. _`BLAS linear-algebra interface`: https://netlib.org/blas/ Input Variables ^^^^^^^^^^^^^^^ @@ -35,6 +35,12 @@ The following variables may be set to influence this module's behavior: if set ``pkg-config`` will be used to search for a BLAS library first and if one is found that is preferred +``BLA_PKGCONFIG_BLAS`` + .. versionadded:: 3.25 + + If set, the ``pkg-config`` method will look for this module name instead of + just ``blas``. + ``BLA_SIZEOF_INTEGER`` .. versionadded:: 3.22 @@ -273,8 +279,11 @@ endif() include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) if(BLA_PREFER_PKGCONFIG) - find_package(PkgConfig) - pkg_check_modules(PKGC_BLAS blas) + if(NOT BLA_PKGCONFIG_BLAS) + set(BLA_PKGCONFIG_BLAS "blas") + endif() + find_package(PkgConfig QUIET) + pkg_check_modules(PKGC_BLAS QUIET ${BLA_PKGCONFIG_BLAS}) if(PKGC_BLAS_FOUND) set(BLAS_FOUND ${PKGC_BLAS_FOUND}) set(BLAS_LIBRARIES "${PKGC_BLAS_LINK_LIBRARIES}") diff --git a/Modules/FindBZip2.cmake b/Modules/FindBZip2.cmake index 355c4bb..326e700 100644 --- a/Modules/FindBZip2.cmake +++ b/Modules/FindBZip2.cmake @@ -29,8 +29,11 @@ This module defines the following variables: Link these to use BZip2 ``BZIP2_NEED_PREFIX`` this is set if the functions are prefixed with ``BZ2_`` -``BZIP2_VERSION_STRING`` - the version of BZip2 found +``BZIP2_VERSION`` + .. versionadded:: 3.26 + the version of BZip2 found. + + See also legacy variable ``BZIP2_VERSION_STRING``. Cache variables ^^^^^^^^^^^^^^^ @@ -39,6 +42,17 @@ The following cache variables may also be set: ``BZIP2_INCLUDE_DIR`` the BZip2 include directory + +Legacy Variables +^^^^^^^^^^^^^^^^ + +The following variables are provided for backward compatibility: + +``BZIP2_VERSION_STRING`` + the version of BZip2 found. + + .. versionchanged:: 3.26 + Superseded by ``BZIP2_VERSION``. #]=======================================================================] set(_BZIP2_PATHS PATHS @@ -60,12 +74,13 @@ endif () if (BZIP2_INCLUDE_DIR AND EXISTS "${BZIP2_INCLUDE_DIR}/bzlib.h") file(STRINGS "${BZIP2_INCLUDE_DIR}/bzlib.h" BZLIB_H REGEX "bzip2/libbzip2 version [0-9]+\\.[^ ]+ of [0-9]+ ") string(REGEX REPLACE ".* bzip2/libbzip2 version ([0-9]+\\.[^ ]+) of [0-9]+ .*" "\\1" BZIP2_VERSION_STRING "${BZLIB_H}") + set(BZIP2_VERSION ${BZIP2_VERSION_STRING}) endif () include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) FIND_PACKAGE_HANDLE_STANDARD_ARGS(BZip2 REQUIRED_VARS BZIP2_LIBRARIES BZIP2_INCLUDE_DIR - VERSION_VAR BZIP2_VERSION_STRING) + VERSION_VAR BZIP2_VERSION) if (BZIP2_FOUND) set(BZIP2_INCLUDE_DIRS ${BZIP2_INCLUDE_DIR}) diff --git a/Modules/FindBacktrace.cmake b/Modules/FindBacktrace.cmake index 3d8ce88..46b62d2 100644 --- a/Modules/FindBacktrace.cmake +++ b/Modules/FindBacktrace.cmake @@ -5,7 +5,7 @@ FindBacktrace ------------- -Find provider for `backtrace(3) <http://man7.org/linux/man-pages/man3/backtrace.3.html>`__. +Find provider for `backtrace(3) <https://man7.org/linux/man-pages/man3/backtrace.3.html>`__. Checks if OS supports ``backtrace(3)`` via either ``libc`` or custom library. This module defines the following variables: diff --git a/Modules/FindBoost.cmake b/Modules/FindBoost.cmake index 0f407c8..72a9a4c 100644 --- a/Modules/FindBoost.cmake +++ b/Modules/FindBoost.cmake @@ -1380,7 +1380,7 @@ function(_Boost_COMPONENT_DEPENDENCIES component _ret) set(_Boost_TIMER_DEPENDENCIES chrono) set(_Boost_WAVE_DEPENDENCIES filesystem serialization thread chrono atomic) set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) - if(Boost_VERSION_STRING VERSION_GREATER_EQUAL 1.80.0 AND NOT Boost_NO_WARN_NEW_VERSIONS) + if(Boost_VERSION_STRING VERSION_GREATER_EQUAL 1.82.0 AND NOT Boost_NO_WARN_NEW_VERSIONS) message(WARNING "New Boost version may have incorrect or missing dependencies and imported targets") endif() endif() @@ -1466,6 +1466,7 @@ function(_Boost_COMPONENT_HEADERS component _hdrs) set(_Boost_TIMER_HEADERS "boost/timer.hpp") set(_Boost_TYPE_ERASURE_HEADERS "boost/type_erasure/config.hpp") set(_Boost_UNIT_TEST_FRAMEWORK_HEADERS "boost/test/framework.hpp") + set(_Boost_URL_HEADERS "boost/url.hpp") set(_Boost_WAVE_HEADERS "boost/wave.hpp") set(_Boost_WSERIALIZATION_HEADERS "boost/archive/text_wiarchive.hpp") set(_Boost_BZIP2_HEADERS "boost/iostreams/filter/bzip2.hpp") @@ -1653,7 +1654,7 @@ else() # _Boost_COMPONENT_HEADERS. See the instructions at the top of # _Boost_COMPONENT_DEPENDENCIES. set(_Boost_KNOWN_VERSIONS ${Boost_ADDITIONAL_VERSIONS} - "1.79.0" "1.79" + "1.81.0" "1.81" "1.80.0" "1.80" "1.79.0" "1.79" "1.78.0" "1.78" "1.77.0" "1.77" "1.76.0" "1.76" "1.75.0" "1.75" "1.74.0" "1.74" "1.73.0" "1.73" "1.72.0" "1.72" "1.71.0" "1.71" "1.70.0" "1.70" "1.69.0" "1.69" "1.68.0" "1.68" "1.67.0" "1.67" "1.66.0" "1.66" "1.65.1" "1.65.0" "1.65" diff --git a/Modules/FindCUDA.cmake b/Modules/FindCUDA.cmake index af5f798..c928157 100644 --- a/Modules/FindCUDA.cmake +++ b/Modules/FindCUDA.cmake @@ -799,7 +799,9 @@ if(NOT "${CUDA_TOOLKIT_ROOT_DIR}" STREQUAL "${CUDA_TOOLKIT_ROOT_DIR_INTERNAL}") unset(CUDA_VERSION CACHE) endif() -if(NOT "${CUDA_TOOLKIT_TARGET_DIR}" STREQUAL "${CUDA_TOOLKIT_TARGET_DIR_INTERNAL}") +# If CUDA_TOOLKIT_TARGET_DIR exists, check if it has changed. +if(DEFINED CUDA_TOOLKIT_TARGET_DIR + AND NOT "${CUDA_TOOLKIT_TARGET_DIR}" STREQUAL "${CUDA_TOOLKIT_TARGET_DIR_INTERNAL}") cuda_unset_include_and_libraries() endif() @@ -1148,8 +1150,10 @@ if(NOT CUDA_VERSION VERSION_LESS "9.0") find_cuda_helper_libs(nppc) find_cuda_helper_libs(nppial) find_cuda_helper_libs(nppicc) + set(CUDA_npp_LIBRARY ${CUDA_nppc_LIBRARY} ${CUDA_nppial_LIBRARY} ${CUDA_nppicc_LIBRARY}) if(CUDA_VERSION VERSION_LESS "11.0") find_cuda_helper_libs(nppicom) + list(APPEND CUDA_npp_LIBRARY ${CUDA_nppicom_LIBRARY}) endif() find_cuda_helper_libs(nppidei) find_cuda_helper_libs(nppif) @@ -1159,7 +1163,7 @@ if(NOT CUDA_VERSION VERSION_LESS "9.0") find_cuda_helper_libs(nppisu) find_cuda_helper_libs(nppitc) find_cuda_helper_libs(npps) - set(CUDA_npp_LIBRARY "${CUDA_nppc_LIBRARY};${CUDA_nppial_LIBRARY};${CUDA_nppicc_LIBRARY};${CUDA_nppicom_LIBRARY};${CUDA_nppidei_LIBRARY};${CUDA_nppif_LIBRARY};${CUDA_nppig_LIBRARY};${CUDA_nppim_LIBRARY};${CUDA_nppist_LIBRARY};${CUDA_nppisu_LIBRARY};${CUDA_nppitc_LIBRARY};${CUDA_npps_LIBRARY}") + list(APPEND CUDA_npp_LIBRARY ${CUDA_nppidei_LIBRARY} ${CUDA_nppif_LIBRARY} ${CUDA_nppig_LIBRARY} ${CUDA_nppim_LIBRARY} ${CUDA_nppist_LIBRARY} ${CUDA_nppisu_LIBRARY} ${CUDA_nppitc_LIBRARY} ${CUDA_npps_LIBRARY}) elseif(CUDA_VERSION VERSION_GREATER "5.0") # In CUDA 5.5 NPP was split into 3 separate libraries. find_cuda_helper_libs(nppc) diff --git a/Modules/FindCUDA/select_compute_arch.cmake b/Modules/FindCUDA/select_compute_arch.cmake index a35b3f8..5fad337 100644 --- a/Modules/FindCUDA/select_compute_arch.cmake +++ b/Modules/FindCUDA/select_compute_arch.cmake @@ -135,10 +135,10 @@ function(CUDA_DETECT_INSTALLED_GPUS OUT_VARIABLE) "}\n") if(CMAKE_CUDA_COMPILER_LOADED) # CUDA as a language - try_run(run_result compile_result ${PROJECT_BINARY_DIR} ${file} + try_run(run_result compile_result SOURCES ${file} RUN_OUTPUT_VARIABLE compute_capabilities) else() - try_run(run_result compile_result ${PROJECT_BINARY_DIR} ${file} + try_run(run_result compile_result SOURCES ${file} CMAKE_FLAGS "-DINCLUDE_DIRECTORIES=${CUDA_INCLUDE_DIRS}" LINK_LIBRARIES ${CUDA_LIBRARIES} RUN_OUTPUT_VARIABLE compute_capabilities) diff --git a/Modules/FindCUDAToolkit.cmake b/Modules/FindCUDAToolkit.cmake index f6dfc4f..c3b6bc3 100644 --- a/Modules/FindCUDAToolkit.cmake +++ b/Modules/FindCUDAToolkit.cmake @@ -109,6 +109,7 @@ of the following libraries that are part of the CUDAToolkit: - :ref:`CUDA Runtime Library<cuda_toolkit_rt_lib>` - :ref:`CUDA Driver Library<cuda_toolkit_driver_lib>` - :ref:`cuBLAS<cuda_toolkit_cuBLAS>` +- :ref:`cuFile<cuda_toolkit_cuFile>` - :ref:`cuFFT<cuda_toolkit_cuFFT>` - :ref:`cuRAND<cuda_toolkit_cuRAND>` - :ref:`cuSOLVER<cuda_toolkit_cuSOLVER>` @@ -119,8 +120,10 @@ of the following libraries that are part of the CUDAToolkit: - :ref:`nvGRAPH<cuda_toolkit_nvGRAPH>` - :ref:`nvJPEG<cuda_toolkit_nvJPEG>` - :ref:`nvidia-ML<cuda_toolkit_nvML>` +- :ref:`nvPTX Compiler<cuda_toolkit_nvptx>` - :ref:`nvRTC<cuda_toolkit_nvRTC>` - :ref:`nvToolsExt<cuda_toolkit_nvToolsExt>` +- :ref:`nvtx3<cuda_toolkit_nvtx3>` - :ref:`OpenCL<cuda_toolkit_opencl>` - :ref:`cuLIBOS<cuda_toolkit_cuLIBOS>` @@ -163,6 +166,22 @@ Targets Created: - ``CUDA::cublasLt`` starting in CUDA 10.1 - ``CUDA::cublasLt_static`` starting in CUDA 10.1 +.. _`cuda_toolkit_cuFile`: + +cuFile +"""""" + +.. versionadded:: 3.25 + +The NVIDIA GPUDirect Storage `cuFile <https://docs.nvidia.com/cuda/cufile-api/index.html>`_ library. + +Targets Created: + +- ``CUDA::cuFile`` starting in CUDA 11.4 +- ``CUDA::cuFile_static`` starting in CUDA 11.4 +- ``CUDA::cuFile_rdma`` starting in CUDA 11.4 +- ``CUDA::cuFile_rdma_static`` starting in CUDA 11.4 + .. _`cuda_toolkit_cuFFT`: cuFFT @@ -333,6 +352,22 @@ Targets Created: - ``CUDA::nvjpeg`` - ``CUDA::nvjpeg_static`` +.. _`cuda_toolkit_nvPTX`: + +nvPTX Compiler +"""""""""""""" + +.. versionadded:: 3.25 + +The `nvPTX <https://docs.nvidia.com/cuda/ptx-compiler-api/index.html>`_ (PTX Compilation) library. +The PTX Compiler APIs are a set of APIs which can be used to compile a PTX program into GPU assembly code. +Introduced in CUDA 11.1 +This is a static library only. + +Targets Created: + +- ``CUDA::nvptxcompiler_static`` starting in CUDA 11.1 + .. _`cuda_toolkit_nvRTC`: nvRTC @@ -345,6 +380,24 @@ Targets Created: - ``CUDA::nvrtc`` +.. versionadded:: 3.26 + + - ``CUDA::nvrtc_builtins`` + - ``CUDA::nvrtc_static`` starting in CUDA 11.5 + - ``CUDA::nvrtc_builtins_static`` starting in CUDA 11.5 + +.. _`cuda_toolkit_nvjitlink`: + +nvJitLink +""""""""" + +The `nvJItLink <https://docs.nvidia.com/cuda/>`_ (Runtime LTO Linking) library. + +Targets Created: + +- ``CUDA::nvJitLink`` starting in CUDA 12.0 +- ``CUDA::nvJitLink_static`` starting in CUDA 12.0 + .. _`cuda_toolkit_nvml`: nvidia-ML @@ -362,6 +415,8 @@ Targets Created: nvToolsExt """""""""" +.. deprecated:: 3.25 With CUDA 10.0+, use :ref:`nvtx3 <cuda_toolkit_nvtx3>`. + The `NVIDIA Tools Extension <https://docs.nvidia.com/gameworks/content/gameworkslibrary/nvtx/nvidia_tools_extension_library_nvtx.htm>`_. This is a shared library only. @@ -369,6 +424,20 @@ Targets Created: - ``CUDA::nvToolsExt`` +.. _`cuda_toolkit_nvtx3`: + +nvtx3 +""""" + +.. versionadded:: 3.25 + +The header-only `NVIDIA Tools Extension Library <https://nvidia.github.io/NVTX/doxygen/index.html>`_. +Introduced in CUDA 10.0. + +Targets created: + +- ``CUDA::nvtx3`` + .. _`cuda_toolkit_opencl`: OpenCL @@ -732,32 +801,35 @@ endif() if(CMAKE_CROSSCOMPILING) if(CMAKE_SYSTEM_PROCESSOR STREQUAL "armv7-a") # Support for NVPACK - set(CUDAToolkit_TARGET_NAME "armv7-linux-androideabi") + set(CUDAToolkit_TARGET_NAMES "armv7-linux-androideabi") elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "arm") - set(CUDAToolkit_TARGET_NAME "armv7-linux-gnueabihf") + set(CUDAToolkit_TARGET_NAMES "armv7-linux-gnueabihf") elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64") if(ANDROID_ARCH_NAME STREQUAL "arm64") - set(CUDAToolkit_TARGET_NAME "aarch64-linux-androideabi") + set(CUDAToolkit_TARGET_NAMES "aarch64-linux-androideabi") elseif (CMAKE_SYSTEM_NAME STREQUAL "QNX") - set(CUDAToolkit_TARGET_NAME "aarch64-qnx") + set(CUDAToolkit_TARGET_NAMES "aarch64-qnx") else() - set(CUDAToolkit_TARGET_NAME "aarch64-linux") - endif(ANDROID_ARCH_NAME STREQUAL "arm64") + set(CUDAToolkit_TARGET_NAMES "aarch64-linux" "sbsa-linux") + endif() elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64") - set(CUDAToolkit_TARGET_NAME "x86_64-linux") + set(CUDAToolkit_TARGET_NAMES "x86_64-linux") endif() - if(EXISTS "${CUDAToolkit_ROOT_DIR}/targets/${CUDAToolkit_TARGET_NAME}") - set(CUDAToolkit_TARGET_DIR "${CUDAToolkit_ROOT_DIR}/targets/${CUDAToolkit_TARGET_NAME}") - # add known CUDA target root path to the set of directories we search for programs, libraries and headers - list(PREPEND CMAKE_FIND_ROOT_PATH "${CUDAToolkit_TARGET_DIR}") - - # Mark that we need to pop the root search path changes after we have - # found all cuda libraries so that searches for our cross-compilation - # libraries work when another cuda sdk is in CMAKE_PREFIX_PATH or - # PATh - set(_CUDAToolkit_Pop_ROOT_PATH True) - endif() + foreach(CUDAToolkit_TARGET_NAME IN LISTS CUDAToolkit_TARGET_NAMES) + if(EXISTS "${CUDAToolkit_ROOT_DIR}/targets/${CUDAToolkit_TARGET_NAME}") + set(CUDAToolkit_TARGET_DIR "${CUDAToolkit_ROOT_DIR}/targets/${CUDAToolkit_TARGET_NAME}") + # add known CUDA target root path to the set of directories we search for programs, libraries and headers + list(PREPEND CMAKE_FIND_ROOT_PATH "${CUDAToolkit_TARGET_DIR}") + + # Mark that we need to pop the root search path changes after we have + # found all cuda libraries so that searches for our cross-compilation + # libraries work when another cuda sdk is in CMAKE_PREFIX_PATH or + # PATh + set(_CUDAToolkit_Pop_ROOT_PATH True) + break() + endif() + endforeach() endif() # If not already set we can simply use the toolkit root or it's a scattered installation. @@ -780,11 +852,18 @@ elseif(NOT CUDAToolkit_FIND_QUIETLY) message(STATUS "Unable to find cuda_runtime.h in \"${CUDAToolkit_TARGET_DIR}/include\" for CUDAToolkit_INCLUDE_DIR.") endif() -# The NVHPC layout moves math library headers and libraries to a sibling directory. +# The NVHPC layout moves math library headers and libraries to a sibling directory and it could be nested under +# the version of the CUDA toolchain # Create a separate variable so this directory can be selectively added to math targets. if(NOT EXISTS "${CUDAToolkit_INCLUDE_DIR}/cublas_v2.h") - set(CUDAToolkit_MATH_INCLUDE_DIR "${CUDAToolkit_TARGET_DIR}/../../math_libs/include") + file(REAL_PATH "${CUDAToolkit_TARGET_DIR}" CUDAToolkit_MATH_INCLUDE_DIR) + cmake_path(APPEND CUDAToolkit_MATH_INCLUDE_DIR "../../math_libs/") + if(EXISTS "${CUDAToolkit_MATH_INCLUDE_DIR}/${CUDAToolkit_VERSION_MAJOR}.${CUDAToolkit_VERSION_MINOR}/") + cmake_path(APPEND CUDAToolkit_MATH_INCLUDE_DIR "${CUDAToolkit_VERSION_MAJOR}.${CUDAToolkit_VERSION_MINOR}/") + endif() + cmake_path(APPEND CUDAToolkit_MATH_INCLUDE_DIR "include") cmake_path(NORMAL_PATH CUDAToolkit_MATH_INCLUDE_DIR) + if(NOT EXISTS "${CUDAToolkit_MATH_INCLUDE_DIR}/cublas_v2.h") if(NOT CUDAToolkit_FIND_QUIETLY) message(STATUS "Unable to find cublas_v2.h in either \"${CUDAToolkit_INCLUDE_DIR}\" or \"${CUDAToolkit_MATH_INCLUDE_DIR}\"") @@ -836,34 +915,51 @@ mark_as_advanced(CUDA_CUDART if(CUDAToolkit_FOUND) set(CUDAToolkit_INCLUDE_DIRS ${CUDAToolkit_INCLUDE_DIR}) get_filename_component(CUDAToolkit_LIBRARY_DIR ${CUDA_CUDART} DIRECTORY ABSOLUTE) + + # Build search paths without any symlinks + file(REAL_PATH "${CUDAToolkit_LIBRARY_DIR}" _cmake_search_dir) + set(CUDAToolkit_LIBRARY_SEARCH_DIRS "${_cmake_search_dir}") + + # Detect we are in a splayed nvhpc toolkit layout and add extra + # search paths without symlinks + if(CUDAToolkit_LIBRARY_DIR MATCHES ".*/cuda/${CUDAToolkit_VERSION_MAJOR}.${CUDAToolkit_VERSION_MINOR}/lib64$") + # Search location for math_libs/ + file(REAL_PATH "${CUDAToolkit_LIBRARY_DIR}/../../../" _cmake_search_dir) + list(APPEND CUDAToolkit_LIBRARY_SEARCH_DIRS "${_cmake_search_dir}") + + # Search location for extras like cupti + file(REAL_PATH "${CUDAToolkit_LIBRARY_DIR}/../" _cmake_search_dir) + list(APPEND CUDAToolkit_LIBRARY_SEARCH_DIRS "${_cmake_search_dir}") + endif() endif() + #----------------------------------------------------------------------------- # Construct import targets if(CUDAToolkit_FOUND) function(_CUDAToolkit_find_and_add_import_lib lib_name) - cmake_parse_arguments(arg "" "" "ALT;DEPS;EXTRA_PATH_SUFFIXES" ${ARGN}) + cmake_parse_arguments(arg "" "" "ALT;DEPS;EXTRA_PATH_SUFFIXES;EXTRA_INCLUDE_DIRS" ${ARGN}) set(search_names ${lib_name} ${arg_ALT}) find_library(CUDA_${lib_name}_LIBRARY NAMES ${search_names} - HINTS ${CUDAToolkit_LIBRARY_DIR} + HINTS ${CUDAToolkit_LIBRARY_SEARCH_DIRS} ENV CUDA_PATH PATH_SUFFIXES nvidia/current lib64 lib/x64 lib + # Support NVHPC splayed math library layout + math_libs/${CUDAToolkit_VERSION_MAJOR}.${CUDAToolkit_VERSION_MINOR}/lib64 + math_libs/lib64 ${arg_EXTRA_PATH_SUFFIXES} ) # Don't try any stub directories until we have exhausted all other # search locations. find_library(CUDA_${lib_name}_LIBRARY NAMES ${search_names} - HINTS ${CUDAToolkit_LIBRARY_DIR} + HINTS ${CUDAToolkit_LIBRARY_SEARCH_DIRS} ENV CUDA_PATH PATH_SUFFIXES lib64/stubs lib/x64/stubs lib/stubs stubs - # Support NVHPC splayed math library layout - ../../math_libs/${CUDAToolkit_VERSION_MAJOR}.${CUDAToolkit_VERSION_MINOR}/lib64 - ../../math_libs/lib64 ) mark_as_advanced(CUDA_${lib_name}_LIBRARY) @@ -883,6 +979,9 @@ if(CUDAToolkit_FOUND) target_link_libraries(CUDA::${lib_name} INTERFACE CUDA::${dep}) endif() endforeach() + if(arg_EXTRA_INCLUDE_DIRS) + target_include_directories(CUDA::${lib_name} SYSTEM INTERFACE "${arg_EXTRA_INCLUDE_DIRS}") + endif() endif() endfunction() @@ -939,6 +1038,14 @@ if(CUDAToolkit_FOUND) _CUDAToolkit_find_and_add_import_lib(cublas_static DEPS culibos) endif() + if(CUDAToolkit_VERSION VERSION_GREATER_EQUAL 11.4) + _CUDAToolkit_find_and_add_import_lib(cuFile DEPS culibos) + _CUDAToolkit_find_and_add_import_lib(cuFile_static DEPS culibos) + + _CUDAToolkit_find_and_add_import_lib(cuFile_rdma DEPS cuFile culibos) + _CUDAToolkit_find_and_add_import_lib(cuFile_rdma_static DEPS cuFile_static culibos) + endif() + # cuFFTW depends on cuFFT _CUDAToolkit_find_and_add_import_lib(cufftw DEPS cufft) _CUDAToolkit_find_and_add_import_lib(cufftw_static DEPS cufft_static) @@ -977,14 +1084,47 @@ if(CUDAToolkit_FOUND) _CUDAToolkit_find_and_add_import_lib(${cuda_lib}_static DEPS nppc_static) endforeach() - _CUDAToolkit_find_and_add_import_lib(cupti - EXTRA_PATH_SUFFIXES ../extras/CUPTI/lib64/ - ../extras/CUPTI/lib/) - _CUDAToolkit_find_and_add_import_lib(cupti_static - EXTRA_PATH_SUFFIXES ../extras/CUPTI/lib64/ - ../extras/CUPTI/lib/) + find_path(CUDAToolkit_CUPTI_INCLUDE_DIR cupti.h PATHS + "${CUDAToolkit_ROOT_DIR}/extras/CUPTI/include" + "${CUDAToolkit_INCLUDE_DIR}/../extras/CUPTI/include" + "${CUDAToolkit_INCLUDE_DIR}" + NO_DEFAULT_PATH) + + if(CUDAToolkit_CUPTI_INCLUDE_DIR) + _CUDAToolkit_find_and_add_import_lib(cupti + EXTRA_PATH_SUFFIXES extras/CUPTI/lib64/ + extras/CUPTI/lib/ + ../extras/CUPTI/lib64/ + ../extras/CUPTI/lib/ + EXTRA_INCLUDE_DIRS "${CUDAToolkit_CUPTI_INCLUDE_DIR}") + _CUDAToolkit_find_and_add_import_lib(cupti_static + EXTRA_PATH_SUFFIXES extras/CUPTI/lib64/ + extras/CUPTI/lib/ + ../extras/CUPTI/lib64/ + ../extras/CUPTI/lib/ + EXTRA_INCLUDE_DIRS "${CUDAToolkit_CUPTI_INCLUDE_DIR}") + endif() + + if(CUDAToolkit_VERSION VERSION_GREATER_EQUAL 11.1.0) + if(NOT TARGET CUDA::nvptxcompiler_static) + _CUDAToolkit_find_and_add_import_lib(nvptxcompiler_static DEPS cuda_driver) + if(TARGET CUDA::nvptxcompiler_static) + target_link_libraries(CUDA::nvptxcompiler_static INTERFACE Threads::Threads) + endif() + endif() + endif() - _CUDAToolkit_find_and_add_import_lib(nvrtc DEPS cuda_driver) + if(CUDAToolkit_VERSION VERSION_GREATER_EQUAL 12.0.0) + _CUDAToolkit_find_and_add_import_lib(nvJitLink DEPS cuda_driver) + _CUDAToolkit_find_and_add_import_lib(nvJitLink_static DEPS cuda_driver) + endif() + + _CUDAToolkit_find_and_add_import_lib(nvrtc_builtins DEPS cuda_driver) + _CUDAToolkit_find_and_add_import_lib(nvrtc DEPS nvrtc_builtins nvJitLink) + if(CUDAToolkit_VERSION VERSION_GREATER_EQUAL 11.5.0) + _CUDAToolkit_find_and_add_import_lib(nvrtc_builtins_static ALT nvrtc-builtins_static DEPS cuda_driver) + _CUDAToolkit_find_and_add_import_lib(nvrtc_static DEPS nvrtc_builtins_static nvptxcompiler_static nvJitLink_static) + endif() _CUDAToolkit_find_and_add_import_lib(nvml ALT nvidia-ml nvml) @@ -1001,6 +1141,21 @@ if(CUDAToolkit_FOUND) endif() _CUDAToolkit_find_and_add_import_lib(nvToolsExt ALT nvToolsExt64) + if(CUDAToolkit_VERSION VERSION_GREATER_EQUAL 10.0) + # nvToolsExt is deprecated since nvtx3 introduction. + # Warn only if the project requires a sufficiently new CMake to make migration possible. + if(TARGET CUDA::nvToolsExt AND CMAKE_MINIMUM_REQUIRED_VERSION VERSION_GREATER_EQUAL 3.25) + set_property(TARGET CUDA::nvToolsExt PROPERTY DEPRECATION "nvToolsExt has been superseded by nvtx3 since CUDA 10.0 and CMake 3.25. Use CUDA::nvtx3 and include <nvtx3/nvToolsExt.h> instead.") + endif() + + # Header-only variant. Uses dlopen(). + if(NOT TARGET CUDA::nvtx3) + add_library(CUDA::nvtx3 INTERFACE IMPORTED) + target_include_directories(CUDA::nvtx3 SYSTEM INTERFACE "${CUDAToolkit_INCLUDE_DIRS}") + target_link_libraries(CUDA::nvtx3 INTERFACE ${CMAKE_DL_LIBS}) + endif() + endif() + _CUDAToolkit_find_and_add_import_lib(OpenCL) endif() diff --git a/Modules/FindCURL.cmake b/Modules/FindCURL.cmake index e37d225..acb87dc 100644 --- a/Modules/FindCURL.cmake +++ b/Modules/FindCURL.cmake @@ -72,6 +72,8 @@ if(NOT CURL_NO_CURL_CMAKE) # can print what we found and return. if(CURL_FOUND) find_package_handle_standard_args(CURL HANDLE_COMPONENTS CONFIG_MODE) + # The upstream curl package sets CURL_VERSION, not CURL_VERSION_STRING. + set(CURL_VERSION_STRING "${CURL_VERSION}") return() endif() endif() @@ -80,7 +82,6 @@ find_package(PkgConfig QUIET) if(PKG_CONFIG_FOUND) pkg_check_modules(PC_CURL QUIET libcurl) if(PC_CURL_FOUND) - set(CURL_VERSION_STRING ${PC_CURL_VERSION}) pkg_get_variable(CURL_SUPPORTED_PROTOCOLS libcurl supported_protocols) pkg_get_variable(CURL_SUPPORTED_FEATURES libcurl supported_features) endif() @@ -120,7 +121,7 @@ if(NOT CURL_LIBRARY) select_library_configurations(CURL) endif() -if(CURL_INCLUDE_DIR AND NOT CURL_VERSION_STRING) +if(CURL_INCLUDE_DIR) foreach(_curl_version_header curlver.h curl.h) if(EXISTS "${CURL_INCLUDE_DIR}/curl/${_curl_version_header}") file(STRINGS "${CURL_INCLUDE_DIR}/curl/${_curl_version_header}" curl_version_str REGEX "^#define[\t ]+LIBCURL_VERSION[\t ]+\".*\"") diff --git a/Modules/FindCoin3D.cmake b/Modules/FindCoin3D.cmake index 301e70b..5910ad1 100644 --- a/Modules/FindCoin3D.cmake +++ b/Modules/FindCoin3D.cmake @@ -31,11 +31,11 @@ if (WIN32) "[HKEY_LOCAL_MACHINE\\SOFTWARE\\SIM\\Coin3D\\2;Installation Path]/include" ) - find_library(COIN3D_LIBRARY_DEBUG coin2d + find_library(COIN3D_LIBRARY_DEBUG NAMES coin2d coin4d "[HKEY_LOCAL_MACHINE\\SOFTWARE\\SIM\\Coin3D\\2;Installation Path]/lib" ) - find_library(COIN3D_LIBRARY_RELEASE coin2 + find_library(COIN3D_LIBRARY_RELEASE NAMES coin2 coin4 "[HKEY_LOCAL_MACHINE\\SOFTWARE\\SIM\\Coin3D\\2;Installation Path]/lib" ) diff --git a/Modules/FindCxxTest.cmake b/Modules/FindCxxTest.cmake index 3fc0e93..04f8b59 100644 --- a/Modules/FindCxxTest.cmake +++ b/Modules/FindCxxTest.cmake @@ -9,7 +9,7 @@ Find CxxTest unit testing framework. Find the CxxTest suite and declare a helper macro for creating unit tests and integrating them with CTest. For more details on CxxTest -see http://cxxtest.tigris.org +see https://cxxtest.com INPUT Variables diff --git a/Modules/FindDCMTK.cmake b/Modules/FindDCMTK.cmake index b2e00df..0154a05 100644 --- a/Modules/FindDCMTK.cmake +++ b/Modules/FindDCMTK.cmake @@ -18,15 +18,16 @@ Compatibility ^^^^^^^^^^^^^ This module is able to find a version of DCMTK that does or does not export -a *DCMTKConfig.cmake* file. It applies a two step process: +a ``DCMTKConfig.cmake`` file. It applies a two step process: -* Step 1: Attempt to find DCMTK version providing a *DCMTKConfig.cmake* file. -* Step 2: If step 1 failed, rely on *FindDCMTK.cmake* to set `DCMTK_*` variables details below. +* Step 1: Attempt to find DCMTK version providing a ``DCMTKConfig.cmake`` file. +* Step 2: If step 1 failed, rely on ``FindDCMTK.cmake`` to set ``DCMTK_*`` + variables details below. `Recent DCMTK -<http://git.dcmtk.org/web?p=dcmtk.git;a=commit;h=662ae187c493c6b9a73dd5e3875372cebd0c11fe>`_ -provides a *DCMTKConfig.cmake* :manual:`package configuration file +<https://git.dcmtk.org/?p=dcmtk.git;a=commit;h=662ae187c493c6b9a73dd5e3875372cebd0c11fe>`_ +provides a ``DCMTKConfig.cmake`` :manual:`package configuration file <cmake-packages(7)>`. To exclusively use the package configuration file (recommended when possible), pass the `NO_MODULE` option to :command:`find_package`. For example, `find_package(DCMTK NO_MODULE)`. diff --git a/Modules/FindDevIL.cmake b/Modules/FindDevIL.cmake index c8e5e31..7f726ff 100644 --- a/Modules/FindDevIL.cmake +++ b/Modules/FindDevIL.cmake @@ -8,7 +8,7 @@ FindDevIL This module locates the developer's image library. -http://openil.sourceforge.net/ +https://openil.sourceforge.net/ IMPORTED Targets ^^^^^^^^^^^^^^^^ diff --git a/Modules/FindDoxygen.cmake b/Modules/FindDoxygen.cmake index 4a16e31..ef9801e 100644 --- a/Modules/FindDoxygen.cmake +++ b/Modules/FindDoxygen.cmake @@ -5,14 +5,14 @@ FindDoxygen ----------- -Doxygen is a documentation generation tool (see http://www.doxygen.org). +Doxygen is a documentation generation tool (see https://www.doxygen.nl). This module looks for Doxygen and some optional tools it supports: ``dot`` - `Graphviz <http://graphviz.org>`_ ``dot`` utility used to render various + `Graphviz <https://graphviz.org>`_ ``dot`` utility used to render various graphs. ``mscgen`` - `Message Chart Generator <http://www.mcternan.me.uk/mscgen/>`_ utility used + `Message Chart Generator <https://www.mcternan.me.uk/mscgen/>`_ utility used by Doxygen's ``\msc`` and ``\mscfile`` commands. ``dia`` `Dia <https://wiki.gnome.org/Apps/Dia>`_ the diagram editor used by Doxygen's @@ -91,7 +91,7 @@ Functions base point. Note also that Doxygen's default behavior is to strip the working directory from relative paths in the generated documentation (see the ``STRIP_FROM_PATH`` `Doxygen config option - <http://www.doxygen.org/manual/config.html>`_ for details). + <https://www.doxygen.nl/manual/config.html>`_ for details). If provided, the optional ``comment`` will be passed as the ``COMMENT`` for the :command:`add_custom_target` command used to create the custom target @@ -117,7 +117,7 @@ Functions variables before calling ``doxygen_add_docs()``. Any variable with a name of the form ``DOXYGEN_<tag>`` will have its value substituted for the corresponding ``<tag>`` configuration option in the ``Doxyfile``. See the - `Doxygen documentation <http://www.doxygen.org/manual/config.html>`_ for the + `Doxygen documentation <https://www.doxygen.nl/manual/config.html>`_ for the full list of supported configuration options. Some of Doxygen's defaults are overridden to provide more appropriate @@ -432,9 +432,44 @@ endif() # or use something like homebrew. # ============== End OSX stuff ================ +include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) + # # Find Doxygen... # +function(_Doxygen_get_version doxy_version result_var doxy_path) + execute_process( + COMMAND "${doxy_path}" --version + OUTPUT_VARIABLE full_doxygen_version + OUTPUT_STRIP_TRAILING_WHITESPACE + RESULT_VARIABLE version_result + ) + + # Ignore any commit hashes, etc. + string(REGEX MATCH [[^[0-9]+\.[0-9]+\.[0-9]+]] sem_doxygen_version "${full_doxygen_version}") + + set(${result_var} ${version_result} PARENT_SCOPE) + set(${doxy_version} ${sem_doxygen_version} PARENT_SCOPE) +endfunction() + +function(_Doxygen_version_validator version_match doxy_path) + if(NOT DEFINED Doxygen_FIND_VERSION) + set(${is_valid_version} TRUE PARENT_SCOPE) + else() + _Doxygen_get_version(candidate_version version_result "${doxy_path}") + + if(version_result) + message(DEBUG "Unable to determine candidate doxygen version at ${doxy_path}: ${version_result}") + endif() + + find_package_check_version("${candidate_version}" valid_doxy_version + HANDLE_VERSION_RANGE + ) + + set(${version_match} "${valid_doxy_version}" PARENT_SCOPE) + endif() +endfunction() + macro(_Doxygen_find_doxygen) find_program( DOXYGEN_EXECUTABLE @@ -445,17 +480,14 @@ macro(_Doxygen_find_doxygen) /Applications/Doxygen.app/Contents/MacOS /Applications/Utilities/Doxygen.app/Contents/Resources /Applications/Utilities/Doxygen.app/Contents/MacOS - DOC "Doxygen documentation generation tool (http://www.doxygen.org)" + DOC "Doxygen documentation generation tool (https://www.doxygen.nl)" + VALIDATOR _Doxygen_version_validator ) mark_as_advanced(DOXYGEN_EXECUTABLE) if(DOXYGEN_EXECUTABLE) - execute_process( - COMMAND "${DOXYGEN_EXECUTABLE}" --version - OUTPUT_VARIABLE DOXYGEN_VERSION - OUTPUT_STRIP_TRAILING_WHITESPACE - RESULT_VARIABLE _Doxygen_version_result - ) + _Doxygen_get_version(DOXYGEN_VERSION _Doxygen_version_result "${DOXYGEN_EXECUTABLE}") + if(_Doxygen_version_result) message(WARNING "Unable to determine doxygen version: ${_Doxygen_version_result}") endif() @@ -642,11 +674,11 @@ endforeach() unset(_comp) # Verify find results -include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) find_package_handle_standard_args( Doxygen REQUIRED_VARS DOXYGEN_EXECUTABLE VERSION_VAR DOXYGEN_VERSION + HANDLE_VERSION_RANGE HANDLE_COMPONENTS ) @@ -919,7 +951,7 @@ doxygen_add_docs() for target ${targetName}") if(NOT DEFINED DOXYGEN_HAVE_DOT) # If you set the HAVE_DOT tag to YES then doxygen will assume the dot # tool is available from the path. This tool is part of Graphviz (see: - # http://www.graphviz.org/), a graph visualization toolkit from AT&T + # https://www.graphviz.org/), a graph visualization toolkit from AT&T # and Lucent Bell Labs. The other options in this section have no # effect if this option is set to NO. # Doxygen's default value is: NO. diff --git a/Modules/FindEnvModules.cmake b/Modules/FindEnvModules.cmake index a4ac0b4..dab97ac 100644 --- a/Modules/FindEnvModules.cmake +++ b/Modules/FindEnvModules.cmake @@ -259,7 +259,7 @@ function(env_module_swap out_mod in_mod) ) if(MOD_ARGS_OUTPUT_VARIABLE) - set(${MOD_ARGS_OUTPUT_VARIABLE} "${err_var}" PARENT_SCOPE) + set(${MOD_ARGS_OUTPUT_VARIABLE} "${tmp_out}" PARENT_SCOPE) endif() if(MOD_ARGS_RESULT_VARIABLE) set(${MOD_ARGS_RESULT_VARIABLE} ${tmp_ret} PARENT_SCOPE) diff --git a/Modules/FindGDAL.cmake b/Modules/FindGDAL.cmake index 5237e15..e6eac30 100644 --- a/Modules/FindGDAL.cmake +++ b/Modules/FindGDAL.cmake @@ -160,7 +160,7 @@ unset(_gdal_version) unset(_gdal_versions) find_library(GDAL_LIBRARY - NAMES ${_gdal_lib} ${_gdal_libnames} gdal gdal_i gdal1.5.0 gdal1.4.0 gdal1.3.2 GDAL + NAMES ${_gdal_lib} ${_gdal_libnames} gdal gdald gdal_i gdal1.5.0 gdal1.4.0 gdal1.3.2 GDAL HINTS ENV GDAL_DIR ENV GDAL_ROOT diff --git a/Modules/FindGLEW.cmake b/Modules/FindGLEW.cmake index b9ebe08..bfde40b 100644 --- a/Modules/FindGLEW.cmake +++ b/Modules/FindGLEW.cmake @@ -63,11 +63,36 @@ This module defines the following variables: #]=======================================================================] include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) +include(${CMAKE_CURRENT_LIST_DIR}/SelectLibraryConfigurations.cmake) find_package(GLEW CONFIG QUIET) if(GLEW_FOUND) find_package_handle_standard_args(GLEW DEFAULT_MSG GLEW_CONFIG) + get_target_property(GLEW_INCLUDE_DIRS GLEW::GLEW INTERFACE_INCLUDE_DIRECTORIES) + set(GLEW_INCLUDE_DIR ${GLEW_INCLUDE_DIRS}) + get_target_property(_GLEW_DEFS GLEW::GLEW INTERFACE_COMPILE_DEFINITIONS) + if("${_GLEW_DEFS}" MATCHES "GLEW_STATIC") + get_target_property(GLEW_LIBRARY_DEBUG GLEW::GLEW IMPORTED_LOCATION_DEBUG) + get_target_property(GLEW_LIBRARY_RELEASE GLEW::GLEW IMPORTED_LOCATION_RELEASE) + else() + get_target_property(GLEW_LIBRARY_DEBUG GLEW::GLEW IMPORTED_IMPLIB_DEBUG) + get_target_property(GLEW_LIBRARY_RELEASE GLEW::GLEW IMPORTED_IMPLIB_RELEASE) + endif() + get_target_property(_GLEW_LINK_INTERFACE GLEW::GLEW IMPORTED_LINK_INTERFACE_LIBRARIES_RELEASE) # same for debug and release + list(APPEND GLEW_LIBRARIES ${_GLEW_LINK_INTERFACE}) + list(APPEND GLEW_LIBRARY ${_GLEW_LINK_INTERFACE}) + select_library_configurations(GLEW) + if("${_GLEW_DEFS}" MATCHES "GLEW_STATIC") + set(GLEW_STATIC_LIBRARIES ${GLEW_LIBRARIES}) + else() + set(GLEW_SHARED_LIBRARIES ${GLEW_LIBRARIES}) + endif() + unset(_GLEW_DEFS) + unset(_GLEW_LINK_INTERFACE) + unset(GLEW_LIBRARY) + unset(GLEW_LIBRARY_DEBUG) + unset(GLEW_LIBRARY_RELEASE) return() endif() @@ -171,8 +196,6 @@ find_library(GLEW_STATIC_LIBRARY_DEBUG set(CMAKE_FIND_LIBRARY_SUFFIXES ${__GLEW_CURRENT_FIND_LIBRARY_SUFFIXES}) unset(__GLEW_CURRENT_FIND_LIBRARY_SUFFIXES) -include(${CMAKE_CURRENT_LIST_DIR}/SelectLibraryConfigurations.cmake) - select_library_configurations(GLEW_SHARED) select_library_configurations(GLEW_STATIC) diff --git a/Modules/FindGLUT.cmake b/Modules/FindGLUT.cmake index fe274de..09403bc 100644 --- a/Modules/FindGLUT.cmake +++ b/Modules/FindGLUT.cmake @@ -67,66 +67,41 @@ The following variables may also be provided, for backwards compatibility: include(${CMAKE_CURRENT_LIST_DIR}/SelectLibraryConfigurations.cmake) include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) -function(_add_glut_target_simple) - if(TARGET GLUT::GLUT) - return() - endif() - add_library(GLUT::GLUT INTERFACE IMPORTED) - if(GLUT_INCLUDE_DIRS) - target_include_directories(GLUT::GLUT SYSTEM - INTERFACE "${GLUT_INCLUDE_DIRS}") - endif() - if(GLUT_LIBRARIES) - target_link_libraries(GLUT::GLUT INTERFACE ${GLUT_LIBRARIES}) - endif() - if(GLUT_LIBRARY_DIRS) - target_link_directories(GLUT::GLUT INTERFACE ${GLUT_LIBRARY_DIRS}) - endif() - if(GLUT_LDFLAGS) - target_link_options(GLUT::GLUT INTERFACE ${GLUT_LDFLAGS}) - endif() - if(GLUT_CFLAGS) - separate_arguments(GLUT_CFLAGS_SPLIT UNIX_COMMAND "${GLUT_CFLAGS}") - target_compile_options(GLUT::GLUT INTERFACE ${GLUT_CFLAGS_SPLIT}) - endif() - - set_property(TARGET GLUT::GLUT APPEND PROPERTY - IMPORTED_LOCATION "${GLUT_glut_LIBRARY}") -endfunction() - -find_package(PkgConfig) +find_package(PkgConfig QUIET) if(PKG_CONFIG_FOUND) - pkg_check_modules(GLUT glut) - if(GLUT_FOUND) - # GLUT_INCLUDE_DIRS is now the official result variable, but - # older versions of CMake only provided GLUT_INCLUDE_DIR. - set(GLUT_INCLUDE_DIR "${GLUT_INCLUDE_DIRS}") - _add_glut_target_simple() - FIND_PACKAGE_HANDLE_STANDARD_ARGS(GLUT REQUIRED_VARS GLUT_FOUND) - return() + pkg_check_modules(PC_GLUT QUIET glut) + if(NOT PC_GLUT_FOUND) + pkg_check_modules(PC_GLUT QUIET freeglut) endif() endif() if(WIN32) find_path( GLUT_INCLUDE_DIR NAMES GL/glut.h - PATHS ${GLUT_ROOT_PATH}/include ) + PATHS ${GLUT_ROOT_PATH}/include + HINTS ${PC_GLUT_INCLUDE_DIRS}) mark_as_advanced(GLUT_INCLUDE_DIR) - find_library( GLUT_glut_LIBRARY_RELEASE NAMES glut glut32 freeglut + find_library( GLUT_glut_LIBRARY_RELEASE NAMES freeglut glut glut32 PATHS ${OPENGL_LIBRARY_DIR} ${GLUT_ROOT_PATH}/Release + HINTS + ${PC_GLUT_LIBRARY_DIRS} ) +# N.B. As the pkg-config cannot distinguish between release and debug libraries, +# assume that their hint was the both Debug and Release library. find_library( GLUT_glut_LIBRARY_DEBUG NAMES freeglutd PATHS ${OPENGL_LIBRARY_DIR} ${GLUT_ROOT_PATH}/Debug + HINTS + ${PC_GLUT_LIBRARY_DIRS} ) mark_as_advanced(GLUT_glut_LIBRARY_RELEASE GLUT_glut_LIBRARY_DEBUG) select_library_configurations(GLUT_glut) elseif(APPLE) - find_path(GLUT_INCLUDE_DIR glut.h ${OPENGL_LIBRARY_DIR}) + find_path(GLUT_INCLUDE_DIR glut.h PATHS ${OPENGL_LIBRARY_DIR} HINTS ${PC_GLUT_INCLUDE_DIRS}) mark_as_advanced(GLUT_INCLUDE_DIR) - find_library(GLUT_glut_LIBRARY GLUT DOC "GLUT library for OSX") + find_library(GLUT_glut_LIBRARY GLUT HINTS ${PC_GLUT_LIBRARY_DIRS} DOC "GLUT library for OSX") find_library(GLUT_cocoa_LIBRARY Cocoa DOC "Cocoa framework for OSX") mark_as_advanced(GLUT_glut_LIBRARY GLUT_cocoa_LIBRARY) @@ -175,18 +150,24 @@ else() endif () find_path( GLUT_INCLUDE_DIR GL/glut.h + PATHS /usr/include/GL /usr/openwin/share/include /usr/openwin/include /opt/graphics/OpenGL/include /opt/graphics/OpenGL/contrib/libglut ${_GLUT_INC_DIR} + HINTS + ${PC_GLUT_INCLUDE_DIRS} ) mark_as_advanced(GLUT_INCLUDE_DIR) find_library( GLUT_glut_LIBRARY glut + PATHS /usr/openwin/lib ${_GLUT_glut_LIB_DIR} + HINTS + ${PC_GLUT_LIBRARY_DIRS} ) mark_as_advanced(GLUT_glut_LIBRARY) @@ -258,8 +239,4 @@ if (GLUT_FOUND) PROPERTY INTERFACE_LINK_LIBRARIES GLUT::Cocoa) endif() endif() - - #The following deprecated settings are for backwards compatibility with CMake1.4 - set (GLUT_LIBRARY ${GLUT_LIBRARIES}) - set (GLUT_INCLUDE_PATH ${GLUT_INCLUDE_DIRS}) endif() diff --git a/Modules/FindGSL.cmake b/Modules/FindGSL.cmake index 485735a..1943847 100644 --- a/Modules/FindGSL.cmake +++ b/Modules/FindGSL.cmake @@ -77,7 +77,7 @@ endif() # *NIX systems. See :module:`findpkgconfig` # This will return ``GSL_INCLUDEDIR`` and ``GSL_LIBDIR`` used below. if( GSL_USE_PKGCONFIG ) - find_package(PkgConfig) + find_package(PkgConfig QUIET) pkg_check_modules( GSL QUIET gsl ) if( EXISTS "${GSL_INCLUDEDIR}" ) diff --git a/Modules/FindGTK2.cmake b/Modules/FindGTK2.cmake index 00bfc29..4634876 100644 --- a/Modules/FindGTK2.cmake +++ b/Modules/FindGTK2.cmake @@ -313,6 +313,7 @@ function(_GTK2_FIND_INCLUDE_DIR _var _hdr) /usr/openwin/lib /sw/lib /opt/local/lib + /opt/homebrew/lib /usr/pkg/lib /usr/pkg/include/glib $ENV{GTKMM_BASEPATH}/include diff --git a/Modules/FindGit.cmake b/Modules/FindGit.cmake index 99850b4..08a386a 100644 --- a/Modules/FindGit.cmake +++ b/Modules/FindGit.cmake @@ -31,16 +31,16 @@ Example usage: endif() #]=======================================================================] -# Look for 'git' or 'eg' (easy git) +# Look for 'git' # -set(git_names git eg) +set(git_names git) # Prefer .cmd variants on Windows unless running in a Makefile # in the MSYS shell. # if(CMAKE_HOST_WIN32) if(NOT CMAKE_GENERATOR MATCHES "MSYS") - set(git_names git.cmd git eg.cmd eg) + set(git_names git.cmd git) # GitHub search path for Windows file(GLOB github_path "$ENV{LOCALAPPDATA}/Github/PortableGit*/cmd" diff --git a/Modules/FindHDF5.cmake b/Modules/FindHDF5.cmake index 40ed9a9..db03c54 100644 --- a/Modules/FindHDF5.cmake +++ b/Modules/FindHDF5.cmake @@ -222,6 +222,10 @@ function(_HDF5_test_regular_compiler_C success version is_parallel) if(NOT ${success} OR NOT EXISTS ${scratch_directory}/compiler_has_h5_c) set(test_file ${scratch_directory}/cmake_hdf5_test.c) + # CXX project without C enabled + if(CMAKE_CXX_COMPILER_LOADED AND NOT CMAKE_C_COMPILER_LOADED) + set(test_file ${scratch_directory}/cmake_hdf5_test.cpp) + endif() file(WRITE ${test_file} "#include <hdf5.h>\n" "const char* info_ver = \"INFO\" \":\" H5_VERSION;\n" @@ -238,7 +242,7 @@ function(_HDF5_test_regular_compiler_C success version is_parallel) " fid = H5Fcreate(\"foo.h5\",H5F_ACC_TRUNC,H5P_DEFAULT,H5P_DEFAULT);\n" " return 0;\n" "}") - try_compile(${success} ${scratch_directory} ${test_file} + try_compile(${success} SOURCES ${test_file} COPY_FILE ${scratch_directory}/compiler_has_h5_c ) endif() @@ -286,7 +290,7 @@ function(_HDF5_test_regular_compiler_CXX success version is_parallel) " H5File file(\"foo.h5\", H5F_ACC_TRUNC);\n" " return 0;\n" "}") - try_compile(${success} ${scratch_directory} ${test_file} + try_compile(${success} SOURCES ${test_file} COPY_FILE ${scratch_directory}/compiler_has_h5_cxx ) endif() @@ -323,7 +327,7 @@ function(_HDF5_test_regular_compiler_Fortran success is_parallel) " call h5open_f(error)\n" " call h5close_f(error)\n" "end\n") - try_compile(${success} ${scratch_directory} ${test_file}) + try_compile(${success} SOURCES ${test_file}) if(${success}) execute_process(COMMAND ${CMAKE_Fortran_COMPILER} -showconfig OUTPUT_VARIABLE config_output diff --git a/Modules/FindICU.cmake b/Modules/FindICU.cmake index 1bae825..b4f4d71 100644 --- a/Modules/FindICU.cmake +++ b/Modules/FindICU.cmake @@ -254,17 +254,10 @@ function(_ICU_FIND) set("${component_found}" ON) set("${component_found_compat}" ON) list(APPEND ICU_LIBRARY "${${component_cache}}") - endif() - mark_as_advanced("${component_found}") - mark_as_advanced("${component_found_compat}") - set("${component_cache}" "${${component_cache}}" PARENT_SCOPE) - set("${component_found}" "${${component_found}}" PARENT_SCOPE) - set("${component_found_compat}" "${${component_found_compat}}" PARENT_SCOPE) - if(component_found OR component_found_compat) if (ICU_FIND_REQUIRED_${component}) - list(APPEND ICU_LIBS_FOUND "${component} (required)") + list(APPEND ICU_LIBS_FOUND "${component} (required): ${${component_cache}}") else() - list(APPEND ICU_LIBS_FOUND "${component} (optional)") + list(APPEND ICU_LIBS_FOUND "${component} (optional): ${${component_cache}}") endif() else() if (ICU_FIND_REQUIRED_${component}) @@ -274,6 +267,11 @@ function(_ICU_FIND) list(APPEND ICU_LIBS_NOTFOUND "${component} (optional)") endif() endif() + mark_as_advanced("${component_found}") + mark_as_advanced("${component_found_compat}") + set("${component_cache}" "${${component_cache}}" PARENT_SCOPE) + set("${component_found}" "${${component_found}}" PARENT_SCOPE) + set("${component_found_compat}" "${${component_found_compat}}" PARENT_SCOPE) endforeach() set(_ICU_REQUIRED_LIBS_FOUND "${ICU_REQUIRED_LIBS_FOUND}" PARENT_SCOPE) set(ICU_LIBRARY "${ICU_LIBRARY}" PARENT_SCOPE) diff --git a/Modules/FindImageMagick.cmake b/Modules/FindImageMagick.cmake index d7de0dd..6baf471 100644 --- a/Modules/FindImageMagick.cmake +++ b/Modules/FindImageMagick.cmake @@ -5,7 +5,9 @@ FindImageMagick --------------- -Find ImageMagick binary suite. +Find ImageMagick, software suite for displaying, converting and +manipulating raster images. + .. versionadded:: 3.9 Added support for ImageMagick 7. @@ -15,76 +17,92 @@ components in the :command:`find_package` call. Typical components include, but are not limited to (future versions of ImageMagick might have additional components not listed here): -:: +* ``animate`` +* ``compare`` +* ``composite`` +* ``conjure`` +* ``convert`` +* ``display`` +* ``identify`` +* ``import`` +* ``mogrify`` +* ``montage`` +* ``stream`` - animate - compare - composite - conjure - convert - display - identify - import - mogrify - montage - stream +If no component is specified in the :command:`find_package` call, then it only +searches for the ImageMagick executable directory. +There are also components for the following ImageMagick APIs: +* ``Magick++``: ImageMagick C++ API, if found. +* ``MagickWand``: ImageMagick MagickWand C API, if found. +* ``MagickCore``: ImageMagick MagickCore low-level C API, if found. -If no component is specified in the :command:`find_package` call, then it only -searches for the ImageMagick executable directory. This code defines -the following variables: -:: +Imported targets +^^^^^^^^^^^^^^^^ - ImageMagick_FOUND - TRUE if all components are found. - ImageMagick_EXECUTABLE_DIR - Full path to executables directory. - ImageMagick_<component>_FOUND - TRUE if <component> is found. - ImageMagick_<component>_EXECUTABLE - Full path to <component> executable. - ImageMagick_VERSION_STRING - the version of ImageMagick found - (since CMake 2.8.8) +.. versionadded:: 3.26 +This module defines the following :prop_tgt:`IMPORTED` targets: +``ImageMagick::Magick++`` + ImageMagick C++ API, if found. -``ImageMagick_VERSION_STRING`` will not work for old versions like 5.2.3. +``ImageMagick::MagickWand`` + ImageMagick MagickWand C API, if found. -There are also components for the following ImageMagick APIs: +``ImageMagick::MagickCore`` + ImageMagick MagickCore low-level C API, if found. -:: - Magick++ - MagickWand - MagickCore +Result Variables +^^^^^^^^^^^^^^^^ +``ImageMagick_FOUND`` + TRUE if all components are found. +``ImageMagick_EXECUTABLE_DIR`` + Full path to executables directory. -For these components the following variables are set: +``ImageMagick_INCLUDE_DIRS`` + Full paths to all include dirs. -:: +``ImageMagick_LIBRARIES`` + Full paths to all libraries. - ImageMagick_FOUND - TRUE if all components are found. - ImageMagick_INCLUDE_DIRS - Full paths to all include dirs. - ImageMagick_LIBRARIES - Full paths to all libraries. - ImageMagick_<component>_FOUND - TRUE if <component> is found. - ImageMagick_<component>_INCLUDE_DIRS - Full path to <component> include dirs. - ImageMagick_<component>_LIBRARIES - Full path to <component> libraries. +``ImageMagick_COMPILE_OPTIONS`` + Compile options of all libraries. +``ImageMagick_VERSION_STRING`` + The version of ImageMagick found (since CMake 2.8.8). + Will not work for old versions like 5.2.3. +``ImageMagick_<component>_FOUND`` + TRUE if <component> is found. -Example Usages: +``ImageMagick_<component>_EXECUTABLE`` + Full path to <component> executable. -:: +``ImageMagick_<component>_INCLUDE_DIRS`` + Full path to <component> include dirs. - find_package(ImageMagick) - find_package(ImageMagick COMPONENTS convert) - find_package(ImageMagick COMPONENTS convert mogrify display) - find_package(ImageMagick COMPONENTS Magick++) - find_package(ImageMagick COMPONENTS Magick++ convert) +``ImageMagick_<component>_COMPILE_OPTIONS`` + .. versionadded:: 3.26 + + Compile options of <component>. +``ImageMagick_<component>_LIBRARIES`` + Full path to <component> libraries. -Note that the standard :command:`find_package` features are supported (i.e., -``QUIET``, ``REQUIRED``, etc.). +Example Usage +^^^^^^^^^^^^^ + +.. code-block:: cmake + + find_package(ImageMagick COMPONENTS Magick++) + target_link_libraries(example PRIVATE ImageMagick::Magick++) #]=======================================================================] find_package(PkgConfig QUIET) @@ -150,6 +168,8 @@ function(FIND_IMAGEMAGICK_API component header) set(ImageMagick_${component}_INCLUDE_DIRS ${ImageMagick_${component}_INCLUDE_DIRS} PARENT_SCOPE) + set(ImageMagick_${component}_COMPILE_OPTIONS ${PC_${component}_CFLAGS_OTHER}) + # Add the per-component include directories to the full include dirs. list(APPEND ImageMagick_INCLUDE_DIRS ${ImageMagick_${component}_INCLUDE_DIRS}) list(REMOVE_DUPLICATES ImageMagick_INCLUDE_DIRS) @@ -159,6 +179,17 @@ function(FIND_IMAGEMAGICK_API component header) ${ImageMagick_${component}_LIBRARY} ) set(ImageMagick_LIBRARIES ${ImageMagick_LIBRARIES} PARENT_SCOPE) + + list(APPEND ImageMagick_COMPILE_OPTIONS + ${ImageMagick_${component}_COMPILE_OPTIONS} + ) + set(ImageMagick_COMPILE_OPTIONS ${ImageMagick_COMPILE_OPTIONS} PARENT_SCOPE) + + add_library(ImageMagick::${component} UNKNOWN IMPORTED) + set_target_properties(ImageMagick::${component} PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES "${ImageMagick_${component}_INCLUDE_DIRS}" + INTERFACE_COMPILE_OPTIONS "${ImageMagick_${component}_COMPILE_OPTIONS}" + IMPORTED_LOCATION "${ImageMagick_${component}_LIBRARY}") endif() endfunction() diff --git a/Modules/FindJNI.cmake b/Modules/FindJNI.cmake index 5182401..64163b0 100644 --- a/Modules/FindJNI.cmake +++ b/Modules/FindJNI.cmake @@ -5,28 +5,79 @@ FindJNI ------- -Find Java Native Interface (JNI) libraries. +Find Java Native Interface (JNI) headers and libraries. -JNI enables Java code running in a Java Virtual Machine (JVM) to call -and be called by native applications and libraries written in other -languages such as C, C++. +JNI enables Java code running in a Java Virtual Machine (JVM) or Dalvik Virtual +Machine (DVM) on Android to call and be called by native applications and +libraries written in other languages such as C and C++. This module finds if Java is installed and determines where the include files and libraries are. It also determines what the name of the library is. The caller may set variable ``JAVA_HOME`` to specify a Java installation prefix explicitly. +.. versionadded:: 3.24 + + Added imported targets, components ``AWT``, ``JVM``, and Android NDK support. + If no components are specified, the module defaults to an empty components + list while targeting Android, and all available components otherwise. + + When using Android NDK, the corresponding package version is reported and a + specific release can be requested. At Android API level 31 and above, the + additional ``NativeHelper`` component can be requested. ``NativeHelper`` is + also exposed as an implicit dependency of the ``JVM`` component (only if this + does not cause a conflict) which provides a uniform access to JVM functions. + +Imported Targets +^^^^^^^^^^^^^^^^ + +.. versionadded:: 3.24 + +``JNI::JNI`` + Main JNI target, defined only if ``jni.h`` was found. + +``JNI::AWT`` + Java AWT Native Interface (JAWT) library, defined only if component ``AWT`` was + found. + +``JNI::JVM`` + Java Virtual Machine (JVM) library, defined only if component ``JVM`` was found. + +``JNI::NativeHelper`` + When targeting Android API level 31 and above, the import target will provide + access to ``libnativehelper.so`` that exposes JVM functions such as + ``JNI_CreateJavaVM``. + Result Variables ^^^^^^^^^^^^^^^^ This module sets the following result variables: ``JNI_INCLUDE_DIRS`` - the include dirs to use + The include directories to use. ``JNI_LIBRARIES`` - the libraries to use (JAWT and JVM) + The libraries to use (JAWT and JVM). ``JNI_FOUND`` - TRUE if JNI headers and libraries were found. + ``TRUE`` if JNI headers and libraries were found. +``JNI_<component>_FOUND`` + .. versionadded:: 3.24 + + ``TRUE`` if ``<component>`` was found. +``JNI_VERSION`` + Full Android NDK package version (including suffixes such as ``-beta3`` and + ``-rc1``) or undefined otherwise. +``JNI_VERSION_MAJOR`` + .. versionadded:: 3.24 + + Android NDK major version or undefined otherwise. +``JNI_VERSION_MINOR`` + .. versionadded:: 3.24 + + Android NDK minor version or undefined otherwise. +``JNI_VERSION_PATCH`` + .. versionadded:: 3.24 + + Android NDK patch version or undefined otherwise. Cache Variables ^^^^^^^^^^^^^^^ @@ -34,17 +85,55 @@ Cache Variables The following cache variables are also available to set or use: ``JAVA_AWT_LIBRARY`` - the path to the Java AWT Native Interface (JAWT) library + The path to the Java AWT Native Interface (JAWT) library. ``JAVA_JVM_LIBRARY`` - the path to the Java Virtual Machine (JVM) library + The path to the Java Virtual Machine (JVM) library. ``JAVA_INCLUDE_PATH`` - the include path to jni.h + The include path to ``jni.h``. ``JAVA_INCLUDE_PATH2`` - the include path to jni_md.h and jniport.h + The include path to machine-dependant headers ``jni_md.h`` and ``jniport.h``. + The variable is defined only if ``jni.h`` depends on one of these headers. In + contrast, Android NDK ``jni.h`` can be typically used standalone. ``JAVA_AWT_INCLUDE_PATH`` - the include path to jawt.h + The include path to ``jawt.h``. #]=======================================================================] +cmake_policy(PUSH) +cmake_policy(SET CMP0057 NEW) + +include(CheckSourceCompiles) +include(CMakePushCheckState) +include(FindPackageHandleStandardArgs) + +if(NOT JNI_FIND_COMPONENTS) + if(ANDROID) + if(CMAKE_SYSTEM_VERSION LESS 31) + # There are no components for Android NDK + set(JNI_FIND_COMPONENTS) + else() + set(JNI_FIND_COMPONENTS NativeHelper) + set(JNI_FIND_REQUIRED_NativeHelper TRUE) + endif() + else(ANDROID) + set(JNI_FIND_COMPONENTS AWT JVM) + # For compatibility purposes, if no components are specified both are + # considered required. + set(JNI_FIND_REQUIRED_AWT TRUE) + set(JNI_FIND_REQUIRED_JVM TRUE) + endif() +else() + # On Android, if JVM was requested we need to find NativeHelper as well which + # is an implicit dependency of JVM allowing to provide uniform access to basic + # JVM/DVM functionality. + if(ANDROID AND CMAKE_SYSTEM_VERSION GREATER_EQUAL 31 AND JVM IN_LIST JNI_FIND_COMPONENTS) + if(NOT NativeHelper IN_LIST JNI_FIND_COMPONENTS) + list(APPEND JNI_FIND_COMPONENTS NativeHelper) + # NativeHelper is required only if JVM was requested as such. + set(JNI_FIND_REQUIRED_NativeHelper ${JNI_FIND_REQUIRED_JVM}) + endif() + endif() +endif() + # Expand {libarch} occurrences to java_libarch subdirectory(-ies) and set ${_var} macro(java_append_library_directories _var) # Determine java arch-specific library subdir @@ -313,10 +402,19 @@ set(_JNI_NORMAL_JAWT ) foreach(search ${_JNI_SEARCHES}) - find_library(JAVA_JVM_LIBRARY ${_JNI_${search}_JVM}) - find_library(JAVA_AWT_LIBRARY ${_JNI_${search}_JAWT}) - if(JAVA_JVM_LIBRARY) - break() + if(JVM IN_LIST JNI_FIND_COMPONENTS) + find_library(JAVA_JVM_LIBRARY ${_JNI_${search}_JVM} + DOC "Java Virtual Machine library" + ) + endif(JVM IN_LIST JNI_FIND_COMPONENTS) + + if(AWT IN_LIST JNI_FIND_COMPONENTS) + find_library(JAVA_AWT_LIBRARY ${_JNI_${search}_JAWT} + DOC "Java AWT Native Interface library" + ) + if(JAVA_JVM_LIBRARY) + break() + endif() endif() endforeach() unset(_JNI_SEARCHES) @@ -335,11 +433,46 @@ endif() # add in the include path find_path(JAVA_INCLUDE_PATH jni.h ${JAVA_AWT_INCLUDE_DIRECTORIES} + DOC "JNI include directory" ) +if(JAVA_INCLUDE_PATH) + if(CMAKE_C_COMPILER_LOADED) + set(_JNI_CHECK_LANG C) + elseif(CMAKE_CXX_COMPILER_LOADED) + set(_JNI_CHECK_LANG CXX) + else() + set(_JNI_CHECK_LANG FALSE) + endif() + + # Skip the check if neither C nor CXX is loaded. + if(_JNI_CHECK_LANG) + cmake_push_check_state(RESET) + # The result of the following check is not relevant for the user as + # JAVA_INCLUDE_PATH2 will be added to REQUIRED_VARS if necessary. + set(CMAKE_REQUIRED_QUIET ON) + set(CMAKE_REQUIRED_INCLUDES ${JAVA_INCLUDE_PATH}) + + # Determine whether jni.h requires jni_md.h and add JAVA_INCLUDE_PATH2 + # correspondingly to REQUIRED_VARS + check_source_compiles(${_JNI_CHECK_LANG} +" +#include <jni.h> +int main(void) { return 0; } +" + JNI_INCLUDE_PATH2_OPTIONAL) + + cmake_pop_check_state() + else() + # If the above check is skipped assume jni_md.h is not needed. + set(JNI_INCLUDE_PATH2_OPTIONAL TRUE) + endif() + + unset(_JNI_CHECK_LANG) +endif() + find_path(JAVA_INCLUDE_PATH2 NAMES jni_md.h jniport.h - PATHS - ${JAVA_INCLUDE_PATH} + PATHS ${JAVA_INCLUDE_PATH} ${JAVA_INCLUDE_PATH}/darwin ${JAVA_INCLUDE_PATH}/win32 ${JAVA_INCLUDE_PATH}/linux @@ -349,11 +482,50 @@ find_path(JAVA_INCLUDE_PATH2 NAMES jni_md.h jniport.h ${JAVA_INCLUDE_PATH}/hp-ux ${JAVA_INCLUDE_PATH}/alpha ${JAVA_INCLUDE_PATH}/aix + DOC "jni_md.h jniport.h include directory" ) -find_path(JAVA_AWT_INCLUDE_PATH jawt.h - ${JAVA_INCLUDE_PATH} -) +if(AWT IN_LIST JNI_FIND_COMPONENTS) + find_path(JAVA_AWT_INCLUDE_PATH jawt.h + ${JAVA_INCLUDE_PATH} + DOC "Java AWT Native Interface include directory" + ) +endif() + +if(ANDROID) + # Some functions in jni.h (e.g., JNI_GetCreatedJavaVMs) are exported by + # libnativehelper.so, however, only when targeting Android API level >= 31. + find_library(JAVA_NativeHelper_LIBRARY NAMES nativehelper + DOC "Android nativehelper library" + ) +endif() + +# Set found components +if(JAVA_AWT_INCLUDE_PATH AND JAVA_AWT_LIBRARY) + set(JNI_AWT_FOUND TRUE) +else() + set(JNI_AWT_FOUND FALSE) +endif() + +# JVM is available even on Android referencing the nativehelper library +if(JAVA_JVM_LIBRARY) + set(JNI_JVM_FOUND TRUE) +else(JAVA_JVM_LIBRARY) + set(JNI_JVM_FOUND FALSE) +endif() + +if(JAVA_NativeHelper_LIBRARY) + # Alias JAVA_JVM_LIBRARY to JAVA_NativeHelper_LIBRARY + if(NOT JAVA_JVM_LIBRARY) + set(JAVA_JVM_LIBRARY "${JAVA_NativeHelper_LIBRARY}" CACHE FILEPATH + "Alias to nativehelper library" FORCE) + # Make JVM component available + set(JNI_JVM_FOUND TRUE) + endif() + set(JNI_NativeHelper_FOUND TRUE) +else() + set(JNI_NativeHelper_FOUND FALSE) +endif() # Restore CMAKE_FIND_FRAMEWORK if(DEFINED _JNI_CMAKE_FIND_FRAMEWORK) @@ -363,12 +535,35 @@ else() unset(CMAKE_FIND_FRAMEWORK) endif() -include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) -FIND_PACKAGE_HANDLE_STANDARD_ARGS(JNI DEFAULT_MSG JAVA_AWT_LIBRARY - JAVA_JVM_LIBRARY - JAVA_INCLUDE_PATH - JAVA_INCLUDE_PATH2 - JAVA_AWT_INCLUDE_PATH) +if(ANDROID) + # Extract NDK version from source.properties in the NDK root + set(JAVA_SOURCE_PROPERTIES_FILE ${CMAKE_ANDROID_NDK}/source.properties) + + if(EXISTS ${JAVA_SOURCE_PROPERTIES_FILE}) + file(READ ${JAVA_SOURCE_PROPERTIES_FILE} NDK_VERSION_CONTENTS) + string (REGEX REPLACE + ".*Pkg\\.Revision = (([0-9]+)\\.([0-9]+)\\.([0-9]+)([^\n]+)?).*" "\\1" + JNI_VERSION "${NDK_VERSION_CONTENTS}") + set(JNI_VERSION_MAJOR ${CMAKE_MATCH_1}) + set(JNI_VERSION_MINOR ${CMAKE_MATCH_2}) + set(JNI_VERSION_PATCH ${CMAKE_MATCH_3}) + set(JNI_VERSION_COMPONENTS 3) + + set(JNI_FPHSA_ARGS VERSION_VAR JNI_VERSION HANDLE_VERSION_RANGE) + endif() +endif() + +set(JNI_REQUIRED_VARS JAVA_INCLUDE_PATH) + +if(NOT JNI_INCLUDE_PATH2_OPTIONAL) + list(APPEND JNI_REQUIRED_VARS JAVA_INCLUDE_PATH2) +endif() + +find_package_handle_standard_args(JNI + REQUIRED_VARS ${JNI_REQUIRED_VARS} + ${JNI_FPHSA_ARGS} + HANDLE_COMPONENTS +) mark_as_advanced( JAVA_AWT_LIBRARY @@ -378,13 +573,93 @@ mark_as_advanced( JAVA_INCLUDE_PATH2 ) -set(JNI_LIBRARIES - ${JAVA_AWT_LIBRARY} - ${JAVA_JVM_LIBRARY} -) +set(JNI_LIBRARIES) -set(JNI_INCLUDE_DIRS - ${JAVA_INCLUDE_PATH} - ${JAVA_INCLUDE_PATH2} - ${JAVA_AWT_INCLUDE_PATH} -) +foreach(component IN LISTS JNI_FIND_COMPONENTS) + if(JNI_${component}_FOUND) + list(APPEND JNI_LIBRARIES ${JAVA_${component}_LIBRARY}) + endif() +endforeach() + +set(JNI_INCLUDE_DIRS ${JAVA_INCLUDE_PATH}) + +if(NOT JNI_INCLUDE_PATH2_OPTIONAL) + list(APPEND JNI_INCLUDE_DIRS ${JAVA_INCLUDE_PATH2}) +endif() + +if(JNI_FIND_REQUIRED_AWT) + list(APPEND JNI_INCLUDE_DIRS ${JAVA_AWT_INCLUDE_PATH}) +endif() + +if(JNI_FOUND) + if(NOT TARGET JNI::JNI) + add_library(JNI::JNI IMPORTED INTERFACE) + endif() + + set_property(TARGET JNI::JNI PROPERTY INTERFACE_INCLUDE_DIRECTORIES + ${JAVA_INCLUDE_PATH}) + + if(JNI_NativeHelper_FOUND) + if(NOT TARGET JNI::NativeHelper) + add_library(JNI::NativeHelper IMPORTED UNKNOWN) + endif() + + set_property(TARGET JNI::NativeHelper PROPERTY INTERFACE_LINK_LIBRARIES + JNI::JNI) + set_property(TARGET JNI::NativeHelper PROPERTY IMPORTED_LOCATION + ${JAVA_NativeHelper_LIBRARY}) + endif() + + if(NOT JNI_INCLUDE_PATH2_OPTIONAL AND JAVA_INCLUDE_PATH2) + set_property(TARGET JNI::JNI APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES + ${JAVA_INCLUDE_PATH2}) + endif() + + if(JNI_AWT_FOUND) + if(NOT TARGET JNI::AWT) + add_library(JNI::AWT IMPORTED UNKNOWN) + endif(NOT TARGET JNI::AWT) + + set_property(TARGET JNI::AWT PROPERTY INTERFACE_INCLUDE_DIRECTORIES + ${JAVA_AWT_INCLUDE_PATH}) + set_property(TARGET JNI::AWT PROPERTY IMPORTED_LOCATION + ${JAVA_AWT_LIBRARY}) + set_property(TARGET JNI::AWT PROPERTY INTERFACE_LINK_LIBRARIES JNI::JNI) + endif() + + if(JNI_JVM_FOUND OR JNI_NativeHelper_FOUND) + # If Android nativehelper is available but not the JVM library, we still + # define the JNI::JVM target but only declare JNI::NativeHelper as an + # interface link library of the former. This provides a uniform access to + # fundamental JVM functionality regardless of whether JVM or DVM is used. At + # the same time, this allows the user to detect whenever exclusively + # nativehelper functionality is available. + if(NOT TARGET JNI::JVM) + if(JAVA_JVM_LIBRARY AND NOT JAVA_JVM_LIBRARY STREQUAL JAVA_NativeHelper_LIBRARY) + # JAVA_JVM_LIBRARY is not an alias of JAVA_NativeHelper_LIBRARY + add_library(JNI::JVM IMPORTED UNKNOWN) + else() + add_library(JNI::JVM IMPORTED INTERFACE) + endif() + endif(NOT TARGET JNI::JVM) + + set_property(TARGET JNI::JVM PROPERTY INTERFACE_LINK_LIBRARIES JNI::JNI) + get_property(_JNI_JVM_TYPE TARGET JNI::JVM PROPERTY TYPE) + + if(NOT _JNI_JVM_TYPE STREQUAL "INTERFACE_LIBRARY") + set_property(TARGET JNI::JVM PROPERTY IMPORTED_LOCATION + ${JAVA_JVM_LIBRARY}) + else() + # We declare JNI::NativeHelper a dependency of JNI::JVM only if the latter + # was not initially found. If the solely theoretical situation occurs + # where both libraries are available, we want to avoid any potential + # errors that can occur due to duplicate symbols. + set_property(TARGET JNI::JVM APPEND PROPERTY INTERFACE_LINK_LIBRARIES + JNI::NativeHelper) + endif() + + unset(_JNI_JVM_TYPE) + endif() +endif() + +cmake_policy(POP) diff --git a/Modules/FindJava.cmake b/Modules/FindJava.cmake index 7a95ef5..e8fb120 100644 --- a/Modules/FindJava.cmake +++ b/Modules/FindJava.cmake @@ -144,23 +144,25 @@ find_program(Java_JAVA_EXECUTABLE if(Java_JAVA_EXECUTABLE) execute_process(COMMAND "${Java_JAVA_EXECUTABLE}" -version - RESULT_VARIABLE res - OUTPUT_VARIABLE var - ERROR_VARIABLE var # sun-java output to stderr + RESULT_VARIABLE _java_res + OUTPUT_VARIABLE _java_var + ERROR_VARIABLE _java_var # sun-java output to stderr OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_STRIP_TRAILING_WHITESPACE) - if( res ) - if(var MATCHES "Unable to locate a Java Runtime to invoke|No Java runtime present, requesting install") - set(Java_JAVA_EXECUTABLE Java_JAVA_EXECUTABLE-NOTFOUND) - elseif(${Java_FIND_REQUIRED}) - message( FATAL_ERROR "Error executing java -version" ) - else() - message( STATUS "Warning, could not run java -version") + if(_java_res) + if(NOT Java_FIND_QUIETLY) + message(STATUS "Java version check failed: " + "${Java_JAVA_EXECUTABLE} -version returned an error: \"${_java_var}\"") + endif() + if(_java_var MATCHES "Unable to locate a Java Runtime|No Java runtime present, requesting install") + # macOS distributes a java stub that provides an error message + set(Java_JAVA_EXECUTABLE "Java_JAVA_EXECUTABLE-NOTFOUND" CACHE PATH + "Path to the Java executable" FORCE) endif() else() # Extract version components (up to 4 levels) from "java -version" output. set(_java_version_regex [[(([0-9]+)(\.([0-9]+)(\.([0-9]+)(_([0-9]+))?)?)?.*)]]) - if(var MATCHES "java version \"${_java_version_regex}\"") + if(_java_var MATCHES "java version \"${_java_version_regex}\"") # Sun, GCJ, older OpenJDK set(Java_VERSION_STRING "${CMAKE_MATCH_1}") set(Java_VERSION_MAJOR "${CMAKE_MATCH_2}") @@ -175,7 +177,7 @@ if(Java_JAVA_EXECUTABLE) set(Java_VERSION_PATCH 0) endif() set(Java_VERSION_TWEAK "${CMAKE_MATCH_8}") - elseif(var MATCHES "openjdk version \"${_java_version_regex}\"") + elseif(_java_var MATCHES "openjdk version \"${_java_version_regex}\"") # OpenJDK set(Java_VERSION_STRING "${CMAKE_MATCH_1}") set(Java_VERSION_MAJOR "${CMAKE_MATCH_2}") @@ -190,14 +192,14 @@ if(Java_JAVA_EXECUTABLE) set(Java_VERSION_PATCH 0) endif() set(Java_VERSION_TWEAK "${CMAKE_MATCH_8}") - elseif(var MATCHES "openjdk version \"([0-9]+)-[A-Za-z]+\"") + elseif(_java_var MATCHES "openjdk version \"([0-9]+)-[A-Za-z]+\"") # OpenJDK 9 early access builds or locally built set(Java_VERSION_STRING "1.${CMAKE_MATCH_1}.0") set(Java_VERSION_MAJOR "1") set(Java_VERSION_MINOR "${CMAKE_MATCH_1}") set(Java_VERSION_PATCH "0") set(Java_VERSION_TWEAK "") - elseif(var MATCHES "java full version \"kaffe-${_java_version_regex}\"") + elseif(_java_var MATCHES "java full version \"kaffe-${_java_version_regex}\"") # Kaffe style set(Java_VERSION_STRING "${CMAKE_MATCH_1}") set(Java_VERSION_MAJOR "${CMAKE_MATCH_2}") @@ -206,7 +208,7 @@ if(Java_JAVA_EXECUTABLE) set(Java_VERSION_TWEAK "${CMAKE_MATCH_8}") else() if(NOT Java_FIND_QUIETLY) - string(REPLACE "\n" "\n " ver_msg "\n${var}") + string(REPLACE "\n" "\n " ver_msg "\n${_java_var}") message(WARNING "Java version not recognized:${ver_msg}\nPlease report.") endif() set(Java_VERSION_STRING "") @@ -215,18 +217,21 @@ if(Java_JAVA_EXECUTABLE) set(Java_VERSION_PATCH "") set(Java_VERSION_TWEAK "") endif() + unset(_java_version_regex) + unset(_java_var) set(Java_VERSION "${Java_VERSION_MAJOR}") if(NOT "x${Java_VERSION}" STREQUAL "x") - foreach(c MINOR PATCH TWEAK) - if(NOT "x${Java_VERSION_${c}}" STREQUAL "x") - string(APPEND Java_VERSION ".${Java_VERSION_${c}}") + foreach(_java_c MINOR PATCH TWEAK) + if(NOT "x${Java_VERSION_${_java_c}}" STREQUAL "x") + string(APPEND Java_VERSION ".${Java_VERSION_${_java_c}}") else() break() endif() endforeach() + unset(_java_c) endif() endif() - + unset(_java_res) endif() @@ -315,6 +320,7 @@ if(Java_FIND_COMPONENTS) set(Java_${component}_FOUND TRUE) endforeach() endif() + unset(_JAVA_REQUIRED_VARS) else() # Check for Development if(Java_VERSION VERSION_LESS "10") @@ -341,7 +347,7 @@ mark_as_advanced( Java_JAVADOC_EXECUTABLE Java_IDLJ_EXECUTABLE Java_JARSIGNER_EXECUTABLE - ) +) # LEGACY set(JAVA_RUNTIME ${Java_JAVA_EXECUTABLE}) diff --git a/Modules/FindLAPACK.cmake b/Modules/FindLAPACK.cmake index 91086a3..1eecb1c 100644 --- a/Modules/FindLAPACK.cmake +++ b/Modules/FindLAPACK.cmake @@ -12,7 +12,7 @@ This module finds an installed Fortran library that implements the At least one of the ``C``, ``CXX``, or ``Fortran`` languages must be enabled. -.. _`LAPACK linear-algebra interface`: http://www.netlib.org/lapack/ +.. _`LAPACK linear-algebra interface`: https://netlib.org/lapack/ Input Variables ^^^^^^^^^^^^^^^ @@ -35,6 +35,13 @@ The following variables may be set to influence this module's behavior: if set ``pkg-config`` will be used to search for a LAPACK library first and if one is found that is preferred +``BLA_PKGCONFIG_LAPACK`` + .. versionadded:: 3.25 + + If set, the ``pkg-config`` method will look for this module name instead of + just ``lapack``. + + ``BLA_SIZEOF_INTEGER`` .. versionadded:: 3.22 @@ -278,8 +285,11 @@ endif() # Search with pkg-config if specified if(BLA_PREFER_PKGCONFIG) - find_package(PkgConfig) - pkg_check_modules(PKGC_LAPACK lapack) + if(NOT BLA_PKGCONFIG_LAPACK) + set(BLA_PKGCONFIG_LAPACK "lapack") + endif() + find_package(PkgConfig QUIET) + pkg_check_modules(PKGC_LAPACK QUIET ${BLA_PKGCONFIG_LAPACK}) if(PKGC_LAPACK_FOUND) set(LAPACK_FOUND TRUE) set(LAPACK_LIBRARIES "${PKGC_LAPACK_LINK_LIBRARIES}") diff --git a/Modules/FindLTTngUST.cmake b/Modules/FindLTTngUST.cmake index a70a418..eaace4f 100644 --- a/Modules/FindLTTngUST.cmake +++ b/Modules/FindLTTngUST.cmake @@ -8,7 +8,7 @@ FindLTTngUST .. versionadded:: 3.6 Find -`Linux Trace Toolkit Next Generation (LTTng-UST) <http://lttng.org/>`__ library. +`Linux Trace Toolkit Next Generation (LTTng-UST) <https://lttng.org/>`__ library. Imported target ^^^^^^^^^^^^^^^ diff --git a/Modules/FindLibArchive.cmake b/Modules/FindLibArchive.cmake index 08078a2..9d3ac13 100644 --- a/Modules/FindLibArchive.cmake +++ b/Modules/FindLibArchive.cmake @@ -26,6 +26,9 @@ The module defines the following ``IMPORTED`` targets: .. versionadded:: 3.6 Support for new libarchive 3.2 version string format. +.. versionadded:: 3.17 + Provides an imported target. + #]=======================================================================] find_path(LibArchive_INCLUDE_DIR diff --git a/Modules/FindLibLZMA.cmake b/Modules/FindLibLZMA.cmake index 9ec8f07..1b3929b 100644 --- a/Modules/FindLibLZMA.cmake +++ b/Modules/FindLibLZMA.cmake @@ -33,6 +33,17 @@ This module will set the following variables in your project: True if lzma_easy_encoder() is found (required). ``LIBLZMA_HAS_LZMA_PRESET`` True if lzma_lzma_preset() is found (required). +``LIBLZMA_VERSION`` + .. versionadded:: 3.26 + the version of LZMA found. + + See also legacy variable ``LIBLZMA_VERSION_STRING``. + +Legacy Variables +^^^^^^^^^^^^^^^^ + +The following variables are provided for backward compatibility: + ``LIBLZMA_VERSION_MAJOR`` The major version of lzma ``LIBLZMA_VERSION_MINOR`` @@ -41,6 +52,10 @@ This module will set the following variables in your project: The patch version of lzma ``LIBLZMA_VERSION_STRING`` version number as a string (ex: "5.0.3") + + .. versionchanged:: 3.26 + Superseded by ``LIBLZMA_VERSION``. + #]=======================================================================] find_path(LIBLZMA_INCLUDE_DIR lzma.h ) @@ -61,6 +76,7 @@ if(LIBLZMA_INCLUDE_DIR AND EXISTS "${LIBLZMA_INCLUDE_DIR}/lzma/version.h") string(REGEX REPLACE ".*#define LZMA_VERSION_PATCH ([0-9]+).*" "\\1" LIBLZMA_VERSION_PATCH "${LIBLZMA_HEADER_CONTENTS}") set(LIBLZMA_VERSION_STRING "${LIBLZMA_VERSION_MAJOR}.${LIBLZMA_VERSION_MINOR}.${LIBLZMA_VERSION_PATCH}") + set(LIBLZMA_VERSION ${LIBLZMA_VERSION_STRING}) unset(LIBLZMA_HEADER_CONTENTS) endif() @@ -91,7 +107,7 @@ find_package_handle_standard_args(LibLZMA REQUIRED_VARS LIBLZMA_LIBRARY LIBLZMA_HAS_AUTO_DECODER LIBLZMA_HAS_EASY_ENCODER LIBLZMA_HAS_LZMA_PRESET - VERSION_VAR LIBLZMA_VERSION_STRING + VERSION_VAR LIBLZMA_VERSION ) mark_as_advanced( LIBLZMA_INCLUDE_DIR LIBLZMA_LIBRARY ) @@ -101,7 +117,7 @@ if (LIBLZMA_FOUND) if(NOT TARGET LibLZMA::LibLZMA) add_library(LibLZMA::LibLZMA UNKNOWN IMPORTED) set_target_properties(LibLZMA::LibLZMA PROPERTIES - INTERFACE_INCLUDE_DIRECTORIES ${LIBLZMA_INCLUDE_DIR} + INTERFACE_INCLUDE_DIRECTORIES "${LIBLZMA_INCLUDE_DIR}" IMPORTED_LINK_INTERFACE_LANGUAGES C) if(LIBLZMA_LIBRARY_RELEASE) diff --git a/Modules/FindLua.cmake b/Modules/FindLua.cmake index 32642fe..b56a7b1 100644 --- a/Modules/FindLua.cmake +++ b/Modules/FindLua.cmake @@ -10,19 +10,22 @@ Locate Lua library. .. versionadded:: 3.18 Support for Lua 5.4. -This module defines:: - -:: - - LUA_FOUND - if false, do not try to link to Lua - LUA_LIBRARIES - both lua and lualib - LUA_INCLUDE_DIR - where to find lua.h - LUA_VERSION_STRING - the version of Lua found - LUA_VERSION_MAJOR - the major version of Lua - LUA_VERSION_MINOR - the minor version of Lua - LUA_VERSION_PATCH - the patch version of Lua - - +This module defines: + +``LUA_FOUND`` + if false, do not try to link to Lua +``LUA_LIBRARIES`` + both lua and lualib +``LUA_INCLUDE_DIR`` + where to find lua.h +``LUA_VERSION_STRING`` + the version of Lua found +``LUA_VERSION_MAJOR`` + the major version of Lua +``LUA_VERSION_MINOR`` + the minor version of Lua +``LUA_VERSION_PATCH`` + the patch version of Lua Note that the expected include convention is diff --git a/Modules/FindMFC.cmake b/Modules/FindMFC.cmake index b8ca71b..38259c3 100644 --- a/Modules/FindMFC.cmake +++ b/Modules/FindMFC.cmake @@ -29,23 +29,19 @@ endif() if(MFC_ATTEMPT_TRY_COMPILE) if(NOT DEFINED MFC_HAVE_MFC) set(CHECK_INCLUDE_FILE_VAR "afxwin.h") - configure_file(${CMAKE_ROOT}/Modules/CheckIncludeFile.cxx.in - ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckIncludeFile.cxx) + file(READ ${CMAKE_ROOT}/Modules/CheckIncludeFile.cxx.in _CIF_SOURCE_CONTENT) + string(CONFIGURE "${_CIF_SOURCE_CONTENT}" _CIF_SOURCE_CONTENT) message(CHECK_START "Looking for MFC") # Try both shared and static as the root project may have set the /MT flag try_compile(MFC_HAVE_MFC - ${CMAKE_BINARY_DIR} - ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckIncludeFile.cxx + SOURCE_FROM_VAR CheckIncludeFile.cxx _CIF_SOURCE_CONTENT CMAKE_FLAGS -DCMAKE_MFC_FLAG:STRING=2 -DCOMPILE_DEFINITIONS:STRING=-D_AFXDLL OUTPUT_VARIABLE OUTPUT) if(NOT MFC_HAVE_MFC) - configure_file(${CMAKE_ROOT}/Modules/CheckIncludeFile.cxx.in - ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckIncludeFile.cxx) try_compile(MFC_HAVE_MFC - ${CMAKE_BINARY_DIR} - ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckIncludeFile.cxx + SOURCE_FROM_VAR CheckIncludeFile.cxx _CIF_SOURCE_CONTENT CMAKE_FLAGS -DCMAKE_MFC_FLAG:STRING=1 OUTPUT_VARIABLE OUTPUT) @@ -53,15 +49,9 @@ if(MFC_ATTEMPT_TRY_COMPILE) if(MFC_HAVE_MFC) message(CHECK_PASS "found") set(MFC_HAVE_MFC 1 CACHE INTERNAL "Have MFC?") - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log - "Determining if MFC exists passed with the following output:\n" - "${OUTPUT}\n\n") else() message(CHECK_FAIL "not found") set(MFC_HAVE_MFC 0 CACHE INTERNAL "Have MFC?") - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log - "Determining if MFC exists failed with the following output:\n" - "${OUTPUT}\n\n") endif() endif() diff --git a/Modules/FindMPI.cmake b/Modules/FindMPI.cmake index c974d33..1fbb4f9 100644 --- a/Modules/FindMPI.cmake +++ b/Modules/FindMPI.cmake @@ -391,11 +391,11 @@ function (_MPI_check_compiler LANG QUERY_FLAG OUTPUT_VARIABLE RESULT_VARIABLE) # library that has invalid or missing version information there would be warning # messages emitted by ld.so in the compiler output. In either case, we'll treat # the output as invalid. - if("${WRAPPER_OUTPUT}" MATCHES "undefined reference|unrecognized|need to set|no version information available|command not found") + if(WRAPPER_OUTPUT MATCHES "undefined reference|unrecognized|need to set|no version information available|command not found") set(WRAPPER_RETURN 255) endif() # Ensure that no error output might be passed upwards. - if(NOT WRAPPER_RETURN EQUAL 0) + if(NOT WRAPPER_RETURN EQUAL "0") unset(WRAPPER_OUTPUT) else() # Strip leading whitespace @@ -441,13 +441,13 @@ function (_MPI_interrogate_compiler LANG) if(MSVC) get_filename_component(_MPI_UNDERLAYING_COMPILER "${_MPI_UNDERLAYING_COMPILER}" NAME) endif() - if("${LANG}" STREQUAL "C") + if(LANG STREQUAL "C") _MPI_env_set_ifnot(I_MPI_CC _MPI_UNDERLAYING_COMPILER) _MPI_env_set_ifnot(MPICH_CC _MPI_UNDERLAYING_COMPILER) - elseif("${LANG}" STREQUAL "CXX") + elseif(LANG STREQUAL "CXX") _MPI_env_set_ifnot(I_MPI_CXX _MPI_UNDERLAYING_COMPILER) _MPI_env_set_ifnot(MPICH_CXX _MPI_UNDERLAYING_COMPILER) - elseif("${LANG}" STREQUAL "Fortran") + elseif(LANG STREQUAL "Fortran") _MPI_env_set_ifnot(I_MPI_FC _MPI_UNDERLAYING_COMPILER) _MPI_env_set_ifnot(MPICH_FC _MPI_UNDERLAYING_COMPILER) _MPI_env_set_ifnot(I_MPI_F77 _MPI_UNDERLAYING_COMPILER) @@ -470,10 +470,10 @@ function (_MPI_interrogate_compiler LANG) # or a newer version of LAM/MPI, and implies that -showme:link will also work. # Open MPI also supports -show, but separates linker and compiler information _MPI_check_compiler(${LANG} "-showme:compile" MPI_COMPILE_CMDLINE MPI_COMPILER_RETURN) - if (MPI_COMPILER_RETURN EQUAL 0) + if (MPI_COMPILER_RETURN EQUAL "0") _MPI_check_compiler(${LANG} "-showme:link" MPI_LINK_CMDLINE MPI_COMPILER_RETURN) - if (NOT MPI_COMPILER_RETURN EQUAL 0) + if (NOT MPI_COMPILER_RETURN EQUAL "0") unset(MPI_COMPILE_CMDLINE) endif() endif() @@ -482,13 +482,13 @@ function (_MPI_interrogate_compiler LANG) # For modern versions, both do the same as -show. However, for old versions, they do differ # when called for mpicxx and mpif90 and it's necessary to use them over -show in order to find the # removed MPI C++ bindings. - if (NOT MPI_COMPILER_RETURN EQUAL 0) + if (NOT MPI_COMPILER_RETURN EQUAL "0") _MPI_check_compiler(${LANG} "-compile-info" MPI_COMPILE_CMDLINE MPI_COMPILER_RETURN) - if (MPI_COMPILER_RETURN EQUAL 0) + if (MPI_COMPILER_RETURN EQUAL "0") _MPI_check_compiler(${LANG} "-link-info" MPI_LINK_CMDLINE MPI_COMPILER_RETURN) - if (NOT MPI_COMPILER_RETURN EQUAL 0) + if (NOT MPI_COMPILER_RETURN EQUAL "0") unset(MPI_COMPILE_CMDLINE) endif() endif() @@ -496,18 +496,18 @@ function (_MPI_interrogate_compiler LANG) # Cray compiler wrappers come usually without a separate mpicc/c++/ftn, but offer # --cray-print-opts=... - if (NOT MPI_COMPILER_RETURN EQUAL 0) + if (NOT MPI_COMPILER_RETURN EQUAL "0") _MPI_check_compiler(${LANG} "--cray-print-opts=cflags" MPI_COMPILE_CMDLINE MPI_COMPILER_RETURN) - if (MPI_COMPILER_RETURN EQUAL 0) + if (MPI_COMPILER_RETURN EQUAL "0") # Pass --no-as-needed so the mpi library is always linked. Otherwise, the # Cray compiler wrapper puts an --as-needed flag around the mpi library, # and it is not linked unless code directly refers to it. _MPI_check_compiler(${LANG} "--no-as-needed;--cray-print-opts=libs" MPI_LINK_CMDLINE MPI_COMPILER_RETURN) - if (NOT MPI_COMPILER_RETURN EQUAL 0) + if (NOT MPI_COMPILER_RETURN EQUAL "0") unset(MPI_COMPILE_CMDLINE) unset(MPI_LINK_CMDLINE) endif() @@ -516,24 +516,24 @@ function (_MPI_interrogate_compiler LANG) # MPICH, MVAPICH2 and Intel MPI just use "-show". Open MPI also offers this, but the # -showme commands are more specialized. - if (NOT MPI_COMPILER_RETURN EQUAL 0) + if (NOT MPI_COMPILER_RETURN EQUAL "0") _MPI_check_compiler(${LANG} "-show" MPI_COMPILE_CMDLINE MPI_COMPILER_RETURN) endif() # Older versions of LAM/MPI have "-showme". Open MPI also supports this. # Unknown to MPICH, MVAPICH and Intel MPI. - if (NOT MPI_COMPILER_RETURN EQUAL 0) + if (NOT MPI_COMPILER_RETURN EQUAL "0") _MPI_check_compiler(${LANG} "-showme" MPI_COMPILE_CMDLINE MPI_COMPILER_RETURN) endif() - if (MPI_COMPILER_RETURN EQUAL 0 AND DEFINED MPI_COMPILE_CMDLINE) + if (MPI_COMPILER_RETURN EQUAL "0" AND DEFINED MPI_COMPILE_CMDLINE) # Intel MPI can be run with -compchk or I_MPI_CHECK_COMPILER set to 1. # In this case, -show will be prepended with a line to the compiler checker. This is a script that performs # compatibility checks and returns a non-zero exit code together with an error if something fails. # It has to be called as "compchk.sh <arch> <compiler>". Here, <arch> is one out of 32 (i686), 64 (ia64) or 32e (x86_64). # The compiler is identified by filename, and can be either the MPI compiler or the underlying compiler. # NOTE: It is vital to run this script while the environment variables are set up, otherwise it can check the wrong compiler. - if("${MPI_COMPILE_CMDLINE}" MATCHES "^([^\" ]+/compchk.sh|\"[^\"]+/compchk.sh\") +([^ ]+)") + if(MPI_COMPILE_CMDLINE MATCHES "^([^\" ]+/compchk.sh|\"[^\"]+/compchk.sh\") +([^ ]+)") # Now CMAKE_MATCH_1 contains the path to the compchk.sh file and CMAKE_MATCH_2 the architecture flag. unset(COMPILER_CHECKER_OUTPUT) execute_process( @@ -542,7 +542,7 @@ function (_MPI_interrogate_compiler LANG) ERROR_VARIABLE COMPILER_CHECKER_OUTPUT ERROR_STRIP_TRAILING_WHITESPACE RESULT_VARIABLE MPI_COMPILER_RETURN) # If it returned a non-zero value, the check below will fail and cause the interrogation to be aborted. - if(NOT MPI_COMPILER_RETURN EQUAL 0) + if(NOT MPI_COMPILER_RETURN EQUAL "0") if(NOT MPI_FIND_QUIETLY) message(STATUS "Intel MPI compiler check failed: ${COMPILER_CHECKER_OUTPUT}") endif() @@ -554,13 +554,13 @@ function (_MPI_interrogate_compiler LANG) endif() # Revert changes to the environment made previously - if("${LANG}" STREQUAL "C") + if(LANG STREQUAL "C") _MPI_env_unset_ifnot(I_MPI_CC) _MPI_env_unset_ifnot(MPICH_CC) - elseif("${LANG}" STREQUAL "CXX") + elseif(LANG STREQUAL "CXX") _MPI_env_unset_ifnot(I_MPI_CXX) _MPI_env_unset_ifnot(MPICH_CXX) - elseif("${LANG}" STREQUAL "Fortran") + elseif(LANG STREQUAL "Fortran") _MPI_env_unset_ifnot(I_MPI_FC) _MPI_env_unset_ifnot(MPICH_FC) _MPI_env_unset_ifnot(I_MPI_F77) @@ -572,7 +572,7 @@ function (_MPI_interrogate_compiler LANG) _MPI_env_unset_ifnot(I_MPI_DEBUG_INFO_STRIP) _MPI_env_unset_ifnot(I_MPI_FORT_BIND) - if (NOT (MPI_COMPILER_RETURN EQUAL 0) OR NOT (DEFINED MPI_COMPILE_CMDLINE)) + if (NOT (MPI_COMPILER_RETURN EQUAL "0") OR NOT (DEFINED MPI_COMPILE_CMDLINE)) # Cannot interrogate this compiler, so exit. set(MPI_${LANG}_WRAPPER_FOUND FALSE PARENT_SCOPE) return() @@ -613,13 +613,13 @@ function (_MPI_interrogate_compiler LANG) if(UNIX) # At this point, we obtained some output from a compiler wrapper that works. # We'll now try to parse it into variables with meaning to us. - if("${LANG}" STREQUAL "Fortran") + if(LANG STREQUAL "Fortran") # If MPICH (and derivates) didn't recognize the Fortran compiler include flag during configuration, # they'll return a set of three commands, consisting out of a symlink command for mpif.h, # the actual compiler command and deletion of the created symlink. # Especially with M(VA)PICH-1, this appears to happen erroneously, and therefore we should translate # this output into an additional include directory and then drop it from the output. - if("${MPI_COMPILE_CMDLINE}" MATCHES "^ln -s ([^\" ]+|\"[^\"]+\") mpif.h") + if(MPI_COMPILE_CMDLINE MATCHES "^ln -s ([^\" ]+|\"[^\"]+\") mpif.h") get_filename_component(MPI_INCLUDE_DIRS_WORK "${CMAKE_MATCH_1}" DIRECTORY) string(REGEX REPLACE "^ln -s ([^\" ]+|\"[^\"]+\") mpif.h\n" "" MPI_COMPILE_CMDLINE "${MPI_COMPILE_CMDLINE}") string(REGEX REPLACE "^ln -s ([^\" ]+|\"[^\"]+\") mpif.h\n" "" MPI_LINK_CMDLINE "${MPI_LINK_CMDLINE}") @@ -651,7 +651,7 @@ function (_MPI_interrogate_compiler LANG) # produce inconsistent results with the regularly flags. # Similarly, aliasing flags do not belong into our flag array. # Also strip out `-framework` flags. - if(NOT "${_MPI_COMPILE_OPTION}" MATCHES "^-f((no-|)(stack-protector|strict-aliasing)|PI[CE]|pi[ce]|ramework)") + if(NOT _MPI_COMPILE_OPTION MATCHES "^-f((no-|)(stack-protector|strict-aliasing)|PI[CE]|pi[ce]|ramework)") list(APPEND MPI_COMPILE_OPTIONS_WORK "${_MPI_COMPILE_OPTION}") endif() endforeach() @@ -673,7 +673,7 @@ function (_MPI_interrogate_compiler LANG) foreach(_MPI_COMPILE_DEFINITION IN LISTS MPI_ALL_COMPILE_DEFINITIONS) string(REGEX REPLACE "^ ?${_MPI_PREPROCESSOR_FLAG_REGEX}-D *" "" _MPI_COMPILE_DEFINITION "${_MPI_COMPILE_DEFINITION}") string(REPLACE "\"" "" _MPI_COMPILE_DEFINITION "${_MPI_COMPILE_DEFINITION}") - if(NOT "${_MPI_COMPILE_DEFINITION}" MATCHES "^_FORTIFY_SOURCE.*") + if(NOT _MPI_COMPILE_DEFINITION MATCHES "^_FORTIFY_SOURCE.*") list(APPEND MPI_COMPILE_DEFINITIONS_WORK "${_MPI_COMPILE_DEFINITION}") endif() endforeach() @@ -775,7 +775,8 @@ function (_MPI_interrogate_compiler LANG) MPI_LIBNAMES "${MPI_LINK_CMDLINE}") foreach(_MPI_LIB_NAME IN LISTS MPI_LIBNAMES) - string(REGEX REPLACE "^ ?${CMAKE_LINK_LIBRARY_FLAG}" "" _MPI_LIB_NAME "${_MPI_LIB_NAME}") + # also match flags starting with "-l:" here + string(REGEX REPLACE "^ ?${CMAKE_LINK_LIBRARY_FLAG}(:lib|:)?" "" _MPI_LIB_NAME "${_MPI_LIB_NAME}") string(REPLACE "\"" "" _MPI_LIB_NAME "${_MPI_LIB_NAME}") list(APPEND MPI_LIB_NAMES_WORK "${_MPI_LIB_NAME}") endforeach() @@ -787,8 +788,8 @@ function (_MPI_interrogate_compiler LANG) # decide how to link it based on file type, not based on a prefix like 'lib'. set(_MPI_LIB_SUFFIX_REGEX "${CMAKE_STATIC_LIBRARY_SUFFIX}") if(DEFINED CMAKE_IMPORT_LIBRARY_SUFFIX) - if(NOT ("${CMAKE_IMPORT_LIBRARY_SUFFIX}" STREQUAL "${CMAKE_STATIC_LIBRARY_SUFFIX}")) - string(APPEND _MPI_SUFFIX_REGEX "|${CMAKE_IMPORT_LIBRARY_SUFFIX}") + if(NOT (CMAKE_IMPORT_LIBRARY_SUFFIX STREQUAL CMAKE_STATIC_LIBRARY_SUFFIX)) + string(APPEND _MPI_LIB_SUFFIX_REGEX "|${CMAKE_IMPORT_LIBRARY_SUFFIX}") endif() else() string(APPEND _MPI_LIB_SUFFIX_REGEX "|${CMAKE_SHARED_LIBRARY_SUFFIX}") @@ -798,12 +799,16 @@ function (_MPI_interrogate_compiler LANG) string(REGEX MATCHALL "${_MPI_LIB_NAME_REGEX}" MPI_LIBNAMES "${MPI_LINK_CMDLINE}") foreach(_MPI_LIB_NAME IN LISTS MPI_LIBNAMES) - string(REGEX REPLACE "^ +\"?|\"? +$" "" _MPI_LIB_NAME "${_MPI_LIB_NAME}") - get_filename_component(_MPI_LIB_PATH "${_MPI_LIB_NAME}" DIRECTORY) - if(NOT "${_MPI_LIB_PATH}" STREQUAL "") - list(APPEND MPI_LIB_FULLPATHS_WORK "${_MPI_LIB_NAME}") - else() - list(APPEND MPI_LIB_NAMES_WORK "${_MPI_LIB_NAME}") + # Do not match "-l:" flags + string(REGEX MATCH "^ ?${CMAKE_LINK_LIBRARY_FLAG}:" _MPI_LIB_NAME_TEST "${_MPI_LIB_NAME}") + if(_MPI_LIB_NAME_TEST STREQUAL "") + string(REGEX REPLACE "^ +\"?|\"? +$" "" _MPI_LIB_NAME "${_MPI_LIB_NAME}") + get_filename_component(_MPI_LIB_PATH "${_MPI_LIB_NAME}" DIRECTORY) + if(NOT _MPI_LIB_PATH STREQUAL "") + list(APPEND MPI_LIB_FULLPATHS_WORK "${_MPI_LIB_NAME}") + else() + list(APPEND MPI_LIB_NAMES_WORK "${_MPI_LIB_NAME}") + endif() endif() endforeach() @@ -840,7 +845,7 @@ function (_MPI_interrogate_compiler LANG) foreach(_MPI_LINK_DIRECTORY IN LISTS MPI_LINK_DIRECTORIES_LEFTOVER) file(TO_NATIVE_PATH "${_MPI_LINK_DIRECTORY}" _MPI_LINK_DIRECTORY_ACTUAL) string(FIND "${_MPI_LINK_DIRECTORY_ACTUAL}" " " _MPI_LINK_DIRECTORY_CONTAINS_SPACE) - if(NOT _MPI_LINK_DIRECTORY_CONTAINS_SPACE EQUAL -1) + if(NOT _MPI_LINK_DIRECTORY_CONTAINS_SPACE EQUAL "-1") set(_MPI_LINK_DIRECTORY_ACTUAL "\"${_MPI_LINK_DIRECTORY_ACTUAL}\"") endif() if(MPI_LINK_FLAGS_WORK) @@ -866,7 +871,7 @@ function (_MPI_interrogate_compiler LANG) # MPI might require pthread to work. The above mechanism wouldn't detect it, but we need to # link it in that case. -lpthread is covered by the normal library treatment on the other hand. - if("${MPI_COMPILE_CMDLINE}" MATCHES "-pthread") + if(MPI_COMPILE_CMDLINE MATCHES "-pthread") list(APPEND MPI_COMPILE_OPTIONS_WORK "-pthread") if(MPI_LINK_FLAGS_WORK) string(APPEND MPI_LINK_FLAGS_WORK " -pthread") @@ -913,10 +918,10 @@ function(_MPI_guess_settings LANG) # The environment variables MSMPI_INC and MSMPILIB32/64 are the only ways of locating the MSMPI_SDK, # which is installed separately from the runtime. Thus it's possible to have mpiexec but not MPI headers # or import libraries and vice versa. - if(NOT MPI_GUESS_LIBRARY_NAME OR "${MPI_GUESS_LIBRARY_NAME}" STREQUAL "MSMPI") + if(NOT MPI_GUESS_LIBRARY_NAME OR MPI_GUESS_LIBRARY_NAME STREQUAL "MSMPI") # We first attempt to locate the msmpi.lib. Should be find it, we'll assume that the MPI present is indeed # Microsoft MPI. - if("${CMAKE_SIZEOF_VOID_P}" EQUAL 8) + if(CMAKE_SIZEOF_VOID_P EQUAL "8") file(TO_CMAKE_PATH "$ENV{MSMPI_LIB64}" MPI_MSMPI_LIB_PATH) file(TO_CMAKE_PATH "$ENV{MSMPI_INC}/x64" MPI_MSMPI_INC_PATH_EXTRA) else() @@ -970,9 +975,9 @@ function(_MPI_guess_settings LANG) # Our strategy is now to locate all libraries, but enter msmpifec into the LIB_NAMES array. # Should this not be adequate it's a straightforward way for a user to change the LIB_NAMES array and # have his library found. Still, this should not be necessary outside of exceptional cases, as reasoned. - if ("${LANG}" STREQUAL "Fortran") + if (LANG STREQUAL "Fortran") set(MPI_MSMPI_CALLINGCONVS c) - if("${CMAKE_SIZEOF_VOID_P}" EQUAL 4) + if(CMAKE_SIZEOF_VOID_P EQUAL "4") list(APPEND MPI_MSMPI_CALLINGCONVS s) endif() foreach(mpistrlenpos IN ITEMS e m) @@ -1020,7 +1025,7 @@ function(_MPI_guess_settings LANG) # At this point there's not many MPIs that we could still consider. # OpenMPI 1.6.x and below supported Windows, but these ship compiler wrappers that still work. # The only other relevant MPI implementation without a wrapper is MPICH2, which had Windows support in 1.4.1p1 and older. - if(NOT MPI_GUESS_FOUND AND (NOT MPI_GUESS_LIBRARY_NAME OR "${MPI_GUESS_LIBRARY_NAME}" STREQUAL "MPICH2")) + if(NOT MPI_GUESS_FOUND AND (NOT MPI_GUESS_LIBRARY_NAME OR MPI_GUESS_LIBRARY_NAME STREQUAL "MPICH2")) set(MPI_MPICH_PREFIX_PATHS "$ENV{ProgramW6432}/MPICH2/lib" "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MPICH\\SMPD;binary]/../lib" @@ -1037,7 +1042,7 @@ function(_MPI_guess_settings LANG) set(MPI_MPICH_LIB_NAMES "mpi") # If MPI-2 C++ bindings are requested, we need to locate cxx.lib as well. # Otherwise, MPICH_SKIP_MPICXX will be defined and these bindings aren't needed. - if("${LANG}" STREQUAL "CXX" AND NOT MPI_CXX_SKIP_MPICXX) + if(LANG STREQUAL "CXX" AND NOT MPI_CXX_SKIP_MPICXX) find_library(MPI_cxx_LIBRARY NAMES cxx HINTS ${MPI_MPICH_PREFIX_PATHS}) @@ -1050,7 +1055,7 @@ function(_MPI_guess_settings LANG) # fmpich2s.lib would be useful for Compaq Visual Fortran, fmpich2g.lib has to be used with GNU g77 and is also # provided in the form of an .a archive for MinGW and Cygwin. From our perspective, fmpich2.lib is the only one # we need to try, and if it doesn't work with the given Fortran compiler we'd find out later on during validation - elseif("${LANG}" STREQUAL "Fortran") + elseif(LANG STREQUAL "Fortran") find_library(MPI_fmpich2_LIBRARY NAMES fmpich2 HINTS ${MPI_MPICH_PREFIX_PATHS}) @@ -1098,7 +1103,7 @@ function(_MPI_guess_settings LANG) endfunction() function(_MPI_adjust_compile_definitions LANG) - if("${LANG}" STREQUAL "CXX") + if(LANG STREQUAL "CXX") # To disable the C++ bindings, we need to pass some definitions since the mpi.h header has to deal with both C and C++ # bindings in MPI-2. if(MPI_CXX_SKIP_MPICXX AND NOT MPI_${LANG}_COMPILE_DEFINITIONS MATCHES "SKIP_MPICXX") @@ -1114,7 +1119,7 @@ endfunction() macro(_MPI_assemble_libraries LANG) set(MPI_${LANG}_LIBRARIES "") # Only for libraries do we need to check whether the compiler's linking stage is separate. - if(NOT "${MPI_${LANG}_COMPILER}" STREQUAL "${CMAKE_${LANG}_COMPILER}" OR NOT MPI_${LANG}_WORKS_IMPLICIT) + if(NOT MPI_${LANG}_COMPILER STREQUAL CMAKE_${LANG}_COMPILER OR NOT MPI_${LANG}_WORKS_IMPLICIT) foreach(mpilib IN LISTS MPI_${LANG}_LIB_NAMES) list(APPEND MPI_${LANG}_LIBRARIES ${MPI_${mpilib}_LIBRARY}) endforeach() @@ -1126,7 +1131,7 @@ macro(_MPI_assemble_include_dirs LANG) ${MPI_${LANG}_COMPILER_INCLUDE_DIRS} ${MPI_${LANG}_ADDITIONAL_INCLUDE_DIRS} ) - if("${LANG}" MATCHES "(C|CXX)") + if(LANG MATCHES "^(C|CXX)$") if(MPI_${LANG}_HEADER_DIR) list(APPEND MPI_${LANG}_INCLUDE_DIRS "${MPI_${LANG}_HEADER_DIR}") endif() @@ -1151,7 +1156,7 @@ macro(_MPI_split_include_dirs LANG) # We try to find the headers/modules among those paths (and system paths) # For C/C++, we just need to have a look for mpi.h. - if("${LANG}" MATCHES "(C|CXX)") + if(LANG MATCHES "^(C|CXX)$") find_path(MPI_${LANG}_HEADER_DIR "mpi.h" HINTS ${MPI_${LANG}_COMPILER_INCLUDE_DIRS} @@ -1166,7 +1171,7 @@ macro(_MPI_split_include_dirs LANG) # any of the Fortran 77/90/2008 APIs for MPI. For example, MSMPI # only provides Fortran 77 and - if mpi.f90 is built - potentially # a Fortran 90 module. - elseif("${LANG}" STREQUAL "Fortran") + elseif(LANG STREQUAL "Fortran") find_path(MPI_${LANG}_F77_HEADER_DIR "mpif.h" HINTS ${MPI_${LANG}_COMPILER_INCLUDE_DIRS} @@ -1233,28 +1238,37 @@ function(_MPI_try_staged_settings LANG MPI_TEST_FILE_NAME MODE RUN_BINARY SUPPRE set(SRC_DIR "${CMAKE_ROOT}/Modules/FindMPI") set(BIN_FILE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/FindMPI/${MPI_TEST_FILE_NAME}_${LANG}.bin") unset(MPI_TEST_COMPILE_DEFINITIONS) - if("${LANG}" STREQUAL "Fortran") - if("${MODE}" STREQUAL "F90_MODULE") + if(LANG STREQUAL "Fortran") + if(MODE STREQUAL "F90_MODULE") set(MPI_Fortran_INCLUDE_LINE "use mpi\n implicit none") - elseif("${MODE}" STREQUAL "F08_MODULE") + elseif(MODE STREQUAL "F08_MODULE") set(MPI_Fortran_INCLUDE_LINE "use mpi_f08\n implicit none") else() # F77 header set(MPI_Fortran_INCLUDE_LINE "implicit none\n include 'mpif.h'") endif() - configure_file("${SRC_DIR}/${MPI_TEST_FILE_NAME}.f90.in" "${WORK_DIR}/${MPI_TEST_FILE_NAME}.f90" @ONLY) - set(MPI_TEST_SOURCE_FILE "${WORK_DIR}/${MPI_TEST_FILE_NAME}.f90") - elseif("${LANG}" STREQUAL "CXX") - configure_file("${SRC_DIR}/${MPI_TEST_FILE_NAME}.c" "${WORK_DIR}/${MPI_TEST_FILE_NAME}.cpp" COPYONLY) - set(MPI_TEST_SOURCE_FILE "${WORK_DIR}/${MPI_TEST_FILE_NAME}.cpp") - if("${MODE}" STREQUAL "TEST_MPICXX") + file(READ "${SRC_DIR}/${MPI_TEST_FILE_NAME}.f90.in" MPI_TEST_SOURCE_CONTENT) + string(CONFIGURE "${MPI_TEST_SOURCE_CONTENT}" MPI_TEST_SOURCE_CONTENT) + set(MPI_TEST_SOURCE_FILE "${MPI_TEST_FILE_NAME}.f90") + elseif(LANG STREQUAL "CXX") + file(READ "${SRC_DIR}/${MPI_TEST_FILE_NAME}.c" MPI_TEST_SOURCE_CONTENT) + set(MPI_TEST_SOURCE_FILE "${MPI_TEST_FILE_NAME}.cpp") + if(MODE STREQUAL "TEST_MPICXX") set(MPI_TEST_COMPILE_DEFINITIONS TEST_MPI_MPICXX) endif() else() # C - set(MPI_TEST_SOURCE_FILE "${SRC_DIR}/${MPI_TEST_FILE_NAME}.c") + file(READ "${SRC_DIR}/${MPI_TEST_FILE_NAME}.c" MPI_TEST_SOURCE_CONTENT) + set(MPI_TEST_SOURCE_FILE "${MPI_TEST_FILE_NAME}.c") + endif() + if(SUPPRESS_ERRORS) + set(maybe_no_log NO_LOG) + else() + set(maybe_no_log "") endif() if(RUN_BINARY) try_run(MPI_RUN_RESULT_${LANG}_${MPI_TEST_FILE_NAME}_${MODE} MPI_RESULT_${LANG}_${MPI_TEST_FILE_NAME}_${MODE} - "${CMAKE_BINARY_DIR}" SOURCES "${MPI_TEST_SOURCE_FILE}" + SOURCE_FROM_VAR "${MPI_TEST_SOURCE_FILE}" MPI_TEST_SOURCE_CONTENT + ${maybe_no_log} + LOG_DESCRIPTION "The MPI test ${MPI_TEST_FILE_NAME} for ${LANG} in mode ${MODE}" COMPILE_DEFINITIONS ${MPI_TEST_COMPILE_DEFINITIONS} LINK_LIBRARIES MPI::MPI_${LANG} RUN_OUTPUT_VARIABLE MPI_RUN_OUTPUT_${LANG}_${MPI_TEST_FILE_NAME}_${MODE} @@ -1262,21 +1276,14 @@ function(_MPI_try_staged_settings LANG MPI_TEST_FILE_NAME MODE RUN_BINARY SUPPRE set(MPI_RUN_OUTPUT_${LANG}_${MPI_TEST_FILE_NAME}_${MODE} "${MPI_RUN_OUTPUT_${LANG}_${MPI_TEST_FILE_NAME}_${MODE}}" PARENT_SCOPE) else() try_compile(MPI_RESULT_${LANG}_${MPI_TEST_FILE_NAME}_${MODE} - "${CMAKE_BINARY_DIR}" SOURCES "${MPI_TEST_SOURCE_FILE}" + SOURCE_FROM_VAR "${MPI_TEST_SOURCE_FILE}" MPI_TEST_SOURCE_CONTENT + ${maybe_no_log} + LOG_DESCRIPTION "The MPI test ${MPI_TEST_FILE_NAME} for ${LANG} in mode ${MODE}" COMPILE_DEFINITIONS ${MPI_TEST_COMPILE_DEFINITIONS} LINK_LIBRARIES MPI::MPI_${LANG} COPY_FILE "${BIN_FILE}" OUTPUT_VARIABLE _MPI_TRY_${MPI_TEST_FILE_NAME}_${MODE}_OUTPUT) endif() - if(NOT SUPPRESS_ERRORS) - if(NOT MPI_RESULT_${LANG}_${MPI_TEST_FILE_NAME}_${MODE}) - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log - "The MPI test ${MPI_TEST_FILE_NAME} for ${LANG} in mode ${MODE} failed to compile with the following output:\n${_MPI_TRY_${MPI_TEST_FILE_NAME}_${MODE}_OUTPUT}\n\n") - elseif(DEFINED MPI_RUN_RESULT_${LANG}_${MPI_TEST_FILE_NAME}_${MODE} AND MPI_RUN_RESULT_${LANG}_${MPI_TEST_FILE_NAME}_${MODE}) - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log - "The MPI test ${MPI_TEST_FILE_NAME} for ${LANG} in mode ${MODE} failed to run with the following output:\n${MPI_RUN_OUTPUT_${LANG}_${MPI_TEST_FILE_NAME}_${MODE}}\n\n") - endif() - endif() endfunction() macro(_MPI_check_lang_works LANG SUPPRESS_ERRORS) @@ -1285,7 +1292,7 @@ macro(_MPI_check_lang_works LANG SUPPRESS_ERRORS) # - *both*, the mpi module and 'mpif.h' # Since older MPI standards (MPI-1) did not define anything but 'mpif.h', we need to check all three individually. if( NOT MPI_${LANG}_WORKS ) - if("${LANG}" STREQUAL "Fortran") + if(LANG STREQUAL "Fortran") set(MPI_Fortran_INTEGER_LINE "(kind=MPI_INTEGER_KIND)") _MPI_try_staged_settings(${LANG} test_mpi F77_HEADER FALSE ${SUPPRESS_ERRORS}) _MPI_try_staged_settings(${LANG} test_mpi F90_MODULE FALSE ${SUPPRESS_ERRORS}) @@ -1334,11 +1341,11 @@ macro(MPI_search_mpi_prefix_folder PREFIX_FOLDER) endmacro() set(MPI_HINT_DIRS ${MPI_HOME} $ENV{MPI_HOME} $ENV{I_MPI_ROOT}) -if("${CMAKE_HOST_SYSTEM_NAME}" STREQUAL "Linux") +if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Linux") # SUSE Linux Enterprise Server stores its MPI implementations under /usr/lib64/mpi/gcc/<name> # We enumerate the subfolders and append each as a prefix MPI_search_mpi_prefix_folder("/usr/lib64/mpi/gcc") -elseif("${CMAKE_HOST_SYSTEM_NAME}" STREQUAL "FreeBSD") +elseif(CMAKE_HOST_SYSTEM_NAME STREQUAL "FreeBSD") # FreeBSD ships mpich under the normal system paths - but available openmpi implementations # will be found in /usr/local/mpi/<name> MPI_search_mpi_prefix_folder("/usr/local/mpi") @@ -1405,7 +1412,7 @@ if(NOT MPI_IGNORE_LEGACY_VARIABLES) if(MPI_${LANG}_COMPILE_FLAGS) separate_arguments(MPI_SEPARATE_FLAGS NATIVE_COMMAND "${MPI_${LANG}_COMPILE_FLAGS}") foreach(_MPI_FLAG IN LISTS MPI_SEPARATE_FLAGS) - if("${_MPI_FLAG}" MATCHES "^ *-D([^ ]+)") + if(_MPI_FLAG MATCHES "^ *-D([^ ]+)") list(APPEND MPI_${LANG}_EXTRA_COMPILE_DEFINITIONS "${CMAKE_MATCH_1}") else() list(APPEND MPI_${LANG}_EXTRA_COMPILE_OPTIONS "${_MPI_FLAG}") @@ -1452,21 +1459,21 @@ foreach(LANG IN ITEMS C CXX Fortran) if(CMAKE_${LANG}_COMPILER_LOADED) if(NOT MPI_FIND_COMPONENTS) set(_MPI_FIND_${LANG} TRUE) - elseif( ${LANG} IN_LIST MPI_FIND_COMPONENTS) + elseif( LANG IN_LIST MPI_FIND_COMPONENTS) set(_MPI_FIND_${LANG} TRUE) - elseif( ${LANG} STREQUAL CXX AND NOT MPI_CXX_SKIP_MPICXX AND MPICXX IN_LIST MPI_FIND_COMPONENTS ) + elseif( LANG STREQUAL "CXX" AND NOT MPI_CXX_SKIP_MPICXX AND MPICXX IN_LIST MPI_FIND_COMPONENTS ) set(_MPI_FIND_${LANG} TRUE) else() set(_MPI_FIND_${LANG} FALSE) endif() else() set(_MPI_FIND_${LANG} FALSE) - if(${LANG} IN_LIST MPI_FIND_COMPONENTS) + if(LANG IN_LIST MPI_FIND_COMPONENTS) string(APPEND _MPI_FAIL_REASON "MPI component '${LANG}' was requested, but language ${LANG} is not enabled. ") endif() endif() if(_MPI_FIND_${LANG}) - if( ${LANG} STREQUAL CXX AND NOT MPICXX IN_LIST MPI_FIND_COMPONENTS ) + if( LANG STREQUAL "CXX" AND NOT MPICXX IN_LIST MPI_FIND_COMPONENTS ) option(MPI_CXX_SKIP_MPICXX "If true, the MPI-2 C++ bindings are disabled using definitions." FALSE) mark_as_advanced(MPI_CXX_SKIP_MPICXX) endif() @@ -1488,7 +1495,7 @@ foreach(LANG IN ITEMS C CXX Fortran) set(MPI_${LANG}_TRIED_IMPLICIT TRUE) endif() - if(NOT "${MPI_${LANG}_COMPILER}" STREQUAL "${CMAKE_${LANG}_COMPILER}" OR NOT MPI_${LANG}_WORKS) + if(NOT MPI_${LANG}_COMPILER STREQUAL CMAKE_${LANG}_COMPILER OR NOT MPI_${LANG}_WORKS) set(MPI_${LANG}_WRAPPER_FOUND FALSE) set(MPI_PINNED_COMPILER FALSE) @@ -1524,7 +1531,7 @@ foreach(LANG IN ITEMS C CXX Fortran) DOC "MPI compiler for ${LANG}" ) - if("${MPI_${LANG}_COMPILER}" STREQUAL "${CMAKE_${LANG}_COMPILER}") + if(MPI_${LANG}_COMPILER STREQUAL CMAKE_${LANG}_COMPILER) set(MPI_PINNED_COMPILER TRUE) # If we haven't made the implicit compiler test yet, perform it now. @@ -1585,7 +1592,7 @@ foreach(LANG IN ITEMS C CXX Fortran) endif() if(_MPI_PKG AND PKG_CONFIG_FOUND) pkg_check_modules("MPI_${LANG}_PKG" "${_MPI_PKG}") - if("${MPI_${LANG}_PKG_FOUND}") + if(MPI_${LANG}_PKG_FOUND) set(MPI_${LANG}_COMPILE_OPTIONS ${MPI_${LANG}_PKG_CFLAGS} CACHE STRING "MPI ${LANG} compilation options" FORCE) set(MPI_${LANG}_INCLUDE_PATH ${MPI_${LANG}_PKG_INCLUDE_DIRS} CACHE STRING "MPI ${LANG} include directories" FORCE) set(MPI_${LANG}_LINK_FLAGS ${MPI_${LANG}_PKG_LDFLAGS} CACHE STRING "MPI ${LANG} linker flags" FORCE) @@ -1606,10 +1613,10 @@ foreach(LANG IN ITEMS C CXX Fortran) endif() endif() - if(NOT MPI_SKIP_GUESSING AND NOT "${MPI_${LANG}_PKG_FOUND}") + if(NOT MPI_SKIP_GUESSING AND NOT MPI_${LANG}_PKG_FOUND) # For C++, we may use the settings for C. Should a given compiler wrapper for C++ not exist, but one for C does, we copy over the # settings for C. An MPI distribution that is in this situation would be IBM Platform MPI. - if("${LANG}" STREQUAL "CXX" AND MPI_C_WRAPPER_FOUND) + if(LANG STREQUAL "CXX" AND MPI_C_WRAPPER_FOUND) set(MPI_${LANG}_COMPILE_OPTIONS ${MPI_C_COMPILE_OPTIONS} CACHE STRING "MPI ${LANG} compilation options" ) set(MPI_${LANG}_COMPILE_DEFINITIONS ${MPI_C_COMPILE_DEFINITIONS} CACHE STRING "MPI ${LANG} compilation definitions" ) set(MPI_${LANG}_COMPILER_INCLUDE_DIRS ${MPI_C_INCLUDE_DIRS} CACHE STRING "MPI ${LANG} compiler wrapper include directories") @@ -1623,7 +1630,7 @@ foreach(LANG IN ITEMS C CXX Fortran) endif() endif() - if(NOT "${MPI_${LANG}_COMPILER}" STREQUAL "${CMAKE_${LANG}_COMPILER}") + if(NOT MPI_${LANG}_COMPILER STREQUAL CMAKE_${LANG}_COMPILER) _MPI_split_include_dirs(${LANG}) _MPI_assemble_include_dirs(${LANG}) else() @@ -1660,7 +1667,7 @@ foreach(LANG IN ITEMS C CXX Fortran) # If we've found MPI, then we'll perform additional analysis: Determine the MPI version, MPI library version, supported # MPI APIs (i.e. MPI-2 C++ bindings). For Fortran we also need to find specific parameters if we're under MPI-3. if(MPI_${LANG}_WORKS) - if("${LANG}" STREQUAL "CXX" AND NOT DEFINED MPI_MPICXX_FOUND) + if(LANG STREQUAL "CXX" AND NOT DEFINED MPI_MPICXX_FOUND) if(NOT MPI_CXX_SKIP_MPICXX AND NOT MPI_CXX_VALIDATE_SKIP_MPICXX) _MPI_try_staged_settings(${LANG} test_mpi MPICXX FALSE FALSE) if(MPI_RESULT_${LANG}_test_mpi_MPICXX) @@ -1684,7 +1691,7 @@ foreach(LANG IN ITEMS C CXX Fortran) # Fortran parameters, since those depend on the method of consumption. # For C++, we can always use the C bindings, and should do so, since the C++ bindings do not exist in MPI-3 # whereas the C bindings do, and the C++ bindings never offered any feature advantage over their C counterparts. - if("${LANG}" STREQUAL "Fortran") + if(LANG STREQUAL "Fortran") if(MPI_${LANG}_HAVE_F08_MODULE) set(MPI_${LANG}_HIGHEST_METHOD F08_MODULE) elseif(MPI_${LANG}_HAVE_F90_MODULE) @@ -1700,7 +1707,7 @@ foreach(LANG IN ITEMS C CXX Fortran) _MPI_try_staged_settings(${LANG} mpiver ${MPI_${LANG}_HIGHEST_METHOD} FALSE FALSE) if(MPI_RESULT_${LANG}_mpiver_${MPI_${LANG}_HIGHEST_METHOD}) file(STRINGS ${MPI_BIN_FOLDER}/mpiver_${LANG}.bin _MPI_VERSION_STRING LIMIT_COUNT 1 REGEX "INFO:MPI-VER") - if("${_MPI_VERSION_STRING}" MATCHES ".*INFO:MPI-VER\\[([0-9]+)\\.([0-9]+)\\].*") + if(_MPI_VERSION_STRING MATCHES ".*INFO:MPI-VER\\[([0-9]+)\\.([0-9]+)\\].*") set(MPI_${LANG}_VERSION_MAJOR "${CMAKE_MATCH_1}") set(MPI_${LANG}_VERSION_MINOR "${CMAKE_MATCH_2}") set(MPI_${LANG}_VERSION "${MPI_${LANG}_VERSION_MAJOR}.${MPI_${LANG}_VERSION_MINOR}") @@ -1719,12 +1726,12 @@ foreach(LANG IN ITEMS C CXX Fortran) _MPI_try_staged_settings(${LANG} fortranparam_mpi ${mpimethod} TRUE FALSE) if(MPI_RESULT_${LANG}_fortranparam_mpi_${mpimethod} AND NOT "${MPI_RUN_RESULT_${LANG}_fortranparam_mpi_${mpimethod}}" STREQUAL "FAILED_TO_RUN") - if("${MPI_RUN_OUTPUT_${LANG}_fortranparam_mpi_${mpimethod}}" MATCHES + if(MPI_RUN_OUTPUT_${LANG}_fortranparam_mpi_${mpimethod} MATCHES ".*INFO:SUBARRAYS\\[ *([TF]) *\\]-ASYNCPROT\\[ *([TF]) *\\].*") - if("${CMAKE_MATCH_1}" STREQUAL "T") + if(CMAKE_MATCH_1 STREQUAL "T") set(MPI_${LANG}_${mpimethod}_SUBARRAYS TRUE) endif() - if("${CMAKE_MATCH_2}" STREQUAL "T") + if(CMAKE_MATCH_2 STREQUAL "T") set(MPI_${LANG}_${mpimethod}_ASYNCPROT TRUE) endif() endif() @@ -1739,7 +1746,7 @@ foreach(LANG IN ITEMS C CXX Fortran) # By the MPI-2 standard, MPI_VERSION and MPI_SUBVERSION are valid for both C and C++ bindings. if(NOT DEFINED MPI_${LANG}_VERSION) file(STRINGS ${MPI_BIN_FOLDER}/test_mpi_${LANG}.bin _MPI_VERSION_STRING LIMIT_COUNT 1 REGEX "INFO:MPI-VER") - if("${_MPI_VERSION_STRING}" MATCHES ".*INFO:MPI-VER\\[([0-9]+)\\.([0-9]+)\\].*") + if(_MPI_VERSION_STRING MATCHES ".*INFO:MPI-VER\\[([0-9]+)\\.([0-9]+)\\].*") set(MPI_${LANG}_VERSION_MAJOR "${CMAKE_MATCH_1}") set(MPI_${LANG}_VERSION_MINOR "${CMAKE_MATCH_2}") set(MPI_${LANG}_VERSION "${MPI_${LANG}_VERSION_MAJOR}.${MPI_${LANG}_VERSION_MINOR}") @@ -1759,7 +1766,7 @@ foreach(LANG IN ITEMS C CXX Fortran) if(MPI_DETERMINE_LIBRARY_VERSION AND NOT MPI_${LANG}_LIBRARY_VERSION_STRING) _MPI_try_staged_settings(${LANG} libver_mpi ${MPI_${LANG}_HIGHEST_METHOD} TRUE FALSE) if(MPI_RESULT_${LANG}_libver_mpi_${MPI_${LANG}_HIGHEST_METHOD} AND - "${MPI_RUN_RESULT_${LANG}_libver_mpi_${MPI_${LANG}_HIGHEST_METHOD}}" EQUAL "0") + MPI_RUN_RESULT_${LANG}_libver_mpi_${MPI_${LANG}_HIGHEST_METHOD} EQUAL "0") string(STRIP "${MPI_RUN_OUTPUT_${LANG}_libver_mpi_${MPI_${LANG}_HIGHEST_METHOD}}" MPI_${LANG}_LIBRARY_VERSION_STRING) else() @@ -1773,12 +1780,12 @@ foreach(LANG IN ITEMS C CXX Fortran) set(MPI_${LANG}_FIND_VERSION_EXACT ${MPI_FIND_VERSION_EXACT}) unset(MPI_${LANG}_REQUIRED_VARS) - if (NOT "${MPI_${LANG}_COMPILER}" STREQUAL "${CMAKE_${LANG}_COMPILER}") + if (NOT MPI_${LANG}_COMPILER STREQUAL CMAKE_${LANG}_COMPILER) foreach(mpilibname IN LISTS MPI_${LANG}_LIB_NAMES) list(APPEND MPI_${LANG}_REQUIRED_VARS "MPI_${mpilibname}_LIBRARY") endforeach() list(APPEND MPI_${LANG}_REQUIRED_VARS "MPI_${LANG}_LIB_NAMES") - if("${LANG}" STREQUAL "Fortran") + if(LANG STREQUAL "Fortran") # For Fortran we only need one of the module or header directories to have *some* support for MPI. if(NOT MPI_${LANG}_MODULE_DIR) list(APPEND MPI_${LANG}_REQUIRED_VARS "MPI_${LANG}_F77_HEADER_DIR") @@ -1878,7 +1885,7 @@ else() endif() list(LENGTH MPI_LIBRARIES MPI_NUMLIBS) -if (MPI_NUMLIBS GREATER 1) +if (MPI_NUMLIBS GREATER "1") set(MPI_EXTRA_LIBRARY_WORK "${MPI_LIBRARIES}") list(REMOVE_AT MPI_EXTRA_LIBRARY_WORK 0) set(MPI_EXTRA_LIBRARY "${MPI_EXTRA_LIBRARY_WORK}") diff --git a/Modules/FindMatlab.cmake b/Modules/FindMatlab.cmake index 17c1fa1..0f1e451 100644 --- a/Modules/FindMatlab.cmake +++ b/Modules/FindMatlab.cmake @@ -85,10 +85,18 @@ Module Input Variables Users or projects may set the following variables to configure the module behavior: +:variable:`Matlab_ROOT <<PackageName>_ROOT>` + .. versionadded:: 3.25 + + Default value for :variable:`Matlab_ROOT_DIR`, the root of the Matlab + installation. + :variable:`Matlab_ROOT_DIR` - the root of the Matlab installation. + The root of the Matlab installation. + :variable:`MATLAB_FIND_DEBUG` outputs debug information + :variable:`MATLAB_ADDITIONAL_VERSIONS` additional versions of Matlab for the automatic retrieval of the installed versions. @@ -288,6 +296,7 @@ if(NOT MATLAB_ADDITIONAL_VERSIONS) endif() set(MATLAB_VERSIONS_MAPPING + "R2022b=9.13" "R2022a=9.12" "R2021b=9.11" "R2021a=9.10" @@ -627,42 +636,26 @@ endfunction() #]=======================================================================] function(matlab_get_mex_suffix matlab_root mex_suffix) - # todo setup the extension properly. Currently I do not know if this is - # sufficient for all win32 distributions. - # there is also CMAKE_EXECUTABLE_SUFFIX that could be tweaked + # find_program does not consider script suffix .bat for Matlab mexext.bat on Windows set(mexext_suffix "") if(WIN32) - list(APPEND mexext_suffix ".bat") + set(mexext_suffix ".bat") endif() - # we first try without suffix, since cmake does not understand a list with - # one empty string element find_program( Matlab_MEXEXTENSIONS_PROG - NAMES mexext + NAMES mexext mexext${mexext_suffix} PATHS ${matlab_root}/bin DOC "Matlab MEX extension provider" NO_DEFAULT_PATH ) - foreach(current_mexext_suffix IN LISTS mexext_suffix) - if(NOT DEFINED Matlab_MEXEXTENSIONS_PROG OR NOT Matlab_MEXEXTENSIONS_PROG) - # this call should populate the cache automatically - find_program( - Matlab_MEXEXTENSIONS_PROG - "mexext${current_mexext_suffix}" - PATHS ${matlab_root}/bin - DOC "Matlab MEX extension provider" - NO_DEFAULT_PATH - ) - endif() - endforeach(current_mexext_suffix) if(MATLAB_FIND_DEBUG) message(STATUS "[MATLAB] Determining mex files extensions from '${matlab_root}/bin' with program '${Matlab_MEXEXTENSIONS_PROG}'") endif() # the program has been found? - if((NOT Matlab_MEXEXTENSIONS_PROG) OR (NOT EXISTS ${Matlab_MEXEXTENSIONS_PROG})) + if(NOT Matlab_MEXEXTENSIONS_PROG) if(MATLAB_FIND_DEBUG) message(WARNING "[MATLAB] Cannot found mexext program. Matlab root is ${matlab_root}") endif() @@ -713,7 +706,6 @@ function(matlab_get_mex_suffix matlab_root mex_suffix) message(STATUS "[MATLAB] '${Matlab_MEXEXTENSIONS_PROG}' : determined extension '${_matlab_mex_extension}' and error string is '${_matlab_mex_extension_error}'") endif() - unset(Matlab_MEXEXTENSIONS_PROG CACHE) set(${mex_suffix} ${_matlab_mex_extension} PARENT_SCOPE) endfunction() @@ -769,6 +761,10 @@ function(matlab_get_version_from_matlab_run matlab_binary_program matlab_list_ve set(devnull INPUT_FILE NUL) endif() + # we first try to run a simple program using the -r option, and then we use the + # -batch option that is supported and recommended since R2019a + set(_matlab_get_version_failed_with_r_option FALSE) + # timeout set to 120 seconds, in case it does not start # note as said before OUTPUT_VARIABLE cannot be used in a platform # independent manner however, not setting it would flush the output of Matlab @@ -786,20 +782,65 @@ function(matlab_get_version_from_matlab_run matlab_binary_program matlab_list_ve if(_matlab_result_version_call MATCHES "timeout") if(MATLAB_FIND_DEBUG) message(WARNING "[MATLAB] Unable to determine the version of Matlab." - " Matlab call timed out after 120 seconds.") + " Matlab call with -r option timed out after 120 seconds.") endif() - return() + set(_matlab_get_version_failed_with_r_option TRUE) endif() - if(${_matlab_result_version_call}) + if(NOT ${_matlab_get_version_failed_with_r_option} AND ${_matlab_result_version_call}) if(MATLAB_FIND_DEBUG) - message(WARNING "[MATLAB] Unable to determine the version of Matlab. Matlab call returned with error ${_matlab_result_version_call}.") + message(WARNING "[MATLAB] Unable to determine the version of Matlab. Matlab call with -r option returned with error ${_matlab_result_version_call}.") endif() - return() - elseif(NOT EXISTS "${_matlab_temporary_folder}/matlabVersionLog.cmaketmp") + set(_matlab_get_version_failed_with_r_option TRUE) + elseif(NOT ${_matlab_get_version_failed_with_r_option} AND NOT EXISTS "${_matlab_temporary_folder}/matlabVersionLog.cmaketmp") if(MATLAB_FIND_DEBUG) message(WARNING "[MATLAB] Unable to determine the version of Matlab. The log file does not exist.") endif() + set(_matlab_get_version_failed_with_r_option TRUE) + endif() + + if(_matlab_get_version_failed_with_r_option) + execute_process( + COMMAND "${matlab_binary_program}" -nosplash -nojvm ${_matlab_additional_commands} -logfile "matlabVersionLog.cmaketmp" -nodesktop -nodisplay -batch "version, exit" + OUTPUT_VARIABLE _matlab_version_from_cmd_dummy_batch + RESULT_VARIABLE _matlab_result_version_call_batch + ERROR_VARIABLE _matlab_result_version_call_error_batch + TIMEOUT 120 + WORKING_DIRECTORY "${_matlab_temporary_folder}" + ${devnull} + ) + + if(_matlab_result_version_call_batch MATCHES "timeout") + if(MATLAB_FIND_DEBUG) + message(WARNING "[MATLAB] Unable to determine the version of Matlab." + " Matlab call with -batch option timed out after 120 seconds.") + endif() + return() + endif() + + if(${_matlab_result_version_call_batch}) + if(MATLAB_FIND_DEBUG) + message(WARNING "[MATLAB] Command executed \"${matlab_binary_program}\" -nosplash -nojvm ${_matlab_additional_commands} -logfile \"matlabVersionLog.cmaketmp\" -nodesktop -nodisplay -batch \"version, exit\"") + message(WARNING "_matlab_version_from_cmd_dummy_batch (OUTPUT_VARIABLE): ${_matlab_version_from_cmd_dummy_batch}") + message(WARNING "_matlab_result_version_call_batch (RESULT_VARIABLE): ${_matlab_result_version_call_batch}") + message(WARNING "_matlab_result_version_call_error_batch (ERROR_VARIABLE): ${_matlab_result_version_call_error_batch}") + message(WARNING "[MATLAB] Unable to determine the version of Matlab. Matlab call with -batch option returned with error ${_matlab_result_version_call_batch}.") + endif() + return() + elseif(NOT ${_matlab_get_version_failed_with_r_option} AND NOT EXISTS "${_matlab_temporary_folder}/matlabVersionLog.cmaketmp") + if(MATLAB_FIND_DEBUG) + message(WARNING "[MATLAB] Unable to determine the version of Matlab. The log file does not exist.") + endif() + return() + endif() + endif() + + if(NOT EXISTS "${_matlab_temporary_folder}/matlabVersionLog.cmaketmp") + # last resort check as some HPC with "module load matlab" not enacted fail to catch in earlier checks + # and error CMake configure even if find_package(Matlab) is not REQUIRED + if(MATLAB_FIND_DEBUG) + message(WARNING "[MATLAB] Unable to determine the version of Matlab. The version log file does not exist.") + endif() return() endif() @@ -928,6 +969,16 @@ function(matlab_add_unit_test) message(FATAL_ERROR "[MATLAB] The Matlab test name cannot be empty") endif() + # The option to run a batch program with MATLAB changes depending on the MATLAB version + # For MATLAB before R2019a (9.6), the only supported option is -r, afterwords the suggested option + # is -batch as -r is deprecated + set(maut_BATCH_OPTION "-r") + if(NOT (Matlab_VERSION_STRING STREQUAL "")) + if(Matlab_VERSION_STRING VERSION_GREATER_EQUAL "9.6") + set(maut_BATCH_OPTION "-batch") + endif() + endif() + add_test(NAME ${${prefix}_NAME} COMMAND ${CMAKE_COMMAND} "-Dtest_name=${${prefix}_NAME}" @@ -941,6 +992,7 @@ function(matlab_add_unit_test) "-Dunittest_file_to_run=${${prefix}_UNITTEST_FILE}" "-Dcustom_Matlab_test_command=${${prefix}_CUSTOM_TEST_COMMAND}" "-Dcmd_to_run_before_test=${${prefix}_UNITTEST_PRECOMMAND}" + "-Dmaut_BATCH_OPTION=${maut_BATCH_OPTION}" -P ${_FindMatlab_SELF_DIR}/MatlabTestsRedirect.cmake ${${prefix}_TEST_ARGS} ${${prefix}_UNPARSED_ARGUMENTS} @@ -969,6 +1021,7 @@ endfunction() [LINK_TO target1 target2 ...] [R2017b | R2018a] [EXCLUDE_FROM_ALL] + [NO_IMPLICIT_LINK_TO_MATLAB_LIBRARIES] [...] ) @@ -978,7 +1031,8 @@ endfunction() list of source files. ``LINK_TO`` a list of additional link dependencies. The target links to ``libmex`` - and ``libmx`` by default. + and ``libmx`` by default, unless the + ``NO_IMPLICIT_LINK_TO_MATLAB_LIBRARIES`` option is passed. ``OUTPUT_NAME`` if given, overrides the default name. The default name is the name of the target without any prefix and @@ -1014,6 +1068,12 @@ endfunction() This option has the same meaning as for :prop_tgt:`EXCLUDE_FROM_ALL` and is forwarded to :command:`add_library` or :command:`add_executable` commands. + ``NO_IMPLICIT_LINK_TO_MATLAB_LIBRARIES`` + .. versionadded:: 3.24 + + This option permits to disable the automatic linking of MATLAB + libraries, so that only the libraries that are actually required can be + linked via the ``LINK_TO`` option. The documentation file is not processed and should be in the following format: @@ -1040,7 +1100,7 @@ function(matlab_add_mex) endif() - set(options EXECUTABLE MODULE SHARED R2017b R2018a EXCLUDE_FROM_ALL) + set(options EXECUTABLE MODULE SHARED R2017b R2018a EXCLUDE_FROM_ALL NO_IMPLICIT_LINK_TO_MATLAB_LIBRARIES) set(oneValueArgs NAME DOCUMENTATION OUTPUT_NAME) set(multiValueArgs LINK_TO SRC) @@ -1110,18 +1170,21 @@ function(matlab_add_mex) ${${prefix}_UNPARSED_ARGUMENTS}) endif() - target_include_directories(${${prefix}_NAME} PRIVATE ${Matlab_INCLUDE_DIRS}) + target_include_directories(${${prefix}_NAME} SYSTEM PRIVATE ${Matlab_INCLUDE_DIRS}) - if(Matlab_HAS_CPP_API) - if(Matlab_ENGINE_LIBRARY) - target_link_libraries(${${prefix}_NAME} ${Matlab_ENGINE_LIBRARY}) - endif() - if(Matlab_DATAARRAY_LIBRARY) - target_link_libraries(${${prefix}_NAME} ${Matlab_DATAARRAY_LIBRARY}) + if(NOT ${prefix}_NO_IMPLICIT_LINK_TO_MATLAB_LIBRARIES) + if(Matlab_HAS_CPP_API) + if(Matlab_ENGINE_LIBRARY) + target_link_libraries(${${prefix}_NAME} ${Matlab_ENGINE_LIBRARY}) + endif() + if(Matlab_DATAARRAY_LIBRARY) + target_link_libraries(${${prefix}_NAME} ${Matlab_DATAARRAY_LIBRARY}) + endif() endif() - endif() - target_link_libraries(${${prefix}_NAME} ${Matlab_MEX_LIBRARY} ${Matlab_MX_LIBRARY} ${${prefix}_LINK_TO}) + target_link_libraries(${${prefix}_NAME} ${Matlab_MEX_LIBRARY} ${Matlab_MX_LIBRARY}) + endif() + target_link_libraries(${${prefix}_NAME} ${${prefix}_LINK_TO}) set_target_properties(${${prefix}_NAME} PROPERTIES PREFIX "" @@ -1510,6 +1573,13 @@ endfunction() # this variable will get all Matlab installations found in the current system. set(_matlab_possible_roots) +if(NOT DEFINED Matlab_ROOT AND DEFINED ENV{Matlab_ROOT}) + set(Matlab_ROOT $ENV{Matlab_ROOT}) +endif() +if(DEFINED Matlab_ROOT) + set(Matlab_ROOT_DIR ${Matlab_ROOT}) +endif() + if(Matlab_ROOT_DIR) # if the user specifies a possible root, we keep this one @@ -1676,10 +1746,26 @@ else() set(_matlab_64Build TRUE) endif() + +if(NOT DEFINED Matlab_MEX_EXTENSION) + set(_matlab_mex_extension "") + matlab_get_mex_suffix("${Matlab_ROOT_DIR}" _matlab_mex_extension) + + # This variable goes to the cache. + set(Matlab_MEX_EXTENSION ${_matlab_mex_extension} CACHE STRING "Extensions for the mex targets (automatically given by Matlab)") + unset(_matlab_mex_extension) +endif() + if(APPLE) set(_matlab_bin_prefix "mac") # i should be for intel set(_matlab_bin_suffix_32bits "i") - set(_matlab_bin_suffix_64bits "i64") + if(CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64" AND Matlab_MEX_EXTENSION MATCHES "a64$") + # native Apple Silicon Matlab + set(_matlab_bin_suffix_64bits "a64") + else() + # Intel Mac OR Apple Silicon using Rosetta for Matlab + set(_matlab_bin_suffix_64bits "i64") + endif() elseif(UNIX) set(_matlab_bin_prefix "gln") set(_matlab_bin_suffix_32bits "x86") @@ -1721,16 +1807,6 @@ endif() unset(_matlab_64Build) -if(NOT DEFINED Matlab_MEX_EXTENSION) - set(_matlab_mex_extension "") - matlab_get_mex_suffix("${Matlab_ROOT_DIR}" _matlab_mex_extension) - - # This variable goes to the cache. - set(Matlab_MEX_EXTENSION ${_matlab_mex_extension} CACHE STRING "Extensions for the mex targets (automatically given by Matlab)") - unset(_matlab_mex_extension) -endif() - - if(MATLAB_FIND_DEBUG) message(STATUS "[MATLAB] [DEBUG]_matlab_lib_prefix_for_search = ${_matlab_lib_prefix_for_search} | _matlab_lib_dir_for_search = ${_matlab_lib_dir_for_search}") endif() diff --git a/Modules/FindMsys.cmake b/Modules/FindMsys.cmake index b4796d2..86597c2 100644 --- a/Modules/FindMsys.cmake +++ b/Modules/FindMsys.cmake @@ -19,11 +19,12 @@ if (WIN32) find_program(MSYS_CMD NAMES msys2_shell.cmd PATHS - "C:/msys64" + # Typical install path for MSYS2 (https://repo.msys2.org/distrib/msys2-i686-latest.sfx.exe) "C:/msys32" - "C:/MSYS" - "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MSYS\\setup;rootdir]" - "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Cygnus Solutions\\MSYS\\mounts v2\\/;native]" + # Typical install path for MSYS2 (https://repo.msys2.org/distrib/msys2-x86_64-latest.sfx.exe) + "C:/msys64" + # Git for Windows (https://gitforwindows.org/) + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\GitForWindows;InstallPath]" ) get_filename_component(MSYS_INSTALL_PATH "${MSYS_CMD}" DIRECTORY) mark_as_advanced(MSYS_CMD) diff --git a/Modules/FindOpenACC.cmake b/Modules/FindOpenACC.cmake index cf58f3b..00e42b8 100644 --- a/Modules/FindOpenACC.cmake +++ b/Modules/FindOpenACC.cmake @@ -27,6 +27,13 @@ The module provides :prop_tgt:`IMPORTED` targets: Variables ^^^^^^^^^ +The module defines the following variables: + +``OpenACC_FOUND`` + .. versionadded:: 3.25 + + Variable indicating that OpenACC flags for at least one languages have been found. + This module will set the following variables per language in your project, where ``<lang>`` is one of C, CXX, or Fortran: @@ -121,21 +128,18 @@ set(OpenACC_Fortran_CHECK_VERSION_SOURCE ) -function(_OPENACC_WRITE_SOURCE_FILE LANG SRC_FILE_CONTENT_VAR SRC_FILE_NAME SRC_FILE_FULLPATH) - set(WORK_DIR ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/FindOpenACC) +macro(_OPENACC_PREPARE_SOURCE LANG CONTENT_ID NAME_PREFIX FULLNAME_VAR CONTENT_VAR) if("${LANG}" STREQUAL "C") - set(SRC_FILE "${WORK_DIR}/${SRC_FILE_NAME}.c") - file(WRITE "${SRC_FILE}" "${OpenACC_C_CXX_${SRC_FILE_CONTENT_VAR}}") + set(${FULLNAME_VAR} "${NAME_PREFIX}.c") + set(${CONTENT_VAR} "${OpenACC_C_CXX_${CONTENT_ID}}") elseif("${LANG}" STREQUAL "CXX") - set(SRC_FILE "${WORK_DIR}/${SRC_FILE_NAME}.cpp") - file(WRITE "${SRC_FILE}" "${OpenACC_C_CXX_${SRC_FILE_CONTENT_VAR}}") + set(${FULLNAME_VAR} "${NAME_PREFIX}.cpp") + set(${CONTENT_VAR} "${OpenACC_C_CXX_${CONTENT_ID}}") elseif("${LANG}" STREQUAL "Fortran") - set(SRC_FILE "${WORK_DIR}/${SRC_FILE_NAME}.F90") - file(WRITE "${SRC_FILE}_in" "${OpenACC_Fortran_${SRC_FILE_CONTENT_VAR}}") - configure_file("${SRC_FILE}_in" "${SRC_FILE}" @ONLY) + set(${FULLNAME_VAR} "${NAME_PREFIX}.F90") + set(${CONTENT_VAR} "${OpenACC_Fortran_${CONTENT_ID}}") endif() - set(${SRC_FILE_FULLPATH} "${SRC_FILE}" PARENT_SCOPE) -endfunction() +endmacro() function(_OPENACC_GET_FLAGS_CANDIDATE LANG FLAG_VAR) @@ -177,10 +181,12 @@ endfunction() function(_OPENACC_GET_FLAGS LANG FLAG_VAR) set(FLAG_CANDIDATES "") _OPENACC_GET_FLAGS_CANDIDATE("${LANG}" FLAG_CANDIDATES) - _OPENACC_WRITE_SOURCE_FILE("${LANG}" "TEST_SOURCE" OpenACCTryFlag _OPENACC_TEST_SRC) + _OPENACC_PREPARE_SOURCE("${LANG}" TEST_SOURCE OpenACCTryFlag + _OPENACC_TEST_SRC_NAME _OPENACC_TEST_SRC_CONTENT) foreach(FLAG IN LISTS FLAG_CANDIDATES) - try_compile(OpenACC_FLAG_TEST_RESULT ${CMAKE_BINARY_DIR} ${_OPENACC_TEST_SRC} + try_compile(OpenACC_FLAG_TEST_RESULT + SOURCE_FROM_VAR "${_OPENACC_TEST_SRC_NAME}" _OPENACC_TEST_SRC_CONTENT CMAKE_FLAGS "-DCOMPILE_DEFINITIONS:STRING=${FLAG}" OUTPUT_VARIABLE OpenACC_TRY_COMPILE_OUTPUT ) @@ -205,13 +211,15 @@ endfunction() function(_OPENACC_GET_SPEC_DATE LANG SPEC_DATE) - _OPENACC_WRITE_SOURCE_FILE("${LANG}" "CHECK_VERSION_SOURCE" OpenACCCheckVersion _OPENACC_TEST_SRC) + _OPENACC_PREPARE_SOURCE(${LANG} CHECK_VERSION_SOURCE OpenACCCheckVersion + _OPENACC_TEST_SRC_NAME _OPENACC_TEST_SRC_CONTENT) set(BIN_FILE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/FindOpenACC/accver_${LANG}.bin") - try_compile(OpenACC_SPECTEST_${LANG} "${CMAKE_BINARY_DIR}" "${_OPENACC_TEST_SRC}" - CMAKE_FLAGS "-DCOMPILE_DEFINITIONS:STRING=${OpenACC_${LANG}_FLAGS}" - COPY_FILE ${BIN_FILE} - OUTPUT_VARIABLE OUTPUT) + try_compile(OpenACC_SPECTEST_${LANG} + SOURCE_FROM_VAR "${_OPENACC_TEST_SRC_NAME}" _OPENACC_TEST_SRC_CONTENT + CMAKE_FLAGS "-DCOMPILE_DEFINITIONS:STRING=${OpenACC_${LANG}_FLAGS}" + COPY_FILE "${BIN_FILE}" + OUTPUT_VARIABLE OUTPUT) if(${OpenACC_SPECTEST_${LANG}}) file(STRINGS ${BIN_FILE} specstr LIMIT_COUNT 1 REGEX "INFO:OpenACC-date") @@ -270,6 +278,9 @@ foreach (LANG IN ITEMS C CXX Fortran) REQUIRED_VARS OpenACC_${LANG}_FLAGS VERSION_VAR OpenACC_${LANG}_VERSION ) + if(OpenACC_${LANG}_FOUND) + set(OpenACC_FOUND TRUE) + endif() endif() endforeach() diff --git a/Modules/FindOpenAL.cmake b/Modules/FindOpenAL.cmake index b5b92c5..53aafdc 100644 --- a/Modules/FindOpenAL.cmake +++ b/Modules/FindOpenAL.cmake @@ -29,6 +29,16 @@ OpenAL is searched in the following order: 5. Manually compiled framework: ``/Library/Frameworks``. 6. Add-on package: ``/opt``. +IMPORTED Targets +^^^^^^^^^^^^^^^^ + +.. versionadded:: 3.25 + +This module defines the :prop_tgt:`IMPORTED` target: + +``OpenAL::OpenAL`` + The OpenAL library, if found. + Result Variables ^^^^^^^^^^^^^^^^ @@ -94,3 +104,19 @@ find_package_handle_standard_args( ) mark_as_advanced(OPENAL_LIBRARY OPENAL_INCLUDE_DIR) + +if(OPENAL_INCLUDE_DIR AND OPENAL_LIBRARY) + if(NOT TARGET OpenAL::OpenAL) + if(EXISTS "${OPENAL_LIBRARY}") + add_library(OpenAL::OpenAL UNKNOWN IMPORTED) + set_target_properties(OpenAL::OpenAL PROPERTIES + IMPORTED_LOCATION "${OPENAL_LIBRARY}") + else() + add_library(OpenAL::OpenAL INTERFACE IMPORTED) + set_target_properties(OpenAL::OpenAL PROPERTIES + IMPORTED_LIBNAME "${OPENAL_LIBRARY}") + endif() + set_target_properties(OpenAL::OpenAL PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES "${OPENAL_INCLUDE_DIR}") + endif() +endif() diff --git a/Modules/FindOpenCL.cmake b/Modules/FindOpenCL.cmake index 1b4662b..2b700ff 100644 --- a/Modules/FindOpenCL.cmake +++ b/Modules/FindOpenCL.cmake @@ -45,10 +45,10 @@ function(_FIND_OPENCL_VERSION) set(CMAKE_REQUIRED_QUIET ${OpenCL_FIND_QUIETLY}) CMAKE_PUSH_CHECK_STATE() - foreach(VERSION "2_2" "2_1" "2_0" "1_2" "1_1" "1_0") + foreach(VERSION "3_0" "2_2" "2_1" "2_0" "1_2" "1_1" "1_0") set(CMAKE_REQUIRED_INCLUDES "${OpenCL_INCLUDE_DIR}") - if(APPLE) + if(EXISTS ${OpenCL_INCLUDE_DIR}/Headers/cl.h) CHECK_SYMBOL_EXISTS( CL_VERSION_${VERSION} "${OpenCL_INCLUDE_DIR}/Headers/cl.h" diff --git a/Modules/FindOpenGL.cmake b/Modules/FindOpenGL.cmake index d6d1c00..a9a1b2a 100644 --- a/Modules/FindOpenGL.cmake +++ b/Modules/FindOpenGL.cmake @@ -377,7 +377,7 @@ else() (NOT OPENGL_USE_EGL AND NOT OPENGL_glx_LIBRARY AND OPENGL_gl_LIBRARY)) - list(APPEND _OpenGL_REQUIRED_VARS OPENGL_gl_LIBRARY) + list(PREPEND _OpenGL_REQUIRED_VARS OPENGL_gl_LIBRARY) endif() # We always need the 'gl.h' include dir. diff --git a/Modules/FindOpenMP.cmake b/Modules/FindOpenMP.cmake index ecfb7f9..68be2d6 100644 --- a/Modules/FindOpenMP.cmake +++ b/Modules/FindOpenMP.cmake @@ -178,27 +178,25 @@ set(OpenMP_Fortran_TEST_SOURCE " ) -function(_OPENMP_WRITE_SOURCE_FILE LANG SRC_FILE_CONTENT_VAR SRC_FILE_NAME SRC_FILE_FULLPATH) - set(WORK_DIR ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/FindOpenMP) +macro(_OPENMP_PREPARE_SOURCE LANG CONTENT_ID NAME_PREFIX FULLNAME_VAR CONTENT_VAR) if("${LANG}" STREQUAL "C") - set(SRC_FILE "${WORK_DIR}/${SRC_FILE_NAME}.c") - file(WRITE "${SRC_FILE}" "${OpenMP_C_CXX_${SRC_FILE_CONTENT_VAR}}") + set(${FULLNAME_VAR} "${NAME_PREFIX}.c") + set(${CONTENT_VAR} "${OpenMP_C_CXX_${CONTENT_ID}}") elseif("${LANG}" STREQUAL "CXX") - set(SRC_FILE "${WORK_DIR}/${SRC_FILE_NAME}.cpp") - file(WRITE "${SRC_FILE}" "${OpenMP_C_CXX_${SRC_FILE_CONTENT_VAR}}") + set(${FULLNAME_VAR} "${NAME_PREFIX}.cpp") + set(${CONTENT_VAR} "${OpenMP_C_CXX_${CONTENT_ID}}") elseif("${LANG}" STREQUAL "Fortran") - set(SRC_FILE "${WORK_DIR}/${SRC_FILE_NAME}.f90") - file(WRITE "${SRC_FILE}_in" "${OpenMP_Fortran_${SRC_FILE_CONTENT_VAR}}") - configure_file("${SRC_FILE}_in" "${SRC_FILE}" @ONLY) + set(${FULLNAME_VAR} "${NAME_PREFIX}.F90") + string(CONFIGURE "${OpenMP_Fortran_${CONTENT_ID}}" ${CONTENT_VAR} @ONLY) endif() - set(${SRC_FILE_FULLPATH} "${SRC_FILE}" PARENT_SCOPE) -endfunction() +endmacro() include(${CMAKE_CURRENT_LIST_DIR}/CMakeParseImplicitLinkInfo.cmake) function(_OPENMP_GET_FLAGS LANG FLAG_MODE OPENMP_FLAG_VAR OPENMP_LIB_NAMES_VAR) _OPENMP_FLAG_CANDIDATES("${LANG}") - _OPENMP_WRITE_SOURCE_FILE("${LANG}" "TEST_SOURCE" OpenMPTryFlag _OPENMP_TEST_SRC) + _OPENMP_PREPARE_SOURCE("${LANG}" TEST_SOURCE OpenMPTryFlag + _OPENMP_TEST_SRC_NAME _OPENMP_TEST_SRC_CONTENT) unset(OpenMP_VERBOSE_COMPILE_OPTIONS) separate_arguments(OpenMP_VERBOSE_OPTIONS NATIVE_COMMAND "${CMAKE_${LANG}_VERBOSE_FLAG}") @@ -214,8 +212,14 @@ function(_OPENMP_GET_FLAGS LANG FLAG_MODE OPENMP_FLAG_VAR OPENMP_LIB_NAMES_VAR) string(APPEND OPENMP_FLAGS_TEST " ${OpenMP_VERBOSE_COMPILE_OPTIONS}") endif() string(REGEX REPLACE "[-/=+]" "" OPENMP_PLAIN_FLAG "${OPENMP_FLAG}") - try_compile( OpenMP_COMPILE_RESULT_${FLAG_MODE}_${OPENMP_PLAIN_FLAG} ${CMAKE_BINARY_DIR} ${_OPENMP_TEST_SRC} - CMAKE_FLAGS "-DCOMPILE_DEFINITIONS:STRING=${OPENMP_FLAGS_TEST}" + unset(_includeDirFlags) + if(OpenMP_${LANG}_INCLUDE_DIR) + set(_includeDirFlags "-DINCLUDE_DIRECTORIES:STRING=${OpenMP_${LANG}_INCLUDE_DIR}") + endif() + try_compile( OpenMP_COMPILE_RESULT_${FLAG_MODE}_${OPENMP_PLAIN_FLAG} + SOURCE_FROM_VAR "${_OPENMP_TEST_SRC_NAME}" _OPENMP_TEST_SRC_CONTENT + LOG_DESCRIPTION "Detecting ${LANG} OpenMP compiler info" + CMAKE_FLAGS "-DCOMPILE_DEFINITIONS:STRING=${OPENMP_FLAGS_TEST}" ${_includeDirFlags} LINK_LIBRARIES ${CMAKE_${LANG}_VERBOSE_FLAG} OUTPUT_VARIABLE OpenMP_TRY_COMPILE_OUTPUT ) @@ -229,19 +233,34 @@ function(_OPENMP_GET_FLAGS LANG FLAG_MODE OPENMP_FLAG_VAR OPENMP_LIB_NAMES_VAR) unset(OpenMP_${LANG}_IMPLICIT_FWK_DIRS) unset(OpenMP_${LANG}_LOG_VAR) - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log - "Detecting ${LANG} OpenMP compiler ABI info compiled with the following output:\n${OpenMP_TRY_COMPILE_OUTPUT}\n\n") - cmake_parse_implicit_link_info("${OpenMP_TRY_COMPILE_OUTPUT}" OpenMP_${LANG}_IMPLICIT_LIBRARIES OpenMP_${LANG}_IMPLICIT_LINK_DIRS OpenMP_${LANG}_IMPLICIT_FWK_DIRS OpenMP_${LANG}_LOG_VAR "${CMAKE_${LANG}_IMPLICIT_OBJECT_REGEX}" + LANGUAGE ${LANG} ) - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log - "Parsed ${LANG} OpenMP implicit link information from above output:\n${OpenMP_${LANG}_LOG_VAR}\n\n") + # For LCC we should additionally alanyze -print-search-dirs output + # to check for additional implicit_dirs. + # Note: This won't work if CMP0129 policy is set to OLD! + if("${CMAKE_${LANG}_COMPILER_ID}" STREQUAL "LCC") + execute_process( + COMMAND ${CMAKE_${LANG}_COMPILER} -print-search-dirs + OUTPUT_VARIABLE output_lines + COMMAND_ERROR_IS_FATAL ANY + ERROR_QUIET) + if("${output_lines}" MATCHES ".*\nlibraries:[ \t]+(.*:)\n.*") + string(REPLACE ":" ";" implicit_dirs_addon "${CMAKE_MATCH_1}") + list(PREPEND OpenMP_${LANG}_IMPLICIT_LINK_DIRS ${implicit_dirs_addon}) + string(APPEND OpenMP_${LANG}_LOG_VAR + " Extended OpenMP library search paths: [${implicit_dirs}]\n") + endif() + endif() + + message(CONFIGURE_LOG + "Parsed ${LANG} OpenMP implicit link information from above output:\n${OpenMP_${LANG}_LOG_VAR}\n\n") unset(_OPENMP_LIB_NAMES) foreach(_OPENMP_IMPLICIT_LIB IN LISTS OpenMP_${LANG}_IMPLICIT_LIBRARIES) @@ -262,7 +281,9 @@ function(_OPENMP_GET_FLAGS LANG FLAG_MODE OPENMP_FLAG_VAR OPENMP_LIB_NAMES_VAR) DOC "Path to the ${_OPENMP_IMPLICIT_LIB_PLAIN} library for OpenMP" HINTS ${OpenMP_${LANG}_IMPLICIT_LINK_DIRS} CMAKE_FIND_ROOT_PATH_BOTH - NO_DEFAULT_PATH + NO_PACKAGE_ROOT_PATH + NO_CMAKE_PATH + NO_CMAKE_ENVIRONMENT_PATH ) endif() mark_as_advanced(OpenMP_${_OPENMP_IMPLICIT_LIB_PLAIN}_LIBRARY) @@ -291,21 +312,23 @@ function(_OPENMP_GET_FLAGS LANG FLAG_MODE OPENMP_FLAG_VAR OPENMP_LIB_NAMES_VAR) # Try without specifying include directory first. We only want to # explicitly add a search path if the header can't be found on the # default header search path already. - try_compile( OpenMP_COMPILE_RESULT_${FLAG_MODE}_${OPENMP_PLAIN_FLAG} ${CMAKE_BINARY_DIR} ${_OPENMP_TEST_SRC} + try_compile( OpenMP_COMPILE_RESULT_${FLAG_MODE}_${OPENMP_PLAIN_FLAG} + SOURCE_FROM_VAR "${_OPENMP_TEST_SRC_NAME}" _OPENMP_TEST_SRC_CONTENT + LOG_DESCRIPTION "Trying ${LANG} OpenMP compiler with '${OpenMP_libomp_LIBRARY}'" CMAKE_FLAGS "-DCOMPILE_DEFINITIONS:STRING=${OPENMP_FLAGS_TEST}" LINK_LIBRARIES ${CMAKE_${LANG}_VERBOSE_FLAG} ${OpenMP_libomp_LIBRARY} - OUTPUT_VARIABLE OpenMP_TRY_COMPILE_OUTPUT ) if(NOT OpenMP_COMPILE_RESULT_${FLAG_MODE}_${OPENMP_PLAIN_FLAG}) find_path(OpenMP_${LANG}_INCLUDE_DIR omp.h) mark_as_advanced(OpenMP_${LANG}_INCLUDE_DIR) set(OpenMP_${LANG}_INCLUDE_DIR "${OpenMP_${LANG}_INCLUDE_DIR}" PARENT_SCOPE) if(OpenMP_${LANG}_INCLUDE_DIR) - try_compile( OpenMP_COMPILE_RESULT_${FLAG_MODE}_${OPENMP_PLAIN_FLAG} ${CMAKE_BINARY_DIR} ${_OPENMP_TEST_SRC} + try_compile( OpenMP_COMPILE_RESULT_${FLAG_MODE}_${OPENMP_PLAIN_FLAG} + SOURCE_FROM_VAR "${_OPENMP_TEST_SRC_NAME}" _OPENMP_TEST_SRC_CONTENT + LOG_DESCRIPTION "Trying ${LANG} OpenMP compiler with '${OpenMP_libomp_LIBRARY}' and '${OpenMP_${LANG}_INCLUDE_DIR}'" CMAKE_FLAGS "-DCOMPILE_DEFINITIONS:STRING=${OPENMP_FLAGS_TEST}" "-DINCLUDE_DIRECTORIES:STRING=${OpenMP_${LANG}_INCLUDE_DIR}" LINK_LIBRARIES ${CMAKE_${LANG}_VERBOSE_FLAG} ${OpenMP_libomp_LIBRARY} - OUTPUT_VARIABLE OpenMP_TRY_COMPILE_OUTPUT ) endif() endif() @@ -323,10 +346,11 @@ function(_OPENMP_GET_FLAGS LANG FLAG_MODE OPENMP_FLAG_VAR OPENMP_LIB_NAMES_VAR) ) mark_as_advanced(OpenMP_libomp_LIBRARY) if(OpenMP_libomp_LIBRARY) - try_compile( OpenMP_COMPILE_RESULT_${FLAG_MODE}_${OPENMP_PLAIN_FLAG} ${CMAKE_BINARY_DIR} ${_OPENMP_TEST_SRC} + try_compile( OpenMP_COMPILE_RESULT_${FLAG_MODE}_${OPENMP_PLAIN_FLAG} + SOURCE_FROM_VAR "${_OPENMP_TEST_SRC_NAME}" _OPENMP_TEST_SRC_CONTENT + LOG_DESCRIPTION "Trying ${LANG} OpenMP compiler with '${OpenMP_libomp_LIBRARY}'" CMAKE_FLAGS "-DCOMPILE_DEFINITIONS:STRING=${OPENMP_FLAGS_TEST}" LINK_LIBRARIES ${CMAKE_${LANG}_VERBOSE_FLAG} ${OpenMP_libomp_LIBRARY} - OUTPUT_VARIABLE OpenMP_TRY_COMPILE_OUTPUT ) if(OpenMP_COMPILE_RESULT_${FLAG_MODE}_${OPENMP_PLAIN_FLAG}) set("${OPENMP_FLAG_VAR}" "${OPENMP_FLAG}" PARENT_SCOPE) @@ -334,9 +358,6 @@ function(_OPENMP_GET_FLAGS LANG FLAG_MODE OPENMP_FLAG_VAR OPENMP_LIB_NAMES_VAR) break() endif() endif() - else() - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log - "Detecting ${LANG} OpenMP failed with the following output:\n${OpenMP_TRY_COMPILE_OUTPUT}\n\n") endif() set("${OPENMP_LIB_NAMES_VAR}" "NOTFOUND" PARENT_SCOPE) set("${OPENMP_FLAG_VAR}" "NOTFOUND" PARENT_SCOPE) @@ -385,7 +406,8 @@ set(OpenMP_Fortran_CHECK_VERSION_SOURCE ") function(_OPENMP_GET_SPEC_DATE LANG SPEC_DATE) - _OPENMP_WRITE_SOURCE_FILE("${LANG}" "CHECK_VERSION_SOURCE" OpenMPCheckVersion _OPENMP_TEST_SRC) + _OPENMP_PREPARE_SOURCE("${LANG}" CHECK_VERSION_SOURCE OpenMPCheckVersion + _OPENMP_TEST_SRC_NAME _OPENMP_TEST_SRC_CONTENT) unset(_includeDirFlags) if(OpenMP_${LANG}_INCLUDE_DIR) @@ -394,10 +416,12 @@ function(_OPENMP_GET_SPEC_DATE LANG SPEC_DATE) set(BIN_FILE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/FindOpenMP/ompver_${LANG}.bin") string(REGEX REPLACE "[-/=+]" "" OPENMP_PLAIN_FLAG "${OPENMP_FLAG}") - try_compile(OpenMP_SPECTEST_${LANG}_${OPENMP_PLAIN_FLAG} "${CMAKE_BINARY_DIR}" "${_OPENMP_TEST_SRC}" - CMAKE_FLAGS "-DCOMPILE_DEFINITIONS:STRING=${OpenMP_${LANG}_FLAGS}" ${_includeDirFlags} - COPY_FILE ${BIN_FILE} - OUTPUT_VARIABLE OpenMP_TRY_COMPILE_OUTPUT) + try_compile(OpenMP_SPECTEST_${LANG}_${OPENMP_PLAIN_FLAG} + SOURCE_FROM_VAR "${_OPENMP_TEST_SRC_NAME}" _OPENMP_TEST_SRC_CONTENT + LOG_DESCRIPTION "Detecting ${LANG} OpenMP version" + CMAKE_FLAGS "-DCOMPILE_DEFINITIONS:STRING=${OpenMP_${LANG}_FLAGS}" ${_includeDirFlags} + COPY_FILE "${BIN_FILE}" + ) if(${OpenMP_SPECTEST_${LANG}_${OPENMP_PLAIN_FLAG}}) file(STRINGS ${BIN_FILE} specstr LIMIT_COUNT 1 REGEX "INFO:OpenMP-date") @@ -405,9 +429,6 @@ function(_OPENMP_GET_SPEC_DATE LANG SPEC_DATE) if("${specstr}" MATCHES "${regex_spec_date}") set(${SPEC_DATE} "${CMAKE_MATCH_1}" PARENT_SCOPE) endif() - else() - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log - "Detecting ${LANG} OpenMP version failed with the following output:\n${OpenMP_TRY_COMPILE_OUTPUT}\n\n") endif() endfunction() @@ -460,10 +481,14 @@ foreach(LANG IN ITEMS C CXX) if(NOT DEFINED OpenMP_${LANG}_FLAGS OR "${OpenMP_${LANG}_FLAGS}" STREQUAL "NOTFOUND" OR NOT DEFINED OpenMP_${LANG}_LIB_NAMES OR "${OpenMP_${LANG}_LIB_NAMES}" STREQUAL "NOTFOUND") _OPENMP_GET_FLAGS("${LANG}" "${LANG}" OpenMP_${LANG}_FLAGS_WORK OpenMP_${LANG}_LIB_NAMES_WORK) - set(OpenMP_${LANG}_FLAGS "${OpenMP_${LANG}_FLAGS_WORK}" - CACHE STRING "${LANG} compiler flags for OpenMP parallelization" FORCE) - set(OpenMP_${LANG}_LIB_NAMES "${OpenMP_${LANG}_LIB_NAMES_WORK}" - CACHE STRING "${LANG} compiler libraries for OpenMP parallelization" FORCE) + if(NOT DEFINED OpenMP_${LANG}_FLAGS OR "${OpenMP_${LANG}_FLAGS}" STREQUAL "NOTFOUND") + set(OpenMP_${LANG}_FLAGS "${OpenMP_${LANG}_FLAGS_WORK}" + CACHE STRING "${LANG} compiler flags for OpenMP parallelization" FORCE) + endif() + if(NOT DEFINED OpenMP_${LANG}_LIB_NAMES OR "${OpenMP_${LANG}_LIB_NAMES}" STREQUAL "NOTFOUND") + set(OpenMP_${LANG}_LIB_NAMES "${OpenMP_${LANG}_LIB_NAMES_WORK}" + CACHE STRING "${LANG} compiler libraries for OpenMP parallelization" FORCE) + endif() mark_as_advanced(OpenMP_${LANG}_FLAGS OpenMP_${LANG}_LIB_NAMES) endif() endif() @@ -479,10 +504,14 @@ if(CMAKE_Fortran_COMPILER_LOADED) set(OpenMP_Fortran_HAVE_OMPLIB_MODULE TRUE CACHE BOOL INTERNAL "") endif() - set(OpenMP_Fortran_FLAGS "${OpenMP_Fortran_FLAGS_WORK}" - CACHE STRING "Fortran compiler flags for OpenMP parallelization") - set(OpenMP_Fortran_LIB_NAMES "${OpenMP_Fortran_LIB_NAMES_WORK}" - CACHE STRING "Fortran compiler libraries for OpenMP parallelization") + if(NOT DEFINED OpenMP_Fortran_FLAGS OR "${OpenMP_Fortran_FLAGS}" STREQUAL "NOTFOUND") + set(OpenMP_Fortran_FLAGS "${OpenMP_Fortran_FLAGS_WORK}" + CACHE STRING "Fortran compiler flags for OpenMP parallelization" FORCE) + endif() + if(NOT DEFINED OpenMP_Fortran_LIB_NAMES OR "${OpenMP_Fortran_LIB_NAMES}" STREQUAL "NOTFOUND") + set(OpenMP_Fortran_LIB_NAMES "${OpenMP_Fortran_LIB_NAMES_WORK}" + CACHE STRING "Fortran compiler libraries for OpenMP parallelization" FORCE) + endif() mark_as_advanced(OpenMP_Fortran_FLAGS OpenMP_Fortran_LIB_NAMES) endif() @@ -495,11 +524,14 @@ if(CMAKE_Fortran_COMPILER_LOADED) set(OpenMP_Fortran_HAVE_OMPLIB_HEADER TRUE CACHE BOOL INTERNAL "") endif() - set(OpenMP_Fortran_FLAGS "${OpenMP_Fortran_FLAGS_WORK}" - CACHE STRING "Fortran compiler flags for OpenMP parallelization") - - set(OpenMP_Fortran_LIB_NAMES "${OpenMP_Fortran_LIB_NAMES}" - CACHE STRING "Fortran compiler libraries for OpenMP parallelization") + if(NOT DEFINED OpenMP_Fortran_FLAGS OR "${OpenMP_Fortran_FLAGS}" STREQUAL "NOTFOUND") + set(OpenMP_Fortran_FLAGS "${OpenMP_Fortran_FLAGS_WORK}" + CACHE STRING "Fortran compiler flags for OpenMP parallelization" FORCE) + endif() + if(NOT DEFINED OpenMP_Fortran_LIB_NAMES OR "${OpenMP_Fortran_LIB_NAMES}" STREQUAL "NOTFOUND") + set(OpenMP_Fortran_LIB_NAMES "${OpenMP_Fortran_LIB_NAMES_WORK}" + CACHE STRING "Fortran compiler libraries for OpenMP parallelization" FORCE) + endif() endif() if(OpenMP_Fortran_HAVE_OMPLIB_MODULE) @@ -571,7 +603,8 @@ foreach(LANG IN LISTS OpenMP_FINDLIST) separate_arguments(_OpenMP_${LANG}_OPTIONS NATIVE_COMMAND "${OpenMP_${LANG}_FLAGS}") set_property(TARGET OpenMP::OpenMP_${LANG} PROPERTY INTERFACE_COMPILE_OPTIONS "$<$<COMPILE_LANGUAGE:${LANG}>:${_OpenMP_${LANG}_OPTIONS}>") - if(CMAKE_${LANG}_COMPILER_ID STREQUAL "Fujitsu") + if(CMAKE_${LANG}_COMPILER_ID STREQUAL "Fujitsu" + OR ${CMAKE_${LANG}_COMPILER_ID} STREQUAL "IntelLLVM") set_property(TARGET OpenMP::OpenMP_${LANG} PROPERTY INTERFACE_LINK_OPTIONS "${OpenMP_${LANG}_FLAGS}") endif() diff --git a/Modules/FindOpenSP.cmake b/Modules/FindOpenSP.cmake new file mode 100644 index 0000000..25d0e6f --- /dev/null +++ b/Modules/FindOpenSP.cmake @@ -0,0 +1,160 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + +#[=======================================================================[.rst: +FindOpenSP +---------- + +.. versionadded:: 3.25 + +Try to find the OpenSP library. + +Result Variables +^^^^^^^^^^^^^^^^ + +This will define the following variables: + +``OpenSP_FOUND`` + True if (the requested version of) ``OpenSP`` is available + +``OpenSP_VERSION`` + The version of ``OpenSP`` + +``OpenSP_VERSION_MAJOR`` + The major version of ``OpenSP`` + +``OpenSP_VERSION_MINOR`` + The minor version of ``OpenSP`` + +``OpenSP_VERSION_PATCH`` + The patch version of ``OpenSP`` + +``OpenSP_INCLUDE_DIRS`` + The include dirs of ``OpenSP`` with its headers + +``OpenSP_LIBRARIES`` + The OpenSP library for use with target_link_libraries(). + This can be passed to target_link_libraries() instead of + the :prop_tgt:`IMPORTED` ``OpenSP::OpenSP`` target + +``OpenSP_MULTI_BYTE`` + True if ``SP_MULTI_BYTE`` was found to be defined in OpenSP's ``config.h`` + header file, which indicates that the ``OpenSP`` library was compiled with + support for multi-byte characters. The consuming target needs to define the + ``SP_MULTI_BYTE`` to match this value in order to avoid issues with character + decoding. + +IMPORTED Targets +^^^^^^^^^^^^^^^^ + +This module defines the :prop_tgt:`IMPORTED` target ``OpenSP::OpenSP``, if +OpenSP has been found. + +Cache variables +^^^^^^^^^^^^^^^ + +The following cache variables may also be set: + +``OpenSP_INCLUDE_DIR`` + the OpenSP include directory + +``OpenSP_LIBRARY`` + the absolute path of the osp library + +#]=======================================================================] + +find_package(PkgConfig QUIET) +if (PkgConfig_FOUND) + pkg_check_modules(PC_OpenSP QUIET opensp) +endif () + +if (NOT OpenSP_INCLUDE_DIR) + find_path(OpenSP_INCLUDE_DIR + NAMES ParserEventGeneratorKit.h + HINTS + ${PC_OpenSP_INCLUDEDIRS} + ${PC_OpenSP_INCLUDE_DIRS} + PATH_SUFFIXES OpenSP opensp + DOC "The OpenSP include directory" + ) +endif () + +if (NOT OpenSP_LIBRARY) + find_library(OpenSP_LIBRARY_RELEASE + NAMES osp libosp opensp libopensp sp133 libsp + HINTS + ${PC_OpenSP_LIBDIR} + ${PC_OpenSP_LIBRARY_DIRS} + ) + + find_library(OpenSP_LIBRARY_DEBUG + NAMES ospd libospd openspd libopenspd sp133d libspd + HINTS + ${PC_OpenSP_LIBDIR} + ${PC_OpenSP_LIBRARY_DIRS} + ) + + include(SelectLibraryConfigurations) + select_library_configurations(OpenSP) +endif () + +if (OpenSP_INCLUDE_DIR) + if (EXISTS "${OpenSP_INCLUDE_DIR}/config.h") + if (NOT OpenSP_VERSION) + file(STRINGS "${OpenSP_INCLUDE_DIR}/config.h" opensp_version_str REGEX "^#define[\t ]+SP_VERSION[\t ]+\".*\"") + string(REGEX REPLACE "^.*SP_VERSION[\t ]+\"([^\"]*)\".*$" "\\1" OpenSP_VERSION "${opensp_version_str}") + unset(opensp_version_str) + endif () + + if (OpenSP_VERSION MATCHES [=[([0-9]+)\.([0-9]+)\.([0-9]+)]=]) + set(OpenSP_VERSION_MAJOR "${CMAKE_MATCH_1}") + set(OpenSP_VERSION_MINOR "${CMAKE_MATCH_2}") + set(OpenSP_VERSION_PATCH "${CMAKE_MATCH_3}") + endif () + + include(CheckCXXSymbolExists) + check_cxx_symbol_exists(SP_MULTI_BYTE "${OpenSP_INCLUDE_DIR}/config.h" OpenSP_MULTI_BYTE) + endif () +endif () + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(OpenSP + FOUND_VAR OpenSP_FOUND + REQUIRED_VARS OpenSP_LIBRARY OpenSP_INCLUDE_DIR + VERSION_VAR OpenSP_VERSION + ) + +mark_as_advanced(OpenSP_INCLUDE_DIR OpenSP_LIBRARY OpenSP_MULTI_BYTE) + +if (OpenSP_FOUND) + set(OpenSP_INCLUDE_DIRS ${OpenSP_INCLUDE_DIR}) + if (NOT TARGET OpenSP::OpenSP) + add_library(OpenSP::OpenSP UNKNOWN IMPORTED) + if (EXISTS "${OpenSP_LIBRARY}") + set_target_properties(OpenSP::OpenSP PROPERTIES + IMPORTED_LOCATION "${OpenSP_LIBRARY}") + endif () + set_target_properties(OpenSP::OpenSP PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES "${OpenSP_INCLUDE_DIRS}") + + if (OpenSP_LIBRARY_RELEASE) + set_target_properties(OpenSP::OpenSP PROPERTIES + IMPORTED_LOCATION_RELEASE "${OpenSP_LIBRARY_RELEASE}") + set_property(TARGET OpenSP::OpenSP APPEND PROPERTY + IMPORTED_CONFIGURATIONS RELEASE) + endif () + + if (OpenSP_LIBRARY_DEBUG) + set_target_properties(OpenSP::OpenSP PROPERTIES + IMPORTED_LOCATION_DEBUG "${OpenSP_LIBRARY_DEBUG}") + set_property(TARGET OpenSP::OpenSP APPEND PROPERTY + IMPORTED_CONFIGURATIONS DEBUG) + endif () + endif () +endif () + +include(FeatureSummary) +set_package_properties(OpenSP PROPERTIES + URL "http://openjade.sourceforge.net/doc/index.htm" + DESCRIPTION "An SGML System Conforming to International Standard ISO 8879" + ) diff --git a/Modules/FindOpenSSL.cmake b/Modules/FindOpenSSL.cmake index 5a8bfef..4e8374c 100644 --- a/Modules/FindOpenSSL.cmake +++ b/Modules/FindOpenSSL.cmake @@ -90,38 +90,107 @@ This module will set the following variables in your project: Hints ^^^^^ -Set ``OPENSSL_ROOT_DIR`` to the root directory of an OpenSSL installation. +The following variables may be set to control search behavior: -.. versionadded:: 3.4 - Set ``OPENSSL_USE_STATIC_LIBS`` to ``TRUE`` to look for static libraries. +``OPENSSL_ROOT_DIR`` + Set to the root directory of an OpenSSL installation. + +``OPENSSL_USE_STATIC_LIBS`` + .. versionadded:: 3.4 + + Set to ``TRUE`` to look for static libraries. -.. versionadded:: 3.5 - Set ``OPENSSL_MSVC_STATIC_RT`` set ``TRUE`` to choose the MT version of the lib. +``OPENSSL_MSVC_STATIC_RT`` + .. versionadded:: 3.5 + + Set to ``TRUE`` to choose the MT version of the lib. + +``ENV{PKG_CONFIG_PATH}`` + On UNIX-like systems, ``pkg-config`` is used to locate the system OpenSSL. + Set the ``PKG_CONFIG_PATH`` environment varialbe to look in alternate + locations. Useful on multi-lib systems. #]=======================================================================] macro(_OpenSSL_test_and_find_dependencies ssl_library crypto_library) + unset(_OpenSSL_extra_static_deps) if((CMAKE_SYSTEM_NAME STREQUAL "Linux") AND (("${ssl_library}" MATCHES "\\${CMAKE_STATIC_LIBRARY_SUFFIX}$") OR ("${crypto_library}" MATCHES "\\${CMAKE_STATIC_LIBRARY_SUFFIX}$"))) set(_OpenSSL_has_dependencies TRUE) - find_package(Threads) + unset(_OpenSSL_has_dependency_zlib) + if(OPENSSL_USE_STATIC_LIBS) + set(_OpenSSL_libs "${_OPENSSL_STATIC_LIBRARIES}") + set(_OpenSSL_ldflags_other "${_OPENSSL_STATIC_LDFLAGS_OTHER}") + else() + set(_OpenSSL_libs "${_OPENSSL_LIBRARIES}") + set(_OpenSSL_ldflags_other "${_OPENSSL_LDFLAGS_OTHER}") + endif() + if(_OpenSSL_libs) + unset(_OpenSSL_has_dependency_dl) + foreach(_OPENSSL_DEP_LIB IN LISTS _OpenSSL_libs) + if (_OPENSSL_DEP_LIB STREQUAL "ssl" OR _OPENSSL_DEP_LIB STREQUAL "crypto") + # ignoring: these are the targets + elseif(_OPENSSL_DEP_LIB STREQUAL CMAKE_DL_LIBS) + set(_OpenSSL_has_dependency_dl TRUE) + elseif(_OPENSSL_DEP_LIB STREQUAL "z") + find_package(ZLIB) + set(_OpenSSL_has_dependency_zlib TRUE) + else() + list(APPEND _OpenSSL_extra_static_deps "${_OPENSSL_DEP_LIB}") + endif() + endforeach() + unset(_OPENSSL_DEP_LIB) + else() + set(_OpenSSL_has_dependency_dl TRUE) + endif() + if(_OpenSSL_ldflags_other) + unset(_OpenSSL_has_dependency_threads) + foreach(_OPENSSL_DEP_LDFLAG IN LISTS _OpenSSL_ldflags_other) + if (_OPENSSL_DEP_LDFLAG STREQUAL "-pthread") + set(_OpenSSL_has_dependency_threads TRUE) + find_package(Threads) + endif() + endforeach() + unset(_OPENSSL_DEP_LDFLAG) + else() + set(_OpenSSL_has_dependency_threads TRUE) + find_package(Threads) + endif() + unset(_OpenSSL_libs) + unset(_OpenSSL_ldflags_other) else() set(_OpenSSL_has_dependencies FALSE) endif() endmacro() function(_OpenSSL_add_dependencies libraries_var) - if(CMAKE_THREAD_LIBS_INIT) + if(_OpenSSL_has_dependency_zlib) + list(APPEND ${libraries_var} ${ZLIB_LIBRARY}) + endif() + if(_OpenSSL_has_dependency_threads) list(APPEND ${libraries_var} ${CMAKE_THREAD_LIBS_INIT}) endif() - list(APPEND ${libraries_var} ${CMAKE_DL_LIBS}) + if(_OpenSSL_has_dependency_dl) + list(APPEND ${libraries_var} ${CMAKE_DL_LIBS}) + endif() + list(APPEND ${libraries_var} ${_OpenSSL_extra_static_deps}) set(${libraries_var} ${${libraries_var}} PARENT_SCOPE) endfunction() function(_OpenSSL_target_add_dependencies target) if(_OpenSSL_has_dependencies) - set_property( TARGET ${target} APPEND PROPERTY INTERFACE_LINK_LIBRARIES Threads::Threads ) - set_property( TARGET ${target} APPEND PROPERTY INTERFACE_LINK_LIBRARIES ${CMAKE_DL_LIBS} ) + if(_OpenSSL_has_dependency_zlib) + set_property( TARGET ${target} APPEND PROPERTY INTERFACE_LINK_LIBRARIES ZLIB::ZLIB ) + endif() + if(_OpenSSL_has_dependency_threads) + set_property( TARGET ${target} APPEND PROPERTY INTERFACE_LINK_LIBRARIES Threads::Threads) + endif() + if(_OpenSSL_has_dependency_dl) + set_property( TARGET ${target} APPEND PROPERTY INTERFACE_LINK_LIBRARIES ${CMAKE_DL_LIBS} ) + endif() + if(_OpenSSL_extra_static_deps) + set_property( TARGET ${target} APPEND PROPERTY INTERFACE_LINK_LIBRARIES ${_OpenSSL_extra_static_deps}) + endif() endif() if(WIN32 AND OPENSSL_USE_STATIC_LIBS) if(WINCE) @@ -148,6 +217,19 @@ if(OPENSSL_USE_STATIC_LIBS) endif() endif() +if(CMAKE_SYSTEM_NAME STREQUAL "QNX" AND + CMAKE_SYSTEM_VERSION VERSION_GREATER_EQUAL "7.0" AND CMAKE_SYSTEM_VERSION VERSION_LESS "7.1" AND + OpenSSL_FIND_VERSION VERSION_GREATER_EQUAL "1.1" AND OpenSSL_FIND_VERSION VERSION_LESS "1.2") + # QNX 7.0.x provides openssl 1.0.2 and 1.1.1 in parallel: + # * openssl 1.0.2: libcrypto.so.2 and libssl.so.2, headers under usr/include/openssl + # * openssl 1.1.1: libcrypto1_1.so.2.1 and libssl1_1.so.2.1, header under usr/include/openssl1_1 + # See http://www.qnx.com/developers/articles/rel_6726_0.html + set(_OPENSSL_FIND_PATH_SUFFIX "openssl1_1") + set(_OPENSSL_NAME_POSTFIX "1_1") +else() + set(_OPENSSL_FIND_PATH_SUFFIX "include") +endif() + if (WIN32) # http://www.slproweb.com/products/Win32OpenSSL.html set(_OPENSSL_ROOT_HINTS @@ -200,7 +282,7 @@ find_path(OPENSSL_INCLUDE_DIR ${_OPENSSL_INCLUDEDIR} ${_OPENSSL_INCLUDE_DIRS} PATH_SUFFIXES - include + ${_OPENSSL_FIND_PATH_SUFFIX} ) if(WIN32 AND NOT CYGWIN) @@ -379,6 +461,7 @@ if(WIN32 AND NOT CYGWIN) PATH_SUFFIXES "lib/MinGW" "lib" + "lib64" ) find_library(SSL_EAY @@ -389,6 +472,7 @@ if(WIN32 AND NOT CYGWIN) PATH_SUFFIXES "lib/MinGW" "lib" + "lib64" ) mark_as_advanced(SSL_EAY LIB_EAY) @@ -430,7 +514,7 @@ else() find_library(OPENSSL_SSL_LIBRARY NAMES - ssl + ssl${_OPENSSL_NAME_POSTFIX} ssleay32 ssleay32MD NAMES_PER_DIR @@ -444,7 +528,7 @@ else() find_library(OPENSSL_CRYPTO_LIBRARY NAMES - crypto + crypto${_OPENSSL_NAME_POSTFIX} NAMES_PER_DIR ${_OPENSSL_ROOT_HINTS_AND_PATHS} HINTS @@ -542,6 +626,14 @@ if(OPENSSL_INCLUDE_DIR AND EXISTS "${OPENSSL_INCLUDE_DIR}/openssl/opensslv.h") set(OPENSSL_VERSION "${OPENSSL_VERSION_STR}") + # Setting OPENSSL_VERSION_MAJOR OPENSSL_VERSION_MINOR and OPENSSL_VERSION_FIX + string(REGEX MATCHALL "([0-9])+" OPENSSL_VERSION_NUMBER "${OPENSSL_VERSION}") + list(POP_FRONT OPENSSL_VERSION_NUMBER + OPENSSL_VERSION_MAJOR + OPENSSL_VERSION_MINOR + OPENSSL_VERSION_FIX) + + unset(OPENSSL_VERSION_NUMBER) unset(OPENSSL_VERSION_STR) endif () endif () @@ -681,3 +773,10 @@ endif() if(OPENSSL_USE_STATIC_LIBS) set(CMAKE_FIND_LIBRARY_SUFFIXES ${_openssl_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES}) endif() + +unset(_OPENSSL_FIND_PATH_SUFFIX) +unset(_OPENSSL_NAME_POSTFIX) +unset(_OpenSSL_extra_static_deps) +unset(_OpenSSL_has_dependency_dl) +unset(_OpenSSL_has_dependency_threads) +unset(_OpenSSL_has_dependency_zlib) diff --git a/Modules/FindPackageHandleStandardArgs.cmake b/Modules/FindPackageHandleStandardArgs.cmake index fbcf7cd..56ba1e6 100644 --- a/Modules/FindPackageHandleStandardArgs.cmake +++ b/Modules/FindPackageHandleStandardArgs.cmake @@ -535,18 +535,24 @@ function(FIND_PACKAGE_HANDLE_STANDARD_ARGS _NAME _FIRST_ARG) set(VERSION_MSG "") set(VERSION_OK TRUE) - # check with DEFINED here as the requested or found version may be "0" + # check that the version variable is not empty to avoid emitting a misleading + # message (i.e. `Found unsuitable version ""`) if (DEFINED ${_NAME}_FIND_VERSION) if(DEFINED ${FPHSA_VERSION_VAR}) - set(_FOUND_VERSION ${${FPHSA_VERSION_VAR}}) - if (FPHSA_HANDLE_VERSION_RANGE) - set (FPCV_HANDLE_VERSION_RANGE HANDLE_VERSION_RANGE) + if(NOT "${${FPHSA_VERSION_VAR}}" STREQUAL "") + set(_FOUND_VERSION ${${FPHSA_VERSION_VAR}}) + if (FPHSA_HANDLE_VERSION_RANGE) + set (FPCV_HANDLE_VERSION_RANGE HANDLE_VERSION_RANGE) + else() + set(FPCV_HANDLE_VERSION_RANGE NO_AUTHOR_WARNING_VERSION_RANGE) + endif() + find_package_check_version ("${_FOUND_VERSION}" VERSION_OK RESULT_MESSAGE_VARIABLE VERSION_MSG + ${FPCV_HANDLE_VERSION_RANGE}) else() - set(FPCV_HANDLE_VERSION_RANGE NO_AUTHOR_WARNING_VERSION_RANGE) + set(VERSION_OK FALSE) endif() - find_package_check_version ("${_FOUND_VERSION}" VERSION_OK RESULT_MESSAGE_VARIABLE VERSION_MSG - ${FPCV_HANDLE_VERSION_RANGE}) - else() + endif() + if("${${FPHSA_VERSION_VAR}}" STREQUAL "") # if the package was not found, but a version was given, add that to the output: if(${_NAME}_FIND_VERSION_EXACT) set(VERSION_MSG "(Required is exact version \"${${_NAME}_FIND_VERSION}\")") diff --git a/Modules/FindPkgConfig.cmake b/Modules/FindPkgConfig.cmake index ab8af3e..02f7fb4 100644 --- a/Modules/FindPkgConfig.cmake +++ b/Modules/FindPkgConfig.cmake @@ -143,7 +143,9 @@ macro(_pkgconfig_invoke _pkglist _prefix _varname _regexp) string(REGEX REPLACE "${_regexp}" " " _pkgconfig_invoke_result "${_pkgconfig_invoke_result}") endif() - separate_arguments(_pkgconfig_invoke_result) + # pkg-config can represent "spaces within an argument" by backslash-escaping the space. + # UNIX_COMMAND mode treats backslash-escaped spaces as "not a space that delimits arguments". + separate_arguments(_pkgconfig_invoke_result UNIX_COMMAND "${_pkgconfig_invoke_result}") #message(STATUS " ${_varname} ... ${_pkgconfig_invoke_result}") set(_pkgconfig_${_varname} ${_pkgconfig_invoke_result}) diff --git a/Modules/FindPostgreSQL.cmake b/Modules/FindPostgreSQL.cmake index 2233aa0..c92fbdc 100644 --- a/Modules/FindPostgreSQL.cmake +++ b/Modules/FindPostgreSQL.cmake @@ -121,13 +121,16 @@ foreach(suffix ${PostgreSQL_KNOWN_VERSIONS}) if(UNIX) list(APPEND PostgreSQL_LIBRARY_ADDITIONAL_SEARCH_SUFFIXES "postgresql${suffix}" + "postgresql@${suffix}" "pgsql-${suffix}/lib") list(APPEND PostgreSQL_INCLUDE_ADDITIONAL_SEARCH_SUFFIXES "postgresql${suffix}" + "postgresql@${suffix}" "postgresql/${suffix}" "pgsql-${suffix}/include") list(APPEND PostgreSQL_TYPE_ADDITIONAL_SEARCH_SUFFIXES "postgresql${suffix}/server" + "postgresql@${suffix}/server" "postgresql/${suffix}/server" "pgsql-${suffix}/include/server") endif() diff --git a/Modules/FindPython.cmake b/Modules/FindPython.cmake index 375cb70..fd2eeaa 100644 --- a/Modules/FindPython.cmake +++ b/Modules/FindPython.cmake @@ -31,6 +31,13 @@ The following components are supported: * ``Development.Embed``: search for artifacts for Python embedding developments. + .. versionadded:: 3.26 + + * ``Development.SABIModule``: search for artifacts for Python module + developments using the + `Stable Application Binary Interface <https://docs.python.org/3/c-api/stable.html>`_. + This component is available only for version ``3.2`` and upper. + * ``NumPy``: search for NumPy include directories. .. versionadded:: 3.14 @@ -56,7 +63,7 @@ To manage concurrent versions 3 and 2 of Python, use :module:`FindPython3` and If components ``Interpreter`` and ``Development`` (or one of its sub-components) are both specified, this module search only for interpreter - with same platform architecture as the one defined by ``CMake`` + with same platform architecture as the one defined by CMake configuration. This constraint does not apply if only ``Interpreter`` component is specified. @@ -80,6 +87,12 @@ This module defines the following :ref:`Imported Targets <Imported Targets>`: Python library for Python module. Target defined if component ``Development.Module`` is found. +``Python::SABIModule`` + .. versionadded:: 3.26 + + Python library for Python module using the Stable Application Binary + Interface. Target defined if component ``Development.SABIModule`` is found. + ``Python::Python`` Python library for Python embedding. Target defined if component ``Development.Embed`` is found. @@ -139,12 +152,21 @@ This module will set the following variables in your project Extension suffix for modules. - Information returned by - ``distutils.sysconfig.get_config_var('SOABI')`` or computed from - ``distutils.sysconfig.get_config_var('EXT_SUFFIX')`` or - ``python-config --extension-suffix``. If package ``distutils.sysconfig`` is - not available, ``sysconfig.get_config_var('SOABI')`` or - ``sysconfig.get_config_var('EXT_SUFFIX')`` are used. + Information computed from ``distutils.sysconfig.get_config_var('EXT_SUFFIX')`` + or ``distutils.sysconfig.get_config_var('SOABI')`` or + ``python3-config --extension-suffix``. If package ``distutils.sysconfig`` is + not available, ``sysconfig.get_config_var('EXT_SUFFIX')`` or + ``sysconfig.get_config_var('SOABI')`` are used. + +``Python_SOSABI`` + .. versionadded:: 3.26 + + Extension suffix for modules using the Stable Application Binary Interface. + + Information computed from ``importlib.machinery.EXTENSION_SUFFIXES`` if the + COMPONENT ``Interpreter`` was specified. Otherwise, the extension is ``abi3`` + except for ``Windows``, ``MSYS`` and ``CYGWIN`` for which this is an empty + string. ``Python_Compiler_FOUND`` System has the Python compiler. @@ -167,6 +189,12 @@ This module will set the following variables in your project System has the Python development artifacts for Python module. +``Python_Development.SABIModule_FOUND`` + .. versionadded:: 3.26 + + System has the Python development artifacts for Python module using the + Stable Application Binary Interface. + ``Python_Development.Embed_FOUND`` .. versionadded:: 3.18 @@ -188,6 +216,18 @@ This module will set the following variables in your project The Python library directories. ``Python_RUNTIME_LIBRARY_DIRS`` The Python runtime library directories. +``Python_SABI_LIBRARIES`` + .. versionadded:: 3.26 + + The Python libraries for the Stable Application Binary Interface. +``Python_SABI_LIBRARY_DIRS`` + .. versionadded:: 3.26 + + The Python ``SABI`` library directories. +``Python_RUNTIME_SABI_LIBRARY_DIRS`` + .. versionadded:: 3.26 + + The Python runtime ``SABI`` library directories. ``Python_VERSION`` Python version. ``Python_VERSION_MAJOR`` @@ -237,8 +277,8 @@ Hints ``Python_FIND_ABI`` .. versionadded:: 3.16 - This variable defines which ABIs, as defined in - `PEP 3149 <https://www.python.org/dev/peps/pep-3149/>`_, should be searched. + This variable defines which ABIs, as defined in :pep:`3149`, should be + searched. .. note:: @@ -363,7 +403,7 @@ Hints ``Anaconda`` or ``ActivePython``, rely on this implementation. * ``IronPython``: This implementation use the ``CSharp`` language for ``.NET Framework`` on top of the `Dynamic Language Runtime` (``DLR``). - See `IronPython <http://ironpython.net>`_. + See `IronPython <https://ironpython.net>`_. * ``PyPy``: This implementation use ``RPython`` language and ``RPython translation toolchain`` to produce the python interpreter. See `PyPy <https://www.pypy.org>`_. @@ -426,6 +466,13 @@ setting the following variables: variables ``Python_LIBRARIES``, ``Python_LIBRARY_DIRS`` and ``Python_RUNTIME_LIBRARY_DIRS``. +``Python_SABI_LIBRARY`` + .. versionadded:: 3.26 + + The path to the library for Stable Application Binary Interface. It will be + used to compute the variables ``Python_SABI_LIBRARIES``, + ``Python_SABI_LIBRARY_DIRS`` and ``Python_RUNTIME_SABI_LIBRARY_DIRS``. + ``Python_INCLUDE_DIR`` The path to the directory of the ``Python`` headers. It will be used to compute the variable ``Python_INCLUDE_DIRS``. @@ -449,7 +496,7 @@ setting the following variables: By default, this module supports multiple calls in different directories of a project with different version/component requirements while providing correct -and consistent results for each call. To support this behavior, ``CMake`` cache +and consistent results for each call. To support this behavior, CMake cache is not used in the traditional way which can be problematic for interactive specification. So, to enable also interactive specification, module behavior can be controlled with the following variable: @@ -471,10 +518,11 @@ Commands This module defines the command ``Python_add_library`` (when :prop_gbl:`CMAKE_ROLE` is ``PROJECT``), which has the same semantics as :command:`add_library` and adds a dependency to target ``Python::Python`` or, -when library type is ``MODULE``, to target ``Python::Module`` and takes care of -Python module naming rules:: +when library type is ``MODULE``, to target ``Python::Module`` or +``Python::SABIModule`` (when ``USE_SABI`` option is specified) and takes care +of Python module naming rules:: - Python_add_library (<name> [STATIC | SHARED | MODULE [WITH_SOABI]] + Python_add_library (<name> [STATIC | SHARED | MODULE [USE_SABI <version>] [WITH_SOABI]] <source1> [<source2> ...]) If the library type is not specified, ``MODULE`` is assumed. @@ -482,6 +530,19 @@ If the library type is not specified, ``MODULE`` is assumed. .. versionadded:: 3.17 For ``MODULE`` library type, if option ``WITH_SOABI`` is specified, the module suffix will include the ``Python_SOABI`` value, if any. + +.. versionadded:: 3.26 + For ``MODULE`` type, if the option ``USE_SABI`` is specified, the + preprocessor definition ``Py_LIMITED_API`` will be specified, as ``PRIVATE``, + for the target ``<name>`` with the value computed from ``<version>`` argument. + The expected format for ``<version>`` is ``major[.minor]``, where each + component is a numeric value. If ``minor`` component is specified, the + version should be, at least, ``3.2`` which is the version where the + `Stable Application Binary Interface <https://docs.python.org/3/c-api/stable.html>`_ + was introduced. Specifying only major version ``3`` is equivalent to ``3.2``. + + When option ``WITH_SOABI`` is also specified, the module suffix will include + the ``Python3_SOSABI`` value, if any. #]=======================================================================] diff --git a/Modules/FindPython/Support.cmake b/Modules/FindPython/Support.cmake index cbb6c1c..f1be0f4 100644 --- a/Modules/FindPython/Support.cmake +++ b/Modules/FindPython/Support.cmake @@ -10,10 +10,16 @@ # cmake_policy(PUSH) +# list supports empty elements +cmake_policy (SET CMP0007 NEW) # numbers and boolean constants cmake_policy (SET CMP0012 NEW) # IN_LIST operator cmake_policy (SET CMP0057 NEW) +# foreach loop variable scope +cmake_policy (SET CMP0124 NEW) +# registry view behavior +cmake_policy (SET CMP0134 NEW) if (NOT DEFINED _PYTHON_PREFIX) message (FATAL_ERROR "FindPython: INTERNAL ERROR") @@ -51,6 +57,18 @@ macro (_PYTHON_DISPLAY_FAILURE _PYTHON_MSG) endmacro() +function (_PYTHON_ADD_REASON_FAILURE module message) + if (_${_PYTHON_PREFIX}_${module}_REASON_FAILURE) + string (LENGTH "${_${_PYTHON_PREFIX}_${module}_REASON_FAILURE}" length) + math (EXPR length "${length} + 10") + string (REPEAT " " ${length} shift) + set_property (CACHE _${_PYTHON_PREFIX}_${module}_REASON_FAILURE PROPERTY VALUE "${_${_PYTHON_PREFIX}_${module}_REASON_FAILURE}\n${shift}${message}") + else() + set_property (CACHE _${_PYTHON_PREFIX}_${module}_REASON_FAILURE PROPERTY VALUE "${message}") + endif() +endfunction() + + function (_PYTHON_MARK_AS_INTERNAL) foreach (var IN LISTS ARGV) if (DEFINED CACHE{${var}}) @@ -175,30 +193,31 @@ function (_PYTHON_GET_REGISTRIES _PYTHON_PGR_REGISTRY_PATHS) foreach (version IN LISTS _PGR_VERSION) string (REPLACE "." "" version_no_dots ${version}) list (APPEND registries - [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${version}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath] - [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${version}-${_${_PYTHON_PREFIX}_ARCH2}\\InstallPath]) + [HKEY_CURRENT_USER/SOFTWARE/Python/PythonCore/${version}-${_${_PYTHON_PREFIX}_ARCH}/InstallPath] + [HKEY_CURRENT_USER/SOFTWARE/Python/PythonCore/${version}-${_${_PYTHON_PREFIX}_ARCH2}/InstallPath]) if (version VERSION_GREATER_EQUAL "3.5") + # cmake_host_system_information is not usable in bootstrap get_filename_component (arch "[HKEY_CURRENT_USER\\Software\\Python\\PythonCore\\${version};SysArchitecture]" NAME) if (arch MATCHES "(${_${_PYTHON_PREFIX}_ARCH}|${_${_PYTHON_PREFIX}_ARCH2})bit") list (APPEND registries - [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${version}\\InstallPath]) + [HKEY_CURRENT_USER/SOFTWARE/Python/PythonCore/${version}/InstallPath]) endif() else() list (APPEND registries - [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${version}\\InstallPath]) + [HKEY_CURRENT_USER/SOFTWARE/Python/PythonCore/${version}/InstallPath]) endif() list (APPEND registries - [HKEY_CURRENT_USER\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${version_no_dots}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath] - [HKEY_CURRENT_USER\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${version_no_dots}-${_${_PYTHON_PREFIX}_ARCH2}\\InstallPath] - [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${version}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath] - [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${version}-${_${_PYTHON_PREFIX}_ARCH2}\\InstallPath] - [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${version}\\InstallPath] - [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${version_no_dots}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath] - [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${version_no_dots}-${_${_PYTHON_PREFIX}_ARCH2}\\InstallPath]) + [HKEY_CURRENT_USER/SOFTWARE/Python/ContinuumAnalytics/Anaconda${version_no_dots}-${_${_PYTHON_PREFIX}_ARCH}/InstallPath] + [HKEY_CURRENT_USER/SOFTWARE/Python/ContinuumAnalytics/Anaconda${version_no_dots}-${_${_PYTHON_PREFIX}_ARCH2}/InstallPath] + [HKEY_LOCAL_MACHINE/SOFTWARE/Python/PythonCore/${version}-${_${_PYTHON_PREFIX}_ARCH}/InstallPath] + [HKEY_LOCAL_MACHINE/SOFTWARE/Python/PythonCore/${version}-${_${_PYTHON_PREFIX}_ARCH2}/InstallPath] + [HKEY_LOCAL_MACHINE/SOFTWARE/Python/PythonCore/${version}/InstallPath] + [HKEY_LOCAL_MACHINE/SOFTWARE/Python/ContinuumAnalytics/Anaconda${version_no_dots}-${_${_PYTHON_PREFIX}_ARCH}/InstallPath] + [HKEY_LOCAL_MACHINE/SOFTWARE/Python/ContinuumAnalytics/Anaconda${version_no_dots}-${_${_PYTHON_PREFIX}_ARCH2}/InstallPath]) endforeach() elseif (implementation STREQUAL "IronPython") foreach (version IN LISTS _PGR_VERSION) - list (APPEND registries [HKEY_LOCAL_MACHINE\\SOFTWARE\\IronPython\\${version}\\InstallPath]) + list (APPEND registries [HKEY_LOCAL_MACHINE/SOFTWARE/IronPython/${version}/InstallPath]) endforeach() endif() endforeach() @@ -440,11 +459,18 @@ endfunction() function (_PYTHON_GET_CONFIG_VAR _PYTHON_PGCV_VALUE NAME) unset (${_PYTHON_PGCV_VALUE} PARENT_SCOPE) - if (NOT NAME MATCHES "^(PREFIX|ABIFLAGS|CONFIGDIR|INCLUDES|LIBS|SOABI)$") + if (NOT NAME MATCHES "^(PREFIX|ABIFLAGS|CONFIGDIR|INCLUDES|LIBS|SOABI|SOSABI)$") return() endif() - if (_${_PYTHON_PREFIX}_CONFIG) + if (NAME STREQUAL "SOSABI") + # assume some default + if (CMAKE_SYSTEM_NAME STREQUAL "Windows" OR CMAKE_SYSTEM_NAME MATCHES "MSYS|CYGWIN") + set (_values "") + else() + set (_values "abi${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR}") + endif() + elseif (_${_PYTHON_PREFIX}_CONFIG) if (NAME STREQUAL "SOABI") set (config_flag "--extension-suffix") else() @@ -466,7 +492,7 @@ function (_PYTHON_GET_CONFIG_VAR _PYTHON_PGCV_VALUE NAME) list (REMOVE_DUPLICATES _values) elseif (NAME STREQUAL "SOABI") # clean-up: remove prefix character and suffix - if (_values MATCHES "^(\\.${CMAKE_SHARED_LIBRARY_SUFFIX}|\\.so|\\.pyd)$") + if (_values MATCHES "^(${CMAKE_SHARED_LIBRARY_SUFFIX}|\\.so|\\.pyd)$") set(_values "") else() string (REGEX REPLACE "^[.-](.+)(${CMAKE_SHARED_LIBRARY_SUFFIX}|\\.(so|pyd))$" "\\1" _values "${_values}") @@ -505,30 +531,64 @@ function (_PYTHON_GET_CONFIG_VAR _PYTHON_PGCV_VALUE NAME) list (REMOVE_DUPLICATES _values) endif() elseif (NAME STREQUAL "SOABI") + # first step: compute SOABI form EXT_SUFFIX config variable execute_process (COMMAND ${_${_PYTHON_PREFIX}_INTERPRETER_LAUNCHER} "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c - "import sys\ntry:\n from distutils import sysconfig\n sys.stdout.write(';'.join([sysconfig.get_config_var('SOABI') or '',sysconfig.get_config_var('EXT_SUFFIX') or '',sysconfig.get_config_var('SO') or '']))\nexcept Exception:\n import sysconfig;sys.stdout.write(';'.join([sysconfig.get_config_var('SOABI') or '',sysconfig.get_config_var('EXT_SUFFIX') or '',sysconfig.get_config_var('SO') or '']))" + "import sys\ntry:\n from distutils import sysconfig\n sys.stdout.write(sysconfig.get_config_var('EXT_SUFFIX') or '')\nexcept Exception:\n import sysconfig;sys.stdout.write(sysconfig.get_config_var('EXT_SUFFIX') or '')" RESULT_VARIABLE _result - OUTPUT_VARIABLE _soabi + OUTPUT_VARIABLE _values ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) if (_result) unset (_values) else() - foreach (_item IN LISTS _soabi) - if (_item) - set (_values "${_item}") - break() - endif() - endforeach() if (_values) # clean-up: remove prefix character and suffix - if (_values MATCHES "^(\\.${CMAKE_SHARED_LIBRARY_SUFFIX}|\\.so|\\.pyd)$") + if (_values MATCHES "^(${CMAKE_SHARED_LIBRARY_SUFFIX}|\\.so|\\.pyd)$") set(_values "") else() string (REGEX REPLACE "^[.-](.+)(${CMAKE_SHARED_LIBRARY_SUFFIX}|\\.(so|pyd))$" "\\1" _values "${_values}") endif() endif() endif() + + # second step: use SOABI or SO config variables as fallback + if (NOT _values) + execute_process (COMMAND ${_${_PYTHON_PREFIX}_INTERPRETER_LAUNCHER} "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c + "import sys\ntry:\n from distutils import sysconfig\n sys.stdout.write(';'.join([sysconfig.get_config_var('SOABI') or '',sysconfig.get_config_var('SO') or '']))\nexcept Exception:\n import sysconfig;sys.stdout.write(';'.join([sysconfig.get_config_var('SOABI') or '',sysconfig.get_config_var('SO') or '']))" + RESULT_VARIABLE _result + OUTPUT_VARIABLE _soabi + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE) + if (_result) + unset (_values) + else() + foreach (_item IN LISTS _soabi) + if (_item) + set (_values "${_item}") + break() + endif() + endforeach() + if (_values) + # clean-up: remove prefix character and suffix + if (_values MATCHES "^(${CMAKE_SHARED_LIBRARY_SUFFIX}|\\.so|\\.pyd)$") + set(_values "") + else() + string (REGEX REPLACE "^[.-](.+)(${CMAKE_SHARED_LIBRARY_SUFFIX}|\\.(so|pyd))$" "\\1" _values "${_values}") + endif() + endif() + endif() + endif() + elseif (NAME STREQUAL "SOSABI") + execute_process (COMMAND ${_${_PYTHON_PREFIX}_INTERPRETER_LAUNCHER} "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c "import sys\nimport re\nimport importlib\nsys.stdout.write(next(filter(lambda x: re.search('^\\.abi', x), importlib.machinery.EXTENSION_SUFFIXES)))" + RESULT_VARIABLE _result + OUTPUT_VARIABLE _values + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE) + if (_result) + unset (_values) + else() + string (REGEX REPLACE "^\\.(.+)\\.[^.]+$" "\\1" _values "${_values}") + endif() else() set (config_flag "${NAME}") if (NAME STREQUAL "CONFIGDIR") @@ -546,7 +606,7 @@ function (_PYTHON_GET_CONFIG_VAR _PYTHON_PGCV_VALUE NAME) endif() endif() - if (NAME STREQUAL "ABIFLAGS" OR NAME STREQUAL "SOABI") + if (NAME STREQUAL "ABIFLAGS" OR NAME STREQUAL "SOABI" OR NAME STREQUAL "SOSABI") set (${_PYTHON_PGCV_VALUE} "${_values}" PARENT_SCOPE) return() endif() @@ -571,7 +631,7 @@ function (_PYTHON_GET_CONFIG_VAR _PYTHON_PGCV_VALUE NAME) endfunction() function (_PYTHON_GET_VERSION) - cmake_parse_arguments (PARSE_ARGV 0 _PGV "LIBRARY;INCLUDE" "PREFIX" "") + cmake_parse_arguments (PARSE_ARGV 0 _PGV "LIBRARY;SABI_LIBRARY;INCLUDE" "PREFIX" "") unset (${_PGV_PREFIX}VERSION PARENT_SCOPE) unset (${_PGV_PREFIX}VERSION_MAJOR PARENT_SCOPE) @@ -617,6 +677,29 @@ function (_PYTHON_GET_VERSION) set (${_PGV_PREFIX}ABI "" PARENT_SCOPE) endif() endif() + elseif (_PGV_SABI_LIBRARY) + # retrieve version and abi from library name + if (_${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE) + get_filename_component (library_name "${_${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE}" NAME) + # extract version from library name + if (library_name MATCHES "python([23])([dmu]*)") + set (${_PGV_PREFIX}VERSION_MAJOR "${CMAKE_MATCH_1}" PARENT_SCOPE) + set (${_PGV_PREFIX}VERSION "${CMAKE_MATCH_1}" PARENT_SCOPE) + set (${_PGV_PREFIX}ABI "${CMAKE_MATCH_2}" PARENT_SCOPE) + elseif (library_name MATCHES "pypy([23])-c") + set (${_PGV_PREFIX}VERSION_MAJOR "${CMAKE_MATCH_1}" PARENT_SCOPE) + set (${_PGV_PREFIX}VERSION "${CMAKE_MATCH_1}" PARENT_SCOPE) + set (${_PGV_PREFIX}ABI "" PARENT_SCOPE) + elseif (library_name MATCHES "pypy-c") + # try to pick-up a more precise version from the path + get_filename_component (library_dir "${_${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE}" DIRECTORY) + if (library_dir MATCHES "/pypy([23])\\.([0-9]+)/") + set (${_PGV_PREFIX}VERSION_MAJOR "${CMAKE_MATCH_1}" PARENT_SCOPE) + set (${_PGV_PREFIX}VERSION "${CMAKE_MATCH_1}" PARENT_SCOPE) + endif() + set (${_PGV_PREFIX}ABI "" PARENT_SCOPE) + endif() + endif() else() if (_${_PYTHON_PREFIX}_INCLUDE_DIR) # retrieve version from header file @@ -711,7 +794,7 @@ function (_PYTHON_VALIDATE_INTERPRETER) if (_PVI_CHECK_EXISTS AND NOT EXISTS "${_${_PYTHON_PREFIX}_EXECUTABLE}") # interpreter does not exist anymore - set (_${_PYTHON_PREFIX}_Interpreter_REASON_FAILURE "Cannot find the interpreter \"${_${_PYTHON_PREFIX}_EXECUTABLE}\"" PARENT_SCOPE) + set_property (CACHE _${_PYTHON_PREFIX}_Interpreter_REASON_FAILURE PROPERTY VALUE "Cannot find the interpreter \"${_${_PYTHON_PREFIX}_EXECUTABLE}\"") set_property (CACHE _${_PYTHON_PREFIX}_EXECUTABLE PROPERTY VALUE "${_PYTHON_PREFIX}_EXECUTABLE-NOTFOUND") return() endif() @@ -732,7 +815,7 @@ function (_PYTHON_VALIDATE_INTERPRETER) endif() if (NOT abi IN_LIST _${_PYTHON_PREFIX}_ABIFLAGS) # incompatible ABI - set (_${_PYTHON_PREFIX}_Interpreter_REASON_FAILURE "Wrong ABI for the interpreter \"${_${_PYTHON_PREFIX}_EXECUTABLE}\"" PARENT_SCOPE) + set_property (CACHE _${_PYTHON_PREFIX}_Interpreter_REASON_FAILURE PROPERTY VALUE "Wrong ABI for the interpreter \"${_${_PYTHON_PREFIX}_EXECUTABLE}\"") set_property (CACHE _${_PYTHON_PREFIX}_EXECUTABLE PROPERTY VALUE "${_PYTHON_PREFIX}_EXECUTABLE-NOTFOUND") return() endif() @@ -748,7 +831,7 @@ function (_PYTHON_VALIDATE_INTERPRETER) OUTPUT_STRIP_TRAILING_WHITESPACE) if (result) # interpreter is not usable - set (_${_PYTHON_PREFIX}_Interpreter_REASON_FAILURE "Cannot use the interpreter \"${_${_PYTHON_PREFIX}_EXECUTABLE}\"" PARENT_SCOPE) + set_property (CACHE _${_PYTHON_PREFIX}_Interpreter_REASON_FAILURE PROPERTY VALUE "Cannot use the interpreter \"${_${_PYTHON_PREFIX}_EXECUTABLE}\"") set_property (CACHE _${_PYTHON_PREFIX}_EXECUTABLE PROPERTY VALUE "${_PYTHON_PREFIX}_EXECUTABLE-NOTFOUND") return() endif() @@ -773,7 +856,7 @@ function (_PYTHON_VALIDATE_INTERPRETER) if (_PVI_EXACT AND NOT version VERSION_EQUAL _PVI_VERSION) # interpreter has wrong version - set (_${_PYTHON_PREFIX}_Interpreter_REASON_FAILURE "Wrong version for the interpreter \"${_${_PYTHON_PREFIX}_EXECUTABLE}\"" PARENT_SCOPE) + set_property (CACHE _${_PYTHON_PREFIX}_Interpreter_REASON_FAILURE PROPERTY VALUE "Wrong version for the interpreter \"${_${_PYTHON_PREFIX}_EXECUTABLE}\"") set_property (CACHE _${_PYTHON_PREFIX}_EXECUTABLE PROPERTY VALUE "${_PYTHON_PREFIX}_EXECUTABLE-NOTFOUND") return() else() @@ -782,7 +865,7 @@ function (_PYTHON_VALIDATE_INTERPRETER) string(REGEX REPLACE "^([0-9]+)\\.?.*$" "\\1" expected_major_version "${_PVI_VERSION}") if (NOT major_version VERSION_EQUAL expected_major_version OR NOT version VERSION_GREATER_EQUAL _PVI_VERSION) - set (_${_PYTHON_PREFIX}_Interpreter_REASON_FAILURE "Wrong version for the interpreter \"${_${_PYTHON_PREFIX}_EXECUTABLE}\"" PARENT_SCOPE) + set_property (CACHE _${_PYTHON_PREFIX}_Interpreter_REASON_FAILURE PROPERTY VALUE "Wrong version for the interpreter \"${_${_PYTHON_PREFIX}_EXECUTABLE}\"") set_property (CACHE _${_PYTHON_PREFIX}_EXECUTABLE PROPERTY VALUE "${_PYTHON_PREFIX}_EXECUTABLE-NOTFOUND") return() endif() @@ -794,7 +877,7 @@ function (_PYTHON_VALIDATE_INTERPRETER) find_package_check_version ("${version}" in_range HANDLE_VERSION_RANGE) if (NOT in_range) # interpreter has invalid version - set (_${_PYTHON_PREFIX}_Interpreter_REASON_FAILURE "Wrong version for the interpreter \"${_${_PYTHON_PREFIX}_EXECUTABLE}\"" PARENT_SCOPE) + set_property (CACHE _${_PYTHON_PREFIX}_Interpreter_REASON_FAILURE PROPERTY VALUE "Wrong version for the interpreter \"${_${_PYTHON_PREFIX}_EXECUTABLE}\"") set_property (CACHE _${_PYTHON_PREFIX}_EXECUTABLE PROPERTY VALUE "${_PYTHON_PREFIX}_EXECUTABLE-NOTFOUND") return() endif() @@ -813,9 +896,9 @@ function (_PYTHON_VALIDATE_INTERPRETER) if (result OR NOT version EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR) # interpreter not usable or has wrong major version if (result) - set (_${_PYTHON_PREFIX}_Interpreter_REASON_FAILURE "Cannot use the interpreter \"${_${_PYTHON_PREFIX}_EXECUTABLE}\"" PARENT_SCOPE) + set_property (CACHE _${_PYTHON_PREFIX}_Interpreter_REASON_FAILURE PROPERTY VALUE "Cannot use the interpreter \"${_${_PYTHON_PREFIX}_EXECUTABLE}\"") else() - set (_${_PYTHON_PREFIX}_Interpreter_REASON_FAILURE "Wrong major version for the interpreter \"${_${_PYTHON_PREFIX}_EXECUTABLE}\"" PARENT_SCOPE) + set_property (CACHE _${_PYTHON_PREFIX}_Interpreter_REASON_FAILURE PROPERTY VALUE "Wrong major version for the interpreter \"${_${_PYTHON_PREFIX}_EXECUTABLE}\"") endif() set_property (CACHE _${_PYTHON_PREFIX}_EXECUTABLE PROPERTY VALUE "${_PYTHON_PREFIX}_EXECUTABLE-NOTFOUND") return() @@ -824,6 +907,7 @@ function (_PYTHON_VALIDATE_INTERPRETER) endif() if (CMAKE_SIZEOF_VOID_P AND ("Development.Module" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS + OR "Development.SABIModule" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS OR "Development.Embed" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) AND NOT CMAKE_CROSSCOMPILING) # In this case, interpreter must have same architecture as environment @@ -836,9 +920,9 @@ function (_PYTHON_VALIDATE_INTERPRETER) if (result OR NOT size EQUAL CMAKE_SIZEOF_VOID_P) # interpreter not usable or has wrong architecture if (result) - set (_${_PYTHON_PREFIX}_Interpreter_REASON_FAILURE "Cannot use the interpreter \"${_${_PYTHON_PREFIX}_EXECUTABLE}\"" PARENT_SCOPE) + set_property (CACHE _${_PYTHON_PREFIX}_Interpreter_REASON_FAILURE PROPERTY VALUE "Cannot use the interpreter \"${_${_PYTHON_PREFIX}_EXECUTABLE}\"") else() - set (_${_PYTHON_PREFIX}_Interpreter_REASON_FAILURE "Wrong architecture for the interpreter \"${_${_PYTHON_PREFIX}_EXECUTABLE}\"" PARENT_SCOPE) + set_property (CACHE _${_PYTHON_PREFIX}_Interpreter_REASON_FAILURE PROPERTY VALUE "Wrong architecture for the interpreter \"${_${_PYTHON_PREFIX}_EXECUTABLE}\"") endif() set_property (CACHE _${_PYTHON_PREFIX}_EXECUTABLE PROPERTY VALUE "${_PYTHON_PREFIX}_EXECUTABLE-NOTFOUND") return() @@ -846,6 +930,14 @@ function (_PYTHON_VALIDATE_INTERPRETER) endif() endfunction() +function(_python_validate_find_interpreter status interpreter) + set(_${_PYTHON_PREFIX}_EXECUTABLE "${interpreter}" CACHE FILEPATH "" FORCE) + _python_validate_interpreter (${_${_PYTHON_PREFIX}_VALIDATE_OPTIONS}) + if (NOT _${_PYTHON_PREFIX}_EXECUTABLE) + set (${status} FALSE PARENT_SCOPE) + endif() +endfunction() + function (_PYTHON_VALIDATE_COMPILER) if (NOT _${_PYTHON_PREFIX}_COMPILER) @@ -856,7 +948,7 @@ function (_PYTHON_VALIDATE_COMPILER) if (_PVC_CHECK_EXISTS AND NOT EXISTS "${_${_PYTHON_PREFIX}_COMPILER}") # Compiler does not exist anymore - set (_${_PYTHON_PREFIX}_Compiler_REASON_FAILURE "Cannot find the compiler \"${_${_PYTHON_PREFIX}_COMPILER}\"" PARENT_SCOPE) + set_property (CACHE _${_PYTHON_PREFIX}_Compiler_REASON_FAILURE PROPERTY VALUE "Cannot find the compiler \"${_${_PYTHON_PREFIX}_COMPILER}\"") set_property (CACHE _${_PYTHON_PREFIX}_COMPILER PROPERTY VALUE "${_PYTHON_PREFIX}_COMPILER-NOTFOUND") return() endif() @@ -883,7 +975,7 @@ function (_PYTHON_VALIDATE_COMPILER) file (REMOVE_RECURSE "${working_dir}") if (result) # compiler is not usable - set (_${_PYTHON_PREFIX}_Compiler_REASON_FAILURE "Cannot use the compiler \"${_${_PYTHON_PREFIX}_COMPILER}\"" PARENT_SCOPE) + set_property (CACHE _${_PYTHON_PREFIX}_Compiler_REASON_FAILURE PROPERTY VALUE "Cannot use the compiler \"${_${_PYTHON_PREFIX}_COMPILER}\"") set_property (CACHE _${_PYTHON_PREFIX}_COMPILER PROPERTY VALUE "${_PYTHON_PREFIX}_COMPILER-NOTFOUND") return() endif() @@ -909,7 +1001,7 @@ function (_PYTHON_VALIDATE_COMPILER) if (_PVC_EXACT AND NOT version VERSION_EQUAL _PVC_VERSION) # interpreter has wrong version - set (_${_PYTHON_PREFIX}_Compiler_REASON_FAILURE "Wrong version for the compiler \"${_${_PYTHON_PREFIX}_COMPILER}\"" PARENT_SCOPE) + set_property (CACHE _${_PYTHON_PREFIX}_Compiler_REASON_FAILURE PROPERTY VALUE "Wrong version for the compiler \"${_${_PYTHON_PREFIX}_COMPILER}\"") set_property (CACHE _${_PYTHON_PREFIX}_COMPILER PROPERTY VALUE "${_PYTHON_PREFIX}_COMPILER-NOTFOUND") return() else() @@ -918,7 +1010,7 @@ function (_PYTHON_VALIDATE_COMPILER) string(REGEX REPLACE "^([0-9]+)\\.?.*$" "\\1" expected_major_version "${_PVC_VERSION}") if (NOT major_version VERSION_EQUAL expected_major_version OR NOT version VERSION_GREATER_EQUAL _PVC_VERSION) - set (_${_PYTHON_PREFIX}_Compiler_REASON_FAILURE "Wrong version for the compiler \"${_${_PYTHON_PREFIX}_COMPILER}\"" PARENT_SCOPE) + set_property (CACHE _${_PYTHON_PREFIX}_Compiler_REASON_FAILURE PROPERTY VALUE "Wrong version for the compiler \"${_${_PYTHON_PREFIX}_COMPILER}\"") set_property (CACHE _${_PYTHON_PREFIX}_COMPILER PROPERTY VALUE "${_PYTHON_PREFIX}_COMPILER-NOTFOUND") return() endif() @@ -930,7 +1022,7 @@ function (_PYTHON_VALIDATE_COMPILER) find_package_check_version ("${version}" in_range HANDLE_VERSION_RANGE) if (NOT in_range) # interpreter has invalid version - set (_${_PYTHON_PREFIX}_Compiler_REASON_FAILURE "Wrong version for the compiler \"${_${_PYTHON_PREFIX}_COMPILER}\"" PARENT_SCOPE) + set_property (CACHE _${_PYTHON_PREFIX}_Compiler_REASON_FAILURE PROPERTY VALUE "Wrong version for the compiler \"${_${_PYTHON_PREFIX}_COMPILER}\"") set_property (CACHE _${_PYTHON_PREFIX}_COMPILER PROPERTY VALUE "${_PYTHON_PREFIX}_COMPILER-NOTFOUND") return() endif() @@ -939,13 +1031,21 @@ function (_PYTHON_VALIDATE_COMPILER) string(REGEX REPLACE "^([0-9]+)\\.?.*$" "\\1" major_version "${version}") if (NOT major_version EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR) # Compiler has wrong major version - set (_${_PYTHON_PREFIX}_Compiler_REASON_FAILURE "Wrong major version for the compiler \"${_${_PYTHON_PREFIX}_COMPILER}\"" PARENT_SCOPE) + set_property (CACHE _${_PYTHON_PREFIX}_Compiler_REASON_FAILURE PROPERTY VALUE "Wrong major version for the compiler \"${_${_PYTHON_PREFIX}_COMPILER}\"") set_property (CACHE _${_PYTHON_PREFIX}_COMPILER PROPERTY VALUE "${_PYTHON_PREFIX}_COMPILER-NOTFOUND") return() endif() endif() endfunction() +function(_python_validate_find_compiler status compiler) + set(_${_PYTHON_PREFIX}_COMPILER "${compiler}" CACHE FILEPATH "" FORCE) + _python_validate_compiler (${_${_PYTHON_PREFIX}_VALIDATE_OPTIONS}) + if (NOT _${_PYTHON_PREFIX}_COMPILER) + set (${status} FALSE PARENT_SCOPE) + endif() +endfunction() + function (_PYTHON_VALIDATE_LIBRARY) if (NOT _${_PYTHON_PREFIX}_LIBRARY_RELEASE) @@ -957,7 +1057,7 @@ function (_PYTHON_VALIDATE_LIBRARY) if (_PVL_CHECK_EXISTS AND NOT EXISTS "${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}") # library does not exist anymore - set (_${_PYTHON_PREFIX}_Development_REASON_FAILURE "Cannot find the library \"${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}\"" PARENT_SCOPE) + set_property (CACHE _${_PYTHON_PREFIX}_Development_LIBRARY_REASON_FAILURE PROPERTY VALUE "Cannot find the library \"${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}\"") set_property (CACHE _${_PYTHON_PREFIX}_LIBRARY_RELEASE PROPERTY VALUE "${_PYTHON_PREFIX}_LIBRARY_RELEASE-NOTFOUND") if (WIN32) set_property (CACHE _${_PYTHON_PREFIX}_LIBRARY_DEBUG PROPERTY VALUE "${_PYTHON_PREFIX}_LIBRARY_DEBUG-NOTFOUND") @@ -971,7 +1071,7 @@ function (_PYTHON_VALIDATE_LIBRARY) if (DEFINED _${_PYTHON_PREFIX}_FIND_ABI AND NOT lib_ABI IN_LIST _${_PYTHON_PREFIX}_ABIFLAGS) # incompatible ABI - set (_${_PYTHON_PREFIX}_Development_REASON_FAILURE "Wrong ABI for the library \"${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}\"" PARENT_SCOPE) + set_property (CACHE _${_PYTHON_PREFIX}_Development_LIBRARY_REASON_FAILURE PROPERTY VALUE "Wrong ABI for the library \"${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}\"") set_property (CACHE _${_PYTHON_PREFIX}_LIBRARY_RELEASE PROPERTY VALUE "${_PYTHON_PREFIX}_LIBRARY_RELEASE-NOTFOUND") else() if (_PVL_VERSION OR _PVL_IN_RANGE) @@ -980,7 +1080,7 @@ function (_PYTHON_VALIDATE_LIBRARY) string (REGEX MATCH "[0-9](\\.[0-9]+)?" version "${_PVL_VERSION}") if ((_PVL_EXACT AND NOT lib_VERSION VERSION_EQUAL version) OR (lib_VERSION VERSION_LESS version)) # library has wrong version - set (_${_PYTHON_PREFIX}_Development_REASON_FAILURE "Wrong version for the library \"${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}\"" PARENT_SCOPE) + set_property (CACHE _${_PYTHON_PREFIX}_Development_LIBRARY_REASON_FAILURE PROPERTY VALUE "Wrong version for the library \"${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}\"") set_property (CACHE _${_PYTHON_PREFIX}_LIBRARY_RELEASE PROPERTY VALUE "${_PYTHON_PREFIX}_LIBRARY_RELEASE-NOTFOUND") endif() endif() @@ -990,14 +1090,14 @@ function (_PYTHON_VALIDATE_LIBRARY) find_package_check_version ("${lib_VERSION}" in_range HANDLE_VERSION_RANGE) if (NOT in_range) # library has wrong version - set (_${_PYTHON_PREFIX}_Development_REASON_FAILURE "Wrong version for the library \"${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}\"" PARENT_SCOPE) + set_property (CACHE _${_PYTHON_PREFIX}_Development_LIBRARY_REASON_FAILURE PROPERTY VALUE "Wrong version for the library \"${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}\"") set_property (CACHE _${_PYTHON_PREFIX}_LIBRARY_RELEASE PROPERTY VALUE "${_PYTHON_PREFIX}_LIBRARY_RELEASE-NOTFOUND") endif() endif() else() if (NOT lib_VERSION_MAJOR VERSION_EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR) # library has wrong major version - set (_${_PYTHON_PREFIX}_Development_REASON_FAILURE "Wrong major version for the library \"${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}\"" PARENT_SCOPE) + set_property (CACHE _${_PYTHON_PREFIX}_Development_LIBRARY_REASON_FAILURE PROPERTY VALUE "Wrong major version for the library \"${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}\"") set_property (CACHE _${_PYTHON_PREFIX}_LIBRARY_RELEASE PROPERTY VALUE "${_PYTHON_PREFIX}_LIBRARY_RELEASE-NOTFOUND") endif() endif() @@ -1014,6 +1114,51 @@ function (_PYTHON_VALIDATE_LIBRARY) endfunction() +function (_PYTHON_VALIDATE_SABI_LIBRARY) + if (NOT _${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE) + unset (_${_PYTHON_PREFIX}_SABI_LIBRARY_DEBUG) + return() + endif() + + cmake_parse_arguments (PARSE_ARGV 0 _PVL "CHECK_EXISTS" "" "") + + if (_PVL_CHECK_EXISTS AND NOT EXISTS "${_${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE}") + # library does not exist anymore + set_property (CACHE _${_PYTHON_PREFIX}_Development_SABI_LIBRARY_REASON_FAILURE PROPERTY VALUE "Cannot find the library \"${_${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE}\"") + set_property (CACHE _${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE PROPERTY VALUE "${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE-NOTFOUND") + if (WIN32) + set_property (CACHE _${_PYTHON_PREFIX}_SABI_LIBRARY_DEBUG PROPERTY VALUE "${_PYTHON_PREFIX}_SABI_LIBRARY_DEBUG-NOTFOUND") + endif() + set_property (CACHE _${_PYTHON_PREFIX}_INCLUDE_DIR PROPERTY VALUE "${_PYTHON_PREFIX}_INCLUDE_DIR-NOTFOUND") + return() + endif() + + # retrieve version and abi from library name + _python_get_version (SABI_LIBRARY PREFIX lib_) + + if (DEFINED _${_PYTHON_PREFIX}_FIND_ABI AND NOT lib_ABI IN_LIST _${_PYTHON_PREFIX}_ABIFLAGS) + # incompatible ABI + set_property (CACHE _${_PYTHON_PREFIX}_Development_SABI_LIBRARY_REASON_FAILURE PROPERTY VALUE "Wrong ABI for the library \"${_${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE}\"") + set_property (CACHE _${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE PROPERTY VALUE "${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE-NOTFOUND") + else() + if (NOT lib_VERSION_MAJOR VERSION_EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR) + # library has wrong major version + set_property (CACHE _${_PYTHON_PREFIX}_Development_SABI_LIBRARY_REASON_FAILURE PROPERTY VALUE "Wrong major version for the library \"${_${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE}\"") + set_property (CACHE _${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE PROPERTY VALUE "${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE-NOTFOUND") + endif() + endif() + + if (NOT _${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE) + if (WIN32) + set_property (CACHE _${_PYTHON_PREFIX}_SABI_LIBRARY_DEBUG PROPERTY VALUE "${_PYTHON_PREFIX}_LIBRARY_DEBUG-NOTFOUND") + endif() + unset (_${_PYTHON_PREFIX}_RUNTIME_SABI_LIBRARY_RELEASE CACHE) + unset (_${_PYTHON_PREFIX}_RUNTIME_SABI_LIBRARY_DEBUG CACHE) + set_property (CACHE _${_PYTHON_PREFIX}_INCLUDE_DIR PROPERTY VALUE "${_PYTHON_PREFIX}_INCLUDE_DIR-NOTFOUND") + endif() +endfunction() + + function (_PYTHON_VALIDATE_INCLUDE_DIR) if (NOT _${_PYTHON_PREFIX}_INCLUDE_DIR) return() @@ -1023,7 +1168,7 @@ function (_PYTHON_VALIDATE_INCLUDE_DIR) if (_PVID_CHECK_EXISTS AND NOT EXISTS "${_${_PYTHON_PREFIX}_INCLUDE_DIR}") # include file does not exist anymore - set (_${_PYTHON_PREFIX}_Development_REASON_FAILURE "Cannot find the directory \"${_${_PYTHON_PREFIX}_INCLUDE_DIR}\"" PARENT_SCOPE) + set_property (CACHE _${_PYTHON_PREFIX}_Development_INCLUDE_DIR_REASON_FAILURE PROPERTY VALUE "Cannot find the directory \"${_${_PYTHON_PREFIX}_INCLUDE_DIR}\"") set_property (CACHE _${_PYTHON_PREFIX}_INCLUDE_DIR PROPERTY VALUE "${_PYTHON_PREFIX}_INCLUDE_DIR-NOTFOUND") return() endif() @@ -1033,14 +1178,14 @@ function (_PYTHON_VALIDATE_INCLUDE_DIR) if (DEFINED _${_PYTHON_PREFIX}_FIND_ABI AND NOT inc_ABI IN_LIST _${_PYTHON_PREFIX}_ABIFLAGS) # incompatible ABI - set (_${_PYTHON_PREFIX}_Development_REASON_FAILURE "Wrong ABI for the directory \"${_${_PYTHON_PREFIX}_INCLUDE_DIR}\"" PARENT_SCOPE) + set_property (CACHE _${_PYTHON_PREFIX}_Development_INCLUDE_DIR_REASON_FAILURE PROPERTY VALUE "Wrong ABI for the directory \"${_${_PYTHON_PREFIX}_INCLUDE_DIR}\"") set_property (CACHE _${_PYTHON_PREFIX}_INCLUDE_DIR PROPERTY VALUE "${_PYTHON_PREFIX}_INCLUDE_DIR-NOTFOUND") else() if (_PVID_VERSION OR _PVID_IN_RANGE) if (_PVID_VERSION) if ((_PVID_EXACT AND NOT inc_VERSION VERSION_EQUAL expected_version) OR (inc_VERSION VERSION_LESS expected_version)) # include dir has wrong version - set (_${_PYTHON_PREFIX}_Development_REASON_FAILURE "Wrong version for the directory \"${_${_PYTHON_PREFIX}_INCLUDE_DIR}\"" PARENT_SCOPE) + set_property (CACHE _${_PYTHON_PREFIX}_Development_INCLUDE_DIR_REASON_FAILURE PROPERTY VALUE "Wrong version for the directory \"${_${_PYTHON_PREFIX}_INCLUDE_DIR}\"") set_property (CACHE _${_PYTHON_PREFIX}_INCLUDE_DIR PROPERTY VALUE "${_PYTHON_PREFIX}_INCLUDE_DIR-NOTFOUND") endif() endif() @@ -1050,14 +1195,14 @@ function (_PYTHON_VALIDATE_INCLUDE_DIR) find_package_check_version ("${inc_VERSION}" in_range HANDLE_VERSION_RANGE) if (NOT in_range) # include dir has wrong version - set (_${_PYTHON_PREFIX}_Development_REASON_FAILURE "Wrong version for the directory \"${_${_PYTHON_PREFIX}_INCLUDE_DIR}\"" PARENT_SCOPE) + set_property (CACHE _${_PYTHON_PREFIX}_Development_INCLUDE_DIR_REASON_FAILURE PROPERTY VALUE "Wrong version for the directory \"${_${_PYTHON_PREFIX}_INCLUDE_DIR}\"") set_property (CACHE _${_PYTHON_PREFIX}_INCLUDE_DIR PROPERTY VALUE "${_PYTHON_PREFIX}_INCLUDE_DIR-NOTFOUND") endif() endif() else() if (NOT inc_VERSION_MAJOR VERSION_EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR) # include dir has wrong major version - set (_${_PYTHON_PREFIX}_Development_REASON_FAILURE "Wrong major version for the directory \"${_${_PYTHON_PREFIX}_INCLUDE_DIR}\"" PARENT_SCOPE) + set_property (CACHE _${_PYTHON_PREFIX}_Development_INCLUDE_DIR_REASON_FAILURE PROPERTY VALUE "Wrong major version for the directory \"${_${_PYTHON_PREFIX}_INCLUDE_DIR}\"") set_property (CACHE _${_PYTHON_PREFIX}_INCLUDE_DIR PROPERTY VALUE "${_PYTHON_PREFIX}_INCLUDE_DIR-NOTFOUND") endif() endif() @@ -1097,6 +1242,14 @@ endfunction() function (_PYTHON_SET_DEVELOPMENT_MODULE_FOUND module) if ("Development.${module}" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) + if (module STREQUAL "SABIModule" + AND "${_${_PYTHON_PREFIX}_VERSION_MAJOR}.${_${_PYTHON_PREFIX}_VERSION_MINOR}" VERSION_LESS "3.2") + # Stable API was introduced in version 3.2 + set (${_PYTHON_PREFIX}_Development.SABIModule_FOUND FALSE PARENT_SCOPE) + _python_add_reason_failure ("Development" "SABIModule requires version 3.2 or upper.") + return() + endif() + string(TOUPPER "${module}" id) set (module_found TRUE) @@ -1104,6 +1257,10 @@ function (_PYTHON_SET_DEVELOPMENT_MODULE_FOUND module) AND NOT _${_PYTHON_PREFIX}_LIBRARY_RELEASE) set (module_found FALSE) endif() + if ("SABI_LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_${id}_ARTIFACTS + AND NOT _${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE) + set (module_found FALSE) + endif() if ("INCLUDE_DIR" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_${id}_ARTIFACTS AND NOT _${_PYTHON_PREFIX}_INCLUDE_DIR) set (module_found FALSE) @@ -1150,7 +1307,7 @@ if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) list (APPEND ${_PYTHON_PREFIX}_FIND_COMPONENTS "Development.Module" "Development.Embed") endif() list (REMOVE_DUPLICATES ${_PYTHON_PREFIX}_FIND_COMPONENTS) -foreach (_${_PYTHON_PREFIX}_COMPONENT IN ITEMS Interpreter Compiler Development Development.Module Development.Embed NumPy) +foreach (_${_PYTHON_PREFIX}_COMPONENT IN ITEMS Interpreter Compiler Development Development.Module Development.SABIModule Development.Embed NumPy) set (${_PYTHON_PREFIX}_${_${_PYTHON_PREFIX}_COMPONENT}_FOUND FALSE) endforeach() if (${_PYTHON_PREFIX}_FIND_REQUIRED_Development) @@ -1160,6 +1317,7 @@ endif() unset (_${_PYTHON_PREFIX}_FIND_DEVELOPMENT_ARTIFACTS) unset (_${_PYTHON_PREFIX}_FIND_DEVELOPMENT_MODULE_ARTIFACTS) +unset (_${_PYTHON_PREFIX}_FIND_DEVELOPMENT_SABIMODULE_ARTIFACTS) unset (_${_PYTHON_PREFIX}_FIND_DEVELOPMENT_EMBED_ARTIFACTS) if ("Development.Module" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) if (CMAKE_SYSTEM_NAME MATCHES "^(Windows.*|CYGWIN|MSYS)$") @@ -1167,10 +1325,16 @@ if ("Development.Module" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) endif() list (APPEND _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_MODULE_ARTIFACTS "INCLUDE_DIR") endif() +if ("Development.SABIModule" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) + if (CMAKE_SYSTEM_NAME MATCHES "^(Windows.*|CYGWIN|MSYS)$") + list (APPEND _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_SABIMODULE_ARTIFACTS "SABI_LIBRARY") + endif() + list (APPEND _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_SABIMODULE_ARTIFACTS "INCLUDE_DIR") +endif() if ("Development.Embed" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) list (APPEND _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_EMBED_ARTIFACTS "LIBRARY" "INCLUDE_DIR") endif() -set (_${_PYTHON_PREFIX}_FIND_DEVELOPMENT_ARTIFACTS ${_${_PYTHON_PREFIX}_FIND_DEVELOPMENT_MODULE_ARTIFACTS} ${_${_PYTHON_PREFIX}_FIND_DEVELOPMENT_EMBED_ARTIFACTS}) +set (_${_PYTHON_PREFIX}_FIND_DEVELOPMENT_ARTIFACTS ${_${_PYTHON_PREFIX}_FIND_DEVELOPMENT_MODULE_ARTIFACTS} ${_${_PYTHON_PREFIX}_FIND_DEVELOPMENT_SABIMODULE_ARTIFACTS} ${_${_PYTHON_PREFIX}_FIND_DEVELOPMENT_EMBED_ARTIFACTS}) list (REMOVE_DUPLICATES _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_ARTIFACTS) # Set versions to search @@ -1229,6 +1393,7 @@ else() endif() endif() unset (${_PYTHON_PREFIX}_SOABI) +unset (${_PYTHON_PREFIX}_SOSABI) # Define lookup strategy cmake_policy (GET CMP0094 _${_PYTHON_PREFIX}_LOOKUP_POLICY) @@ -1247,10 +1412,22 @@ if (DEFINED ${_PYTHON_PREFIX}_FIND_STRATEGY) endif() # Python and Anaconda distributions: define which architectures can be used +unset (_${_PYTHON_PREFIX}_REGISTRY_VIEW) if (CMAKE_SIZEOF_VOID_P) - # In this case, search only for 64bit or 32bit math (EXPR _${_PYTHON_PREFIX}_ARCH "${CMAKE_SIZEOF_VOID_P} * 8") - set (_${_PYTHON_PREFIX}_ARCH2 ${_${_PYTHON_PREFIX}_ARCH}) + if ("Development.Module" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS + OR "Development.SABIModule" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS + OR "Development.Embed" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) + # In this case, search only for 64bit or 32bit + set (_${_PYTHON_PREFIX}_ARCH2 ${_${_PYTHON_PREFIX}_ARCH}) + set (_${_PYTHON_PREFIX}_REGISTRY_VIEW REGISTRY_VIEW ${_${_PYTHON_PREFIX}_ARCH}) + else() + if (_${_PYTHON_PREFIX}_ARCH EQUAL "32") + set (_${_PYTHON_PREFIX}_ARCH2 64) + else() + set (_${_PYTHON_PREFIX}_ARCH2 32) + endif() + endif() else() # architecture unknown, search for both 64bit and 32bit set (_${_PYTHON_PREFIX}_ARCH 64) @@ -1430,6 +1607,9 @@ function (_PYTHON_CHECK_DEVELOPMENT_SIGNATURE module) if ("LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_${id}_ARTIFACTS) list (APPEND signature "${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}:") endif() + if ("SABI_LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_${id}_ARTIFACTS) + list (APPEND signature "${_${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE}:") + endif() if ("INCLUDE_DIR" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_${id}_ARTIFACTS) list (APPEND signature "${_${_PYTHON_PREFIX}_INCLUDE_DIR}:") endif() @@ -1446,6 +1626,9 @@ function (_PYTHON_CHECK_DEVELOPMENT_SIGNATURE module) _python_validate_library (CHECK_EXISTS) endif() endif() + if ("SABI_LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_${id}_ARTIFACTS) + _python_validate_sabi_library (CHECK_EXISTS) + endif() if ("INCLUDE_DIR" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_${id}_ARTIFACTS) if (${_PYTHON_PREFIX}_FIND_VERSION_EXACT) _python_validate_include_dir (VERSION ${${_PYTHON_PREFIX}_FIND_VERSION} EXACT CHECK_EXISTS) @@ -1462,12 +1645,18 @@ function (_PYTHON_CHECK_DEVELOPMENT_SIGNATURE module) unset (_${_PYTHON_PREFIX}_LIBRARY_RELEASE CACHE) unset (_${_PYTHON_PREFIX}_LIBRARY_DEBUG CACHE) endif() + if ("SABI_LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_${id}_ARTIFACTS) + unset (_${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE CACHE) + unset (_${_PYTHON_PREFIX}_SABI_LIBRARY_DEBUG CACHE) + endif() if ("INCLUDE_DIR" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_${id}_ARTIFACTS) unset (_${_PYTHON_PREFIX}_INCLUDE_DIR CACHE) endif() endif() if (("LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_${id}_ARTIFACTS AND NOT _${_PYTHON_PREFIX}_LIBRARY_RELEASE) + OR ("SABI_LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_${id}_ARTIFACTS + AND NOT _${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE) OR ("INCLUDE_DIR" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_${id}_ARTIFACTS AND NOT _${_PYTHON_PREFIX}_INCLUDE_DIR)) unset (_${_PYTHON_PREFIX}_CONFIG CACHE) @@ -1483,6 +1672,9 @@ function (_PYTHON_COMPUTE_DEVELOPMENT_SIGNATURE module) if ("LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_${id}_ARTIFACTS) list (APPEND signature "${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}:") endif() + if ("SABI_LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_${id}_ARTIFACTS) + list (APPEND signature "${_${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE}:") + endif() if ("INCLUDE_DIR" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_${id}_ARTIFACTS) list (APPEND signature "${_${_PYTHON_PREFIX}_INCLUDE_DIR}:") endif() @@ -1493,13 +1685,20 @@ function (_PYTHON_COMPUTE_DEVELOPMENT_SIGNATURE module) endif() endfunction() - unset (_${_PYTHON_PREFIX}_REQUIRED_VARS) unset (_${_PYTHON_PREFIX}_CACHED_VARS) unset (_${_PYTHON_PREFIX}_Interpreter_REASON_FAILURE) +set (_${_PYTHON_PREFIX}_Interpreter_REASON_FAILURE CACHE INTERNAL "Interpreter reason failure") unset (_${_PYTHON_PREFIX}_Compiler_REASON_FAILURE) +set (_${_PYTHON_PREFIX}_Compiler_REASON_FAILURE CACHE INTERNAL "Compiler reason failure") +foreach (artifact IN LISTS _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_ARTIFACTS) + unset (_${_PYTHON_PREFIX}_Development_${artifact}_REASON_FAILURE) + set (_${_PYTHON_PREFIX}_Development_${artifact}_REASON_FAILURE CACHE INTERNAL "Development ${artifact} reason failure") +endforeach() unset (_${_PYTHON_PREFIX}_Development_REASON_FAILURE) +set (_${_PYTHON_PREFIX}_Development_REASON_FAILURE CACHE INTERNAL "Development reason failure") unset (_${_PYTHON_PREFIX}_NumPy_REASON_FAILURE) +set (_${_PYTHON_PREFIX}_NumPy_REASON_FAILURE CACHE INTERNAL "NumPy reason failure") # preamble @@ -1581,9 +1780,8 @@ if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) NO_CMAKE_PATH NO_CMAKE_ENVIRONMENT_PATH NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - - _python_validate_interpreter (${_${_PYTHON_PREFIX}_VALIDATE_OPTIONS}) + NO_CMAKE_SYSTEM_PATH + VALIDATOR _python_validate_find_interpreter) if (_${_PYTHON_PREFIX}_EXECUTABLE) break() endif() @@ -1603,8 +1801,8 @@ if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) NO_CMAKE_PATH NO_CMAKE_ENVIRONMENT_PATH NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - _python_validate_interpreter (${${_PYTHON_PREFIX}_VALIDATE_OPTIONS}) + NO_CMAKE_SYSTEM_PATH + VALIDATOR _python_validate_find_interpreter) if (_${_PYTHON_PREFIX}_EXECUTABLE) break() endif() @@ -1617,9 +1815,10 @@ if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) HINTS ${_${_PYTHON_PREFIX}_HINTS} PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS} PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES} + ${_${_PYTHON_PREFIX}_REGISTRY_VIEW} NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - _python_validate_interpreter (${${_PYTHON_PREFIX}_VALIDATE_OPTIONS}) + NO_CMAKE_SYSTEM_PATH + VALIDATOR _python_validate_find_interpreter) if (_${_PYTHON_PREFIX}_EXECUTABLE) break() endif() @@ -1632,8 +1831,8 @@ if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) HINTS ${_${_PYTHON_PREFIX}_HINTS} PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES} NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - _python_validate_interpreter (${${_PYTHON_PREFIX}_VALIDATE_OPTIONS}) + NO_CMAKE_SYSTEM_PATH + VALIDATOR _python_validate_find_interpreter) if (_${_PYTHON_PREFIX}_EXECUTABLE) break() endif() @@ -1641,8 +1840,8 @@ if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) find_program (_${_PYTHON_PREFIX}_EXECUTABLE NAMES ${_${_PYTHON_PREFIX}_NAMES} NAMES_PER_DIR - PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}) - _python_validate_interpreter (${${_PYTHON_PREFIX}_VALIDATE_OPTIONS}) + PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES} + VALIDATOR _python_validate_find_interpreter) if (_${_PYTHON_PREFIX}_EXECUTABLE) break() endif() @@ -1654,8 +1853,8 @@ if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) NAMES_PER_DIR PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS} PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES} - NO_DEFAULT_PATH) - _python_validate_interpreter (${${_PYTHON_PREFIX}_VALIDATE_OPTIONS}) + NO_DEFAULT_PATH + VALIDATOR _python_validate_find_interpreter) if (_${_PYTHON_PREFIX}_EXECUTABLE) break() endif() @@ -1667,8 +1866,9 @@ if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) NAMES_PER_DIR PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS} PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES} - NO_DEFAULT_PATH) - _python_validate_interpreter (${${_PYTHON_PREFIX}_VALIDATE_OPTIONS}) + ${_${_PYTHON_PREFIX}_REGISTRY_VIEW} + NO_DEFAULT_PATH + VALIDATOR _python_validate_find_interpreter) if (_${_PYTHON_PREFIX}_EXECUTABLE) break() endif() @@ -1678,9 +1878,9 @@ if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) endwhile() else() # look-up for various versions and locations - set (_${_PYTHON_PREFIX}_VALIDATE_OPTIONS EXACT) + set (_${_PYTHON_PREFIX}_COMMON_VALIDATE_OPTIONS EXACT) if (${_PYTHON_PREFIX}_FIND_VERSION_RANGE) - list (APPEND _${_PYTHON_PREFIX}_VALIDATE_OPTIONS IN_RANGE) + list (APPEND _${_PYTHON_PREFIX}_COMMON_VALIDATE_OPTIONS IN_RANGE) endif() foreach (_${_PYTHON_PREFIX}_VERSION IN LISTS _${_PYTHON_PREFIX}_FIND_VERSIONS) @@ -1689,6 +1889,7 @@ if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) _python_get_frameworks (_${_PYTHON_PREFIX}_FRAMEWORK_PATHS VERSION ${_${_PYTHON_PREFIX}_VERSION}) _python_get_registries (_${_PYTHON_PREFIX}_REGISTRY_PATHS VERSION ${_${_PYTHON_PREFIX}_VERSION}) + set (_${_PYTHON_PREFIX}_VALIDATE_OPTIONS VERSION ${_${_PYTHON_PREFIX}_VERSION} ${_${_PYTHON_PREFIX}_COMMON_VALIDATE_OPTIONS}) # Virtual environments handling if (_${_PYTHON_PREFIX}_FIND_VIRTUALENV MATCHES "^(FIRST|ONLY)$") @@ -1701,8 +1902,8 @@ if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) NO_CMAKE_PATH NO_CMAKE_ENVIRONMENT_PATH NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - _python_validate_interpreter (VERSION ${_${_PYTHON_PREFIX}_VERSION} ${_${_PYTHON_PREFIX}_VALIDATE_OPTIONS}) + NO_CMAKE_SYSTEM_PATH + VALIDATOR _python_validate_find_interpreter) if (_${_PYTHON_PREFIX}_EXECUTABLE) break() endif() @@ -1722,7 +1923,8 @@ if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) NO_CMAKE_PATH NO_CMAKE_ENVIRONMENT_PATH NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) + NO_CMAKE_SYSTEM_PATH + VALIDATOR _python_validate_find_interpreter) endif() # Windows registry @@ -1733,11 +1935,12 @@ if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) HINTS ${_${_PYTHON_PREFIX}_HINTS} PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS} PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES} + ${_${_PYTHON_PREFIX}_REGISTRY_VIEW} NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) + NO_CMAKE_SYSTEM_PATH + VALIDATOR _python_validate_find_interpreter) endif() - _python_validate_interpreter (VERSION ${_${_PYTHON_PREFIX}_VERSION} ${_${_PYTHON_PREFIX}_VALIDATE_OPTIONS}) if (_${_PYTHON_PREFIX}_EXECUTABLE) break() endif() @@ -1749,21 +1952,18 @@ if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) HINTS ${_${_PYTHON_PREFIX}_HINTS} PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES} NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - _python_validate_interpreter (VERSION ${_${_PYTHON_PREFIX}_VERSION} ${_${_PYTHON_PREFIX}_VALIDATE_OPTIONS}) + NO_CMAKE_SYSTEM_PATH + VALIDATOR _python_validate_find_interpreter) if (_${_PYTHON_PREFIX}_EXECUTABLE) break() endif() + # try using standard paths. - # NAMES_PER_DIR is not defined on purpose to have a chance to find - # expected version. - # For example, typical systems have 'python' for version 2.* and 'python3' - # for version 3.*. So looking for names per dir will find, potentially, - # systematically 'python' (i.e. version 2) even if version 3 is searched. find_program (_${_PYTHON_PREFIX}_EXECUTABLE NAMES ${_${_PYTHON_PREFIX}_NAMES} - PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}) - _python_validate_interpreter (VERSION ${_${_PYTHON_PREFIX}_VERSION} ${_${_PYTHON_PREFIX}_VALIDATE_OPTIONS}) + NAMES_PER_DIR + PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES} + VALIDATOR _python_validate_find_interpreter) if (_${_PYTHON_PREFIX}_EXECUTABLE) break() endif() @@ -1775,7 +1975,8 @@ if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) NAMES_PER_DIR PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS} PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES} - NO_DEFAULT_PATH) + NO_DEFAULT_PATH + VALIDATOR _python_validate_find_interpreter) endif() # Windows registry @@ -1785,10 +1986,11 @@ if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) NAMES_PER_DIR PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS} PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES} - NO_DEFAULT_PATH) + ${_${_PYTHON_PREFIX}_REGISTRY_VIEW} + NO_DEFAULT_PATH + VALIDATOR _python_validate_find_interpreter) endif() - _python_validate_interpreter (VERSION ${_${_PYTHON_PREFIX}_VERSION} ${_${_PYTHON_PREFIX}_VALIDATE_OPTIONS}) if (_${_PYTHON_PREFIX}_EXECUTABLE) break() endif() @@ -1797,15 +1999,12 @@ if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) if (NOT _${_PYTHON_PREFIX}_EXECUTABLE AND NOT _${_PYTHON_PREFIX}_FIND_VIRTUALENV STREQUAL "ONLY") # No specific version found. Retry with generic names and standard paths. - # NAMES_PER_DIR is not defined on purpose to have a chance to find - # expected version. - # For example, typical systems have 'python' for version 2.* and 'python3' - # for version 3.*. So looking for names per dir will find, potentially, - # systematically 'python' (i.e. version 2) even if version 3 is searched. _python_get_names (_${_PYTHON_PREFIX}_NAMES POSIX INTERPRETER) + unset (_${_PYTHON_PREFIX}_VALIDATE_OPTIONS) find_program (_${_PYTHON_PREFIX}_EXECUTABLE - NAMES ${_${_PYTHON_PREFIX}_NAMES}) - _python_validate_interpreter () + NAMES ${_${_PYTHON_PREFIX}_NAMES} + NAMES_PER_DIR + VALIDATOR _python_validate_find_interpreter) endif() endif() endif() @@ -1827,11 +2026,18 @@ if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) # Interpreter is not usable set (_${_PYTHON_PREFIX}_EXECUTABLE_USABLE FALSE) unset (${_PYTHON_PREFIX}_VERSION) - set (_${_PYTHON_PREFIX}_Interpreter_REASON_FAILURE "Cannot run the interpreter \"${_${_PYTHON_PREFIX}_EXECUTABLE}\"") + set_property (CACHE _${_PYTHON_PREFIX}_Interpreter_REASON_FAILURE PROPERTY VALUE "Cannot run the interpreter \"${_${_PYTHON_PREFIX}_EXECUTABLE}\"") endif() endif() if (_${_PYTHON_PREFIX}_EXECUTABLE AND _${_PYTHON_PREFIX}_EXECUTABLE_USABLE) + list (LENGTH _${_PYTHON_PREFIX}_INTERPRETER_PROPERTIES _properties_length) + if (NOT _properties_length EQUAL "12") + # cache variable comes from some older Python module version: not usable + unset (_${_PYTHON_PREFIX}_INTERPRETER_PROPERTIES CACHE) + endif() + unset (_properties_length) + if (_${_PYTHON_PREFIX}_INTERPRETER_PROPERTIES) set (${_PYTHON_PREFIX}_Interpreter_FOUND TRUE) @@ -1846,11 +2052,12 @@ if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) list (GET _${_PYTHON_PREFIX}_INTERPRETER_PROPERTIES 5 _${_PYTHON_PREFIX}_ABIFLAGS) list (GET _${_PYTHON_PREFIX}_INTERPRETER_PROPERTIES 6 ${_PYTHON_PREFIX}_SOABI) + list (GET _${_PYTHON_PREFIX}_INTERPRETER_PROPERTIES 7 ${_PYTHON_PREFIX}_SOSABI) - list (GET _${_PYTHON_PREFIX}_INTERPRETER_PROPERTIES 7 ${_PYTHON_PREFIX}_STDLIB) - list (GET _${_PYTHON_PREFIX}_INTERPRETER_PROPERTIES 8 ${_PYTHON_PREFIX}_STDARCH) - list (GET _${_PYTHON_PREFIX}_INTERPRETER_PROPERTIES 9 ${_PYTHON_PREFIX}_SITELIB) - list (GET _${_PYTHON_PREFIX}_INTERPRETER_PROPERTIES 10 ${_PYTHON_PREFIX}_SITEARCH) + list (GET _${_PYTHON_PREFIX}_INTERPRETER_PROPERTIES 8 ${_PYTHON_PREFIX}_STDLIB) + list (GET _${_PYTHON_PREFIX}_INTERPRETER_PROPERTIES 9 ${_PYTHON_PREFIX}_STDARCH) + list (GET _${_PYTHON_PREFIX}_INTERPRETER_PROPERTIES 10 ${_PYTHON_PREFIX}_SITELIB) + list (GET _${_PYTHON_PREFIX}_INTERPRETER_PROPERTIES 11 ${_PYTHON_PREFIX}_SITEARCH) else() string (REGEX MATCHALL "[0-9]+" _${_PYTHON_PREFIX}_VERSIONS "${${_PYTHON_PREFIX}_VERSION}") list (GET _${_PYTHON_PREFIX}_VERSIONS 0 ${_PYTHON_PREFIX}_VERSION_MAJOR) @@ -1875,7 +2082,7 @@ if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) endif() if (${_PYTHON_PREFIX}_Interpreter_FOUND) - unset (_${_PYTHON_PREFIX}_Interpreter_REASON_FAILURE) + unset (_${_PYTHON_PREFIX}_Interpreter_REASON_FAILURE CACHE) # compute and save interpreter signature string (MD5 __${_PYTHON_PREFIX}_INTERPRETER_SIGNATURE "${_${_PYTHON_PREFIX}_SIGNATURE}:${_${_PYTHON_PREFIX}_EXECUTABLE}") @@ -1949,10 +2156,11 @@ if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) endif() _python_get_config_var (${_PYTHON_PREFIX}_SOABI SOABI) + _python_get_config_var (${_PYTHON_PREFIX}_SOSABI SOSABI) # store properties in the cache to speed-up future searches set (_${_PYTHON_PREFIX}_INTERPRETER_PROPERTIES - "${${_PYTHON_PREFIX}_INTERPRETER_ID};${${_PYTHON_PREFIX}_VERSION_MAJOR};${${_PYTHON_PREFIX}_VERSION_MINOR};${${_PYTHON_PREFIX}_VERSION_PATCH};${_${_PYTHON_PREFIX}_ARCH};${_${_PYTHON_PREFIX}_ABIFLAGS};${${_PYTHON_PREFIX}_SOABI};${${_PYTHON_PREFIX}_STDLIB};${${_PYTHON_PREFIX}_STDARCH};${${_PYTHON_PREFIX}_SITELIB};${${_PYTHON_PREFIX}_SITEARCH}" CACHE INTERNAL "${_PYTHON_PREFIX} Properties") + "${${_PYTHON_PREFIX}_INTERPRETER_ID};${${_PYTHON_PREFIX}_VERSION_MAJOR};${${_PYTHON_PREFIX}_VERSION_MINOR};${${_PYTHON_PREFIX}_VERSION_PATCH};${_${_PYTHON_PREFIX}_ARCH};${_${_PYTHON_PREFIX}_ABIFLAGS};${${_PYTHON_PREFIX}_SOABI};${${_PYTHON_PREFIX}_SOSABI};${${_PYTHON_PREFIX}_STDLIB};${${_PYTHON_PREFIX}_STDARCH};${${_PYTHON_PREFIX}_SITELIB};${${_PYTHON_PREFIX}_SITEARCH}" CACHE INTERNAL "${_PYTHON_PREFIX} Properties") else() unset (_${_PYTHON_PREFIX}_INTERPRETER_SIGNATURE CACHE) unset (${_PYTHON_PREFIX}_INTERPRETER_ID) @@ -2049,8 +2257,8 @@ if ("Compiler" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) NO_CMAKE_PATH NO_CMAKE_ENVIRONMENT_PATH NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - _python_validate_compiler (${_${_PYTHON_PREFIX}_VALIDATE_OPTIONS}) + NO_CMAKE_SYSTEM_PATH + VALIDATOR _python_validate_find_compiler) if (_${_PYTHON_PREFIX}_COMPILER) break() endif() @@ -2063,9 +2271,10 @@ if ("Compiler" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) HINTS ${_${_PYTHON_PREFIX}_IRON_ROOT} ${_${_PYTHON_PREFIX}_HINTS} PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS} PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES} + ${_${_PYTHON_PREFIX}_REGISTRY_VIEW} NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - _python_validate_compiler (${_${_PYTHON_PREFIX}_VALIDATE_OPTIONS}) + NO_CMAKE_SYSTEM_PATH + VALIDATOR _python_validate_find_compiler) if (_${_PYTHON_PREFIX}_COMPILER) break() endif() @@ -2078,8 +2287,8 @@ if ("Compiler" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) HINTS ${_${_PYTHON_PREFIX}_IRON_ROOT} ${_${_PYTHON_PREFIX}_HINTS} PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES} NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - _python_validate_compiler (${_${_PYTHON_PREFIX}_VALIDATE_OPTIONS}) + NO_CMAKE_SYSTEM_PATH + VALIDATOR _python_validate_find_compiler) if (_${_PYTHON_PREFIX}_COMPILER) break() endif() @@ -2088,8 +2297,8 @@ if ("Compiler" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) find_program (_${_PYTHON_PREFIX}_COMPILER NAMES ${_${_PYTHON_PREFIX}_COMPILER_NAMES} NAMES_PER_DIR - PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}) - _python_validate_compiler (${_${_PYTHON_PREFIX}_VALIDATE_OPTIONS}) + PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES} + VALIDATOR _python_validate_find_compiler) if (_${_PYTHON_PREFIX}_COMPILER) break() endif() @@ -2101,12 +2310,13 @@ if ("Compiler" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) NAMES_PER_DIR PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS} PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES} - NO_DEFAULT_PATH) - _python_validate_compiler (${_${_PYTHON_PREFIX}_VALIDATE_OPTIONS}) + NO_DEFAULT_PATH + VALIDATOR _python_validate_find_compiler) if (_${_PYTHON_PREFIX}_COMPILER) break() endif() endif() + # Windows registry if (CMAKE_HOST_WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "LAST") find_program (_${_PYTHON_PREFIX}_COMPILER @@ -2114,8 +2324,9 @@ if ("Compiler" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) NAMES_PER_DIR PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS} PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES} - NO_DEFAULT_PATH) - _python_validate_compiler (${_${_PYTHON_PREFIX}_VALIDATE_OPTIONS}) + ${_${_PYTHON_PREFIX}_REGISTRY_VIEW} + NO_DEFAULT_PATH + VALIDATOR _python_validate_find_compiler) if (_${_PYTHON_PREFIX}_COMPILER) break() endif() @@ -2125,9 +2336,9 @@ if ("Compiler" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) endwhile() else() # try using root dir and registry - set (_${_PYTHON_PREFIX}_VALIDATE_OPTIONS EXACT) + set (_${_PYTHON_PREFIX}_COMMON_VALIDATE_OPTIONS EXACT) if (${_PYTHON_PREFIX}_FIND_VERSION_RANGE) - list (APPEND _${_PYTHON_PREFIX}_VALIDATE_OPTIONS IN_RANGE) + list (APPEND _${_PYTHON_PREFIX}_COMMON_VALIDATE_OPTIONS IN_RANGE) endif() foreach (_${_PYTHON_PREFIX}_VERSION IN LISTS _${_PYTHON_PREFIX}_FIND_VERSIONS) @@ -2148,6 +2359,8 @@ if ("Compiler" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) IMPLEMENTATIONS IronPython VERSION ${_${_PYTHON_PREFIX}_VERSION}) + set (_${_PYTHON_PREFIX}_VALIDATE_OPTIONS VERSION ${_${_PYTHON_PREFIX}_VERSION} ${_${_PYTHON_PREFIX}_COMMON_VALIDATE_OPTIONS}) + # Apple frameworks handling if (CMAKE_HOST_APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "FIRST") find_program (_${_PYTHON_PREFIX}_COMPILER @@ -2159,8 +2372,8 @@ if ("Compiler" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) NO_CMAKE_PATH NO_CMAKE_ENVIRONMENT_PATH NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - _python_validate_compiler (VERSION ${_${_PYTHON_PREFIX}_VERSION} ${_${_PYTHON_PREFIX}_VALIDATE_OPTIONS}) + NO_CMAKE_SYSTEM_PATH + VALIDATOR _python_validate_find_compiler) if (_${_PYTHON_PREFIX}_COMPILER) break() endif() @@ -2173,9 +2386,10 @@ if ("Compiler" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) HINTS ${_${_PYTHON_PREFIX}_IRON_ROOT} ${_${_PYTHON_PREFIX}_HINTS} PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS} PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES} + ${_${_PYTHON_PREFIX}_REGISTRY_VIEW} NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - _python_validate_compiler (VERSION ${_${_PYTHON_PREFIX}_VERSION} ${_${_PYTHON_PREFIX}_VALIDATE_OPTIONS}) + NO_CMAKE_SYSTEM_PATH + VALIDATOR _python_validate_find_compiler) if (_${_PYTHON_PREFIX}_COMPILER) break() endif() @@ -2188,8 +2402,8 @@ if ("Compiler" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) HINTS ${_${_PYTHON_PREFIX}_IRON_ROOT} ${_${_PYTHON_PREFIX}_HINTS} PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES} NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - _python_validate_compiler (VERSION ${_${_PYTHON_PREFIX}_VERSION} ${_${_PYTHON_PREFIX}_VALIDATE_OPTIONS}) + NO_CMAKE_SYSTEM_PATH + VALIDATOR _python_validate_find_compiler) if (_${_PYTHON_PREFIX}_COMPILER) break() endif() @@ -2201,8 +2415,8 @@ if ("Compiler" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) NAMES_PER_DIR PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS} PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES} - NO_DEFAULT_PATH) - _python_validate_compiler (VERSION ${_${_PYTHON_PREFIX}_VERSION} ${_${_PYTHON_PREFIX}_VALIDATE_OPTIONS}) + NO_DEFAULT_PATH + VALIDATOR _python_validate_find_compiler) if (_${_PYTHON_PREFIX}_COMPILER) break() endif() @@ -2214,8 +2428,9 @@ if ("Compiler" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) NAMES_PER_DIR PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS} PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES} - NO_DEFAULT_PATH) - _python_validate_compiler (VERSION ${_${_PYTHON_PREFIX}_VERSION} ${_${_PYTHON_PREFIX}_VALIDATE_OPTIONS}) + ${_${_PYTHON_PREFIX}_REGISTRY_VIEW} + NO_DEFAULT_PATH + VALIDATOR _python_validate_find_compiler) if (_${_PYTHON_PREFIX}_COMPILER) break() endif() @@ -2231,11 +2446,13 @@ if ("Compiler" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) IMPLEMENTATIONS IronPython VERSION ${_${_PYTHON_PREFIX}_FIND_VERSIONS} COMPILER) + unset (_${_PYTHON_PREFIX}_VALIDATE_OPTIONS) find_program (_${_PYTHON_PREFIX}_COMPILER NAMES ${_${_PYTHON_PREFIX}_COMPILER_NAMES} + NAMES_PER_DIR HINTS ${_${_PYTHON_PREFIX}_IRON_ROOT} ${_${_PYTHON_PREFIX}_HINTS} - PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}) - _python_validate_compiler () + PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES} + VALIDATOR _python_validate_find_compiler) endif() endif() @@ -2276,7 +2493,7 @@ if ("Compiler" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) else() # compiler not usable set (_${_PYTHON_PREFIX}_COMPILER_USABLE FALSE) - set (_${_PYTHON_PREFIX}_Compiler_REASON_FAILURE "Cannot run the compiler \"${_${_PYTHON_PREFIX}_COMPILER}\"") + set_property (CACHE _${_PYTHON_PREFIX}_Compiler_REASON_FAILURE PROPERTY VALUE "Cannot run the compiler \"${_${_PYTHON_PREFIX}_COMPILER}\"") endif() file (REMOVE_RECURSE "${_${_PYTHON_PREFIX}_VERSION_DIR}") endif() @@ -2295,7 +2512,7 @@ if ("Compiler" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) endif() if (${_PYTHON_PREFIX}_Compiler_FOUND) - unset (_${_PYTHON_PREFIX}_Compiler_REASON_FAILURE) + unset (_${_PYTHON_PREFIX}_Compiler_REASON_FAILURE CACHE) # compute and save compiler signature string (MD5 __${_PYTHON_PREFIX}_COMPILER_SIGNATURE "${_${_PYTHON_PREFIX}_SIGNATURE}:${_${_PYTHON_PREFIX}_COMPILER}") @@ -2324,6 +2541,14 @@ if (${_PYTHON_PREFIX}_FIND_REQUIRED_Development.Module) list (APPEND _${_PYTHON_PREFIX}_REQUIRED_VARS ${_PYTHON_PREFIX}_INCLUDE_DIRS) endif() endif() +if (${_PYTHON_PREFIX}_FIND_REQUIRED_Development.SABIModule) + if ("SABI_LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_SABIMODULE_ARTIFACTS) + list (APPEND _${_PYTHON_PREFIX}_REQUIRED_VARS ${_PYTHON_PREFIX}_SABI_LIBRARIES) + endif() + if ("INCLUDE_DIR" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_SABIMODULE_ARTIFACTS) + list (APPEND _${_PYTHON_PREFIX}_REQUIRED_VARS ${_PYTHON_PREFIX}_INCLUDE_DIRS) + endif() +endif() if (${_PYTHON_PREFIX}_FIND_REQUIRED_Development.Embed) if ("LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_EMBED_ARTIFACTS) list (APPEND _${_PYTHON_PREFIX}_REQUIRED_VARS ${_PYTHON_PREFIX}_LIBRARIES) @@ -2335,6 +2560,7 @@ endif() list (REMOVE_DUPLICATES _${_PYTHON_PREFIX}_REQUIRED_VARS) ## Development environment is not compatible with IronPython interpreter if (("Development.Module" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS + OR "Development.SABIModule" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS OR "Development.Embed" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) AND ((${_PYTHON_PREFIX}_Interpreter_FOUND AND NOT ${_PYTHON_PREFIX}_INTERPRETER_ID STREQUAL "IronPython") @@ -2355,11 +2581,18 @@ if (("Development.Module" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS _${_PYTHON_PREFIX}_LIBRARY_DEBUG _${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG) endif() + if ("SABI_LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_ARTIFACTS) + list (APPEND _${_PYTHON_PREFIX}_CACHED_VARS _${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE + _${_PYTHON_PREFIX}_RUNTIME_SABI_LIBRARY_RELEASE + _${_PYTHON_PREFIX}_SABI_LIBRARY_DEBUG + _${_PYTHON_PREFIX}_RUNTIME_SABI_LIBRARY_DEBUG) + endif() if ("INCLUDE_DIR" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_ARTIFACTS) list (APPEND _${_PYTHON_PREFIX}_CACHED_VARS _${_PYTHON_PREFIX}_INCLUDE_DIR) endif() _python_check_development_signature (Module) + _python_check_development_signature (SABIModule) _python_check_development_signature (Embed) if (DEFINED ${_PYTHON_PREFIX}_LIBRARY @@ -2368,6 +2601,12 @@ if (("Development.Module" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS unset (_${_PYTHON_PREFIX}_LIBRARY_DEBUG CACHE) unset (_${_PYTHON_PREFIX}_INCLUDE_DIR CACHE) endif() + if (DEFINED ${_PYTHON_PREFIX}_SABI_LIBRARY + AND IS_ABSOLUTE "${${_PYTHON_PREFIX}_SABI_LIBRARY}") + set (_${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE "${${_PYTHON_PREFIX}_SABI_LIBRARY}" CACHE INTERNAL "") + unset (_${_PYTHON_PREFIX}_SABI_LIBRARY_DEBUG CACHE) + unset (_${_PYTHON_PREFIX}_INCLUDE_DIR CACHE) + endif() if (DEFINED ${_PYTHON_PREFIX}_INCLUDE_DIR AND IS_ABSOLUTE "${${_PYTHON_PREFIX}_INCLUDE_DIR}") set (_${_PYTHON_PREFIX}_INCLUDE_DIR "${${_PYTHON_PREFIX}_INCLUDE_DIR}" CACHE INTERNAL "") @@ -2384,7 +2623,8 @@ if (("Development.Module" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS endif() endif() - if (NOT _${_PYTHON_PREFIX}_LIBRARY_RELEASE OR NOT _${_PYTHON_PREFIX}_INCLUDE_DIR) + if (NOT _${_PYTHON_PREFIX}_LIBRARY_RELEASE OR NOT _${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE + OR NOT _${_PYTHON_PREFIX}_INCLUDE_DIR) # if python interpreter is found, use it to look-up for artifacts # to ensure consistency between interpreter and development environments. # If not, try to locate a compatible config tool @@ -2777,8 +3017,10 @@ if (("Development.Module" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS set (${_PYTHON_PREFIX}_LIBRARY_RELEASE "${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}") if (_${_PYTHON_PREFIX}_LIBRARY_RELEASE AND NOT EXISTS "${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}") - set (_${_PYTHON_PREFIX}_Development_REASON_FAILURE "Cannot find the library \"${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}\"") + set_property (CACHE _${_PYTHON_PREFIX}_Development_LIBRARY_REASON_FAILURE PROPERTY VALUE "Cannot find the library \"${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}\"") set_property (CACHE _${_PYTHON_PREFIX}_LIBRARY_RELEASE PROPERTY VALUE "${_PYTHON_PREFIX}_LIBRARY_RELEASE-NOTFOUND") + else() + unset (_${_PYTHON_PREFIX}_Development_LIBRARY_REASON_FAILURE CACHE) endif() set (_${_PYTHON_PREFIX}_HINTS "${${_PYTHON_PREFIX}_ROOT_DIR}" ENV ${_PYTHON_PREFIX}_ROOT_DIR) @@ -2826,10 +3068,280 @@ if (("Development.Module" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS endif() endif() + if ("SABI_LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_ARTIFACTS) + if (NOT _${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE) + ## compute artifact names + _python_get_names (_${_PYTHON_PREFIX}_LIB_NAMES VERSION ${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR} WIN32 POSIX LIBRARY) + _python_get_names (_${_PYTHON_PREFIX}_LIB_NAMES_DEBUG VERSION ${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR} WIN32 DEBUG) + + if ("LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_ARTIFACTS + AND _${_PYTHON_PREFIX}_LIBRARY_RELEASE) + # SABI_LIBRARY_RELEASE search is based on LIBRARY_RELEASE + set (_${_PYTHON_PREFIX}_HINTS "${${_PYTHON_PREFIX}_ROOT_DIR}" ENV ${_PYTHON_PREFIX}_ROOT_DIR) + + get_filename_component (_${_PYTHON_PREFIX}_PATH "${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}" DIRECTORY) + + find_library (_${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE + NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES} + HINTS "${_${_PYTHON_PREFIX}_PATH}" ${_${_PYTHON_PREFIX}_HINTS} + NO_DEFAULT_PATH) + else() + if ((${_PYTHON_PREFIX}_Interpreter_FOUND AND NOT CMAKE_CROSSCOMPILING) OR _${_PYTHON_PREFIX}_CONFIG) + # retrieve root install directory + _python_get_config_var (_${_PYTHON_PREFIX}_PREFIX PREFIX) + + # enforce current ABI + _python_get_config_var (_${_PYTHON_PREFIX}_ABIFLAGS ABIFLAGS) + + set (_${_PYTHON_PREFIX}_HINTS "${_${_PYTHON_PREFIX}_PREFIX}") + + # retrieve SABI library + ## compute some paths + if (_${_PYTHON_PREFIX}_CONFIG) + string (REGEX REPLACE "^.+python([0-9.]+)[a-z]*-config" "\\1" _${_PYTHON_PREFIX}_VERSION "${_${_PYTHON_PREFIX}_CONFIG}") + else() + set (_${_PYTHON_PREFIX}_VERSION "${${_PYTHON_PREFIX}_VERSION_MAJOR}.${${_PYTHON_PREFIX}_VERSION_MINOR}") + endif() + _python_get_path_suffixes (_${_PYTHON_PREFIX}_PATH_SUFFIXES VERSION ${_${_PYTHON_PREFIX}_VERSION} LIBRARY) + + _python_get_config_var (_${_PYTHON_PREFIX}_CONFIGDIR CONFIGDIR) + list (APPEND _${_PYTHON_PREFIX}_HINTS "${_${_PYTHON_PREFIX}_CONFIGDIR}") + + list (APPEND _${_PYTHON_PREFIX}_HINTS "${${_PYTHON_PREFIX}_ROOT_DIR}" ENV ${_PYTHON_PREFIX}_ROOT_DIR) + + find_library (_${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE + NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES} + NAMES_PER_DIR + HINTS ${_${_PYTHON_PREFIX}_HINTS} + PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES} + NO_SYSTEM_ENVIRONMENT_PATH + NO_CMAKE_SYSTEM_PATH) + endif() + + # Rely on HINTS and standard paths if interpreter or config tool failed to locate artifacts + if (NOT _${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE) + set (_${_PYTHON_PREFIX}_HINTS "${${_PYTHON_PREFIX}_ROOT_DIR}" ENV ${_PYTHON_PREFIX}_ROOT_DIR) + + unset (_${_PYTHON_PREFIX}_VIRTUALENV_PATHS) + if (_${_PYTHON_PREFIX}_FIND_VIRTUALENV MATCHES "^(FIRST|ONLY)$") + set (_${_PYTHON_PREFIX}_VIRTUALENV_PATHS ENV VIRTUAL_ENV ENV CONDA_PREFIX) + endif() + + if (_${_PYTHON_PREFIX}_FIND_STRATEGY STREQUAL "LOCATION") + # Paths suffixes + _python_get_path_suffixes (_${_PYTHON_PREFIX}_PATH_SUFFIXES VERSION ${_${_PYTHON_PREFIX}_FIND_VERSIONS} LIBRARY) + + # Framework Paths + _python_get_frameworks (_${_PYTHON_PREFIX}_FRAMEWORK_PATHS VERSION ${_${_PYTHON_PREFIX}_LIB_FIND_VERSIONS}) + # Registry Paths + _python_get_registries (_${_PYTHON_PREFIX}_REGISTRY_PATHS VERSION ${_${_PYTHON_PREFIX}_FIND_VERSIONS} ) + + if (APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "FIRST") + find_library (_${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE + NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES} + NAMES_PER_DIR + HINTS ${_${_PYTHON_PREFIX}_HINTS} + PATHS ${_${_PYTHON_PREFIX}_VIRTUALENV_PATHS} + ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS} + PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES} + NO_CMAKE_PATH + NO_CMAKE_ENVIRONMENT_PATH + NO_SYSTEM_ENVIRONMENT_PATH + NO_CMAKE_SYSTEM_PATH) + endif() + + if (WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "FIRST") + find_library (_${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE + NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES} + NAMES_PER_DIR + HINTS ${_${_PYTHON_PREFIX}_HINTS} + PATHS ${_${_PYTHON_PREFIX}_VIRTUALENV_PATHS} + ${_${_PYTHON_PREFIX}_REGISTRY_PATHS} + PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES} + NO_SYSTEM_ENVIRONMENT_PATH + NO_CMAKE_SYSTEM_PATH) + endif() + + # search in HINTS locations + find_library (_${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE + NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES} + NAMES_PER_DIR + HINTS ${_${_PYTHON_PREFIX}_HINTS} + PATHS ${_${_PYTHON_PREFIX}_VIRTUALENV_PATHS} + PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES} + NO_SYSTEM_ENVIRONMENT_PATH + NO_CMAKE_SYSTEM_PATH) + + if (APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "LAST") + set (__${_PYTHON_PREFIX}_FRAMEWORK_PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS}) + else() + unset (__${_PYTHON_PREFIX}_FRAMEWORK_PATHS) + endif() + + if (WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "LAST") + set (__${_PYTHON_PREFIX}_REGISTRY_PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS}) + else() + unset (__${_PYTHON_PREFIX}_REGISTRY_PATHS) + endif() + + # search in all default paths + find_library (_${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE + NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES} + NAMES_PER_DIR + PATHS ${__${_PYTHON_PREFIX}_FRAMEWORK_PATHS} + ${__${_PYTHON_PREFIX}_REGISTRY_PATHS} + PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}) + else() + foreach (_${_PYTHON_PREFIX}_LIB_VERSION IN LISTS _${_PYTHON_PREFIX}_FIND_VERSIONS) + _python_get_frameworks (_${_PYTHON_PREFIX}_FRAMEWORK_PATHS VERSION ${_${_PYTHON_PREFIX}_LIB_VERSION}) + _python_get_registries (_${_PYTHON_PREFIX}_REGISTRY_PATHS VERSION ${_${_PYTHON_PREFIX}_LIB_VERSION}) + + _python_get_path_suffixes (_${_PYTHON_PREFIX}_PATH_SUFFIXES VERSION ${_${_PYTHON_PREFIX}_LIB_VERSION} LIBRARY) + + if (APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "FIRST") + find_library (_${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE + NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES} + NAMES_PER_DIR + HINTS ${_${_PYTHON_PREFIX}_HINTS} + PATHS ${_${_PYTHON_PREFIX}_VIRTUALENV_PATHS} + ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS} + PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES} + NO_CMAKE_PATH + NO_CMAKE_ENVIRONMENT_PATH + NO_SYSTEM_ENVIRONMENT_PATH + NO_CMAKE_SYSTEM_PATH) + endif() + + if (WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "FIRST") + find_library (_${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE + NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES} + NAMES_PER_DIR + HINTS ${_${_PYTHON_PREFIX}_HINTS} + PATHS ${_${_PYTHON_PREFIX}_VIRTUALENV_PATHS} + ${_${_PYTHON_PREFIX}_REGISTRY_PATHS} + PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES} + NO_SYSTEM_ENVIRONMENT_PATH + NO_CMAKE_SYSTEM_PATH) + endif() + + # search in HINTS locations + find_library (_${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE + NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES} + NAMES_PER_DIR + HINTS ${_${_PYTHON_PREFIX}_HINTS} + PATHS ${_${_PYTHON_PREFIX}_VIRTUALENV_PATHS} + PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES} + NO_SYSTEM_ENVIRONMENT_PATH + NO_CMAKE_SYSTEM_PATH) + + if (APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "LAST") + set (__${_PYTHON_PREFIX}_FRAMEWORK_PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS}) + else() + unset (__${_PYTHON_PREFIX}_FRAMEWORK_PATHS) + endif() + + if (WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "LAST") + set (__${_PYTHON_PREFIX}_REGISTRY_PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS}) + else() + unset (__${_PYTHON_PREFIX}_REGISTRY_PATHS) + endif() + + # search in all default paths + find_library (_${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE + NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES} + NAMES_PER_DIR + PATHS ${__${_PYTHON_PREFIX}_FRAMEWORK_PATHS} + ${__${_PYTHON_PREFIX}_REGISTRY_PATHS} + PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}) + + if (_${_PYTHON_PREFIX}_LIBRARY_RELEASE) + break() + endif() + endforeach() + endif() + endif() + endif() + endif() + + # finalize library version information + _python_get_version (SABI_LIBRARY PREFIX _${_PYTHON_PREFIX}_) + # ABI library does not have the full version information + if (${_PYTHON_PREFIX}_Interpreter_FOUND OR _${_PYTHON_PREFIX}_LIBRARY_RELEASE) + # update from interpreter or library + set (_${_PYTHON_PREFIX}_VERSION ${${_PYTHON_PREFIX}_VERSION}) + set (_${_PYTHON_PREFIX}_VERSION_MAJOR ${${_PYTHON_PREFIX}_VERSION_MAJOR}) + set (_${_PYTHON_PREFIX}_VERSION_MINOR ${${_PYTHON_PREFIX}_VERSION_MINOR}) + set (_${_PYTHON_PREFIX}_VERSION_PATCH ${${_PYTHON_PREFIX}_VERSION_PATCH}) + endif() + + set (${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE "${_${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE}") + + if (_${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE AND NOT EXISTS "${_${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE}") + set_property (CACHE _${_PYTHON_PREFIX}_Development_SABI_LIBRARY_REASON_FAILURE PROPERTY VALUE "Cannot find the library \"${_${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE}\"") + set_property (CACHE _${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE PROPERTY VALUE "${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE-NOTFOUND") + else() + unset (_${_PYTHON_PREFIX}_Development_SABI_LIBRARY_REASON_FAILURE CACHE) + endif() + + if (WIN32 AND _${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE) + # search for debug library + get_filename_component (_${_PYTHON_PREFIX}_PATH "${_${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE}" DIRECTORY) + find_library (_${_PYTHON_PREFIX}_SABI_LIBRARY_DEBUG + NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES_DEBUG} + NAMES_PER_DIR + HINTS "${_${_PYTHON_PREFIX}_PATH}" ${_${_PYTHON_PREFIX}_HINTS} + NO_DEFAULT_PATH) + # second try including CMAKE variables to catch-up non conventional layouts + find_library (_${_PYTHON_PREFIX}_SABI_LIBRARY_DEBUG + NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES_DEBUG} + NAMES_PER_DIR + NO_SYSTEM_ENVIRONMENT_PATH + NO_CMAKE_SYSTEM_PATH) + endif() + + # retrieve runtime libraries + if (_${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE) + get_filename_component (_${_PYTHON_PREFIX}_PATH "${_${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE}" DIRECTORY) + get_filename_component (_${_PYTHON_PREFIX}_PATH2 "${_${_PYTHON_PREFIX}_PATH}" DIRECTORY) + _python_find_runtime_library (_${_PYTHON_PREFIX}_RUNTIME_SABI_LIBRARY_RELEASE + NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES} + NAMES_PER_DIR + HINTS "${_${_PYTHON_PREFIX}_PATH}" + "${_${_PYTHON_PREFIX}_PATH2}" ${_${_PYTHON_PREFIX}_HINTS} + PATH_SUFFIXES bin) + endif() + + if (_${_PYTHON_PREFIX}_SABI_LIBRARY_DEBUG) + get_filename_component (_${_PYTHON_PREFIX}_PATH "${_${_PYTHON_PREFIX}_SABI_LIBRARY_DEBUG}" DIRECTORY) + get_filename_component (_${_PYTHON_PREFIX}_PATH2 "${_${_PYTHON_PREFIX}_PATH}" DIRECTORY) + _python_find_runtime_library (_${_PYTHON_PREFIX}_RUNTIME_SABI_LIBRARY_DEBUG + NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES_DEBUG} + NAMES_PER_DIR + HINTS "${_${_PYTHON_PREFIX}_PATH}" + "${_${_PYTHON_PREFIX}_PATH2}" ${_${_PYTHON_PREFIX}_HINTS} + PATH_SUFFIXES bin) + endif() + endif() + if ("INCLUDE_DIR" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_ARTIFACTS) while (NOT _${_PYTHON_PREFIX}_INCLUDE_DIR) - if ("LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_ARTIFACTS + set (_${_PYTHON_PREFIX}_LIBRARY_REQUIRED FALSE) + set (_${_PYTHON_PREFIX}_SABI_LIBRARY_REQUIRED FALSE) + foreach (_${_PYTHON_PREFIX}_COMPONENT IN ITEMS Module SABIModule Embed) + string (TOUPPER "${_${_PYTHON_PREFIX}_COMPONENT}" _${_PYTHON_PREFIX}_ID) + if ("Development.${_${_PYTHON_PREFIX}_COMPONENT}" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS + AND "LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_${_${_PYTHON_PREFIX}_ID}_ARTIFACTS) + set (_${_PYTHON_PREFIX}_LIBRARY_REQUIRED TRUE) + endif() + if ("Development.${_${_PYTHON_PREFIX}_COMPONENT}" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS + AND "SABI_LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_${_${_PYTHON_PREFIX}_ID}_ARTIFACTS) + set (_${_PYTHON_PREFIX}_SABI_LIBRARY_REQUIRED TRUE) + endif() + endforeach() + if ((_${_PYTHON_PREFIX}_LIBRARY_REQUIRED AND NOT _${_PYTHON_PREFIX}_LIBRARY_RELEASE) + AND (_${_PYTHON_PREFIX}_SABI_LIBRARY_REQUIRED + AND NOT _${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE)) # Don't search for include dir if no library was founded break() endif() @@ -2852,7 +3364,8 @@ if (("Development.Module" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS endif() unset (_${_PYTHON_PREFIX}_INCLUDE_HINTS) - if (_${_PYTHON_PREFIX}_LIBRARY_RELEASE) + if ("LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_ARTIFACTS + AND _${_PYTHON_PREFIX}_LIBRARY_RELEASE) # Use the library's install prefix as a hint if (_${_PYTHON_PREFIX}_LIBRARY_RELEASE MATCHES "^(.+/Frameworks/Python.framework/Versions/[0-9.]+)") list (APPEND _${_PYTHON_PREFIX}_INCLUDE_HINTS "${CMAKE_MATCH_1}") @@ -2866,6 +3379,21 @@ if (("Development.Module" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS get_filename_component (_${_PYTHON_PREFIX}_PREFIX "${_${_PYTHON_PREFIX}_PREFIX}" DIRECTORY) list (APPEND _${_PYTHON_PREFIX}_INCLUDE_HINTS "${_${_PYTHON_PREFIX}_PREFIX}") endif() + elseif ("SABI_LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_ARTIFACTS + AND _${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE) + # Use the library's install prefix as a hint + if (_${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE MATCHES "^(.+/Frameworks/Python.framework/Versions/[0-9.]+)") + list (APPEND _${_PYTHON_PREFIX}_INCLUDE_HINTS "${CMAKE_MATCH_1}") + elseif (_${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE MATCHES "^(.+)/lib(64|32)?/python[0-9.]+/config") + list (APPEND _${_PYTHON_PREFIX}_INCLUDE_HINTS "${CMAKE_MATCH_1}") + elseif (DEFINED CMAKE_LIBRARY_ARCHITECTURE AND ${_${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE} MATCHES "^(.+)/lib/${CMAKE_LIBRARY_ARCHITECTURE}") + list (APPEND _${_PYTHON_PREFIX}_INCLUDE_HINTS "${CMAKE_MATCH_1}") + else() + # assume library is in a directory under root + get_filename_component (_${_PYTHON_PREFIX}_PREFIX "${_${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE}" DIRECTORY) + get_filename_component (_${_PYTHON_PREFIX}_PREFIX "${_${_PYTHON_PREFIX}_PREFIX}" DIRECTORY) + list (APPEND _${_PYTHON_PREFIX}_INCLUDE_HINTS "${_${_PYTHON_PREFIX}_PREFIX}") + endif() endif() _python_get_frameworks (_${_PYTHON_PREFIX}_FRAMEWORK_PATHS VERSION ${_${_PYTHON_PREFIX}_VERSION}) @@ -2929,14 +3457,17 @@ if (("Development.Module" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS set (${_PYTHON_PREFIX}_INCLUDE_DIRS "${_${_PYTHON_PREFIX}_INCLUDE_DIR}") if (_${_PYTHON_PREFIX}_INCLUDE_DIR AND NOT EXISTS "${_${_PYTHON_PREFIX}_INCLUDE_DIR}") - set (_${_PYTHON_PREFIX}_Development_REASON_FAILURE "Cannot find the directory \"${_${_PYTHON_PREFIX}_INCLUDE_DIR}\"") + set_property (CACHE _${_PYTHON_PREFIX}_Development_INCLUDE_DIR_REASON_FAILURE PROPERTY VALUE "Cannot find the directory \"${_${_PYTHON_PREFIX}_INCLUDE_DIR}\"") set_property (CACHE _${_PYTHON_PREFIX}_INCLUDE_DIR PROPERTY VALUE "${_PYTHON_PREFIX}_INCLUDE_DIR-NOTFOUND") + else() + unset (_${_PYTHON_PREFIX}_Development_INCLUDE_DIR_REASON_FAILURE CACHE) endif() if (_${_PYTHON_PREFIX}_INCLUDE_DIR) # retrieve version from header file _python_get_version (INCLUDE PREFIX _${_PYTHON_PREFIX}_INC_) - if (_${_PYTHON_PREFIX}_LIBRARY_RELEASE) + if ("LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_ARTIFACTS + AND _${_PYTHON_PREFIX}_LIBRARY_RELEASE) if ("${_${_PYTHON_PREFIX}_INC_VERSION_MAJOR}.${_${_PYTHON_PREFIX}_INC_VERSION_MINOR}" VERSION_EQUAL _${_PYTHON_PREFIX}_VERSION) # update versioning @@ -2995,36 +3526,59 @@ if (("Development.Module" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS endif() endif() - if (_${_PYTHON_PREFIX}_LIBRARY_RELEASE OR _${_PYTHON_PREFIX}_INCLUDE_DIR) + if ("SABI_LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_ARTIFACTS) + set (${_PYTHON_PREFIX}_SABI_LIBRARY_DEBUG "${_${_PYTHON_PREFIX}_SABI_LIBRARY_DEBUG}") + _python_select_library_configurations (${_PYTHON_PREFIX}_SABI) + + set (${_PYTHON_PREFIX}_RUNTIME_SABI_LIBRARY_RELEASE "${_${_PYTHON_PREFIX}_RUNTIME_SABI_LIBRARY_RELEASE}") + set (${_PYTHON_PREFIX}_RUNTIME_SABI_LIBRARY_DEBUG "${_${_PYTHON_PREFIX}_RUNTIME_SABI_LIBRARY_DEBUG}") + + if (_${_PYTHON_PREFIX}_RUNTIME_SABI_LIBRARY_RELEASE) + set (${_PYTHON_PREFIX}_RUNTIME_SABI_LIBRARY "${_${_PYTHON_PREFIX}_RUNTIME_SABI_LIBRARY_RELEASE}") + elseif (_${_PYTHON_PREFIX}_RUNTIME_SABI_LIBRARY_DEBUG) + set (${_PYTHON_PREFIX}_RUNTIME_SABI_LIBRARY "${_${_PYTHON_PREFIX}_RUNTIME_SABI_LIBRARY_DEBUG}") + else() + set (${_PYTHON_PREFIX}_RUNTIME_SABI_LIBRARY "${_PYTHON_PREFIX}_RUNTIME_SABI_LIBRARY-NOTFOUND") + endif() + + _python_set_library_dirs (${_PYTHON_PREFIX}_SABI_LIBRARY_DIRS + _${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE + _${_PYTHON_PREFIX}_SABI_LIBRARY_DEBUG) + if (UNIX) + if (_${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE MATCHES "${CMAKE_SHARED_LIBRARY_SUFFIX}$") + set (${_PYTHON_PREFIX}_RUNTIME_SABI_LIBRARY_DIRS ${${_PYTHON_PREFIX}_LIBRARY_DIRS}) + endif() + else() + _python_set_library_dirs (${_PYTHON_PREFIX}_RUNTIME_SABI_LIBRARY_DIRS + _${_PYTHON_PREFIX}_RUNTIME_SABI_LIBRARY_RELEASE + _${_PYTHON_PREFIX}_RUNTIME_SABI_LIBRARY_DEBUG) + endif() + endif() + + if (_${_PYTHON_PREFIX}_LIBRARY_RELEASE OR _${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE OR _${_PYTHON_PREFIX}_INCLUDE_DIR) if (${_PYTHON_PREFIX}_Interpreter_FOUND OR ${_PYTHON_PREFIX}_Compiler_FOUND) # development environment must be compatible with interpreter/compiler if ("${_${_PYTHON_PREFIX}_VERSION_MAJOR}.${_${_PYTHON_PREFIX}_VERSION_MINOR}" VERSION_EQUAL "${${_PYTHON_PREFIX}_VERSION_MAJOR}.${${_PYTHON_PREFIX}_VERSION_MINOR}" AND "${_${_PYTHON_PREFIX}_INC_VERSION_MAJOR}.${_${_PYTHON_PREFIX}_INC_VERSION_MINOR}" VERSION_EQUAL "${_${_PYTHON_PREFIX}_VERSION_MAJOR}.${_${_PYTHON_PREFIX}_VERSION_MINOR}") _python_set_development_module_found (Module) + _python_set_development_module_found (SABIModule) _python_set_development_module_found (Embed) endif() elseif (${_PYTHON_PREFIX}_VERSION_MAJOR VERSION_EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR AND "${_${_PYTHON_PREFIX}_INC_VERSION_MAJOR}.${_${_PYTHON_PREFIX}_INC_VERSION_MINOR}" VERSION_EQUAL "${_${_PYTHON_PREFIX}_VERSION_MAJOR}.${_${_PYTHON_PREFIX}_VERSION_MINOR}") _python_set_development_module_found (Module) + _python_set_development_module_found (SABIModule) _python_set_development_module_found (Embed) endif() if (DEFINED _${_PYTHON_PREFIX}_FIND_ABI AND (NOT _${_PYTHON_PREFIX}_ABI IN_LIST _${_PYTHON_PREFIX}_ABIFLAGS OR NOT _${_PYTHON_PREFIX}_INC_ABI IN_LIST _${_PYTHON_PREFIX}_ABIFLAGS)) set (${_PYTHON_PREFIX}_Development.Module_FOUND FALSE) + set (${_PYTHON_PREFIX}_Development.SABIModule_FOUND FALSE) set (${_PYTHON_PREFIX}_Development.Embed_FOUND FALSE) endif() endif() - if (( ${_PYTHON_PREFIX}_Development.Module_FOUND - AND ${_PYTHON_PREFIX}_Development.Embed_FOUND) - OR (NOT "Development.Module" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS - AND ${_PYTHON_PREFIX}_Development.Embed_FOUND) - OR (NOT "Development.Embed" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS - AND ${_PYTHON_PREFIX}_Development.Module_FOUND)) - unset (_${_PYTHON_PREFIX}_Development_REASON_FAILURE) - endif() - if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS AND ${_PYTHON_PREFIX}_Development.Module_FOUND AND ${_PYTHON_PREFIX}_Development.Embed_FOUND) @@ -3032,13 +3586,14 @@ if (("Development.Module" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS endif() if ((${_PYTHON_PREFIX}_Development.Module_FOUND - OR ${_PYTHON_PREFIX}_Development.Embed_FOUND) - AND EXISTS "${_${_PYTHON_PREFIX}_INCLUDE_DIR}/PyPy.h") - # retrieve PyPy version - file (STRINGS "${_${_PYTHON_PREFIX}_INCLUDE_DIR}/patchlevel.h" ${_PYTHON_PREFIX}_PyPy_VERSION - REGEX "^#define[ \t]+PYPY_VERSION[ \t]+\"[^\"]+\"") - string (REGEX REPLACE "^#define[ \t]+PYPY_VERSION[ \t]+\"([^\"]+)\".*" "\\1" - ${_PYTHON_PREFIX}_PyPy_VERSION "${${_PYTHON_PREFIX}_PyPy_VERSION}") + OR ${_PYTHON_PREFIX}_Development.SABIModule_FOUND + OR ${_PYTHON_PREFIX}_Development.Embed_FOUND) + AND EXISTS "${_${_PYTHON_PREFIX}_INCLUDE_DIR}/PyPy.h") + # retrieve PyPy version + file (STRINGS "${_${_PYTHON_PREFIX}_INCLUDE_DIR}/patchlevel.h" ${_PYTHON_PREFIX}_PyPy_VERSION + REGEX "^#define[ \t]+PYPY_VERSION[ \t]+\"[^\"]+\"") + string (REGEX REPLACE "^#define[ \t]+PYPY_VERSION[ \t]+\"([^\"]+)\".*" "\\1" + ${_PYTHON_PREFIX}_PyPy_VERSION "${${_PYTHON_PREFIX}_PyPy_VERSION}") endif() unset(${_PYTHON_PREFIX}_LINK_OPTIONS) @@ -3068,7 +3623,12 @@ if (("Development.Module" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS _python_get_config_var (${_PYTHON_PREFIX}_SOABI SOABI) endif() + if (NOT DEFINED ${_PYTHON_PREFIX}_SOSABI) + _python_get_config_var (${_PYTHON_PREFIX}_SOSABI SOSABI) + endif() + _python_compute_development_signature (Module) + _python_compute_development_signature (SABIModule) _python_compute_development_signature (Embed) # Restore the original find library ordering @@ -3080,6 +3640,9 @@ if (("Development.Module" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS if ("LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_ARTIFACTS) set (${_PYTHON_PREFIX}_LIBRARY "${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}" CACHE FILEPATH "${_PYTHON_PREFIX} Library") endif() + if ("SABI_LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_ARTIFACTS) + set (${_PYTHON_PREFIX}_SABI_LIBRARY "${_${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE}" CACHE FILEPATH "${_PYTHON_PREFIX} ABI Library") + endif() if ("INCLUDE_DIR" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_ARTIFACTS) set (${_PYTHON_PREFIX}_INCLUDE_DIR "${_${_PYTHON_PREFIX}_INCLUDE_DIR}" CACHE FILEPATH "${_PYTHON_PREFIX} Include Directory") endif() @@ -3089,6 +3652,10 @@ if (("Development.Module" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS _${_PYTHON_PREFIX}_LIBRARY_DEBUG _${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE _${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG + _${_PYTHON_PREFIX}_SABI_LIBRARY_RELEASE + _${_PYTHON_PREFIX}_SABI_LIBRARY_DEBUG + _${_PYTHON_PREFIX}_RUNTIME_SABI_LIBRARY_RELEASE + _${_PYTHON_PREFIX}_RUNTIME_SABI_LIBRARY_DEBUG _${_PYTHON_PREFIX}_INCLUDE_DIR _${_PYTHON_PREFIX}_CONFIG _${_PYTHON_PREFIX}_DEVELOPMENT_MODULE_SIGNATURE @@ -3133,7 +3700,7 @@ if ("NumPy" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS AND ${_PYTHON_PREFIX}_Inte set (${_PYTHON_PREFIX}_NumPy_INCLUDE_DIRS "${_${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR}") if(_${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR AND NOT EXISTS "${_${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR}") - set (_${_PYTHON_PREFIX}_NumPy_REASON_FAILURE "Cannot find the directory \"${_${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR}\"") + set_property (CACHE _${_PYTHON_PREFIX}_NumPy_REASON_FAILURE PROPERTY VALUE "Cannot find the directory \"${_${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR}\"") set_property (CACHE _${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR PROPERTY VALUE "${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR-NOTFOUND") endif() @@ -3155,7 +3722,7 @@ if ("NumPy" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS AND ${_PYTHON_PREFIX}_Inte endif() if (${_PYTHON_PREFIX}_NumPy_FOUND) - unset (_${_PYTHON_PREFIX}_NumPy_REASON_FAILURE) + unset (_${_PYTHON_PREFIX}_NumPy_REASON_FAILURE CACHE) # compute and save numpy signature string (MD5 __${_PYTHON_PREFIX}_NUMPY_SIGNATURE "${_${_PYTHON_PREFIX}_INTERPRETER_SIGNATURE}:${_${_PYTHON_PREFIX}_DEVELOPMENT_MODULE_SIGNATURE}:${${_PYTHON_PREFIX}_NumPyINCLUDE_DIR}") @@ -3183,9 +3750,16 @@ endif() unset (_${_PYTHON_PREFIX}_REASON_FAILURE) foreach (_${_PYTHON_PREFIX}_COMPONENT IN ITEMS Interpreter Compiler Development NumPy) + if (_${_PYTHON_PREFIX}_COMPONENT STREQUAL "Development") + foreach (artifact IN LISTS _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_ARTIFACTS) + if (_${_PYTHON_PREFIX}_Development_${artifact}_REASON_FAILURE) + _python_add_reason_failure ("Development" "${_${_PYTHON_PREFIX}_Development_${artifact}_REASON_FAILURE}") + endif() + endforeach() + endif() if (_${_PYTHON_PREFIX}_${_${_PYTHON_PREFIX}_COMPONENT}_REASON_FAILURE) string (APPEND _${_PYTHON_PREFIX}_REASON_FAILURE "\n ${_${_PYTHON_PREFIX}_COMPONENT}: ${_${_PYTHON_PREFIX}_${_${_PYTHON_PREFIX}_COMPONENT}_REASON_FAILURE}") - unset (_${_PYTHON_PREFIX}_${_${_PYTHON_PREFIX}_COMPONENT}_REASON_FAILURE) + unset (_${_PYTHON_PREFIX}_${_${_PYTHON_PREFIX}_COMPONENT}_REASON_FAILURE CACHE) endif() endforeach() @@ -3216,12 +3790,19 @@ if(_${_PYTHON_PREFIX}_CMAKE_ROLE STREQUAL "PROJECT") if (("Development.Module" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS AND ${_PYTHON_PREFIX}_Development.Module_FOUND) + OR ("Development.SABIModule" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS + AND ${_PYTHON_PREFIX}_Development.SABIModule_FOUND) OR ("Development.Embed" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS AND ${_PYTHON_PREFIX}_Development.Embed_FOUND)) macro (__PYTHON_IMPORT_LIBRARY __name) - if (${_PYTHON_PREFIX}_LIBRARY_RELEASE MATCHES "${CMAKE_SHARED_LIBRARY_SUFFIX}$" - OR ${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE) + if (${ARGC} GREATER 1) + set (_PREFIX "${ARGV1}_") + else() + set (_PREFIX "") + endif() + if (${_PYTHON_PREFIX}_${_PREFIX}LIBRARY_RELEASE MATCHES "${CMAKE_SHARED_LIBRARY_SUFFIX}$" + OR ${_PYTHON_PREFIX}_RUNTIME_${_PREFIX}LIBRARY_RELEASE) set (_${_PYTHON_PREFIX}_LIBRARY_TYPE SHARED) else() set (_${_PYTHON_PREFIX}_LIBRARY_TYPE STATIC) @@ -3234,37 +3815,37 @@ if(_${_PYTHON_PREFIX}_CMAKE_ROLE STREQUAL "PROJECT") set_property (TARGET ${__name} PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${${_PYTHON_PREFIX}_INCLUDE_DIRS}") - if (${_PYTHON_PREFIX}_LIBRARY_RELEASE AND ${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE) + if (${_PYTHON_PREFIX}_${_PREFIX}LIBRARY_RELEASE AND ${_PYTHON_PREFIX}_RUNTIME_${_PREFIX}LIBRARY_RELEASE) # System manage shared libraries in two parts: import and runtime - if (${_PYTHON_PREFIX}_LIBRARY_RELEASE AND ${_PYTHON_PREFIX}_LIBRARY_DEBUG) + if (${_PYTHON_PREFIX}_${_PREFIX}LIBRARY_RELEASE AND ${_PYTHON_PREFIX}_${_PREFIX}LIBRARY_DEBUG) set_property (TARGET ${__name} PROPERTY IMPORTED_CONFIGURATIONS RELEASE DEBUG) set_target_properties (${__name} PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES_RELEASE "C" - IMPORTED_IMPLIB_RELEASE "${${_PYTHON_PREFIX}_LIBRARY_RELEASE}" - IMPORTED_LOCATION_RELEASE "${${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE}") + IMPORTED_IMPLIB_RELEASE "${${_PYTHON_PREFIX}_${_PREFIX}LIBRARY_RELEASE}" + IMPORTED_LOCATION_RELEASE "${${_PYTHON_PREFIX}_${_PREFIX}RUNTIME_LIBRARY_RELEASE}") set_target_properties (${__name} PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES_DEBUG "C" - IMPORTED_IMPLIB_DEBUG "${${_PYTHON_PREFIX}_LIBRARY_DEBUG}" - IMPORTED_LOCATION_DEBUG "${${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG}") + IMPORTED_IMPLIB_DEBUG "${${_PYTHON_PREFIX}_${_PREFIX}LIBRARY_DEBUG}" + IMPORTED_LOCATION_DEBUG "${${_PYTHON_PREFIX}_RUNTIME_${_PREFIX}LIBRARY_DEBUG}") else() set_target_properties (${__name} PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES "C" - IMPORTED_IMPLIB "${${_PYTHON_PREFIX}_LIBRARIES}" - IMPORTED_LOCATION "${${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE}") + IMPORTED_IMPLIB "${${_PYTHON_PREFIX}_${_PREFIX}LIBRARIES}" + IMPORTED_LOCATION "${${_PYTHON_PREFIX}_RUNTIME_${_PREFIX}LIBRARY_RELEASE}") endif() else() - if (${_PYTHON_PREFIX}_LIBRARY_RELEASE AND ${_PYTHON_PREFIX}_LIBRARY_DEBUG) + if (${_PYTHON_PREFIX}_${_PREFIX}LIBRARY_RELEASE AND ${_PYTHON_PREFIX}_${_PREFIX}LIBRARY_DEBUG) set_property (TARGET ${__name} PROPERTY IMPORTED_CONFIGURATIONS RELEASE DEBUG) set_target_properties (${__name} PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES_RELEASE "C" - IMPORTED_LOCATION_RELEASE "${${_PYTHON_PREFIX}_LIBRARY_RELEASE}") + IMPORTED_LOCATION_RELEASE "${${_PYTHON_PREFIX}_${_PREFIX}LIBRARY_RELEASE}") set_target_properties (${__name} PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES_DEBUG "C" - IMPORTED_LOCATION_DEBUG "${${_PYTHON_PREFIX}_LIBRARY_DEBUG}") + IMPORTED_LOCATION_DEBUG "${${_PYTHON_PREFIX}_${_PREFIX}LIBRARY_DEBUG}") else() set_target_properties (${__name} PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES "C" - IMPORTED_LOCATION "${${_PYTHON_PREFIX}_LIBRARY_RELEASE}") + IMPORTED_LOCATION "${${_PYTHON_PREFIX}_${_PREFIX}LIBRARY_RELEASE}") endif() endif() @@ -3283,6 +3864,28 @@ if(_${_PYTHON_PREFIX}_CMAKE_ROLE STREQUAL "PROJECT") endif() endmacro() + macro (__PYTHON_IMPORT_MODULE __name) + if (NOT TARGET ${__name}) + add_library (${__name} INTERFACE IMPORTED) + endif() + set_property (TARGET ${__name} + PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${${_PYTHON_PREFIX}_INCLUDE_DIRS}") + + # When available, enforce shared library generation with undefined symbols + if (APPLE) + set_property (TARGET ${__name} + PROPERTY INTERFACE_LINK_OPTIONS "LINKER:-undefined,dynamic_lookup") + endif() + if (CMAKE_SYSTEM_NAME STREQUAL "SunOS") + set_property (TARGET ${__name} + PROPERTY INTERFACE_LINK_OPTIONS "LINKER:-z,nodefs") + endif() + if (CMAKE_SYSTEM_NAME STREQUAL "AIX") + set_property (TARGET ${__name} + PROPERTY INTERFACE_LINK_OPTIONS "LINKER:-b,erok") + endif() + endmacro() + if (${_PYTHON_PREFIX}_Development.Embed_FOUND) __python_import_library (${_PYTHON_PREFIX}::Python) endif() @@ -3293,25 +3896,15 @@ if(_${_PYTHON_PREFIX}_CMAKE_ROLE STREQUAL "PROJECT") # but ALIAS cannot be used because the imported library is not GLOBAL. __python_import_library (${_PYTHON_PREFIX}::Module) else() - if (NOT TARGET ${_PYTHON_PREFIX}::Module) - add_library (${_PYTHON_PREFIX}::Module INTERFACE IMPORTED) - endif() - set_property (TARGET ${_PYTHON_PREFIX}::Module - PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${${_PYTHON_PREFIX}_INCLUDE_DIRS}") + __python_import_module (${_PYTHON_PREFIX}::Module) + endif() + endif() - # When available, enforce shared library generation with undefined symbols - if (APPLE) - set_property (TARGET ${_PYTHON_PREFIX}::Module - PROPERTY INTERFACE_LINK_OPTIONS "LINKER:-undefined,dynamic_lookup") - endif() - if (CMAKE_SYSTEM_NAME STREQUAL "SunOS") - set_property (TARGET ${_PYTHON_PREFIX}::Module - PROPERTY INTERFACE_LINK_OPTIONS "LINKER:-z,nodefs") - endif() - if (CMAKE_SYSTEM_NAME STREQUAL "AIX") - set_property (TARGET ${_PYTHON_PREFIX}::Module - PROPERTY INTERFACE_LINK_OPTIONS "LINKER:-b,erok") - endif() + if (${_PYTHON_PREFIX}_Development.SABIModule_FOUND) + if ("SABI_LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_SABIMODULE_ARTIFACTS) + __python_import_library (${_PYTHON_PREFIX}::SABIModule SABI) + else() + __python_import_module (${_PYTHON_PREFIX}::SABIModule) endif() endif() @@ -3320,7 +3913,7 @@ if(_${_PYTHON_PREFIX}_CMAKE_ROLE STREQUAL "PROJECT") # It is used to build modules for python. # function (__${_PYTHON_PREFIX}_ADD_LIBRARY prefix name) - cmake_parse_arguments (PARSE_ARGV 2 PYTHON_ADD_LIBRARY "STATIC;SHARED;MODULE;WITH_SOABI" "" "") + cmake_parse_arguments (PARSE_ARGV 2 PYTHON_ADD_LIBRARY "STATIC;SHARED;MODULE;WITH_SOABI" "USE_SABI" "") if (PYTHON_ADD_LIBRARY_STATIC) set (type STATIC) @@ -3330,9 +3923,51 @@ if(_${_PYTHON_PREFIX}_CMAKE_ROLE STREQUAL "PROJECT") set (type MODULE) endif() - if (type STREQUAL "MODULE" AND NOT TARGET ${prefix}::Module) - message (SEND_ERROR "${prefix}_ADD_LIBRARY: dependent target '${prefix}::Module' is not defined.\n Did you miss to request COMPONENT 'Development.Module'?") - return() + if (PYTHON_ADD_LIBRARY_USE_SABI) + if (NOT type STREQUAL MODULE) + message (SEND_ERROR "${prefix}_ADD_LIBRARY: 'USE_SABI' option is only valid for 'MODULE' type.") + return() + endif() + if (NOT PYTHON_ADD_LIBRARY_USE_SABI MATCHES "^(3)(\\.([0-9]+))?$") + message (SEND_ERROR "${prefix}_ADD_LIBRARY: ${PYTHON_ADD_LIBRARY_USE_SABI}: wrong version specified for 'USE_SABI'.") + return() + endif() + # compute value for Py_LIMITED_API macro + set (major_version "${CMAKE_MATCH_1}") + unset (minor_version) + if (CMAKE_MATCH_3) + set (minor_version "${CMAKE_MATCH_3}") + endif() + if (major_version EQUAL "3" AND NOT minor_version) + set (Py_LIMITED_API "3") + elseif ("${major_version}.${minor_version}" VERSION_LESS "3.2") + message (SEND_ERROR "${prefix}_ADD_LIBRARY: ${PYTHON_ADD_LIBRARY_USE_SABI}: invalid version. Version must be '3.2' or upper.") + return() + else() + set (Py_LIMITED_API "0x0${major_version}") + if (NOT minor_version) + string (APPEND Py_LIMITED_API "00") + else() + if (minor_version LESS 16) + string (APPEND Py_LIMITED_API "0") + endif() + math (EXPR minor_version "${minor_version}" OUTPUT_FORMAT HEXADECIMAL) + string (REGEX REPLACE "^0x(.+)$" "\\1" minor_version "${minor_version}") + string (APPEND Py_LIMITED_API "${minor_version}") + endif() + string (APPEND Py_LIMITED_API "0000") + endif() + endif() + + if (type STREQUAL "MODULE") + if (PYTHON_ADD_LIBRARY_USE_SABI AND NOT TARGET ${prefix}::SABIModule) + message (SEND_ERROR "${prefix}_ADD_LIBRARY: dependent target '${prefix}::SABIModule' is not defined.\n Did you miss to request COMPONENT 'Development.SABIModule'?") + return() + endif() + if (NOT PYTHON_ADD_LIBRARY_USE_SABI AND NOT TARGET ${prefix}::Module) + message (SEND_ERROR "${prefix}_ADD_LIBRARY: dependent target '${prefix}::Module' is not defined.\n Did you miss to request COMPONENT 'Development.Module'?") + return() + endif() endif() if (NOT type STREQUAL "MODULE" AND NOT TARGET ${prefix}::Python) message (SEND_ERROR "${prefix}_ADD_LIBRARY: dependent target '${prefix}::Python' is not defined.\n Did you miss to request COMPONENT 'Development.Embed'?") @@ -3344,23 +3979,37 @@ if(_${_PYTHON_PREFIX}_CMAKE_ROLE STREQUAL "PROJECT") get_property (type TARGET ${name} PROPERTY TYPE) if (type STREQUAL "MODULE_LIBRARY") - target_link_libraries (${name} PRIVATE ${prefix}::Module) + if (PYTHON_ADD_LIBRARY_USE_SABI) + target_compile_definitions (${name} PRIVATE Py_LIMITED_API=${Py_LIMITED_API}) + target_link_libraries (${name} PRIVATE ${prefix}::SABIModule) + else() + target_link_libraries (${name} PRIVATE ${prefix}::Module) + endif() # customize library name to follow module name rules set_property (TARGET ${name} PROPERTY PREFIX "") if(CMAKE_SYSTEM_NAME STREQUAL "Windows") set_property (TARGET ${name} PROPERTY SUFFIX ".pyd") endif() - if (PYTHON_ADD_LIBRARY_WITH_SOABI AND ${prefix}_SOABI) - get_property (suffix TARGET ${name} PROPERTY SUFFIX) - if (NOT suffix) - set (suffix "${CMAKE_SHARED_MODULE_SUFFIX}") + if (PYTHON_ADD_LIBRARY_WITH_SOABI) + if (NOT PYTHON_ADD_LIBRARY_USE_SABI AND ${prefix}_SOABI) + get_property (suffix TARGET ${name} PROPERTY SUFFIX) + if (NOT suffix) + set (suffix "${CMAKE_SHARED_MODULE_SUFFIX}") + endif() + set_property (TARGET ${name} PROPERTY SUFFIX ".${${prefix}_SOABI}${suffix}") + endif() + if (PYTHON_ADD_LIBRARY_USE_SABI AND ${prefix}_SOSABI) + get_property (suffix TARGET ${name} PROPERTY SUFFIX) + if (NOT suffix) + set (suffix "${CMAKE_SHARED_MODULE_SUFFIX}") + endif() + set_property (TARGET ${name} PROPERTY SUFFIX ".${${prefix}_SOSABI}${suffix}") endif() - set_property (TARGET ${name} PROPERTY SUFFIX ".${${prefix}_SOABI}${suffix}") endif() else() - if (PYTHON_ADD_LIBRARY_WITH_SOABI) - message (AUTHOR_WARNING "Find${prefix}: Option `WITH_SOABI` is only supported for `MODULE` library type.") + if (PYTHON_ADD_LIBRARY_WITH_SOABI OR PYTHON_ADD_LIBRARY_USE_SABI) + message (AUTHOR_WARNING "Find${prefix}: Options 'WITH_SOABI' and 'USE_SABI' are only supported for `MODULE` library type.") endif() target_link_libraries (${name} PRIVATE ${prefix}::Python) endif() diff --git a/Modules/FindPython2.cmake b/Modules/FindPython2.cmake index 0888fad..41d9b68 100644 --- a/Modules/FindPython2.cmake +++ b/Modules/FindPython2.cmake @@ -57,7 +57,7 @@ for you. If components ``Interpreter`` and ``Development`` (or one of its sub-components) are both specified, this module search only for interpreter - with same platform architecture as the one defined by ``CMake`` + with same platform architecture as the one defined by CMake configuration. This constraint does not apply if only ``Interpreter`` component is specified. @@ -302,7 +302,7 @@ Hints ``Anaconda`` or ``ActivePython``, rely on this implementation. * ``IronPython``: This implementation use the ``CSharp`` language for ``.NET Framework`` on top of the `Dynamic Language Runtime` (``DLR``). - See `IronPython <http://ironpython.net>`_. + See `IronPython <https://ironpython.net>`_. * ``PyPy``: This implementation use ``RPython`` language and ``RPython translation toolchain`` to produce the python interpreter. See `PyPy <https://www.pypy.org>`_. @@ -388,7 +388,7 @@ setting the following variables: By default, this module supports multiple calls in different directories of a project with different version/component requirements while providing correct -and consistent results for each call. To support this behavior, ``CMake`` cache +and consistent results for each call. To support this behavior, CMake cache is not used in the traditional way which can be problematic for interactive specification. So, to enable also interactive specification, module behavior can be controlled with the following variable: diff --git a/Modules/FindPython3.cmake b/Modules/FindPython3.cmake index 145c95e..ae086e8 100644 --- a/Modules/FindPython3.cmake +++ b/Modules/FindPython3.cmake @@ -31,6 +31,13 @@ The following components are supported: * ``Development.Embed``: search for artifacts for Python 3 embedding developments. + .. versionadded:: 3.26 + + * ``Development.SABIModule``: search for artifacts for Python 3 module + developments using the + `Stable Application Binary Interface <https://docs.python.org/3/c-api/stable.html>`_. + This component is available only for version ``3.2`` and upper. + * ``NumPy``: search for NumPy include directories. .. versionadded:: 3.14 @@ -57,7 +64,7 @@ for you. If components ``Interpreter`` and ``Development`` (or one of its sub-components) are both specified, this module search only for interpreter - with same platform architecture as the one defined by ``CMake`` + with same platform architecture as the one defined by CMake configuration. This constraint does not apply if only ``Interpreter`` component is specified. @@ -81,6 +88,12 @@ This module defines the following :ref:`Imported Targets <Imported Targets>`: Python 3 library for Python module. Target defined if component ``Development.Module`` is found. +``Python3::SABIModule`` + .. versionadded:: 3.26 + + Python 3 library for Python module using the Stable Application Binary + Interface. Target defined if component ``Development.SABIModule`` is found. + ``Python3::Python`` Python 3 library for Python embedding. Target defined if component ``Development.Embed`` is found. @@ -140,12 +153,21 @@ This module will set the following variables in your project Extension suffix for modules. - Information returned by - ``distutils.sysconfig.get_config_var('SOABI')`` or computed from - ``distutils.sysconfig.get_config_var('EXT_SUFFIX')`` or + Information computed from ``distutils.sysconfig.get_config_var('EXT_SUFFIX')`` + or ``distutils.sysconfig.get_config_var('SOABI')`` or ``python3-config --extension-suffix``. If package ``distutils.sysconfig`` is - not available, ``sysconfig.get_config_var('SOABI')`` or - ``sysconfig.get_config_var('EXT_SUFFIX')`` are used. + not available, ``sysconfig.get_config_var('EXT_SUFFIX')`` or + ``sysconfig.get_config_var('SOABI')`` are used. + +``Python3_SOSABI`` + .. versionadded:: 3.26 + + Extension suffix for modules using the Stable Application Binary Interface. + + Information computed from ``importlib.machinery.EXTENSION_SUFFIXES`` if the + COMPONENT ``Interpreter`` was specified. Otherwise, the extension is ``abi3`` + except for ``Windows``, ``MSYS`` and ``CYGWIN`` for which this is an empty + string. ``Python3_Compiler_FOUND`` System has the Python 3 compiler. @@ -169,6 +191,12 @@ This module will set the following variables in your project System has the Python 3 development artifacts for Python module. +``Python3_Development.SABIModule_FOUND`` + .. versionadded:: 3.26 + + System has the Python 3 development artifacts for Python module using the + Stable Application Binary Interface. + ``Python3_Development.Embed_FOUND`` .. versionadded:: 3.18 @@ -190,6 +218,18 @@ This module will set the following variables in your project The Python 3 library directories. ``Python3_RUNTIME_LIBRARY_DIRS`` The Python 3 runtime library directories. +``Python3_SABI_LIBRARIES`` + .. versionadded:: 3.26 + + The Python 3 libraries for the Stable Application Binary Interface. +``Python3_SABI_LIBRARY_DIRS`` + .. versionadded:: 3.26 + + The Python 3 ``SABI`` library directories. +``Python3_RUNTIME_SABI_LIBRARY_DIRS`` + .. versionadded:: 3.26 + + The Python 3 runtime ``SABI`` library directories. ``Python3_VERSION`` Python 3 version. ``Python3_VERSION_MAJOR`` @@ -239,8 +279,8 @@ Hints ``Python3_FIND_ABI`` .. versionadded:: 3.16 - This variable defines which ABIs, as defined in - `PEP 3149 <https://www.python.org/dev/peps/pep-3149/>`_, should be searched. + This variable defines which ABIs, as defined in :pep:`3149`, should be + searched. .. note:: @@ -361,7 +401,7 @@ Hints ``Anaconda`` or ``ActivePython``, rely on this implementation. * ``IronPython``: This implementation use the ``CSharp`` language for ``.NET Framework`` on top of the `Dynamic Language Runtime` (``DLR``). - See `IronPython <http://ironpython.net>`_. + See `IronPython <https://ironpython.net>`_. * ``PyPy``: This implementation use ``RPython`` language and ``RPython translation toolchain`` to produce the python interpreter. See `PyPy <https://www.pypy.org>`_. @@ -424,6 +464,13 @@ setting the following variables: variables ``Python3_LIBRARIES``, ``Python3_LIBRARY_DIRS`` and ``Python3_RUNTIME_LIBRARY_DIRS``. +``Python3_SABI_LIBRARY`` + .. versionadded:: 3.26 + + The path to the library for Stable Application Binary Interface. It will be + used to compute the variables ``Python3_SABI_LIBRARIES``, + ``Python3_SABI_LIBRARY_DIRS`` and ``Python3_RUNTIME_SABI_LIBRARY_DIRS``. + ``Python3_INCLUDE_DIR`` The path to the directory of the ``Python`` headers. It will be used to compute the variable ``Python3_INCLUDE_DIRS``. @@ -447,7 +494,7 @@ setting the following variables: By default, this module supports multiple calls in different directories of a project with different version/component requirements while providing correct -and consistent results for each call. To support this behavior, ``CMake`` cache +and consistent results for each call. To support this behavior, CMake cache is not used in the traditional way which can be problematic for interactive specification. So, to enable also interactive specification, module behavior can be controlled with the following variable: @@ -469,10 +516,11 @@ Commands This module defines the command ``Python3_add_library`` (when :prop_gbl:`CMAKE_ROLE` is ``PROJECT``), which has the same semantics as :command:`add_library` and adds a dependency to target ``Python3::Python`` or, -when library type is ``MODULE``, to target ``Python3::Module`` and takes care +when library type is ``MODULE``, to target ``Python3::Module`` or +``Python3::SABIModule`` (when ``USE_SABI`` option is specified) and takes care of Python module naming rules:: - Python3_add_library (<name> [STATIC | SHARED | MODULE [WITH_SOABI]] + Python3_add_library (<name> [STATIC | SHARED | MODULE [USE_SABI <version>] [WITH_SOABI]] <source1> [<source2> ...]) If the library type is not specified, ``MODULE`` is assumed. @@ -480,6 +528,19 @@ If the library type is not specified, ``MODULE`` is assumed. .. versionadded:: 3.17 For ``MODULE`` library type, if option ``WITH_SOABI`` is specified, the module suffix will include the ``Python3_SOABI`` value, if any. + +.. versionadded:: 3.26 + For ``MODULE`` type, if the option ``USE_SABI`` is specified, the + preprocessor definition ``Py_LIMITED_API`` will be specified, as ``PRIVATE``, + for the target ``<name>`` with the value computed from ``<version>`` argument. + The expected format for ``<version>`` is ``major[.minor]``, where each + component is a numeric value. If ``minor`` component is specified, the + version should be, at least, ``3.2`` which is the version where the + `Stable Application Binary Interface <https://docs.python.org/3/c-api/stable.html>`_ + was introduced. Specifying only major version ``3`` is equivalent to ``3.2``. + + When option ``WITH_SOABI`` is also specified, the module suffix will include + the ``Python3_SOSABI`` value, if any. #]=======================================================================] diff --git a/Modules/FindQt4.cmake b/Modules/FindQt4.cmake index ec0f453..3154ad3 100644 --- a/Modules/FindQt4.cmake +++ b/Modules/FindQt4.cmake @@ -623,7 +623,7 @@ if (QT_QMAKE_EXECUTABLE AND endif() set(Qt4_FOUND FALSE) if(Qt4_FIND_REQUIRED) - message( FATAL_ERROR "Could NOT find QtCore. Check ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log for more details.") + message( FATAL_ERROR "Could NOT find QtCore.") else() return() endif() diff --git a/Modules/FindRuby.cmake b/Modules/FindRuby.cmake index a80758d..d82f41d 100644 --- a/Modules/FindRuby.cmake +++ b/Modules/FindRuby.cmake @@ -71,9 +71,6 @@ Hints .. versionadded:: 3.18 -``Ruby_ROOT_DIR`` - Define the root directory of a Ruby installation. - ``Ruby_FIND_VIRTUALENV`` This variable defines the handling of virtual environments managed by ``rvm``. It is meaningful only when a virtual environment @@ -369,56 +366,17 @@ if(Ruby_EXECUTABLE AND NOT Ruby_VERSION_MAJOR) set(Ruby_VERSION_MAJOR 1) set(Ruby_VERSION_MINOR 9) endif() - # check whether we found 2.0.x - if(${Ruby_EXECUTABLE} MATCHES "ruby2\\.?0") - set(Ruby_VERSION_MAJOR 2) - set(Ruby_VERSION_MINOR 0) - endif() - # check whether we found 2.1.x - if(${Ruby_EXECUTABLE} MATCHES "ruby2\\.?1") - set(Ruby_VERSION_MAJOR 2) - set(Ruby_VERSION_MINOR 1) - endif() - # check whether we found 2.2.x - if(${Ruby_EXECUTABLE} MATCHES "ruby2\\.?2") - set(Ruby_VERSION_MAJOR 2) - set(Ruby_VERSION_MINOR 2) - endif() - # check whether we found 2.3.x - if(${Ruby_EXECUTABLE} MATCHES "ruby2\\.?3") - set(Ruby_VERSION_MAJOR 2) - set(Ruby_VERSION_MINOR 3) - endif() - # check whether we found 2.4.x - if(${Ruby_EXECUTABLE} MATCHES "ruby2\\.?4") + # check whether we found 2.[0-7].x + if(${Ruby_EXECUTABLE} MATCHES "ruby2") set(Ruby_VERSION_MAJOR 2) - set(Ruby_VERSION_MINOR 4) + string(REGEX_REPLACE ${Ruby_EXECUTABLE} "ruby2\\.?([0-7])" "\\1" Ruby_VERSION_MINOR) endif() - # check whether we found 2.5.x - if(${Ruby_EXECUTABLE} MATCHES "ruby2\\.?5") - set(Ruby_VERSION_MAJOR 2) - set(Ruby_VERSION_MINOR 5) - endif() - # check whether we found 2.6.x - if(${Ruby_EXECUTABLE} MATCHES "ruby2\\.?6") - set(Ruby_VERSION_MAJOR 2) - set(Ruby_VERSION_MINOR 6) - endif() - # check whether we found 2.7.x - if(${Ruby_EXECUTABLE} MATCHES "ruby2\\.?7") - set(Ruby_VERSION_MAJOR 2) - set(Ruby_VERSION_MINOR 7) - endif() - # check whether we found 3.0.x - if(${Ruby_EXECUTABLE} MATCHES "ruby3\\.?0") - set(Ruby_VERSION_MAJOR 3) - set(Ruby_VERSION_MINOR 0) - endif() - # check whether we found 3.1.x - if(${Ruby_EXECUTABLE} MATCHES "ruby3\\.?1") + # check whether we found 3.[0-1].x + if(${Ruby_EXECUTABLE} MATCHES "ruby3") set(Ruby_VERSION_MAJOR 3) - set(Ruby_VERSION_MINOR 1) + string(REGEX_REPLACE ${Ruby_EXECUTABLE} "ruby3\\.?([0-1])" "\\1" Ruby_VERSION_MINOR) endif() + endif() if(Ruby_VERSION_MAJOR) diff --git a/Modules/FindSDL_gfx.cmake b/Modules/FindSDL_gfx.cmake new file mode 100644 index 0000000..2dd96e9 --- /dev/null +++ b/Modules/FindSDL_gfx.cmake @@ -0,0 +1,86 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + +#[=======================================================================[.rst: +FindSDL_gfx +----------- + +.. versionadded:: 3.25 + +Locate SDL_gfx library + +This module defines: + +:: + + SDL::SDL_gfx, the name of the target to use with target_*() commands + SDL_GFX_LIBRARIES, the name of the library to link against + SDL_GFX_INCLUDE_DIRS, where to find the headers + SDL_GFX_FOUND, if false, do not try to link against + SDL_GFX_VERSION_STRING - human-readable string containing the + version of SDL_gfx + +``$SDLDIR`` is an environment variable that would correspond to the +``./configure --prefix=$SDLDIR`` used in building SDL. +#]=======================================================================] + +find_path(SDL_GFX_INCLUDE_DIRS + NAMES + SDL_framerate.h + SDL_gfxBlitFunc.h + SDL_gfxPrimitives.h + SDL_gfxPrimitives_font.h + SDL_imageFilter.h + SDL_rotozoom.h + HINTS + ENV SDLGFXDIR + ENV SDLDIR + PATH_SUFFIXES SDL + # path suffixes to search inside ENV{SDLDIR} + include/SDL include/SDL12 include/SDL11 include +) + +if(CMAKE_SIZEOF_VOID_P EQUAL 8) + set(VC_LIB_PATH_SUFFIX lib/x64) +else() + set(VC_LIB_PATH_SUFFIX lib/x86) +endif() + +find_library(SDL_GFX_LIBRARIES + NAMES SDL_gfx + HINTS + ENV SDLGFXDIR + ENV SDLDIR + PATH_SUFFIXES lib ${VC_LIB_PATH_SUFFIX} +) + +if(SDL_GFX_INCLUDE_DIRS AND EXISTS "${SDL_GFX_INCLUDE_DIRS}/SDL_gfxPrimitives.h") + file(STRINGS "${SDL_GFX_INCLUDE_DIRS}/SDL_gfxPrimitives.h" SDL_GFX_VERSION_MAJOR_LINE REGEX "^#define[ \t]+SDL_GFXPRIMITIVES_MAJOR[ \t]+[0-9]+$") + file(STRINGS "${SDL_GFX_INCLUDE_DIRS}/SDL_gfxPrimitives.h" SDL_GFX_VERSION_MINOR_LINE REGEX "^#define[ \t]+SDL_GFXPRIMITIVES_MINOR[ \t]+[0-9]+$") + file(STRINGS "${SDL_GFX_INCLUDE_DIRS}/SDL_gfxPrimitives.h" SDL_GFX_VERSION_PATCH_LINE REGEX "^#define[ \t]+SDL_GFXPRIMITIVES_MICRO[ \t]+[0-9]+$") + string(REGEX REPLACE "^#define[ \t]+SDL_GFXPRIMITIVES_MAJOR[ \t]+([0-9]+)$" "\\1" SDL_GFX_VERSION_MAJOR "${SDL_GFX_VERSION_MAJOR_LINE}") + string(REGEX REPLACE "^#define[ \t]+SDL_GFXPRIMITIVES_MINOR[ \t]+([0-9]+)$" "\\1" SDL_GFX_VERSION_MINOR "${SDL_GFX_VERSION_MINOR_LINE}") + string(REGEX REPLACE "^#define[ \t]+SDL_GFXPRIMITIVES_MICRO[ \t]+([0-9]+)$" "\\1" SDL_GFX_VERSION_PATCH "${SDL_GFX_VERSION_PATCH_LINE}") + set(SDL_GFX_VERSION_STRING ${SDL_GFX_VERSION_MAJOR}.${SDL_GFX_VERSION_MINOR}.${SDL_GFX_VERSION_PATCH}) + unset(SDL_GFX_VERSION_MAJOR_LINE) + unset(SDL_GFX_VERSION_MINOR_LINE) + unset(SDL_GFX_VERSION_PATCH_LINE) + unset(SDL_GFX_VERSION_MAJOR) + unset(SDL_GFX_VERSION_MINOR) + unset(SDL_GFX_VERSION_PATCH) +endif() + +include(FindPackageHandleStandardArgs) + +FIND_PACKAGE_HANDLE_STANDARD_ARGS(SDL_gfx + REQUIRED_VARS SDL_GFX_LIBRARIES SDL_GFX_INCLUDE_DIRS + VERSION_VAR SDL_GFX_VERSION_STRING) + +if(SDL_gfx_FOUND) + if(NOT TARGET SDL::SDL_gfx) + add_library(SDL::SDL_gfx INTERFACE IMPORTED) + set_target_properties(SDL::SDL_gfx PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES "${SDL_GFX_INCLUDE_DIRS}" + INTERFACE_LINK_LIBRARIES "${SDL_GFX_LIBRARIES}") + endif() +endif() diff --git a/Modules/FindSDL_image.cmake b/Modules/FindSDL_image.cmake index e687b49..324fef5 100644 --- a/Modules/FindSDL_image.cmake +++ b/Modules/FindSDL_image.cmake @@ -31,10 +31,6 @@ For backward compatibility the following variables are also set: $SDLDIR is an environment variable that would correspond to the ./configure --prefix=$SDLDIR used in building SDL. - -Created by Eric Wing. This was influenced by the FindSDL.cmake -module, but with modifications to recognize OS X frameworks and -additional Unix paths (FreeBSD, etc). #]=======================================================================] if(NOT SDL_IMAGE_INCLUDE_DIR AND SDLIMAGE_INCLUDE_DIR) diff --git a/Modules/FindSDL_mixer.cmake b/Modules/FindSDL_mixer.cmake index 315400a..8ed3cb4 100644 --- a/Modules/FindSDL_mixer.cmake +++ b/Modules/FindSDL_mixer.cmake @@ -31,10 +31,6 @@ For backward compatibility the following variables are also set: $SDLDIR is an environment variable that would correspond to the ./configure --prefix=$SDLDIR used in building SDL. - -Created by Eric Wing. This was influenced by the FindSDL.cmake -module, but with modifications to recognize OS X frameworks and -additional Unix paths (FreeBSD, etc). #]=======================================================================] if(NOT SDL_MIXER_INCLUDE_DIR AND SDLMIXER_INCLUDE_DIR) diff --git a/Modules/FindSDL_net.cmake b/Modules/FindSDL_net.cmake index 28cb4d6..639e5bd 100644 --- a/Modules/FindSDL_net.cmake +++ b/Modules/FindSDL_net.cmake @@ -30,10 +30,6 @@ For backward compatibility the following variables are also set: $SDLDIR is an environment variable that would correspond to the ./configure --prefix=$SDLDIR used in building SDL. - -Created by Eric Wing. This was influenced by the FindSDL.cmake -module, but with modifications to recognize OS X frameworks and -additional Unix paths (FreeBSD, etc). #]=======================================================================] if(NOT SDL_NET_INCLUDE_DIR AND SDLNET_INCLUDE_DIR) diff --git a/Modules/FindSDL_sound.cmake b/Modules/FindSDL_sound.cmake index 8d2f9f8..d863e3c 100644 --- a/Modules/FindSDL_sound.cmake +++ b/Modules/FindSDL_sound.cmake @@ -54,7 +54,19 @@ Typically, you should not use these variables directly, and you should use SDL_SOUND_LIBRARIES which contains SDL_SOUND_LIBRARY and the other audio libraries (if needed) to successfully compile on your system. -Created by Eric Wing. This module is a bit more complicated than the +Responds to the $SDLDIR and $SDLSOUNDDIR environmental variable that +would correspond to the ./configure --prefix=$SDLDIR used in building +SDL. + +On OSX, this will prefer the Framework version (if found) over others. +People will have to manually change the cache values of SDL_LIBRARY to +override this selectionor set the CMake environment CMAKE_INCLUDE_PATH +to modify the search paths. +#]=======================================================================] + + +#[[ +This module is a bit more complicated than the other FindSDL* family modules. The reason is that SDL_sound can be compiled in a large variety of different ways which are independent of platform. SDL_sound may dynamically link against other 3rd party @@ -70,16 +82,7 @@ This module uses a brute force approach to create a test program that uses SDL_sound, and then tries to build it. If the build fails, it parses the error output for known symbol names to figure out which libraries are needed. - -Responds to the $SDLDIR and $SDLSOUNDDIR environmental variable that -would correspond to the ./configure --prefix=$SDLDIR used in building -SDL. - -On OSX, this will prefer the Framework version (if found) over others. -People will have to manually change the cache values of SDL_LIBRARY to -override this selectionor set the CMake environment CMAKE_INCLUDE_PATH -to modify the search paths. -#]=======================================================================] +#]] set(SDL_SOUND_EXTRAS "" CACHE STRING "SDL_sound extra flags") mark_as_advanced(SDL_SOUND_EXTRAS) @@ -182,9 +185,9 @@ if(SDL_FOUND AND SDL_SOUND_INCLUDE_DIR AND SDL_SOUND_LIBRARY) try_compile( MY_RESULT - ${PROJECT_BINARY_DIR}/CMakeTmp - ${PROJECT_BINARY_DIR}/CMakeTmp - DetermineSoundLibs + PROJECT DetermineSoundLibs + SOURCE_DIR ${PROJECT_BINARY_DIR}/CMakeTmp + BINARY_DIR ${PROJECT_BINARY_DIR}/CMakeTmp OUTPUT_VARIABLE MY_OUTPUT ) diff --git a/Modules/FindSDL_ttf.cmake b/Modules/FindSDL_ttf.cmake index d5721da..d67c089 100644 --- a/Modules/FindSDL_ttf.cmake +++ b/Modules/FindSDL_ttf.cmake @@ -30,10 +30,6 @@ For backward compatibility the following variables are also set: $SDLDIR is an environment variable that would correspond to the ./configure --prefix=$SDLDIR used in building SDL. - -Created by Eric Wing. This was influenced by the FindSDL.cmake -module, but with modifications to recognize OS X frameworks and -additional Unix paths (FreeBSD, etc). #]=======================================================================] if(NOT SDL_TTF_INCLUDE_DIR AND SDLTTF_INCLUDE_DIR) diff --git a/Modules/FindSWIG.cmake b/Modules/FindSWIG.cmake index 7c610d9..370fff0 100644 --- a/Modules/FindSWIG.cmake +++ b/Modules/FindSWIG.cmake @@ -54,7 +54,7 @@ optional Fortran support: endif() endif() -.. _`SWIG`: http://swig.org +.. _SWIG: https://swig.org #]=======================================================================] diff --git a/Modules/FindThreads.cmake b/Modules/FindThreads.cmake index e4d6cf3..0fa6ae7 100644 --- a/Modules/FindThreads.cmake +++ b/Modules/FindThreads.cmake @@ -91,12 +91,27 @@ int main(void) # Internal helper macro. # Do NOT even think about using it outside of this file! -macro(_check_threads_lib LIBNAME FUNCNAME VARNAME) +macro(_threads_check_libc) + if(NOT Threads_FOUND) + if(CMAKE_C_COMPILER_LOADED) + CHECK_C_SOURCE_COMPILES("${PTHREAD_C_CXX_TEST_SOURCE}" CMAKE_HAVE_LIBC_PTHREAD) + elseif(CMAKE_CXX_COMPILER_LOADED) + CHECK_CXX_SOURCE_COMPILES("${PTHREAD_C_CXX_TEST_SOURCE}" CMAKE_HAVE_LIBC_PTHREAD) + endif() + if(CMAKE_HAVE_LIBC_PTHREAD) + set(CMAKE_THREAD_LIBS_INIT "") + set(Threads_FOUND TRUE) + endif() + endif () +endmacro() + +# Internal helper macro. +# Do NOT even think about using it outside of this file! +macro(_threads_check_lib LIBNAME FUNCNAME VARNAME) if(NOT Threads_FOUND) CHECK_LIBRARY_EXISTS(${LIBNAME} ${FUNCNAME} "" ${VARNAME}) if(${VARNAME}) set(CMAKE_THREAD_LIBS_INIT "-l${LIBNAME}") - set(CMAKE_HAVE_THREADS_LIBRARY 1) set(Threads_FOUND TRUE) endif() endif () @@ -104,25 +119,25 @@ endmacro() # Internal helper macro. # Do NOT even think about using it outside of this file! -macro(_check_pthreads_flag) +macro(_threads_check_flag_pthread) if(NOT Threads_FOUND) # If we did not find -lpthreads, -lpthread, or -lthread, look for -pthread - if(NOT DEFINED THREADS_HAVE_PTHREAD_ARG) + # except on compilers known to not have it. + if(MSVC) + # Compilers targeting the MSVC ABI do not have a -pthread flag. + set(THREADS_HAVE_PTHREAD_ARG FALSE) + elseif(NOT DEFINED THREADS_HAVE_PTHREAD_ARG) message(CHECK_START "Check if compiler accepts -pthread") if(CMAKE_C_COMPILER_LOADED) - set(_threads_src ${CMAKE_CURRENT_LIST_DIR}/CheckForPthreads.c) + set(_threads_src CheckForPthreads.c) elseif(CMAKE_CXX_COMPILER_LOADED) - set(_threads_src ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/FindThreads/CheckForPthreads.cxx) - configure_file(${CMAKE_CURRENT_LIST_DIR}/CheckForPthreads.c "${_threads_src}" COPYONLY) + set(_threads_src CheckForPthreads.cxx) endif() try_compile(THREADS_HAVE_PTHREAD_ARG - ${CMAKE_BINARY_DIR} - ${_threads_src} + SOURCE_FROM_FILE "${_threads_src}" "${CMAKE_CURRENT_LIST_DIR}/CheckForPthreads.c" CMAKE_FLAGS -DLINK_LIBRARIES:STRING=-pthread - OUTPUT_VARIABLE _cmake_check_pthreads_output) + ) - string(APPEND _cmake_find_threads_output "${_cmake_check_pthreads_output}") - unset(_cmake_check_pthreads_output) unset(_threads_src) if(THREADS_HAVE_PTHREAD_ARG) @@ -141,54 +156,27 @@ macro(_check_pthreads_flag) endif() endmacro() -# Do we have pthreads? -if(CMAKE_C_COMPILER_LOADED) - CHECK_INCLUDE_FILE("pthread.h" CMAKE_HAVE_PTHREAD_H) -else() - CHECK_INCLUDE_FILE_CXX("pthread.h" CMAKE_HAVE_PTHREAD_H) +# Check if pthread functions are in normal C library. +# We list some pthread functions in PTHREAD_C_CXX_TEST_SOURCE test code. +# If the pthread functions already exist in C library, we could just use +# them instead of linking to the additional pthread library. +_threads_check_libc() + +# Check for -pthread first if enabled. This is the recommended +# way, but not backwards compatible as one must also pass -pthread +# as compiler flag then. +if (THREADS_PREFER_PTHREAD_FLAG) + _threads_check_flag_pthread() +endif () + +if(CMAKE_SYSTEM MATCHES "GHS-MULTI") + _threads_check_lib(posix pthread_create CMAKE_HAVE_PTHREADS_CREATE) endif() +_threads_check_lib(pthreads pthread_create CMAKE_HAVE_PTHREADS_CREATE) +_threads_check_lib(pthread pthread_create CMAKE_HAVE_PTHREAD_CREATE) -if(CMAKE_HAVE_PTHREAD_H) - # - # We have pthread.h - # Let's check for the library now. - # - set(CMAKE_HAVE_THREADS_LIBRARY) - if(NOT THREADS_HAVE_PTHREAD_ARG) - # Check if pthread functions are in normal C library. - # We list some pthread functions in PTHREAD_C_CXX_TEST_SOURCE test code. - # If the pthread functions already exist in C library, we could just use - # them instead of linking to the additional pthread library. - if(CMAKE_C_COMPILER_LOADED) - CHECK_C_SOURCE_COMPILES("${PTHREAD_C_CXX_TEST_SOURCE}" CMAKE_HAVE_LIBC_PTHREAD) - elseif(CMAKE_CXX_COMPILER_LOADED) - CHECK_CXX_SOURCE_COMPILES("${PTHREAD_C_CXX_TEST_SOURCE}" CMAKE_HAVE_LIBC_PTHREAD) - endif() - if(CMAKE_HAVE_LIBC_PTHREAD) - set(CMAKE_THREAD_LIBS_INIT "") - set(CMAKE_HAVE_THREADS_LIBRARY 1) - set(Threads_FOUND TRUE) - else() - # Check for -pthread first if enabled. This is the recommended - # way, but not backwards compatible as one must also pass -pthread - # as compiler flag then. - if (THREADS_PREFER_PTHREAD_FLAG) - _check_pthreads_flag() - endif () - - if(CMAKE_SYSTEM MATCHES "GHS-MULTI") - _check_threads_lib(posix pthread_create CMAKE_HAVE_PTHREADS_CREATE) - endif() - _check_threads_lib(pthreads pthread_create CMAKE_HAVE_PTHREADS_CREATE) - _check_threads_lib(pthread pthread_create CMAKE_HAVE_PTHREAD_CREATE) - if(CMAKE_SYSTEM_NAME MATCHES "SunOS") - # On sun also check for -lthread - _check_threads_lib(thread thr_create CMAKE_HAVE_THR_CREATE) - endif() - endif() - endif() - - _check_pthreads_flag() +if (NOT THREADS_PREFER_PTHREAD_FLAG) + _threads_check_flag_pthread() endif() if(CMAKE_THREAD_LIBS_INIT OR CMAKE_HAVE_LIBC_PTHREAD) @@ -243,16 +231,10 @@ if(THREADS_FOUND AND NOT TARGET Threads::Threads) if(THREADS_HAVE_PTHREAD_ARG) set_property(TARGET Threads::Threads PROPERTY INTERFACE_COMPILE_OPTIONS "$<$<COMPILE_LANG_AND_ID:CUDA,NVIDIA>:SHELL:-Xcompiler -pthread>" - "$<$<NOT:$<COMPILE_LANG_AND_ID:CUDA,NVIDIA>>:-pthread>") + "$<$<AND:$<NOT:$<COMPILE_LANG_AND_ID:CUDA,NVIDIA>>,$<NOT:$<COMPILE_LANGUAGE:Swift>>>:-pthread>") endif() if(CMAKE_THREAD_LIBS_INIT) set_property(TARGET Threads::Threads PROPERTY INTERFACE_LINK_LIBRARIES "${CMAKE_THREAD_LIBS_INIT}") endif() -elseif(NOT THREADS_FOUND AND _cmake_find_threads_output) - file(APPEND - ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log - "Determining if compiler accepts -pthread failed with the following output:\n${_cmake_find_threads_output}\n\n") endif() - -unset(_cmake_find_threads_output) diff --git a/Modules/FindUnixCommands.cmake b/Modules/FindUnixCommands.cmake index 97739fa..d71518f 100644 --- a/Modules/FindUnixCommands.cmake +++ b/Modules/FindUnixCommands.cmake @@ -5,6 +5,10 @@ FindUnixCommands ---------------- +.. deprecated:: 3.26 + + Use :option:`${CMAKE_COMMAND} -E <cmake -E>` subcommands instead. + Find Unix commands, including the ones from Cygwin This module looks for the Unix commands ``bash``, ``cp``, ``gzip``, diff --git a/Modules/FindVulkan.cmake b/Modules/FindVulkan.cmake index 527ca8b..3817987 100644 --- a/Modules/FindVulkan.cmake +++ b/Modules/FindVulkan.cmake @@ -10,6 +10,40 @@ FindVulkan Find Vulkan, which is a low-overhead, cross-platform 3D graphics and computing API. +Optional COMPONENTS +^^^^^^^^^^^^^^^^^^^ + +.. versionadded:: 3.24 + +This module respects several optional COMPONENTS. +There are corresponding imported targets for each of these. + +``glslc`` + The SPIR-V compiler. + +``glslangValidator`` + The ``glslangValidator`` tool. + +``glslang`` + The SPIR-V generator library. + +``shaderc_combined`` + The static library for Vulkan shader compilation. + +``SPIRV-Tools`` + Tools to process SPIR-V modules. + +``MoltenVK`` + On macOS, an additional component ``MoltenVK`` is available. + +``dxc`` + .. versionadded:: 3.25 + + The DirectX Shader Compiler. + +The ``glslc`` and ``glslangValidator`` components are provided even +if not explicitly requested (for backward compatibility). + IMPORTED Targets ^^^^^^^^^^^^^^^^ @@ -36,6 +70,45 @@ This module defines :prop_tgt:`IMPORTED` targets if Vulkan has been found: The glslangValidator tool, if found. It is used to compile GLSL and HLSL shaders into SPIR-V. +``Vulkan::glslang`` + .. versionadded:: 3.24 + + Defined if SDK has the Khronos-reference front-end shader parser and SPIR-V + generator library (glslang). + +``Vulkan::shaderc_combined`` + .. versionadded:: 3.24 + + Defined if SDK has the Google static library for Vulkan shader compilation + (shaderc_combined). + +``Vulkan::SPIRV-Tools`` + .. versionadded:: 3.24 + + Defined if SDK has the Khronos library to process SPIR-V modules + (SPIRV-Tools). + +``Vulkan::MoltenVK`` + .. versionadded:: 3.24 + + Defined if SDK has the Khronos library which implement a subset of Vulkan API + over Apple Metal graphics framework. (MoltenVK). + +``Vulkan::volk`` + .. versionadded:: 3.25 + + Defined if SDK has the Vulkan meta-loader (volk). + +``Vulkan::dxc_lib`` + .. versionadded:: 3.25 + + Defined if SDK has the DirectX shader compiler library. + +``Vulkan::dxc_exe`` + .. versionadded:: 3.25 + + Defined if SDK has the DirectX shader compiler CLI tool. + Result Variables ^^^^^^^^^^^^^^^^ @@ -51,6 +124,45 @@ This module defines the following variables: .. versionadded:: 3.23 value from ``vulkan/vulkan_core.h`` +``Vulkan_glslc_FOUND`` + .. versionadded:: 3.24 + + True, if the SDK has the glslc executable. +``Vulkan_glslangValidator_FOUND`` + .. versionadded:: 3.24 + + True, if the SDK has the glslangValidator executable. +``Vulkan_glslang_FOUND`` + .. versionadded:: 3.24 + + True, if the SDK has the glslang library. +``Vulkan_shaderc_combined_FOUND`` + .. versionadded:: 3.24 + + True, if the SDK has the shaderc_combined library. +``Vulkan_SPIRV-Tools_FOUND`` + .. versionadded:: 3.24 + + True, if the SDK has the SPIRV-Tools library. +``Vulkan_MoltenVK_FOUND`` + .. versionadded:: 3.24 + + True, if the SDK has the MoltenVK library. +``Vulkan_volk_FOUND`` + .. versionadded:: 3.25 + + True, if the SDK has the volk library. + +``Vulkan_dxc_lib_FOUND`` + .. versionadded:: 3.25 + + True, if the SDK has the DirectX shader compiler library. + +``Vulkan_dxc_exe_FOUND`` + .. versionadded:: 3.25 + + True, if the SDK has the DirectX shader compiler CLI tool. + The module will also defines these cache variables: @@ -62,6 +174,37 @@ The module will also defines these cache variables: the path to the GLSL SPIR-V compiler ``Vulkan_GLSLANG_VALIDATOR_EXECUTABLE`` the path to the glslangValidator tool +``Vulkan_glslang_LIBRARY`` + .. versionadded:: 3.24 + + Path to the glslang library. +``Vulkan_shaderc_combined_LIBRARY`` + .. versionadded:: 3.24 + + Path to the shaderc_combined library. +``Vulkan_SPIRV-Tools_LIBRARY`` + .. versionadded:: 3.24 + + Path to the SPIRV-Tools library. +``Vulkan_MoltenVK_LIBRARY`` + .. versionadded:: 3.24 + + Path to the MoltenVK library. + +``Vulkan_volk_LIBRARY`` + .. versionadded:: 3.25 + + Path to the volk library. + +``Vulkan_dxc_LIBRARY`` + .. versionadded:: 3.25 + + Path to the DirectX shader compiler library. + +``Vulkan_dxc_EXECUTABLE`` + .. versionadded:: 3.25 + + Path to the DirectX shader compiler CLI tool. Hints ^^^^^ @@ -76,61 +219,337 @@ environment. #]=======================================================================] -if(WIN32) - find_path(Vulkan_INCLUDE_DIR - NAMES vulkan/vulkan.h - HINTS - "$ENV{VULKAN_SDK}/Include" +cmake_policy(PUSH) +cmake_policy(SET CMP0057 NEW) + +# Provide compatibility with a common invalid component request that +# was silently ignored prior to CMake 3.24. +if("FATAL_ERROR" IN_LIST Vulkan_FIND_COMPONENTS) + message(AUTHOR_WARNING + "Ignoring unknown component 'FATAL_ERROR'.\n" + "The find_package() command documents no such argument." ) + list(REMOVE_ITEM Vulkan_FIND_COMPONENTS "FATAL_ERROR") +endif() +# For backward compatibility as `FindVulkan` in previous CMake versions allow to retrieve `glslc` +# and `glslangValidator` without requesting the corresponding component. +if(NOT glslc IN_LIST Vulkan_FIND_COMPONENTS) + list(APPEND Vulkan_FIND_COMPONENTS glslc) +endif() +if(NOT glslangValidator IN_LIST Vulkan_FIND_COMPONENTS) + list(APPEND Vulkan_FIND_COMPONENTS glslangValidator) +endif() + +if(WIN32) + set(_Vulkan_library_name vulkan-1) + set(_Vulkan_hint_include_search_paths + "$ENV{VULKAN_SDK}/Include" + ) if(CMAKE_SIZEOF_VOID_P EQUAL 8) - find_library(Vulkan_LIBRARY - NAMES vulkan-1 - HINTS - "$ENV{VULKAN_SDK}/Lib" - "$ENV{VULKAN_SDK}/Bin" - ) - find_program(Vulkan_GLSLC_EXECUTABLE - NAMES glslc - HINTS - "$ENV{VULKAN_SDK}/Bin" - ) - find_program(Vulkan_GLSLANG_VALIDATOR_EXECUTABLE - NAMES glslangValidator - HINTS - "$ENV{VULKAN_SDK}/Bin" - ) - elseif(CMAKE_SIZEOF_VOID_P EQUAL 4) - find_library(Vulkan_LIBRARY - NAMES vulkan-1 - HINTS - "$ENV{VULKAN_SDK}/Lib32" - "$ENV{VULKAN_SDK}/Bin32" + set(_Vulkan_hint_executable_search_paths + "$ENV{VULKAN_SDK}/Bin" + ) + set(_Vulkan_hint_library_search_paths + "$ENV{VULKAN_SDK}/Lib" + "$ENV{VULKAN_SDK}/Bin" + ) + else() + set(_Vulkan_hint_executable_search_paths + "$ENV{VULKAN_SDK}/Bin32" + ) + set(_Vulkan_hint_library_search_paths + "$ENV{VULKAN_SDK}/Lib32" + "$ENV{VULKAN_SDK}/Bin32" + ) + endif() +else() + set(_Vulkan_library_name vulkan) + set(_Vulkan_hint_include_search_paths + "$ENV{VULKAN_SDK}/include" + ) + set(_Vulkan_hint_executable_search_paths + "$ENV{VULKAN_SDK}/bin" + ) + set(_Vulkan_hint_library_search_paths + "$ENV{VULKAN_SDK}/lib" + ) +endif() +if(APPLE AND DEFINED ENV{VULKAN_SDK}) + cmake_path(SET _MoltenVK_path NORMALIZE "$ENV{VULKAN_SDK}/../MoltenVK") + if(EXISTS "${_MoltenVK_path}") + list(APPEND _Vulkan_hint_include_search_paths + "${_MoltenVK_path}/include" + ) + if(CMAKE_SYSTEM_NAME STREQUAL "iOS") + list(APPEND _Vulkan_hint_library_search_paths + "${_MoltenVK_path}/dylib/iOS" ) - find_program(Vulkan_GLSLC_EXECUTABLE - NAMES glslc - HINTS - "$ENV{VULKAN_SDK}/Bin32" + elseif(CMAKE_SYSTEM_NAME STREQUAL "tvOS") + list(APPEND _Vulkan_hint_library_search_paths + "${_MoltenVK_path}/dylib/tvOS" ) - find_program(Vulkan_GLSLANG_VALIDATOR_EXECUTABLE - NAMES glslangValidator - HINTS - "$ENV{VULKAN_SDK}/Bin32" + else() + list(APPEND _Vulkan_hint_library_search_paths + "${_MoltenVK_path}/dylib/macOS" ) + endif() endif() -else() - find_path(Vulkan_INCLUDE_DIR - NAMES vulkan/vulkan.h - HINTS "$ENV{VULKAN_SDK}/include") - find_library(Vulkan_LIBRARY - NAMES vulkan - HINTS "$ENV{VULKAN_SDK}/lib") + unset(_MoltenVK_path) +endif() + +find_path(Vulkan_INCLUDE_DIR + NAMES vulkan/vulkan.h + HINTS + ${_Vulkan_hint_include_search_paths} + ) +mark_as_advanced(Vulkan_INCLUDE_DIR) + +find_library(Vulkan_LIBRARY + NAMES ${_Vulkan_library_name} + HINTS + ${_Vulkan_hint_library_search_paths} + ) +mark_as_advanced(Vulkan_LIBRARY) + +if(glslc IN_LIST Vulkan_FIND_COMPONENTS) find_program(Vulkan_GLSLC_EXECUTABLE NAMES glslc - HINTS "$ENV{VULKAN_SDK}/bin") + HINTS + ${_Vulkan_hint_executable_search_paths} + ) + mark_as_advanced(Vulkan_GLSLC_EXECUTABLE) +endif() +if(glslangValidator IN_LIST Vulkan_FIND_COMPONENTS) find_program(Vulkan_GLSLANG_VALIDATOR_EXECUTABLE NAMES glslangValidator - HINTS "$ENV{VULKAN_SDK}/bin") + HINTS + ${_Vulkan_hint_executable_search_paths} + ) + mark_as_advanced(Vulkan_GLSLANG_VALIDATOR_EXECUTABLE) +endif() +if(glslang IN_LIST Vulkan_FIND_COMPONENTS) + find_library(Vulkan_glslang-spirv_LIBRARY + NAMES SPIRV + HINTS + ${_Vulkan_hint_library_search_paths} + ) + mark_as_advanced(Vulkan_glslang-spirv_LIBRARY) + + find_library(Vulkan_glslang-spirv_DEBUG_LIBRARY + NAMES SPIRVd + HINTS + ${_Vulkan_hint_library_search_paths} + ) + mark_as_advanced(Vulkan_glslang-spirv_DEBUG_LIBRARY) + + find_library(Vulkan_glslang-oglcompiler_LIBRARY + NAMES OGLCompiler + HINTS + ${_Vulkan_hint_library_search_paths} + ) + mark_as_advanced(Vulkan_glslang-oglcompiler_LIBRARY) + + find_library(Vulkan_glslang-oglcompiler_DEBUG_LIBRARY + NAMES OGLCompilerd + HINTS + ${_Vulkan_hint_library_search_paths} + ) + mark_as_advanced(Vulkan_glslang-oglcompiler_DEBUG_LIBRARY) + + find_library(Vulkan_glslang-osdependent_LIBRARY + NAMES OSDependent + HINTS + ${_Vulkan_hint_library_search_paths} + ) + mark_as_advanced(Vulkan_glslang-osdependent_LIBRARY) + + find_library(Vulkan_glslang-osdependent_DEBUG_LIBRARY + NAMES OSDependentd + HINTS + ${_Vulkan_hint_library_search_paths} + ) + mark_as_advanced(Vulkan_glslang-osdependent_DEBUG_LIBRARY) + + find_library(Vulkan_glslang-machineindependent_LIBRARY + NAMES MachineIndependent + HINTS + ${_Vulkan_hint_library_search_paths} + ) + mark_as_advanced(Vulkan_glslang-machineindependent_LIBRARY) + + find_library(Vulkan_glslang-machineindependent_DEBUG_LIBRARY + NAMES MachineIndependentd + HINTS + ${_Vulkan_hint_library_search_paths} + ) + mark_as_advanced(Vulkan_glslang-machineindependent_DEBUG_LIBRARY) + + find_library(Vulkan_glslang-genericcodegen_LIBRARY + NAMES GenericCodeGen + HINTS + ${_Vulkan_hint_library_search_paths} + ) + mark_as_advanced(Vulkan_glslang-genericcodegen_LIBRARY) + + find_library(Vulkan_glslang-genericcodegen_DEBUG_LIBRARY + NAMES GenericCodeGend + HINTS + ${_Vulkan_hint_library_search_paths} + ) + mark_as_advanced(Vulkan_glslang-genericcodegen_DEBUG_LIBRARY) + + find_library(Vulkan_glslang_LIBRARY + NAMES glslang + HINTS + ${_Vulkan_hint_library_search_paths} + ) + mark_as_advanced(Vulkan_glslang_LIBRARY) + + find_library(Vulkan_glslang_DEBUG_LIBRARY + NAMES glslangd + HINTS + ${_Vulkan_hint_library_search_paths} + ) + mark_as_advanced(Vulkan_glslang_DEBUG_LIBRARY) +endif() +if(shaderc_combined IN_LIST Vulkan_FIND_COMPONENTS) + find_library(Vulkan_shaderc_combined_LIBRARY + NAMES shaderc_combined + HINTS + ${_Vulkan_hint_library_search_paths}) + mark_as_advanced(Vulkan_shaderc_combined_LIBRARY) + + find_library(Vulkan_shaderc_combined_DEBUG_LIBRARY + NAMES shaderc_combinedd + HINTS + ${_Vulkan_hint_library_search_paths}) + mark_as_advanced(Vulkan_shaderc_combined_DEBUG_LIBRARY) +endif() +if(SPIRV-Tools IN_LIST Vulkan_FIND_COMPONENTS) + find_library(Vulkan_SPIRV-Tools_LIBRARY + NAMES SPIRV-Tools + HINTS + ${_Vulkan_hint_library_search_paths}) + mark_as_advanced(Vulkan_SPIRV-Tools_LIBRARY) + + find_library(Vulkan_SPIRV-Tools_DEBUG_LIBRARY + NAMES SPIRV-Toolsd + HINTS + ${_Vulkan_hint_library_search_paths}) + mark_as_advanced(Vulkan_SPIRV-Tools_DEBUG_LIBRARY) +endif() +if(MoltenVK IN_LIST Vulkan_FIND_COMPONENTS) + find_library(Vulkan_MoltenVK_LIBRARY + NAMES MoltenVK + HINTS + ${_Vulkan_hint_library_search_paths}) + mark_as_advanced(Vulkan_MoltenVK_LIBRARY) + + find_path(Vulkan_MoltenVK_INCLUDE_DIR + NAMES MoltenVK/mvk_vulkan.h + HINTS + ${_Vulkan_hint_include_search_paths} + ) + mark_as_advanced(Vulkan_MoltenVK_INCLUDE_DIR) +endif() +if(volk IN_LIST Vulkan_FIND_COMPONENTS) + find_library(Vulkan_volk_LIBRARY + NAMES volk + HINTS + ${_Vulkan_hint_library_search_paths}) + mark_as_advanced(Vulkan_Volk_LIBRARY) +endif() + +if (dxc IN_LIST Vulkan_FIND_COMPONENTS) + find_library(Vulkan_dxc_LIBRARY + NAMES dxcompiler + HINTS + ${_Vulkan_hint_library_search_paths}) + mark_as_advanced(Vulkan_dxc_LIBRARY) + + find_program(Vulkan_dxc_EXECUTABLE + NAMES dxc + HINTS + ${_Vulkan_hint_executable_search_paths}) + mark_as_advanced(Vulkan_dxc_EXECUTABLE) +endif() + +if(Vulkan_GLSLC_EXECUTABLE) + set(Vulkan_glslc_FOUND TRUE) +else() + set(Vulkan_glslc_FOUND FALSE) +endif() + +if(Vulkan_GLSLANG_VALIDATOR_EXECUTABLE) + set(Vulkan_glslangValidator_FOUND TRUE) +else() + set(Vulkan_glslangValidator_FOUND FALSE) +endif() + +if (Vulkan_dxc_EXECUTABLE) + set(Vulkan_dxc_exe_FOUND TRUE) +else() + set(Vulkan_dxc_exe_FOUND FALSE) +endif() + +function(_Vulkan_set_library_component_found component) + cmake_parse_arguments(PARSE_ARGV 1 _ARG + "NO_WARNING" + "" + "DEPENDENT_COMPONENTS") + + set(all_dependent_component_found TRUE) + foreach(dependent_component IN LISTS _ARG_DEPENDENT_COMPONENTS) + if(NOT Vulkan_${dependent_component}_FOUND) + set(all_dependent_component_found FALSE) + break() + endif() + endforeach() + + if(all_dependent_component_found AND (Vulkan_${component}_LIBRARY OR Vulkan_${component}_DEBUG_LIBRARY)) + set(Vulkan_${component}_FOUND TRUE PARENT_SCOPE) + + # For Windows Vulkan SDK, third party tools binaries are provided with different MSVC ABI: + # - Release binaries uses a runtime library + # - Debug binaries uses a debug runtime library + # This lead to incompatibilities in linking for some configuration types due to CMake-default or project-configured selected MSVC ABI. + if(WIN32 AND NOT _ARG_NO_WARNING) + if(NOT Vulkan_${component}_LIBRARY) + message(WARNING +"Library ${component} for Release configuration is missing, imported target Vulkan::${component} may not be able to link when targeting this build configuration due to incompatible MSVC ABI.") + endif() + if(NOT Vulkan_${component}_DEBUG_LIBRARY) + message(WARNING +"Library ${component} for Debug configuration is missing, imported target Vulkan::${component} may not be able to link when targeting this build configuration due to incompatible MSVC ABI. Consider re-installing the Vulkan SDK and request debug libraries to fix this warning.") + endif() + endif() + else() + set(Vulkan_${component}_FOUND FALSE PARENT_SCOPE) + endif() +endfunction() + +_Vulkan_set_library_component_found(glslang-spirv NO_WARNING) +_Vulkan_set_library_component_found(glslang-oglcompiler NO_WARNING) +_Vulkan_set_library_component_found(glslang-osdependent NO_WARNING) +_Vulkan_set_library_component_found(glslang-machineindependent NO_WARNING) +_Vulkan_set_library_component_found(glslang-genericcodegen NO_WARNING) +_Vulkan_set_library_component_found(glslang + DEPENDENT_COMPONENTS + glslang-spirv + glslang-oglcompiler + glslang-osdependent + glslang-machineindependent + glslang-genericcodegen) +_Vulkan_set_library_component_found(shaderc_combined) +_Vulkan_set_library_component_found(SPIRV-Tools) +_Vulkan_set_library_component_found(volk) +_Vulkan_set_library_component_found(dxc) + +if(Vulkan_MoltenVK_INCLUDE_DIR AND Vulkan_MoltenVK_LIBRARY) + set(Vulkan_MoltenVK_FOUND TRUE) +else() + set(Vulkan_MoltenVK_FOUND FALSE) endif() set(Vulkan_LIBRARIES ${Vulkan_LIBRARY}) @@ -155,6 +574,25 @@ if(Vulkan_INCLUDE_DIR) endif() endif() +if(Vulkan_MoltenVK_FOUND) + set(Vulkan_MoltenVK_VERSION "") + if(Vulkan_MoltenVK_INCLUDE_DIR) + set(VK_MVK_MOLTENVK_H ${Vulkan_MoltenVK_INCLUDE_DIR}/MoltenVK/vk_mvk_moltenvk.h) + if(EXISTS ${VK_MVK_MOLTENVK_H}) + file(STRINGS ${VK_MVK_MOLTENVK_H} _Vulkan_MoltenVK_VERSION_MAJOR REGEX "^#define MVK_VERSION_MAJOR ") + string(REGEX MATCHALL "[0-9]+" _Vulkan_MoltenVK_VERSION_MAJOR "${_Vulkan_MoltenVK_VERSION_MAJOR}") + file(STRINGS ${VK_MVK_MOLTENVK_H} _Vulkan_MoltenVK_VERSION_MINOR REGEX "^#define MVK_VERSION_MINOR ") + string(REGEX MATCHALL "[0-9]+" _Vulkan_MoltenVK_VERSION_MINOR "${_Vulkan_MoltenVK_VERSION_MINOR}") + file(STRINGS ${VK_MVK_MOLTENVK_H} _Vulkan_MoltenVK_VERSION_PATCH REGEX "^#define MVK_VERSION_PATCH ") + string(REGEX MATCHALL "[0-9]+" _Vulkan_MoltenVK_VERSION_PATCH "${_Vulkan_MoltenVK_VERSION_PATCH}") + set(Vulkan_MoltenVK_VERSION "${_Vulkan_MoltenVK_VERSION_MAJOR}.${_Vulkan_MoltenVK_VERSION_MINOR}.${_Vulkan_MoltenVK_VERSION_PATCH}") + unset(_Vulkan_MoltenVK_VERSION_MAJOR) + unset(_Vulkan_MoltenVK_VERSION_MINOR) + unset(_Vulkan_MoltenVK_VERSION_PATCH) + endif() + endif() +endif() + include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) find_package_handle_standard_args(Vulkan REQUIRED_VARS @@ -162,11 +600,9 @@ find_package_handle_standard_args(Vulkan Vulkan_INCLUDE_DIR VERSION_VAR Vulkan_VERSION + HANDLE_COMPONENTS ) -mark_as_advanced(Vulkan_INCLUDE_DIR Vulkan_LIBRARY Vulkan_GLSLC_EXECUTABLE - Vulkan_GLSLANG_VALIDATOR_EXECUTABLE) - if(Vulkan_FOUND AND NOT TARGET Vulkan::Vulkan) add_library(Vulkan::Vulkan UNKNOWN IMPORTED) set_target_properties(Vulkan::Vulkan PROPERTIES @@ -189,3 +625,266 @@ if(Vulkan_FOUND AND Vulkan_GLSLANG_VALIDATOR_EXECUTABLE AND NOT TARGET Vulkan::g add_executable(Vulkan::glslangValidator IMPORTED) set_property(TARGET Vulkan::glslangValidator PROPERTY IMPORTED_LOCATION "${Vulkan_GLSLANG_VALIDATOR_EXECUTABLE}") endif() + +if(Vulkan_FOUND) + if((Vulkan_glslang-spirv_LIBRARY OR Vulkan_glslang-spirv_DEBUG_LIBRARY) AND NOT TARGET Vulkan::glslang-spirv) + add_library(Vulkan::glslang-spirv STATIC IMPORTED) + set_property(TARGET Vulkan::glslang-spirv + PROPERTY + INTERFACE_INCLUDE_DIRECTORIES "${Vulkan_INCLUDE_DIRS}") + if(Vulkan_glslang-spirv_LIBRARY) + set_property(TARGET Vulkan::glslang-spirv APPEND + PROPERTY + IMPORTED_CONFIGURATIONS Release) + set_property(TARGET Vulkan::glslang-spirv + PROPERTY + IMPORTED_LOCATION_RELEASE "${Vulkan_glslang-spirv_LIBRARY}") + endif() + if(Vulkan_glslang-spirv_DEBUG_LIBRARY) + set_property(TARGET Vulkan::glslang-spirv APPEND + PROPERTY + IMPORTED_CONFIGURATIONS Debug) + set_property(TARGET Vulkan::glslang-spirv + PROPERTY + IMPORTED_LOCATION_DEBUG "${Vulkan_glslang-spirv_DEBUG_LIBRARY}") + endif() + endif() + + if((Vulkan_glslang-oglcompiler_LIBRARY OR Vulkan_glslang-oglcompiler_DEBUG_LIBRARY) AND NOT TARGET Vulkan::glslang-oglcompiler) + add_library(Vulkan::glslang-oglcompiler STATIC IMPORTED) + set_property(TARGET Vulkan::glslang-oglcompiler + PROPERTY + INTERFACE_INCLUDE_DIRECTORIES "${Vulkan_INCLUDE_DIRS}") + if(Vulkan_glslang-oglcompiler_LIBRARY) + set_property(TARGET Vulkan::glslang-oglcompiler APPEND + PROPERTY + IMPORTED_CONFIGURATIONS Release) + set_property(TARGET Vulkan::glslang-oglcompiler + PROPERTY + IMPORTED_LOCATION_RELEASE "${Vulkan_glslang-oglcompiler_LIBRARY}") + endif() + if(Vulkan_glslang-oglcompiler_DEBUG_LIBRARY) + set_property(TARGET Vulkan::glslang-oglcompiler APPEND + PROPERTY + IMPORTED_CONFIGURATIONS Debug) + set_property(TARGET Vulkan::glslang-oglcompiler + PROPERTY + IMPORTED_LOCATION_DEBUG "${Vulkan_glslang-oglcompiler_DEBUG_LIBRARY}") + endif() + endif() + + if((Vulkan_glslang-osdependent_LIBRARY OR Vulkan_glslang-osdependent_DEBUG_LIBRARY) AND NOT TARGET Vulkan::glslang-osdependent) + add_library(Vulkan::glslang-osdependent STATIC IMPORTED) + set_property(TARGET Vulkan::glslang-osdependent + PROPERTY + INTERFACE_INCLUDE_DIRECTORIES "${Vulkan_INCLUDE_DIRS}") + if(Vulkan_glslang-osdependent_LIBRARY) + set_property(TARGET Vulkan::glslang-osdependent APPEND + PROPERTY + IMPORTED_CONFIGURATIONS Release) + set_property(TARGET Vulkan::glslang-osdependent + PROPERTY + IMPORTED_LOCATION_RELEASE "${Vulkan_glslang-osdependent_LIBRARY}") + endif() + if(Vulkan_glslang-osdependent_DEBUG_LIBRARY) + set_property(TARGET Vulkan::glslang-osdependent APPEND + PROPERTY + IMPORTED_CONFIGURATIONS Debug) + set_property(TARGET Vulkan::glslang-osdependent + PROPERTY + IMPORTED_LOCATION_DEBUG "${Vulkan_glslang-osdependent_DEBUG_LIBRARY}") + endif() + endif() + + if((Vulkan_glslang-machineindependent_LIBRARY OR Vulkan_glslang-machineindependent_DEBUG_LIBRARY) AND NOT TARGET Vulkan::glslang-machineindependent) + add_library(Vulkan::glslang-machineindependent STATIC IMPORTED) + set_property(TARGET Vulkan::glslang-machineindependent + PROPERTY + INTERFACE_INCLUDE_DIRECTORIES "${Vulkan_INCLUDE_DIRS}") + if(Vulkan_glslang-machineindependent_LIBRARY) + set_property(TARGET Vulkan::glslang-machineindependent APPEND + PROPERTY + IMPORTED_CONFIGURATIONS Release) + set_property(TARGET Vulkan::glslang-machineindependent + PROPERTY + IMPORTED_LOCATION_RELEASE "${Vulkan_glslang-machineindependent_LIBRARY}") + endif() + if(Vulkan_glslang-machineindependent_DEBUG_LIBRARY) + set_property(TARGET Vulkan::glslang-machineindependent APPEND + PROPERTY + IMPORTED_CONFIGURATIONS Debug) + set_property(TARGET Vulkan::glslang-machineindependent + PROPERTY + IMPORTED_LOCATION_DEBUG "${Vulkan_glslang-machineindependent_DEBUG_LIBRARY}") + endif() + endif() + + if((Vulkan_glslang-genericcodegen_LIBRARY OR Vulkan_glslang-genericcodegen_DEBUG_LIBRARY) AND NOT TARGET Vulkan::glslang-genericcodegen) + add_library(Vulkan::glslang-genericcodegen STATIC IMPORTED) + set_property(TARGET Vulkan::glslang-genericcodegen + PROPERTY + INTERFACE_INCLUDE_DIRECTORIES "${Vulkan_INCLUDE_DIRS}") + if(Vulkan_glslang-genericcodegen_LIBRARY) + set_property(TARGET Vulkan::glslang-genericcodegen APPEND + PROPERTY + IMPORTED_CONFIGURATIONS Release) + set_property(TARGET Vulkan::glslang-genericcodegen + PROPERTY + IMPORTED_LOCATION_RELEASE "${Vulkan_glslang-genericcodegen_LIBRARY}") + endif() + if(Vulkan_glslang-genericcodegen_DEBUG_LIBRARY) + set_property(TARGET Vulkan::glslang-genericcodegen APPEND + PROPERTY + IMPORTED_CONFIGURATIONS Debug) + set_property(TARGET Vulkan::glslang-genericcodegen + PROPERTY + IMPORTED_LOCATION_DEBUG "${Vulkan_glslang-genericcodegen_DEBUG_LIBRARY}") + endif() + endif() + + if((Vulkan_glslang_LIBRARY OR Vulkan_glslang_DEBUG_LIBRARY) + AND TARGET Vulkan::glslang-spirv + AND TARGET Vulkan::glslang-oglcompiler + AND TARGET Vulkan::glslang-osdependent + AND TARGET Vulkan::glslang-machineindependent + AND TARGET Vulkan::glslang-genericcodegen + AND NOT TARGET Vulkan::glslang) + add_library(Vulkan::glslang STATIC IMPORTED) + set_property(TARGET Vulkan::glslang + PROPERTY + INTERFACE_INCLUDE_DIRECTORIES "${Vulkan_INCLUDE_DIRS}") + if(Vulkan_glslang_LIBRARY) + set_property(TARGET Vulkan::glslang APPEND + PROPERTY + IMPORTED_CONFIGURATIONS Release) + set_property(TARGET Vulkan::glslang + PROPERTY + IMPORTED_LOCATION_RELEASE "${Vulkan_glslang_LIBRARY}") + endif() + if(Vulkan_glslang_DEBUG_LIBRARY) + set_property(TARGET Vulkan::glslang APPEND + PROPERTY + IMPORTED_CONFIGURATIONS Debug) + set_property(TARGET Vulkan::glslang + PROPERTY + IMPORTED_LOCATION_DEBUG "${Vulkan_glslang_DEBUG_LIBRARY}") + endif() + target_link_libraries(Vulkan::glslang + INTERFACE + Vulkan::glslang-spirv + Vulkan::glslang-oglcompiler + Vulkan::glslang-osdependent + Vulkan::glslang-machineindependent + Vulkan::glslang-genericcodegen + ) + endif() + + if((Vulkan_shaderc_combined_LIBRARY OR Vulkan_shaderc_combined_DEBUG_LIBRARY) AND NOT TARGET Vulkan::shaderc_combined) + add_library(Vulkan::shaderc_combined STATIC IMPORTED) + set_property(TARGET Vulkan::shaderc_combined + PROPERTY + INTERFACE_INCLUDE_DIRECTORIES "${Vulkan_INCLUDE_DIRS}") + if(Vulkan_shaderc_combined_LIBRARY) + set_property(TARGET Vulkan::shaderc_combined APPEND + PROPERTY + IMPORTED_CONFIGURATIONS Release) + set_property(TARGET Vulkan::shaderc_combined + PROPERTY + IMPORTED_LOCATION_RELEASE "${Vulkan_shaderc_combined_LIBRARY}") + endif() + if(Vulkan_shaderc_combined_DEBUG_LIBRARY) + set_property(TARGET Vulkan::shaderc_combined APPEND + PROPERTY + IMPORTED_CONFIGURATIONS Debug) + set_property(TARGET Vulkan::shaderc_combined + PROPERTY + IMPORTED_LOCATION_DEBUG "${Vulkan_shaderc_combined_DEBUG_LIBRARY}") + endif() + + if(UNIX) + find_package(Threads REQUIRED) + target_link_libraries(Vulkan::shaderc_combined + INTERFACE + Threads::Threads) + endif() + endif() + + if((Vulkan_SPIRV-Tools_LIBRARY OR Vulkan_SPIRV-Tools_DEBUG_LIBRARY) AND NOT TARGET Vulkan::SPIRV-Tools) + add_library(Vulkan::SPIRV-Tools STATIC IMPORTED) + set_property(TARGET Vulkan::SPIRV-Tools + PROPERTY + INTERFACE_INCLUDE_DIRECTORIES "${Vulkan_INCLUDE_DIRS}") + if(Vulkan_SPIRV-Tools_LIBRARY) + set_property(TARGET Vulkan::SPIRV-Tools APPEND + PROPERTY + IMPORTED_CONFIGURATIONS Release) + set_property(TARGET Vulkan::SPIRV-Tools + PROPERTY + IMPORTED_LOCATION_RELEASE "${Vulkan_SPIRV-Tools_LIBRARY}") + endif() + if(Vulkan_SPIRV-Tools_DEBUG_LIBRARY) + set_property(TARGET Vulkan::SPIRV-Tools APPEND + PROPERTY + IMPORTED_CONFIGURATIONS Debug) + set_property(TARGET Vulkan::SPIRV-Tools + PROPERTY + IMPORTED_LOCATION_DEBUG "${Vulkan_SPIRV-Tools_DEBUG_LIBRARY}") + endif() + endif() + + if(Vulkan_volk_LIBRARY AND NOT TARGET Vulkan::volk) + add_library(Vulkan::volk STATIC IMPORTED) + set_property(TARGET Vulkan::volk + PROPERTY + INTERFACE_INCLUDE_DIRECTORIES "${Vulkan_INCLUDE_DIRS}") + set_property(TARGET Vulkan::volk APPEND + PROPERTY + IMPORTED_CONFIGURATIONS Release) + set_property(TARGET Vulkan::volk APPEND + PROPERTY + IMPORTED_LOCATION_RELEASE "${Vulkan_volk_LIBRARY}") + + if (NOT WIN32) + set_property(TARGET Vulkan::volk APPEND + PROPERTY + IMPORTED_LINK_INTERFACE_LIBRARIES dl) + endif() + endif() + + if (Vulkan_dxc_LIBRARY AND NOT TARGET Vulkan::dxc_lib) + add_library(Vulkan::dxc_lib STATIC IMPORTED) + set_property(TARGET Vulkan::dxc_lib + PROPERTY + INTERFACE_INCLUDE_DIRECTORIES "${Vulkan_INCLUDE_DIRS}") + set_property(TARGET Vulkan::dxc_lib APPEND + PROPERTY + IMPORTED_CONFIGURATIONS Release) + set_property(TARGET Vulkan::dxc_lib APPEND + PROPERTY + IMPORTED_LOCATION_RELEASE "${Vulkan_dxc_LIBRARY}") + endif() + + if(Vulkan_dxc_EXECUTABLE AND NOT TARGET Vulkan::dxc_exe) + add_executable(Vulkan::dxc_exe IMPORTED) + set_property(TARGET Vulkan::dxc_exe PROPERTY IMPORTED_LOCATION "${Vulkan_dxc_EXECUTABLE}") + endif() + +endif() + +if(Vulkan_MoltenVK_FOUND) + if(Vulkan_MoltenVK_LIBRARY AND NOT TARGET Vulkan::MoltenVK) + add_library(Vulkan::MoltenVK SHARED IMPORTED) + set_target_properties(Vulkan::MoltenVK + PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES "${Vulkan_MoltenVK_INCLUDE_DIR}" + IMPORTED_LOCATION "${Vulkan_MoltenVK_LIBRARY}" + ) + endif() +endif() + +unset(_Vulkan_library_name) +unset(_Vulkan_hint_include_search_paths) +unset(_Vulkan_hint_executable_search_paths) +unset(_Vulkan_hint_library_search_paths) + +cmake_policy(POP) diff --git a/Modules/FindX11.cmake b/Modules/FindX11.cmake index fd5ee53..8e5a5f1 100644 --- a/Modules/FindX11.cmake +++ b/Modules/FindX11.cmake @@ -31,8 +31,11 @@ and also the following more fine grained variables and targets: X11_xcb_INCLUDE_PATH, X11_xcb_LIB, X11_xcb_FOUND, X11::xcb X11_X11_xcb_INCLUDE_PATH, X11_X11_xcb_LIB, X11_X11_xcb_FOUND, X11::X11_xcb X11_xcb_icccm_INCLUDE_PATH, X11_xcb_icccm_LIB, X11_xcb_icccm_FOUND, X11::xcb_icccm + X11_xcb_randr_INCLUDE_PATH, X11_xcb_randr_LIB, X11_xcb_randr_FOUND, X11::xcb_randr X11_xcb_util_INCLUDE_PATH, X11_xcb_util_LIB, X11_xcb_util_FOUND, X11::xcb_util X11_xcb_xfixes_INCLUDE_PATH, X11_xcb_xfixes_LIB, X11_xcb_xfixes_FOUND, X11::xcb_xfixes + X11_xcb_xtest_INCLUDE_PATH, X11_xcb_xtest_LIB, X11_xcb_xtest_FOUND, X11::xcb_xtest + X11_xcb_keysyms_INCLUDE_PATH, X11_xcb_keysyms_LIB,X11_xcb_keysyms_FOUND,X11::xcb_keysyms X11_xcb_xkb_INCLUDE_PATH, X11_xcb_xkb_LIB, X11_xcb_xkb_FOUND, X11::xcb_xkb X11_Xcomposite_INCLUDE_PATH, X11_Xcomposite_LIB, X11_Xcomposite_FOUND, X11::Xcomposite X11_Xcursor_INCLUDE_PATH, X11_Xcursor_LIB, X11_Xcursor_FOUND, X11::Xcursor @@ -82,6 +85,9 @@ and also the following more fine grained variables and targets: .. versionadded:: 3.19 Added the ``Xaw``, ``xcb_util``, and ``xcb_xfixes`` libraries. +.. versionadded:: 3.24 + Added the ``xcb_randr``, ``xcb_xtext``, and ``xcb_keysyms`` libraries. + #]=======================================================================] if (UNIX) @@ -127,8 +133,11 @@ if (UNIX) find_path(X11_xcb_INCLUDE_PATH xcb/xcb.h ${X11_INC_SEARCH_PATH}) find_path(X11_X11_xcb_INCLUDE_PATH X11/Xlib-xcb.h ${X11_INC_SEARCH_PATH}) find_path(X11_xcb_icccm_INCLUDE_PATH xcb/xcb_icccm.h ${X11_INC_SEARCH_PATH}) + find_path(X11_xcb_randr_INCLUDE_PATH xcb/randr.h ${X11_INC_SEARCH_PATH}) find_path(X11_xcb_util_INCLUDE_PATH xcb/xcb_aux.h ${X11_INC_SEARCH_PATH}) find_path(X11_xcb_xfixes_INCLUDE_PATH xcb/xfixes.h ${X11_INC_SEARCH_PATH}) + find_path(X11_xcb_xtest_INCLUDE_PATH xcb/xtest.h ${X11_INC_SEARCH_PATH}) + find_path(X11_xcb_keysyms_INCLUDE_PATH xcb/xcb_keysyms.h ${X11_INC_SEARCH_PATH}) find_path(X11_Xcomposite_INCLUDE_PATH X11/extensions/Xcomposite.h ${X11_INC_SEARCH_PATH}) find_path(X11_Xcursor_INCLUDE_PATH X11/Xcursor/Xcursor.h ${X11_INC_SEARCH_PATH}) find_path(X11_Xdamage_INCLUDE_PATH X11/extensions/Xdamage.h ${X11_INC_SEARCH_PATH}) @@ -180,8 +189,11 @@ if (UNIX) find_library(X11_xcb_LIB xcb ${X11_LIB_SEARCH_PATH}) find_library(X11_X11_xcb_LIB X11-xcb ${X11_LIB_SEARCH_PATH}) find_library(X11_xcb_icccm_LIB xcb-icccm ${X11_LIB_SEARCH_PATH}) + find_library(X11_xcb_randr_LIB xcb-randr ${X11_LIB_SEARCH_PATH}) find_library(X11_xcb_util_LIB xcb-util ${X11_LIB_SEARCH_PATH}) find_library(X11_xcb_xfixes_LIB xcb-xfixes ${X11_LIB_SEARCH_PATH}) + find_library(X11_xcb_xtest_LIB xcb-xtest ${X11_LIB_SEARCH_PATH}) + find_library(X11_xcb_keysyms_LIB xcb-keysyms ${X11_LIB_SEARCH_PATH}) find_library(X11_xcb_xkb_LIB xcb-xkb ${X11_LIB_SEARCH_PATH}) find_library(X11_Xcomposite_LIB Xcomposite ${X11_LIB_SEARCH_PATH}) find_library(X11_Xcursor_LIB Xcursor ${X11_LIB_SEARCH_PATH}) @@ -281,6 +293,10 @@ if (UNIX) set(X11_xcb_icccm_FOUND TRUE) endif () + if (X11_xcb_randr_LIB AND X11_xcb_randr_INCLUDE_PATH) + set(X11_xcb_randr_FOUND TRUE) + endif () + if (X11_xcb_util_LIB AND X11_xcb_util_INCLUDE_PATH) set(X11_xcb_util_FOUND TRUE) endif () @@ -289,6 +305,14 @@ if (UNIX) set(X11_xcb_xfixes_FOUND TRUE) endif () + if (X11_xcb_xtest_LIB) + set(X11_xcb_xtest_FOUND TRUE) + endif () + + if (X11_xcb_keysyms_LIB) + set(X11_xcb_keysyms_FOUND TRUE) + endif () + if (X11_xcb_xkb_LIB) set(X11_xcb_xkb_FOUND TRUE) endif () @@ -600,6 +624,13 @@ if (UNIX) INTERFACE_LINK_LIBRARIES "X11::xcb") endif () + if (X11_xcb_randr_FOUND AND NOT TARGET X11::xcb_randr) + add_library(X11::xcb_randr UNKNOWN IMPORTED) + set_target_properties(X11::xcb_randr PROPERTIES + IMPORTED_LOCATION "${X11_xcb_randr_LIB}" + INTERFACE_LINK_LIBRARIES "X11::xcb") + endif () + if (X11_xcb_util_FOUND AND NOT TARGET X11::xcb_util) add_library(X11::xcb_util UNKNOWN IMPORTED) set_target_properties(X11::xcb_util PROPERTIES @@ -614,6 +645,20 @@ if (UNIX) INTERFACE_LINK_LIBRARIES "X11::xcb") endif () + if (X11_xcb_xtest_FOUND AND NOT TARGET X11::xcb_xtest) + add_library(X11::xcb_xtest UNKNOWN IMPORTED) + set_target_properties(X11::xcb_xtest PROPERTIES + IMPORTED_LOCATION "${X11_xcb_xtest_LIB}" + INTERFACE_LINK_LIBRARIES "X11::xcb") + endif () + + if (X11_xcb_keysyms_FOUND AND NOT TARGET X11::xcb_keysyms) + add_library(X11::xcb_keysyms UNKNOWN IMPORTED) + set_target_properties(X11::xcb_keysyms PROPERTIES + IMPORTED_LOCATION "${X11_xcb_keysyms_LIB}" + INTERFACE_LINK_LIBRARIES "X11::xcb") + endif () + if (X11_xcb_xkb_FOUND AND NOT TARGET X11::xcb_xkb) add_library(X11::xcb_xkb UNKNOWN IMPORTED) set_target_properties(X11::xcb_xkb PROPERTIES @@ -830,10 +875,16 @@ if (UNIX) X11_xcb_INCLUDE_PATH X11_xcb_icccm_LIB X11_xcb_icccm_INCLUDE_PATH + X11_xcb_randr_LIB + X11_xcb_randr_INCLUDE_PATH X11_xcb_util_LIB X11_xcb_util_INCLUDE_PATH X11_xcb_xfixes_LIB X11_xcb_xfixes_INCLUDE_PATH + X11_xcb_xtest_LIB + X11_xcb_xtest_INCLUDE_PATH + X11_xcb_keysyms_LIB + X11_xcb_keysyms_INCLUDE_PATH X11_xcb_xkb_LIB X11_X11_xcb_LIB X11_X11_xcb_INCLUDE_PATH diff --git a/Modules/FindXCTest.cmake b/Modules/FindXCTest.cmake index 00729bc..7118df2 100644 --- a/Modules/FindXCTest.cmake +++ b/Modules/FindXCTest.cmake @@ -13,7 +13,7 @@ An XCTest bundle is a CFBundle with a special product-type and bundle extension. The Mac Developer Library provides more information in the `Testing with Xcode`_ document. -.. _Testing with Xcode: http://developer.apple.com/library/mac/documentation/DeveloperTools/Conceptual/testing_with_xcode/ +.. _Testing with Xcode: https://developer.apple.com/library/mac/documentation/DeveloperTools/Conceptual/testing_with_xcode/ Module Functions ^^^^^^^^^^^^^^^^ diff --git a/Modules/FindZLIB.cmake b/Modules/FindZLIB.cmake index 5778b03..d0deb87 100644 --- a/Modules/FindZLIB.cmake +++ b/Modules/FindZLIB.cmake @@ -20,41 +20,78 @@ Result Variables This module defines the following variables: -:: +``ZLIB_INCLUDE_DIRS`` + where to find zlib.h, etc. +``ZLIB_LIBRARIES`` + List of libraries when using zlib. +``ZLIB_FOUND`` + True if zlib found. +``ZLIB_VERSION`` + .. versionadded:: 3.26 + the version of Zlib found. + + See also legacy variable ``ZLIB_VERSION_STRING``. - ZLIB_INCLUDE_DIRS - where to find zlib.h, etc. - ZLIB_LIBRARIES - List of libraries when using zlib. - ZLIB_FOUND - True if zlib found. +.. versionadded:: 3.4 + Debug and Release variants are found separately. -:: +Legacy Variables +^^^^^^^^^^^^^^^^ - ZLIB_VERSION_STRING - The version of zlib found (x.y.z) - ZLIB_VERSION_MAJOR - The major version of zlib - ZLIB_VERSION_MINOR - The minor version of zlib - ZLIB_VERSION_PATCH - The patch version of zlib - ZLIB_VERSION_TWEAK - The tweak version of zlib +The following variables are provided for backward compatibility: -.. versionadded:: 3.4 - Debug and Release variants are found separately. +``ZLIB_VERSION_MAJOR`` + The major version of zlib. + + .. versionchanged:: 3.26 + Superseded by ``ZLIB_VERSION``. +``ZLIB_VERSION_MINOR`` + The minor version of zlib. -Backward Compatibility -^^^^^^^^^^^^^^^^^^^^^^ + .. versionchanged:: 3.26 + Superseded by ``ZLIB_VERSION``. +``ZLIB_VERSION_PATCH`` + The patch version of zlib. -The following variable are provided for backward compatibility + .. versionchanged:: 3.26 + Superseded by ``ZLIB_VERSION``. +``ZLIB_VERSION_TWEAK`` + The tweak version of zlib. -:: + .. versionchanged:: 3.26 + Superseded by ``ZLIB_VERSION``. +``ZLIB_VERSION_STRING`` + The version of zlib found (x.y.z) - ZLIB_MAJOR_VERSION - The major version of zlib - ZLIB_MINOR_VERSION - The minor version of zlib - ZLIB_PATCH_VERSION - The patch version of zlib + .. versionchanged:: 3.26 + Superseded by ``ZLIB_VERSION``. +``ZLIB_MAJOR_VERSION`` + The major version of zlib. Superseded by ``ZLIB_VERSION_MAJOR``. +``ZLIB_MINOR_VERSION`` + The minor version of zlib. Superseded by ``ZLIB_VERSION_MINOR``. +``ZLIB_PATCH_VERSION`` + The patch version of zlib. Superseded by ``ZLIB_VERSION_PATCH``. Hints ^^^^^ A user may set ``ZLIB_ROOT`` to a zlib installation root to tell this module where to look. + +.. versionadded:: 3.24 + Set ``ZLIB_USE_STATIC_LIBS`` to ``ON`` to look for static libraries. + Default is ``OFF``. + #]=======================================================================] +if(ZLIB_FIND_COMPONENTS AND NOT ZLIB_FIND_QUIETLY) + message(AUTHOR_WARNING + "ZLIB does not provide any COMPONENTS. Calling\n" + " find_package(ZLIB COMPONENTS ...)\n" + "will always fail." + ) +endif() + set(_ZLIB_SEARCHES) # Search ZLIB_ROOT first if it is set. @@ -72,8 +109,13 @@ set(_ZLIB_SEARCH_NORMAL unset(_ZLIB_x86) list(APPEND _ZLIB_SEARCHES _ZLIB_SEARCH_NORMAL) -set(ZLIB_NAMES z zlib zdll zlib1 zlibstatic) -set(ZLIB_NAMES_DEBUG zd zlibd zdlld zlibd1 zlib1d zlibstaticd) +if(ZLIB_USE_STATIC_LIBS) + set(ZLIB_NAMES zlibstatic zlibstat zlib z) + set(ZLIB_NAMES_DEBUG zlibstaticd zlibstatd zlibd zd) +else() + set(ZLIB_NAMES z zlib zdll zlib1 zlibstatic zlibwapi zlibvc zlibstat) + set(ZLIB_NAMES_DEBUG zd zlibd zdlld zlibd1 zlib1d zlibstaticd zlibwapid zlibvcd zlibstatd) +endif() # Try each search configuration. foreach(search ${_ZLIB_SEARCHES}) @@ -82,11 +124,47 @@ endforeach() # Allow ZLIB_LIBRARY to be set manually, as the location of the zlib library if(NOT ZLIB_LIBRARY) + if(DEFINED CMAKE_FIND_LIBRARY_PREFIXES) + set(_zlib_ORIG_CMAKE_FIND_LIBRARY_PREFIXES "${CMAKE_FIND_LIBRARY_PREFIXES}") + else() + set(_zlib_ORIG_CMAKE_FIND_LIBRARY_PREFIXES) + endif() + if(DEFINED CMAKE_FIND_LIBRARY_SUFFIXES) + set(_zlib_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES "${CMAKE_FIND_LIBRARY_SUFFIXES}") + else() + set(_zlib_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES) + endif() + # Prefix/suffix of the win32/Makefile.gcc build + if(WIN32) + list(APPEND CMAKE_FIND_LIBRARY_PREFIXES "" "lib") + list(APPEND CMAKE_FIND_LIBRARY_SUFFIXES ".dll.a") + endif() + # Support preference of static libs by adjusting CMAKE_FIND_LIBRARY_SUFFIXES + if(ZLIB_USE_STATIC_LIBS) + if(WIN32) + set(CMAKE_FIND_LIBRARY_SUFFIXES .lib .a ${CMAKE_FIND_LIBRARY_SUFFIXES}) + else() + set(CMAKE_FIND_LIBRARY_SUFFIXES .a) + endif() + endif() + foreach(search ${_ZLIB_SEARCHES}) find_library(ZLIB_LIBRARY_RELEASE NAMES ${ZLIB_NAMES} NAMES_PER_DIR ${${search}} PATH_SUFFIXES lib) find_library(ZLIB_LIBRARY_DEBUG NAMES ${ZLIB_NAMES_DEBUG} NAMES_PER_DIR ${${search}} PATH_SUFFIXES lib) endforeach() + # Restore the original find library ordering + if(DEFINED _zlib_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES) + set(CMAKE_FIND_LIBRARY_SUFFIXES "${_zlib_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES}") + else() + set(CMAKE_FIND_LIBRARY_SUFFIXES) + endif() + if(DEFINED _zlib_ORIG_CMAKE_FIND_LIBRARY_PREFIXES) + set(CMAKE_FIND_LIBRARY_PREFIXES "${_zlib_ORIG_CMAKE_FIND_LIBRARY_PREFIXES}") + else() + set(CMAKE_FIND_LIBRARY_PREFIXES) + endif() + include(${CMAKE_CURRENT_LIST_DIR}/SelectLibraryConfigurations.cmake) select_library_configurations(ZLIB) endif() @@ -114,11 +192,14 @@ if(ZLIB_INCLUDE_DIR AND EXISTS "${ZLIB_INCLUDE_DIR}/zlib.h") set(ZLIB_MAJOR_VERSION "${ZLIB_VERSION_MAJOR}") set(ZLIB_MINOR_VERSION "${ZLIB_VERSION_MINOR}") set(ZLIB_PATCH_VERSION "${ZLIB_VERSION_PATCH}") + + set(ZLIB_VERSION ${ZLIB_VERSION_STRING}) endif() include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) FIND_PACKAGE_HANDLE_STANDARD_ARGS(ZLIB REQUIRED_VARS ZLIB_LIBRARY ZLIB_INCLUDE_DIR - VERSION_VAR ZLIB_VERSION_STRING) + VERSION_VAR ZLIB_VERSION + HANDLE_COMPONENTS) if(ZLIB_FOUND) set(ZLIB_INCLUDE_DIRS ${ZLIB_INCLUDE_DIR}) diff --git a/Modules/FindwxWidgets.cmake b/Modules/FindwxWidgets.cmake index 63af9b6..3159ff7 100644 --- a/Modules/FindwxWidgets.cmake +++ b/Modules/FindwxWidgets.cmake @@ -29,9 +29,9 @@ select a configuration): :: wxWidgets_ROOT_DIR - Base wxWidgets directory - (e.g., C:/wxWidgets-2.6.3). + (e.g., C:/wxWidgets-3.2.0). wxWidgets_LIB_DIR - Path to wxWidgets libraries - (e.g., C:/wxWidgets-2.6.3/lib/vc_lib). + (e.g., C:/wxWidgets-3.2.0/lib/vc_x64_lib). wxWidgets_CONFIGURATION - Configuration to use (e.g., msw, mswd, mswu, mswunivud, etc.) wxWidgets_EXCLUDE_COMMON_LIBRARIES @@ -53,8 +53,6 @@ the following variables: wxWidgets_USE_UNIVERSAL wxWidgets_USE_STATIC - - There is also a wxWidgets_CONFIG_OPTIONS variable for all other options that need to be passed to the wx-config utility. For example, to use the base toolkit found in the /usr/local path, set the variable @@ -215,6 +213,32 @@ else() set(wxWidgets_USE_FILE UsewxWidgets) endif() +# Known wxWidgets versions. +set(wx_versions 3.3 3.2 3.1 3.0 2.9 2.8 2.7 2.6 2.5) + +macro(wx_extract_version) + unset(_wx_filename) + find_file(_wx_filename wx/version.h PATHS ${wxWidgets_INCLUDE_DIRS} NO_DEFAULT_PATH) + dbg_msg("_wx_filename: ${_wx_filename}") + + if(NOT _wx_filename) + message(FATAL_ERROR "wxWidgets wx/version.h file not found in ${wxWidgets_INCLUDE_DIRS}.") + endif() + + file(READ "${_wx_filename}" _wx_version_h) + unset(_wx_filename CACHE) + + string(REGEX REPLACE "^(.*\n)?#define +wxMAJOR_VERSION +([0-9]+).*" + "\\2" wxWidgets_VERSION_MAJOR "${_wx_version_h}" ) + string(REGEX REPLACE "^(.*\n)?#define +wxMINOR_VERSION +([0-9]+).*" + "\\2" wxWidgets_VERSION_MINOR "${_wx_version_h}" ) + string(REGEX REPLACE "^(.*\n)?#define +wxRELEASE_NUMBER +([0-9]+).*" + "\\2" wxWidgets_VERSION_PATCH "${_wx_version_h}" ) + set(wxWidgets_VERSION_STRING + "${wxWidgets_VERSION_MAJOR}.${wxWidgets_VERSION_MINOR}.${wxWidgets_VERSION_PATCH}" ) + dbg_msg("wxWidgets_VERSION_STRING: ${wxWidgets_VERSION_STRING}") +endmacro() + #===================================================================== # Determine whether unix or win32 paths should be used #===================================================================== @@ -269,10 +293,11 @@ if(wxWidgets_FIND_STYLE STREQUAL "win32") # # Find libraries associated to a configuration. # - macro(WX_FIND_LIBS _PF _UNV _UCD _DBG) + macro(WX_FIND_LIBS _PF _UNV _UCD _DBG _VER) DBG_MSG_V("m_unv = ${_UNV}") DBG_MSG_V("m_ucd = ${_UCD}") DBG_MSG_V("m_dbg = ${_DBG}") + DBG_MSG_V("m_ver = ${_VER}") # FIXME: What if both regex libs are available. regex should be # found outside the loop and only wx${LIB}${_UCD}${_DBG}. @@ -290,28 +315,14 @@ if(wxWidgets_FIND_STYLE STREQUAL "win32") # Find wxWidgets multilib base libraries. find_library(WX_base${_DBG} - NAMES - wxbase31${_UCD}${_DBG} - wxbase30${_UCD}${_DBG} - wxbase29${_UCD}${_DBG} - wxbase28${_UCD}${_DBG} - wxbase27${_UCD}${_DBG} - wxbase26${_UCD}${_DBG} - wxbase25${_UCD}${_DBG} + NAMES wxbase${_VER}${_UCD}${_DBG} PATHS ${WX_LIB_DIR} NO_DEFAULT_PATH ) mark_as_advanced(WX_base${_DBG}) foreach(LIB net odbc xml) find_library(WX_${LIB}${_DBG} - NAMES - wxbase31${_UCD}${_DBG}_${LIB} - wxbase30${_UCD}${_DBG}_${LIB} - wxbase29${_UCD}${_DBG}_${LIB} - wxbase28${_UCD}${_DBG}_${LIB} - wxbase27${_UCD}${_DBG}_${LIB} - wxbase26${_UCD}${_DBG}_${LIB} - wxbase25${_UCD}${_DBG}_${LIB} + NAMES wxbase${_VER}${_UCD}${_DBG}_${LIB} PATHS ${WX_LIB_DIR} NO_DEFAULT_PATH ) @@ -320,14 +331,7 @@ if(wxWidgets_FIND_STYLE STREQUAL "win32") # Find wxWidgets monolithic library. find_library(WX_mono${_DBG} - NAMES - wx${_PF}${_UNV}31${_UCD}${_DBG} - wx${_PF}${_UNV}30${_UCD}${_DBG} - wx${_PF}${_UNV}29${_UCD}${_DBG} - wx${_PF}${_UNV}28${_UCD}${_DBG} - wx${_PF}${_UNV}27${_UCD}${_DBG} - wx${_PF}${_UNV}26${_UCD}${_DBG} - wx${_PF}${_UNV}25${_UCD}${_DBG} + NAMES wx${_PF}${_UNV}${_VER}${_UCD}${_DBG} PATHS ${WX_LIB_DIR} NO_DEFAULT_PATH ) @@ -337,14 +341,7 @@ if(wxWidgets_FIND_STYLE STREQUAL "win32") foreach(LIB core adv aui html media xrc dbgrid gl qa richtext stc ribbon propgrid webview) find_library(WX_${LIB}${_DBG} - NAMES - wx${_PF}${_UNV}31${_UCD}${_DBG}_${LIB} - wx${_PF}${_UNV}30${_UCD}${_DBG}_${LIB} - wx${_PF}${_UNV}29${_UCD}${_DBG}_${LIB} - wx${_PF}${_UNV}28${_UCD}${_DBG}_${LIB} - wx${_PF}${_UNV}27${_UCD}${_DBG}_${LIB} - wx${_PF}${_UNV}26${_UCD}${_DBG}_${LIB} - wx${_PF}${_UNV}25${_UCD}${_DBG}_${LIB} + NAMES wx${_PF}${_UNV}${_VER}${_UCD}${_DBG}_${LIB} PATHS ${WX_LIB_DIR} NO_DEFAULT_PATH ) @@ -447,6 +444,13 @@ if(wxWidgets_FIND_STYLE STREQUAL "win32") # WIN32: Start actual work. #------------------------------------------------------------------- + set(wx_paths "wxWidgets") + foreach(version ${wx_versions}) + foreach(patch RANGE 15 0 -1) + list(APPEND wx_paths "wxWidgets-${version}.${patch}") + endforeach() + endforeach() + # Look for an installation tree. find_path(wxWidgets_ROOT_DIR NAMES include/wx/wx.h @@ -458,50 +462,18 @@ if(wxWidgets_FIND_STYLE STREQUAL "win32") D:/ ENV ProgramFiles PATH_SUFFIXES - wxWidgets-3.1.0 - wxWidgets-3.0.2 - wxWidgets-3.0.1 - wxWidgets-3.0.0 - wxWidgets-2.9.5 - wxWidgets-2.9.4 - wxWidgets-2.9.3 - wxWidgets-2.9.2 - wxWidgets-2.9.1 - wxWidgets-2.9.0 - wxWidgets-2.8.9 - wxWidgets-2.8.8 - wxWidgets-2.8.7 - wxWidgets-2.8.6 - wxWidgets-2.8.5 - wxWidgets-2.8.4 - wxWidgets-2.8.3 - wxWidgets-2.8.2 - wxWidgets-2.8.1 - wxWidgets-2.8.0 - wxWidgets-2.7.4 - wxWidgets-2.7.3 - wxWidgets-2.7.2 - wxWidgets-2.7.1 - wxWidgets-2.7.0 - wxWidgets-2.7.0-1 - wxWidgets-2.6.4 - wxWidgets-2.6.3 - wxWidgets-2.6.2 - wxWidgets-2.6.1 - wxWidgets-2.5.4 - wxWidgets-2.5.3 - wxWidgets-2.5.2 - wxWidgets-2.5.1 - wxWidgets + ${wx_paths} DOC "wxWidgets base/installation directory" ) # If wxWidgets_ROOT_DIR changed, clear lib dir. if(NOT WX_ROOT_DIR STREQUAL wxWidgets_ROOT_DIR) + if(NOT wxWidgets_LIB_DIR OR WX_ROOT_DIR) + set(wxWidgets_LIB_DIR "wxWidgets_LIB_DIR-NOTFOUND" + CACHE PATH "Cleared." FORCE) + endif() set(WX_ROOT_DIR ${wxWidgets_ROOT_DIR} CACHE INTERNAL "wxWidgets_ROOT_DIR") - set(wxWidgets_LIB_DIR "wxWidgets_LIB_DIR-NOTFOUND" - CACHE PATH "Cleared." FORCE) endif() if(WX_ROOT_DIR) @@ -643,7 +615,7 @@ if(wxWidgets_FIND_STYLE STREQUAL "win32") set(wxWidgets_INCLUDE_DIRS ${WX_LIB_DIR}/${wxWidgets_CONFIGURATION}) else() - DBG_MSG("wxWidgets_FOUND FALSE because ${WX_LIB_DIR}/${wxWidgets_CONFIGURATION}/wx/setup.h does not exists.") + DBG_MSG("wxWidgets_FOUND FALSE because ${WX_LIB_DIR}/${wxWidgets_CONFIGURATION}/wx/setup.h does not exist.") set(wxWidgets_FOUND FALSE) endif() @@ -655,10 +627,14 @@ if(wxWidgets_FIND_STYLE STREQUAL "win32") set(wxWidgets_FOUND FALSE) endif() + # Get version number. + wx_extract_version() + set(VER "${wxWidgets_VERSION_MAJOR}${wxWidgets_VERSION_MINOR}") + # Find wxWidgets libraries. - WX_FIND_LIBS("${PF}" "${UNV}" "${UCD}" "${DBG}") + WX_FIND_LIBS("${PF}" "${UNV}" "${UCD}" "${DBG}" "${VER}") if(WX_USE_REL_AND_DBG) - WX_FIND_LIBS("${PF}" "${UNV}" "${UCD}" "d") + WX_FIND_LIBS("${PF}" "${UNV}" "${UCD}" "d" "${VER}") endif() # Settings for requested libs (i.e., include dir, libraries, etc.). @@ -676,11 +652,17 @@ if(wxWidgets_FIND_STYLE STREQUAL "win32") endif() endif() + if(MINGW AND NOT wxWidgets_FOUND) + # Try unix search mode as well. + set(wxWidgets_FIND_STYLE "unix") + dbg_msg_v("wxWidgets_FIND_STYLE changed to unix") + endif() +endif() + #===================================================================== # UNIX_FIND_STYLE #===================================================================== -else() - if(wxWidgets_FIND_STYLE STREQUAL "unix") +if(wxWidgets_FIND_STYLE STREQUAL "unix") #----------------------------------------------------------------- # UNIX: Helper MACROS #----------------------------------------------------------------- @@ -773,12 +755,14 @@ else() # Look for wx-config -- this can be set in the environment, # or try versioned and toolchain-versioned variants of the -config # executable as well. + set(wx_config_names "wx-config") + foreach(version ${wx_versions}) + list(APPEND wx_config_names "wx-config-${version}" "wxgtk3u-${version}-config" "wxgtk2u-${version}-config") + endforeach() find_program(wxWidgets_CONFIG_EXECUTABLE NAMES $ENV{WX_CONFIG} - wx-config - wx-config-3.1 wx-config-3.0 wx-config-2.9 wx-config-2.8 - wxgtk3u-3.1-config wxgtk3u-3.0-config wxgtk2u-2.8-config + ${wx_config_names} DOC "Location of wxWidgets library configuration provider binary (wx-config)." ONLY_CMAKE_FIND_ROOT_PATH ) @@ -942,19 +926,6 @@ else() endif() unset(_cygpath_exe CACHE) endif() - -#===================================================================== -# Neither UNIX_FIND_STYLE, nor WIN32_FIND_STYLE -#===================================================================== - else() - if(NOT wxWidgets_FIND_QUIETLY) - message(STATUS - "${CMAKE_CURRENT_LIST_FILE}(${CMAKE_CURRENT_LIST_LINE}): \n" - " Platform unknown/unsupported. It's neither WIN32 nor UNIX " - "find style." - ) - endif() - endif() endif() # Check that all libraries are present, as wx-config does not check it @@ -981,26 +952,7 @@ unset(_wx_lib_missing) # Check if a specific version was requested by find_package(). if(wxWidgets_FOUND) - unset(_wx_filename) - find_file(_wx_filename wx/version.h PATHS ${wxWidgets_INCLUDE_DIRS} NO_DEFAULT_PATH) - dbg_msg("_wx_filename: ${_wx_filename}") - - if(NOT _wx_filename) - message(FATAL_ERROR "wxWidgets wx/version.h file not found in ${wxWidgets_INCLUDE_DIRS}.") - endif() - - file(READ "${_wx_filename}" _wx_version_h) - unset(_wx_filename CACHE) - - string(REGEX REPLACE "^(.*\n)?#define +wxMAJOR_VERSION +([0-9]+).*" - "\\2" wxWidgets_VERSION_MAJOR "${_wx_version_h}" ) - string(REGEX REPLACE "^(.*\n)?#define +wxMINOR_VERSION +([0-9]+).*" - "\\2" wxWidgets_VERSION_MINOR "${_wx_version_h}" ) - string(REGEX REPLACE "^(.*\n)?#define +wxRELEASE_NUMBER +([0-9]+).*" - "\\2" wxWidgets_VERSION_PATCH "${_wx_version_h}" ) - set(wxWidgets_VERSION_STRING - "${wxWidgets_VERSION_MAJOR}.${wxWidgets_VERSION_MINOR}.${wxWidgets_VERSION_PATCH}" ) - dbg_msg("wxWidgets_VERSION_STRING: ${wxWidgets_VERSION_STRING}") + wx_extract_version() endif() # Debug output: diff --git a/Modules/FindwxWindows.cmake b/Modules/FindwxWindows.cmake index 07fbc1b..15dacbb 100644 --- a/Modules/FindwxWindows.cmake +++ b/Modules/FindwxWindows.cmake @@ -79,8 +79,7 @@ DEPRECATED -AUTHOR Jan Woetzel <http://www.mip.informatik.uni-kiel.de/~jw> -(07/2003-01/2006) +AUTHOR Jan Woetzel (07/2003-01/2006) #]=======================================================================] # ------------------------------------------------------------------ @@ -649,7 +648,7 @@ else() # set CXXFLAGS to be fed into CMAKE_CXX_FLAGS by the user: if (HAVE_ISYSTEM) # does the compiler support -isystem ? - if (NOT APPLE) # -isystem seem sto be unsuppored on Mac + if (NOT APPLE) # -isystem seems to be unsupported on Mac if(CMAKE_COMPILER_IS_GNUCC AND CMAKE_COMPILER_IS_GNUCXX ) if (CMAKE_CXX_COMPILER MATCHES g\\+\\+) set(CMAKE_WXWINDOWS_CXX_FLAGS "`${CMAKE_WXWINDOWS_WXCONFIG_EXECUTABLE} --cxxflags|sed -e s/-I/-isystem/g`") diff --git a/Modules/FortranCInterface.cmake b/Modules/FortranCInterface.cmake index 53df01a..ed8830e 100644 --- a/Modules/FortranCInterface.cmake +++ b/Modules/FortranCInterface.cmake @@ -361,10 +361,10 @@ function(FortranCInterface_VERIFY) # Build a sample project which reports symbols. set(CMAKE_TRY_COMPILE_CONFIGURATION Release) try_compile(FortranCInterface_VERIFY_${lang}_COMPILED - ${FortranCInterface_BINARY_DIR}/Verify${lang} - ${FortranCInterface_SOURCE_DIR}/Verify - VerifyFortranC # project name - VerifyFortranC # target name + PROJECT VerifyFortranC + TARGET VerifyFortranC + SOURCE_DIR ${FortranCInterface_SOURCE_DIR}/Verify + BINARY_DIR ${FortranCInterface_BINARY_DIR}/Verify${lang} CMAKE_FLAGS -DVERIFY_CXX=${verify_cxx} -DCMAKE_VERBOSE_MAKEFILE=ON "-DCMAKE_C_FLAGS:STRING=${CMAKE_C_FLAGS}" @@ -381,13 +381,9 @@ function(FortranCInterface_VERIFY) # Report results. if(FortranCInterface_VERIFY_${lang}_COMPILED) message(CHECK_PASS "Success") - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log - "${_desc} passed with the following output:\n${_output}\n\n") set(FortranCInterface_VERIFIED_${lang} 1 CACHE INTERNAL "Fortran/${lang} compatibility") else() message(CHECK_FAIL "Failed") - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log - "${_desc} failed with the following output:\n${_output}\n\n") set(FortranCInterface_VERIFIED_${lang} 0 CACHE INTERNAL "Fortran/${lang} compatibility") endif() unset(FortranCInterface_VERIFY_${lang}_COMPILED CACHE) diff --git a/Modules/FortranCInterface/CMakeLists.txt b/Modules/FortranCInterface/CMakeLists.txt index fb35ff0..4bd7006 100644 --- a/Modules/FortranCInterface/CMakeLists.txt +++ b/Modules/FortranCInterface/CMakeLists.txt @@ -43,6 +43,8 @@ set(module_symbols MYMODULE_mp_MYSUB # Intel on Windows mymodule_mysub_ # PGI mymodule_MP_mysub # NAG + _QMmy_modulePmy_sub # LLVMFlang + _QMmymodulePmysub # LLVMFlang ${FortranCInterface_MODULE_SYMBOLS} ) list(REMOVE_DUPLICATES module_symbols) diff --git a/Modules/FortranCInterface/Detect.cmake b/Modules/FortranCInterface/Detect.cmake index 72e5544..010661e 100644 --- a/Modules/FortranCInterface/Detect.cmake +++ b/Modules/FortranCInterface/Detect.cmake @@ -47,10 +47,11 @@ unset(_FortranCInterface_CMP0056) # Build a sample project which reports symbols. set(CMAKE_TRY_COMPILE_CONFIGURATION Release) try_compile(FortranCInterface_COMPILED - ${FortranCInterface_BINARY_DIR} - ${FortranCInterface_SOURCE_DIR} - FortranCInterface # project name - FortranCInterface # target name + PROJECT FortranCInterface + TARGET FortranCInterface + SOURCE_DIR ${FortranCInterface_SOURCE_DIR} + BINARY_DIR ${FortranCInterface_BINARY_DIR} + LOG_DESCRIPTION "Fortran/C interface test project" CMAKE_FLAGS "-DCMAKE_C_FLAGS:STRING=${CMAKE_C_FLAGS}" "-DCMAKE_Fortran_FLAGS:STRING=${CMAKE_Fortran_FLAGS}" @@ -58,7 +59,7 @@ try_compile(FortranCInterface_COMPILED "-DCMAKE_Fortran_FLAGS_RELEASE:STRING=${CMAKE_Fortran_FLAGS_RELEASE}" ${_FortranCInterface_OSX_ARCH} ${_FortranCInterface_EXE_LINKER_FLAGS} - OUTPUT_VARIABLE FortranCInterface_OUTPUT) + ) set(FortranCInterface_COMPILED ${FortranCInterface_COMPILED}) unset(FortranCInterface_COMPILED CACHE) unset(_FortranCInterface_EXE_LINKER_FLAGS) @@ -70,9 +71,6 @@ if(FortranCInterface_COMPILED) include(${FortranCInterface_BINARY_DIR}/exe-Release.cmake OPTIONAL) else() set(_result "Failed to compile") - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log - "Fortran/C interface test project failed with the following output:\n" - "${FortranCInterface_OUTPUT}\n") endif() # Load symbols from INFO:symbol[] strings in the executable. @@ -95,8 +93,8 @@ set(_case_MYSUB "UPPER") set(_case_MY_SUB "UPPER") set(_global_regex "^(_*)(mysub|MYSUB)([_$]*)$") set(_global__regex "^(_*)(my_sub|MY_SUB)([_$]*)$") -set(_module_regex "^(_*)(mymodule|MYMODULE)([A-Za-z_$]*)(mysub|MYSUB)([_$]*)$") -set(_module__regex "^(_*)(my_module|MY_MODULE)([A-Za-z_$]*)(my_sub|MY_SUB)([_$]*)$") +set(_module_regex "^(_*)([A-Za-z$]*)(mymodule|MYMODULE)([A-Za-z_$]*)(mysub|MYSUB)([_$]*)$") +set(_module__regex "^(_*)([A-Za-z$]*)(my_module|MY_MODULE)([A-Za-z_$]*)(my_sub|MY_SUB)([_$]*)$") # Parse the symbol names. foreach(symbol ${FortranCInterface_SYMBOLS}) @@ -115,7 +113,7 @@ foreach(symbol ${FortranCInterface_SYMBOLS}) # Look for module symbols. string(REGEX REPLACE "${_module_${form}regex}" - "\\1;\\2;\\3;\\4;\\5" pieces "${symbol}") + "\\1\\2;\\3;\\4;\\5;\\6" pieces "${symbol}") list(LENGTH pieces len) if(len EQUAL 5) set(FortranCInterface_MODULE_${form}SYMBOL "${symbol}") diff --git a/Modules/GNUInstallDirs.cmake b/Modules/GNUInstallDirs.cmake index bd72901..9796854 100644 --- a/Modules/GNUInstallDirs.cmake +++ b/Modules/GNUInstallDirs.cmake @@ -112,6 +112,8 @@ The following values of :variable:`CMAKE_INSTALL_PREFIX` are special: For example, the ``SYSCONFDIR`` value ``etc`` becomes ``/etc/opt/...``. This is defined by the `Filesystem Hierarchy Standard`_. + This behavior does not apply to paths under ``/opt/homebrew/...``. + .. _`Filesystem Hierarchy Standard`: https://refspecs.linuxfoundation.org/FHS_3.0/fhs/index.html Macros @@ -400,7 +402,7 @@ macro(GNUInstallDirs_get_absolute_install_dir absvar var) else() set(${absvar} "${CMAKE_INSTALL_PREFIX}/${${var}}") endif() - elseif("${CMAKE_INSTALL_PREFIX}" MATCHES "^/opt/.*") + elseif("${CMAKE_INSTALL_PREFIX}" MATCHES "^/opt/" AND NOT "${CMAKE_INSTALL_PREFIX}" MATCHES "^/opt/homebrew/") if("${GGAID_dir}" STREQUAL "SYSCONFDIR" OR "${GGAID_dir}" STREQUAL "LOCALSTATEDIR" OR "${GGAID_dir}" STREQUAL "RUNSTATEDIR") set(${absvar} "/${${var}}${CMAKE_INSTALL_PREFIX}") else() diff --git a/Modules/GoogleTest.cmake b/Modules/GoogleTest.cmake index f5f4f02..57a7476 100644 --- a/Modules/GoogleTest.cmake +++ b/Modules/GoogleTest.cmake @@ -212,7 +212,7 @@ same as the Google Test name (i.e. ``suite.testcase``); see also discovery. Note that the expression is a wildcard-based format that matches against the original test names as used by gtest. For type or value-parameterized tests, these names may be different to the potentially - pretty-printed test names that ``ctest`` uses. + pretty-printed test names that :program:`ctest` uses. ``NO_PRETTY_TYPES`` By default, the type index of type-parameterized tests is replaced by the @@ -348,7 +348,7 @@ function(gtest_add_tests) unset(testList) set(gtest_case_name_regex ".*\\( *([A-Za-z_0-9]+) *, *([A-Za-z_0-9]+) *\\).*") - set(gtest_test_type_regex "(TYPED_TEST|TEST_?[FP]?)") + set(gtest_test_type_regex "(TYPED_TEST|TEST)_?[FP]?") foreach(source IN LISTS ARGS_SOURCES) if(NOT ARGS_SKIP_DEPENDENCY) @@ -361,7 +361,9 @@ function(gtest_add_tests) # Parameterized tests have a different signature for the filter if("x${test_type}" STREQUAL "xTEST_P") - string(REGEX REPLACE ${gtest_case_name_regex} "*/\\1.\\2/*" gtest_test_name ${hit}) + string(REGEX REPLACE ${gtest_case_name_regex} "*/\\1.\\2/*" gtest_test_name ${hit}) + elseif("x${test_type}" STREQUAL "xTYPED_TEST_P") + string(REGEX REPLACE ${gtest_case_name_regex} "*/\\1/*.\\2" gtest_test_name ${hit}) elseif("x${test_type}" STREQUAL "xTEST_F" OR "x${test_type}" STREQUAL "xTEST") string(REGEX REPLACE ${gtest_case_name_regex} "\\1.\\2" gtest_test_name ${hit}) elseif("x${test_type}" STREQUAL "xTYPED_TEST") @@ -403,6 +405,12 @@ function(gtest_add_tests) --gtest_filter=${gtest_test_name} ${ARGS_EXTRA_ARGS} ) + # Makes sure a skipped GTest is reported as so by CTest + set_tests_properties( + ${ctest_test_name} + PROPERTIES + SKIP_REGULAR_EXPRESSION "\\[ SKIPPED \\]" + ) list(APPEND testList ${ctest_test_name}) endif() endforeach() diff --git a/Modules/Internal/CMakeTryCompilerOrLinkerFlag.cmake b/Modules/Internal/CMakeTryCompilerOrLinkerFlag.cmake index d6fa5f0..ff8908b 100644 --- a/Modules/Internal/CMakeTryCompilerOrLinkerFlag.cmake +++ b/Modules/Internal/CMakeTryCompilerOrLinkerFlag.cmake @@ -51,7 +51,7 @@ function(CMAKE_TRY_COMPILER_OR_LINKER_FLAG lang flag result) if (NOT lang MATCHES "^(C|CXX|Fortran|ASM)$") # other possible languages are not supported # log message to keep trace of this problem... - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log + message(CONFIGURE_LOG "Function 'CMAKE_CHECK_COMPILER_FLAG' called with unsupported language: ${lang}\n") set(${result} FALSE CACHE INTERNAL ${comment}) return() @@ -69,7 +69,6 @@ function(CMAKE_TRY_COMPILER_OR_LINKER_FLAG lang flag result) set (CCCF_COMMAND_PATTERN "<FLAG> -o <OUTPUT> <SOURCE>") endif() - list (APPEND CCCF_FAIL_REGEX "argument unused during compilation") # clang if (check_lang STREQUAL "C") list(APPEND CCCF_FAIL_REGEX "command line option .* is valid for .* but not for C") # GNU @@ -144,7 +143,7 @@ function(CMAKE_TRY_COMPILER_OR_LINKER_FLAG lang flag result) endforeach() endif() if (DEFINED ${result}) - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log + message(CONFIGURE_LOG "Determining if the ${flag} option " "is supported for ${lang} language failed with the following output:\n" "${COMPILER_FLAG_OUTPUT}\n") diff --git a/Modules/Internal/CPack/CPackDeb.cmake b/Modules/Internal/CPack/CPackDeb.cmake index 958a6db..38e32c2 100644 --- a/Modules/Internal/CPack/CPackDeb.cmake +++ b/Modules/Internal/CPack/CPackDeb.cmake @@ -37,8 +37,8 @@ endfunction() #extract library name and version for given shared object function(extract_so_info shared_object libname version) - if(READELF_EXECUTABLE) - execute_process(COMMAND "${READELF_EXECUTABLE}" -d "${shared_object}" + if(CPACK_READELF_EXECUTABLE) + execute_process(COMMAND "${CPACK_READELF_EXECUTABLE}" -d "${shared_object}" WORKING_DIRECTORY "${CPACK_TEMPORARY_DIRECTORY}" RESULT_VARIABLE result OUTPUT_VARIABLE output @@ -197,15 +197,15 @@ function(cpack_deb_prepare_package_vars) endforeach() endif() - find_program(READELF_EXECUTABLE NAMES readelf) + find_program(CPACK_READELF_EXECUTABLE NAMES readelf) if(CPACK_DEBIAN_DEBUGINFO_PACKAGE AND CPACK_DEB_UNSTRIPPED_FILES) - find_program(OBJCOPY_EXECUTABLE NAMES objcopy) + find_program(CPACK_OBJCOPY_EXECUTABLE NAMES objcopy) - if(NOT OBJCOPY_EXECUTABLE) + if(NOT CPACK_OBJCOPY_EXECUTABLE) message(FATAL_ERROR "debuginfo packages require the objcopy tool") endif() - if(NOT READELF_EXECUTABLE) + if(NOT CPACK_READELF_EXECUTABLE) message(FATAL_ERROR "debuginfo packages require the readelf tool") endif() @@ -213,7 +213,7 @@ function(cpack_deb_prepare_package_vars) foreach(_FILE IN LISTS CPACK_DEB_UNSTRIPPED_FILES) # Get the file's Build ID - execute_process(COMMAND env LC_ALL=C ${READELF_EXECUTABLE} -n "${_FILE}" + execute_process(COMMAND env LC_ALL=C ${CPACK_READELF_EXECUTABLE} -n "${_FILE}" WORKING_DIRECTORY "${CPACK_TEMPORARY_DIRECTORY}" OUTPUT_VARIABLE READELF_OUTPUT RESULT_VARIABLE READELF_RESULT @@ -221,7 +221,7 @@ function(cpack_deb_prepare_package_vars) OUTPUT_STRIP_TRAILING_WHITESPACE ) if(NOT READELF_RESULT EQUAL 0) message(FATAL_ERROR "CPackDeb: readelf: '${READELF_ERROR}';\n" - "executed command: '${READELF_EXECUTABLE} -n ${_FILE}'") + "executed command: '${CPACK_READELF_EXECUTABLE} -n ${_FILE}'") endif() if(READELF_OUTPUT MATCHES "Build ID: ([0-9a-zA-Z][0-9a-zA-Z])([0-9a-zA-Z]*)") set(_BUILD_ID_START ${CMAKE_MATCH_1}) @@ -235,7 +235,7 @@ function(cpack_deb_prepare_package_vars) set(_FILE_DBGSYM ${_DBGSYM_ROOT}/usr/lib/debug/.build-id/${_BUILD_ID_START}/${_BUILD_ID_REMAINING}.debug) get_filename_component(_OUT_DIR "${_FILE_DBGSYM}" DIRECTORY) file(MAKE_DIRECTORY "${CPACK_TEMPORARY_DIRECTORY}/${_OUT_DIR}") - execute_process(COMMAND ${OBJCOPY_EXECUTABLE} --only-keep-debug "${_FILE}" "${_FILE_DBGSYM}" + execute_process(COMMAND ${CPACK_OBJCOPY_EXECUTABLE} --only-keep-debug "${_FILE}" "${_FILE_DBGSYM}" WORKING_DIRECTORY "${CPACK_TEMPORARY_DIRECTORY}" OUTPUT_VARIABLE OBJCOPY_OUTPUT RESULT_VARIABLE OBJCOPY_RESULT @@ -243,9 +243,9 @@ function(cpack_deb_prepare_package_vars) OUTPUT_STRIP_TRAILING_WHITESPACE ) if(NOT OBJCOPY_RESULT EQUAL 0) message(FATAL_ERROR "CPackDeb: objcopy: '${OBJCOPY_ERROR}';\n" - "executed command: '${OBJCOPY_EXECUTABLE} --only-keep-debug ${_FILE} ${_FILE_DBGSYM}'") + "executed command: '${CPACK_OBJCOPY_EXECUTABLE} --only-keep-debug ${_FILE} ${_FILE_DBGSYM}'") endif() - execute_process(COMMAND ${OBJCOPY_EXECUTABLE} --strip-unneeded ${_FILE} + execute_process(COMMAND ${CPACK_OBJCOPY_EXECUTABLE} --strip-unneeded ${_FILE} WORKING_DIRECTORY "${CPACK_TEMPORARY_DIRECTORY}" OUTPUT_VARIABLE OBJCOPY_OUTPUT RESULT_VARIABLE OBJCOPY_RESULT @@ -253,9 +253,9 @@ function(cpack_deb_prepare_package_vars) OUTPUT_STRIP_TRAILING_WHITESPACE ) if(NOT OBJCOPY_RESULT EQUAL 0) message(FATAL_ERROR "CPackDeb: objcopy: '${OBJCOPY_ERROR}';\n" - "executed command: '${OBJCOPY_EXECUTABLE} --strip-debug ${_FILE}'") + "executed command: '${CPACK_OBJCOPY_EXECUTABLE} --strip-debug ${_FILE}'") endif() - execute_process(COMMAND ${OBJCOPY_EXECUTABLE} --add-gnu-debuglink=${_FILE_DBGSYM} ${_FILE} + execute_process(COMMAND ${CPACK_OBJCOPY_EXECUTABLE} --add-gnu-debuglink=${_FILE_DBGSYM} ${_FILE} WORKING_DIRECTORY "${CPACK_TEMPORARY_DIRECTORY}" OUTPUT_VARIABLE OBJCOPY_OUTPUT RESULT_VARIABLE OBJCOPY_RESULT @@ -263,7 +263,7 @@ function(cpack_deb_prepare_package_vars) OUTPUT_STRIP_TRAILING_WHITESPACE ) if(NOT OBJCOPY_RESULT EQUAL 0) message(FATAL_ERROR "CPackDeb: objcopy: '${OBJCOPY_ERROR}';\n" - "executed command: '${OBJCOPY_EXECUTABLE} --add-gnu-debuglink=${_FILE_DBGSYM} ${_FILE}'") + "executed command: '${CPACK_OBJCOPY_EXECUTABLE} --add-gnu-debuglink=${_FILE_DBGSYM} ${_FILE}'") endif() endforeach() endif() @@ -652,7 +652,7 @@ function(cpack_deb_prepare_package_vars) unset(CPACK_DEBIAN_PACKAGE_SHLIBS_LIST) if(CPACK_DEBIAN_PACKAGE_GENERATE_SHLIBS) - if(READELF_EXECUTABLE) + if(CPACK_READELF_EXECUTABLE) foreach(_FILE IN LISTS CPACK_DEB_SHARED_OBJECT_FILES) extract_so_info("${_FILE}" libname soversion) if(libname AND DEFINED soversion) diff --git a/Modules/Internal/CPack/CPackRPM.cmake b/Modules/Internal/CPack/CPackRPM.cmake index c72bf6d..8ac1f6b 100644 --- a/Modules/Internal/CPack/CPackRPM.cmake +++ b/Modules/Internal/CPack/CPackRPM.cmake @@ -625,8 +625,8 @@ function(cpack_rpm_debugsymbol_check INSTALL_FILES WORKING_DIR) endif() # With objdump we should check the debug symbols - find_program(OBJDUMP_EXECUTABLE objdump) - if(NOT OBJDUMP_EXECUTABLE) + find_program(CPACK_OBJDUMP_EXECUTABLE objdump) + if(NOT CPACK_OBJDUMP_EXECUTABLE) message(FATAL_ERROR "CPackRPM: objdump binary could not be found!" " Required for debuginfo packaging. See documentation of" " CPACK_RPM_DEBUGINFO_PACKAGE variable for details.") @@ -649,7 +649,7 @@ function(cpack_rpm_debugsymbol_check INSTALL_FILES WORKING_DIR) continue() endif() - execute_process(COMMAND "${OBJDUMP_EXECUTABLE}" -h ${WORKING_DIR}/${F} + execute_process(COMMAND "${CPACK_OBJDUMP_EXECUTABLE}" -h ${WORKING_DIR}/${F} WORKING_DIRECTORY "${CPACK_TOPLEVEL_DIRECTORY}" RESULT_VARIABLE OBJDUMP_EXEC_RESULT OUTPUT_VARIABLE OBJDUMP_OUT @@ -790,7 +790,7 @@ function(cpack_rpm_variable_fallback OUTPUT_VAR_NAME) set(FALLBACK_VAR_NAMES ${ARGN}) foreach(variable_name IN LISTS FALLBACK_VAR_NAMES) - if(${variable_name}) + if(DEFINED ${variable_name}) set(${OUTPUT_VAR_NAME} "${${variable_name}}" PARENT_SCOPE) break() endif() @@ -1200,7 +1200,7 @@ function(cpack_rpm_generate_package) file(READ ${CPACK_RPM_${RPM_SCRIPT_FILE_TIME_}_${RPM_SCRIPT_FILE_TYPE_}_READ_FILE} "CPACK_RPM_SPEC_${RPM_SCRIPT_FILE_TIME_}${RPM_SCRIPT_FILE_TYPE_}") else() - message("CPackRPM:Warning: CPACK_RPM_${RPM_SCRIPT_FILE_TIME_}_${RPM_SCRIPT_FILE_TYPE_}_SCRIPT_FILE <${CPACK_RPM_${RPM_SCRIPT_FILE_TIME_}_${RPM_SCRIPT_FILE_TYPE_}_READ_FILE}> does not exists - ignoring") + message("CPackRPM:Warning: CPACK_RPM_${RPM_SCRIPT_FILE_TIME_}_${RPM_SCRIPT_FILE_TYPE_}_SCRIPT_FILE <${CPACK_RPM_${RPM_SCRIPT_FILE_TIME_}_${RPM_SCRIPT_FILE_TYPE_}_READ_FILE}> does not exist - ignoring") endif() else() # reset SPEC var value if no file has been specified @@ -1217,7 +1217,7 @@ function(cpack_rpm_generate_package) if(EXISTS ${CPACK_RPM_CHANGELOG_FILE}) file(READ ${CPACK_RPM_CHANGELOG_FILE} CPACK_RPM_SPEC_CHANGELOG) else() - message(SEND_ERROR "CPackRPM:Warning: CPACK_RPM_CHANGELOG_FILE <${CPACK_RPM_CHANGELOG_FILE}> does not exists - ignoring") + message(SEND_ERROR "CPackRPM:Warning: CPACK_RPM_CHANGELOG_FILE <${CPACK_RPM_CHANGELOG_FILE}> does not exist - ignoring") endif() else() set(CPACK_RPM_SPEC_CHANGELOG "* Sun Jul 4 2010 Eric Noulard <eric.noulard@gmail.com> - ${CPACK_RPM_PACKAGE_VERSION}-${CPACK_RPM_PACKAGE_RELEASE}\n Generated by CPack RPM (no Changelog file were provided)") diff --git a/Modules/Internal/CPack/NSIS.template.in b/Modules/Internal/CPack/NSIS.template.in index 701366e..21753af 100644 --- a/Modules/Internal/CPack/NSIS.template.in +++ b/Modules/Internal/CPack/NSIS.template.in @@ -48,7 +48,7 @@ ;--- Component support macros: --- ; The code for the add/remove functionality is from: -; http://nsis.sourceforge.net/Add/Remove_Functionality +; https://nsis.sourceforge.io/Add/Remove_Functionality ; It has been modified slightly and extended to provide ; inter-component dependencies. Var AR_SecFlags @@ -383,7 +383,7 @@ Function un.RemoveFromPath FunctionEnd ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; Uninstall sutff +; Uninstall stuff ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ########################################### @@ -487,15 +487,15 @@ Done: Exch $R1 FunctionEnd -Function ConditionalAddToRegisty +Function ConditionalAddToRegistry Pop $0 Pop $1 - StrCmp "$0" "" ConditionalAddToRegisty_EmptyString + StrCmp "$0" "" ConditionalAddToRegistry_EmptyString WriteRegStr SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" \ "$1" "$0" ;MessageBox MB_OK "Set Registry: '$1' to '$0'" DetailPrint "Set install registry entry: '$1' to '$0'" - ConditionalAddToRegisty_EmptyString: + ConditionalAddToRegistry_EmptyString: FunctionEnd ;-------------------------------- @@ -665,44 +665,44 @@ Section "-Core installation" WriteUninstaller "$INSTDIR\@CPACK_NSIS_UNINSTALL_NAME@.exe" Push "DisplayName" Push "@CPACK_NSIS_DISPLAY_NAME@" - Call ConditionalAddToRegisty + Call ConditionalAddToRegistry Push "DisplayVersion" Push "@CPACK_PACKAGE_VERSION@" - Call ConditionalAddToRegisty + Call ConditionalAddToRegistry Push "Publisher" Push "@CPACK_PACKAGE_VENDOR@" - Call ConditionalAddToRegisty + Call ConditionalAddToRegistry Push "UninstallString" Push "$\"$INSTDIR\@CPACK_NSIS_UNINSTALL_NAME@.exe$\"" - Call ConditionalAddToRegisty + Call ConditionalAddToRegistry Push "NoRepair" Push "1" - Call ConditionalAddToRegisty + Call ConditionalAddToRegistry !ifdef CPACK_NSIS_ADD_REMOVE ;Create add/remove functionality Push "ModifyPath" Push "$INSTDIR\AddRemove.exe" - Call ConditionalAddToRegisty + Call ConditionalAddToRegistry !else Push "NoModify" Push "1" - Call ConditionalAddToRegisty + Call ConditionalAddToRegistry !endif ; Optional registration Push "DisplayIcon" Push "$INSTDIR\@CPACK_NSIS_INSTALLED_ICON_NAME@" - Call ConditionalAddToRegisty + Call ConditionalAddToRegistry Push "HelpLink" Push "@CPACK_NSIS_HELP_LINK@" - Call ConditionalAddToRegisty + Call ConditionalAddToRegistry Push "URLInfoAbout" Push "@CPACK_NSIS_URL_INFO_ABOUT@" - Call ConditionalAddToRegisty + Call ConditionalAddToRegistry Push "Contact" Push "@CPACK_NSIS_CONTACT@" - Call ConditionalAddToRegisty + Call ConditionalAddToRegistry !insertmacro MUI_INSTALLOPTIONS_READ $INSTALL_DESKTOP "NSIS.InstallOptions.ini" "Field 5" "State" !insertmacro MUI_STARTMENU_WRITE_BEGIN Application @@ -720,19 +720,19 @@ Section "-Core installation" ; Write special uninstall registry entries Push "StartMenu" Push "$STARTMENU_FOLDER" - Call ConditionalAddToRegisty + Call ConditionalAddToRegistry Push "DoNotAddToPath" Push "$DO_NOT_ADD_TO_PATH" - Call ConditionalAddToRegisty + Call ConditionalAddToRegistry Push "AddToPathAllUsers" Push "$ADD_TO_PATH_ALL_USERS" - Call ConditionalAddToRegisty + Call ConditionalAddToRegistry Push "AddToPathCurrentUser" Push "$ADD_TO_PATH_CURRENT_USER" - Call ConditionalAddToRegisty + Call ConditionalAddToRegistry Push "InstallToDesktop" Push "$INSTALL_DESKTOP" - Call ConditionalAddToRegisty + Call ConditionalAddToRegistry !insertmacro MUI_STARTMENU_WRITE_END @@ -880,7 +880,7 @@ Section "Uninstall" StrCmp "$MUI_TEMP" "$SMPROGRAMS" startMenuDeleteLoopDone startMenuDeleteLoop startMenuDeleteLoopDone: - ; If the user changed the shortcut, then untinstall may not work. This should + ; If the user changed the shortcut, then uninstall may not work. This should ; try to fix it. StrCpy $MUI_TEMP "$START_MENU" Delete "$SMPROGRAMS\$MUI_TEMP\Uninstall.lnk" diff --git a/Modules/Internal/CheckFlagCommonConfig.cmake b/Modules/Internal/CheckFlagCommonConfig.cmake index c011c24..61eada2 100644 --- a/Modules/Internal/CheckFlagCommonConfig.cmake +++ b/Modules/Internal/CheckFlagCommonConfig.cmake @@ -22,32 +22,30 @@ macro(CMAKE_CHECK_FLAG_COMMON_INIT _FUNC _LANG _SRC _PATTERNS) FAIL_REGEX "-Werror=.* argument .* is not valid for C\\+\\+") elseif("${_LANG}" STREQUAL "CUDA") set(${_SRC} "__host__ int main() { return 0; }") - set(${_PATTERNS} FAIL_REGEX "command[ -]line option .* is valid for .* but not for C\\+\\+" # Host GNU - FAIL_REGEX "argument unused during compilation: .*") # Clang + set(${_PATTERNS} FAIL_REGEX "command[ -]line option .* is valid for .* but not for C\\+\\+") # Host GNU elseif("${_LANG}" STREQUAL "Fortran") set(${_SRC} " program test\n stop\n end program") set(${_PATTERNS} FAIL_REGEX "command[ -]line option .* is valid for .* but not for Fortran") elseif("${_LANG}" STREQUAL "HIP") set(${_SRC} "__host__ int main() { return 0; }") - set(${_PATTERNS} FAIL_REGEX "argument unused during compilation: .*") # Clang elseif("${_LANG}" STREQUAL "OBJC") set(${_SRC} [=[ #ifndef __OBJC__ # error "Not an Objective-C compiler" #endif int main(void) { return 0; }]=]) - set(${_PATTERNS} FAIL_REGEX "command[ -]line option .* is valid for .* but not for Objective-C" # GNU - FAIL_REGEX "argument unused during compilation: .*") # Clang + set(${_PATTERNS} FAIL_REGEX "command[ -]line option .* is valid for .* but not for Objective-C") # GNU elseif("${_LANG}" STREQUAL "OBJCXX") set(${_SRC} [=[ #ifndef __OBJC__ # error "Not an Objective-C++ compiler" #endif int main(void) { return 0; }]=]) - set(${_PATTERNS} FAIL_REGEX "command[ -]line option .* is valid for .* but not for Objective-C\\+\\+" # GNU - FAIL_REGEX "argument unused during compilation: .*") # Clang + set(${_PATTERNS} FAIL_REGEX "command[ -]line option .* is valid for .* but not for Objective-C\\+\\+") # GNU elseif("${_LANG}" STREQUAL "ISPC") set(${_SRC} "float func(uniform int32, float a) { return a / 2.25; }") + elseif("${_LANG}" STREQUAL "Swift") + set(${_SRC} "func blarpy() { }") else() message (SEND_ERROR "${_FUNC}: ${_LANG}: unknown language.") return() diff --git a/Modules/Internal/CheckSourceCompiles.cmake b/Modules/Internal/CheckSourceCompiles.cmake index 27aa3e0..83d7020 100644 --- a/Modules/Internal/CheckSourceCompiles.cmake +++ b/Modules/Internal/CheckSourceCompiles.cmake @@ -9,7 +9,7 @@ cmake_policy(SET CMP0057 NEW) # if() supports IN_LIST function(CMAKE_CHECK_SOURCE_COMPILES _lang _source _var) if(NOT DEFINED "${_var}") - + set(_lang_filename "src") if(_lang STREQUAL "C") set(_lang_textual "C") set(_lang_ext "c") @@ -34,6 +34,13 @@ function(CMAKE_CHECK_SOURCE_COMPILES _lang _source _var) elseif(_lang STREQUAL "OBJCXX") set(_lang_textual "Objective-C++") set(_lang_ext "mm") + elseif(_lang STREQUAL "Swift") + set(_lang_textual "Swift") + set(_lang_ext "swift") + if (NOT DEFINED CMAKE_TRY_COMPILE_TARGET_TYPE + OR CMAKE_TRY_COMPILE_TARGET_TYPE STREQUAL "EXECUTABLE") + set(_lang_filename "main") + endif() else() message (SEND_ERROR "check_source_compiles: ${_lang}: unknown language.") return() @@ -86,15 +93,13 @@ function(CMAKE_CHECK_SOURCE_COMPILES _lang _source _var) else() set(CHECK_${LANG}_SOURCE_COMPILES_ADD_INCLUDES) endif() - file(WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.${_SRC_EXT}" - "${_source}\n") if(NOT CMAKE_REQUIRED_QUIET) message(CHECK_START "Performing Test ${_var}") endif() + string(APPEND _source "\n") try_compile(${_var} - ${CMAKE_BINARY_DIR} - ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.${_SRC_EXT} + SOURCE_FROM_VAR "${_lang_filename}.${_SRC_EXT}" _source COMPILE_DEFINITIONS -D${_var} ${CMAKE_REQUIRED_DEFINITIONS} ${CHECK_${LANG}_SOURCE_COMPILES_ADD_LINK_OPTIONS} ${CHECK_${LANG}_SOURCE_COMPILES_ADD_LIBRARIES} @@ -117,19 +122,11 @@ function(CMAKE_CHECK_SOURCE_COMPILES _lang _source _var) if(NOT CMAKE_REQUIRED_QUIET) message(CHECK_PASS "Success") endif() - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log - "Performing ${_lang_textual} SOURCE FILE Test ${_var} succeeded with the following output:\n" - "${OUTPUT}\n" - "Source file was:\n${_source}\n") else() if(NOT CMAKE_REQUIRED_QUIET) message(CHECK_FAIL "Failed") endif() set(${_var} "" CACHE INTERNAL "Test ${_var}") - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log - "Performing ${_lang_textual} SOURCE FILE Test ${_var} failed with the following output:\n" - "${OUTPUT}\n" - "Source file was:\n${_source}\n") endif() endif() endfunction() diff --git a/Modules/Internal/CheckSourceRuns.cmake b/Modules/Internal/CheckSourceRuns.cmake index 75e9896..805d98d 100644 --- a/Modules/Internal/CheckSourceRuns.cmake +++ b/Modules/Internal/CheckSourceRuns.cmake @@ -85,23 +85,20 @@ function(CMAKE_CHECK_SOURCE_RUNS _lang _source _var) else() set(CHECK_${_lang}_SOURCE_COMPILES_ADD_INCLUDES) endif() - file(WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.${_SRC_EXT}" - "${_source}\n") if(NOT CMAKE_REQUIRED_QUIET) message(CHECK_START "Performing Test ${_var}") endif() + string(APPEND _source "\n") try_run(${_var}_EXITCODE ${_var}_COMPILED - ${CMAKE_BINARY_DIR} - ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.${_SRC_EXT} + SOURCE_FROM_VAR "src.${_SRC_EXT}" _source COMPILE_DEFINITIONS -D${_var} ${CMAKE_REQUIRED_DEFINITIONS} ${CHECK_${_lang}_SOURCE_COMPILES_ADD_LINK_OPTIONS} ${CHECK_${_lang}_SOURCE_COMPILES_ADD_LIBRARIES} CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${CMAKE_REQUIRED_FLAGS} -DCMAKE_SKIP_RPATH:BOOL=${CMAKE_SKIP_RPATH} "${CHECK_${_lang}_SOURCE_COMPILES_ADD_INCLUDES}" - COMPILE_OUTPUT_VARIABLE OUTPUT - RUN_OUTPUT_VARIABLE RUN_OUTPUT) + ) # if it did not compile make the return value fail code of 1 if(NOT ${_var}_COMPILED) set(${_var}_EXITCODE 1) @@ -113,13 +110,6 @@ function(CMAKE_CHECK_SOURCE_RUNS _lang _source _var) if(NOT CMAKE_REQUIRED_QUIET) message(CHECK_PASS "Success") endif() - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log - "Performing ${_lang_textual} SOURCE FILE Test ${_var} succeeded with the following compile output:\n" - "${OUTPUT}\n" - "...and run output:\n" - "${RUN_OUTPUT}\n" - "Return value: ${${_var}}\n" - "Source file was:\n${_source}\n") else() if(CMAKE_CROSSCOMPILING AND "${${_var}_EXITCODE}" MATCHES "FAILED_TO_RUN") set(${_var} "${${_var}_EXITCODE}" PARENT_SCOPE) @@ -130,14 +120,6 @@ function(CMAKE_CHECK_SOURCE_RUNS _lang _source _var) if(NOT CMAKE_REQUIRED_QUIET) message(CHECK_FAIL "Failed") endif() - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log - "Performing ${_lang_textual} SOURCE FILE Test ${_var} failed with the following compile output:\n" - "${OUTPUT}\n" - "...and run output:\n" - "${RUN_OUTPUT}\n" - "Return value: ${${_var}_EXITCODE}\n" - "Source file was:\n${_source}\n") - endif() endif() endfunction() diff --git a/Modules/Internal/FeatureTesting.cmake b/Modules/Internal/FeatureTesting.cmake index b6f3c09..1a8a27e 100644 --- a/Modules/Internal/FeatureTesting.cmake +++ b/Modules/Internal/FeatureTesting.cmake @@ -4,7 +4,7 @@ macro(_record_compiler_features lang compile_flags feature_list) string(TOLOWER ${lang} lang_lc) file(REMOVE "${CMAKE_BINARY_DIR}/CMakeFiles/feature_tests.bin") - file(WRITE "${CMAKE_BINARY_DIR}/CMakeFiles/feature_tests.${lang_lc}" " + set(_content " const char features[] = {\"\\n\"\n") get_property(known_features GLOBAL PROPERTY CMAKE_${lang}_KNOWN_FEATURES) @@ -16,10 +16,11 @@ macro(_record_compiler_features lang compile_flags feature_list) else() set(_feature_condition "#if ${_cmake_feature_test_${feature}}\n\"1\"\n#else\n\"0\"\n#endif\n") endif() - file(APPEND "${CMAKE_BINARY_DIR}/CMakeFiles/feature_tests.${lang_lc}" "\"${lang}_FEATURE:\"\n${_feature_condition}\"${feature}\\n\"\n") + string(APPEND _content + "\"${lang}_FEATURE:\"\n${_feature_condition}\"${feature}\\n\"\n") endif() endforeach() - file(APPEND "${CMAKE_BINARY_DIR}/CMakeFiles/feature_tests.${lang_lc}" + string(APPEND _content "\n};\n\nint main(int argc, char** argv) { (void)argv; return features[argc]; }\n") if(CMAKE_${lang}_LINK_WITH_STANDARD_COMPILE_OPTION) @@ -31,30 +32,28 @@ macro(_record_compiler_features lang compile_flags feature_list) endif() try_compile(CMAKE_${lang}_FEATURE_TEST - ${CMAKE_BINARY_DIR} "${CMAKE_BINARY_DIR}/CMakeFiles/feature_tests.${lang_lc}" + SOURCE_FROM_VAR "feature_tests.${lang_lc}" _content COMPILE_DEFINITIONS "${compile_flags}" LINK_LIBRARIES "${compile_flags_for_link}" - OUTPUT_VARIABLE _output COPY_FILE "${CMAKE_BINARY_DIR}/CMakeFiles/feature_tests.bin" COPY_FILE_ERROR _copy_error ) - if(CMAKE_${lang}_FEATURE_TEST AND NOT _copy_error) - set(_result 0) - else() + if(NOT CMAKE_${lang}_FEATURE_TEST) + set(_result 255) + elseif(_copy_error) set(_result 255) + message(WARNING "${_copy_error}") + else() + set(_result 0) endif() unset(CMAKE_${lang}_FEATURE_TEST CACHE) unset(compile_flags_for_link) if (_result EQUAL 0) - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log - "\n\nDetecting ${lang} [${compile_flags}] compiler features compiled with the following output:\n${_output}\n\n") if(EXISTS "${CMAKE_BINARY_DIR}/CMakeFiles/feature_tests.bin") file(STRINGS "${CMAKE_BINARY_DIR}/CMakeFiles/feature_tests.bin" features REGEX "${lang}_FEATURE:.*") foreach(info ${features}) - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log - " Feature record: ${info}\n") string(REPLACE "${lang}_FEATURE:" "" info ${info}) string(SUBSTRING ${info} 0 1 has_feature) if(has_feature) @@ -63,9 +62,6 @@ macro(_record_compiler_features lang compile_flags feature_list) endif() endforeach() endif() - else() - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log - "Detecting ${lang} [${compile_flags}] compiler features failed to compile with the following output:\n${_output}\n${_copy_error}\n\n") endif() endmacro() diff --git a/Modules/MatlabTestsRedirect.cmake b/Modules/MatlabTestsRedirect.cmake index fc36fc3..d651cdd 100644 --- a/Modules/MatlabTestsRedirect.cmake +++ b/Modules/MatlabTestsRedirect.cmake @@ -15,6 +15,7 @@ # -Dcustom_Matlab_test_command="" # -Dcmd_to_run_before_test="" # -Dunittest_file_to_run +# -Dmaut_BATCH_OPTION="-batch" # -P FindMatlab_TestsRedirect.cmake set(Matlab_UNIT_TESTS_CMD -nosplash -nodesktop -nodisplay ${Matlab_ADDITIONAL_STARTUP_OPTIONS}) @@ -84,7 +85,7 @@ execute_process( # Do not use a full path to log file. Depend on the fact that the log file # is always going to go in the working_directory. This is because matlab # on unix is a shell script that does not handle spaces in the logfile path. - COMMAND "${Matlab_PROGRAM}" ${Matlab_UNIT_TESTS_CMD} -logfile "${log_file_name}" -r "${Matlab_SCRIPT_TO_RUN}" + COMMAND "${Matlab_PROGRAM}" ${Matlab_UNIT_TESTS_CMD} -logfile "${log_file_name}" "${maut_BATCH_OPTION}" "${Matlab_SCRIPT_TO_RUN}" RESULT_VARIABLE res ${test_timeout} OUTPUT_QUIET # we do not want the output twice diff --git a/Modules/Platform/ADSP-C.cmake b/Modules/Platform/ADSP-C.cmake new file mode 100644 index 0000000..c85e746 --- /dev/null +++ b/Modules/Platform/ADSP-C.cmake @@ -0,0 +1,2 @@ +include(Platform/ADSP-Common) +__platform_adsp(C) diff --git a/Modules/Platform/ADSP-CXX.cmake b/Modules/Platform/ADSP-CXX.cmake new file mode 100644 index 0000000..d827c80 --- /dev/null +++ b/Modules/Platform/ADSP-CXX.cmake @@ -0,0 +1,2 @@ +include(Platform/ADSP-Common) +__platform_adsp(CXX) diff --git a/Modules/Platform/ADSP-Common.cmake b/Modules/Platform/ADSP-Common.cmake new file mode 100644 index 0000000..2ba90b2 --- /dev/null +++ b/Modules/Platform/ADSP-Common.cmake @@ -0,0 +1,36 @@ +include_guard() + +macro(__platform_adsp_init) + if(NOT CMAKE_ADSP_PLATFORM_INITIALIZED) + if(NOT CMAKE_SYSTEM_PROCESSOR) + message(FATAL_ERROR "ADSP: CMAKE_SYSTEM_PROCESSOR is required but not set") + endif() + + set(CMAKE_ADSP_PROCESSOR "ADSP-${CMAKE_SYSTEM_PROCESSOR}") + string(TOUPPER "${CMAKE_ADSP_PROCESSOR}" CMAKE_ADSP_PROCESSOR) + + set(CMAKE_ADSP_COMPILER_NAME cc21k.exe) + if(CMAKE_ADSP_PROCESSOR MATCHES "^ADSP-BF") + set(CMAKE_ADSP_COMPILER_NAME ccblkfn.exe) + endif() + + set(CMAKE_ADSP_PLATFORM_INITIALIZED TRUE) + endif() +endmacro() + +macro(__platform_adsp lang) + __platform_adsp_init() + set(CMAKE_${lang}_COMPILER "${CMAKE_ADSP_ROOT}/${CMAKE_ADSP_COMPILER_NAME}") + + execute_process( + COMMAND "${CMAKE_${lang}_COMPILER}" "-proc=${CMAKE_ADSP_PROCESSOR}" "-version" + OUTPUT_QUIET ERROR_QUIET + RESULT_VARIABLE _adsp_is_valid_proc + ) + if(NOT _adsp_is_valid_proc EQUAL 0) + message(FATAL_ERROR + "ADSP: unsupported processor '${CMAKE_ADSP_PROCESSOR}' for CMAKE_${lang}_COMPILER:\n" + " ${CMAKE_${lang}_COMPILER}" + ) + endif() +endmacro() diff --git a/Modules/Platform/ADSP-Determine.cmake b/Modules/Platform/ADSP-Determine.cmake new file mode 100644 index 0000000..6ccf1ea --- /dev/null +++ b/Modules/Platform/ADSP-Determine.cmake @@ -0,0 +1,26 @@ +if(IS_DIRECTORY "$ENV{ADSP_ROOT}") + file(TO_CMAKE_PATH "$ENV{ADSP_ROOT}" CMAKE_ADSP_ROOT) +endif() + +macro(_find_adsp_root path_pattern) + set(CMAKE_ADSP_ROOT "") + set(_adsp_root_version "0") + file(GLOB _adsp_root_paths "${path_pattern}") + foreach(_current_adsp_root_path IN LISTS _adsp_root_paths) + string(REGEX MATCH "([0-9\\.]+)/?$" _current_adsp_root_version "${_current_adsp_root_path}") + if(_current_adsp_root_version VERSION_GREATER _adsp_root_version) + set(CMAKE_ADSP_ROOT "${_current_adsp_root_path}") + set(_adsp_root_version "${_current_adsp_root_version}") + endif() + endforeach() +endmacro() + +if(NOT CMAKE_ADSP_ROOT) + _find_adsp_root("C:/Analog Devices/CrossCore Embedded Studio *") +endif() +if(NOT CMAKE_ADSP_ROOT) + _find_adsp_root("C:/Program Files (x86)/Analog Devices/VisualDSP *") +endif() +if(NOT IS_DIRECTORY "${CMAKE_ADSP_ROOT}") + message(FATAL_ERROR "ADSP: could not find CCES/VDSP++ install directory ${CMAKE_ADSP_ROOT}") +endif() diff --git a/Modules/Platform/ADSP.cmake b/Modules/Platform/ADSP.cmake new file mode 100644 index 0000000..15e9dd2 --- /dev/null +++ b/Modules/Platform/ADSP.cmake @@ -0,0 +1,4 @@ +include(Platform/ADSP-Common) +__platform_adsp_init() + +set_property(GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS FALSE) diff --git a/Modules/Platform/AIX-GNU.cmake b/Modules/Platform/AIX-GNU.cmake index 5a532c7..a9aa8e0 100644 --- a/Modules/Platform/AIX-GNU.cmake +++ b/Modules/Platform/AIX-GNU.cmake @@ -23,11 +23,11 @@ macro(__aix_compiler_gnu lang) # Construct the export list ourselves to pass only the object files so # that we export only the symbols actually provided by the sources. set(CMAKE_${lang}_CREATE_SHARED_LIBRARY - "\"${CMAKE_ROOT}/Modules/Platform/AIX/ExportImportList\" -o <OBJECT_DIR>/exports.exp <AIX_EXPORTS> <OBJECTS>" + "\"${CMAKE_ROOT}/Modules/Platform/AIX/ExportImportList\" -o <OBJECT_DIR>/exports.exp -c <CMAKE_${lang}_COMPILER> <AIX_EXPORTS> <OBJECTS>" "<CMAKE_${lang}_COMPILER> <CMAKE_SHARED_LIBRARY_${lang}_FLAGS> -Wl,-bE:<OBJECT_DIR>/exports.exp <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS> <SONAME_FLAG><TARGET_SONAME> -o <TARGET> <OBJECTS> <LINK_LIBRARIES>" ) set(CMAKE_${lang}_LINK_EXECUTABLE_WITH_EXPORTS - "\"${CMAKE_ROOT}/Modules/Platform/AIX/ExportImportList\" -o <TARGET_IMPLIB> -l . <AIX_EXPORTS> <OBJECTS>" + "\"${CMAKE_ROOT}/Modules/Platform/AIX/ExportImportList\" -o <TARGET_IMPLIB> -c <CMAKE_${lang}_COMPILER> -l . <AIX_EXPORTS> <OBJECTS>" "<CMAKE_${lang}_COMPILER> <FLAGS> <CMAKE_${lang}_LINK_FLAGS> -Wl,-bE:<TARGET_IMPLIB> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>") endmacro() diff --git a/Modules/Platform/AIX-XL.cmake b/Modules/Platform/AIX-XL.cmake index 2a8c159..902cbb3 100644 --- a/Modules/Platform/AIX-XL.cmake +++ b/Modules/Platform/AIX-XL.cmake @@ -29,12 +29,12 @@ macro(__aix_compiler_xl lang) # Construct the export list ourselves to pass only the object files so # that we export only the symbols actually provided by the sources. set(CMAKE_${lang}_CREATE_SHARED_LIBRARY - "\"${CMAKE_ROOT}/Modules/Platform/AIX/ExportImportList\" -o <OBJECT_DIR>/exports.exp <AIX_EXPORTS>${_OBJECTS}" + "\"${CMAKE_ROOT}/Modules/Platform/AIX/ExportImportList\" -o <OBJECT_DIR>/exports.exp -c <CMAKE_${lang}_COMPILER> <AIX_EXPORTS>${_OBJECTS}" "<CMAKE_${lang}_COMPILER> <CMAKE_SHARED_LIBRARY_${lang}_FLAGS> -Wl,-bE:<OBJECT_DIR>/exports.exp <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS> <SONAME_FLAG><TARGET_SONAME> -o <TARGET> <OBJECTS> <LINK_LIBRARIES>" ) set(CMAKE_${lang}_LINK_EXECUTABLE_WITH_EXPORTS - "\"${CMAKE_ROOT}/Modules/Platform/AIX/ExportImportList\" -o <TARGET_IMPLIB> -l . <AIX_EXPORTS> <OBJECTS>" + "\"${CMAKE_ROOT}/Modules/Platform/AIX/ExportImportList\" -o <TARGET_IMPLIB> -c <CMAKE_${lang}_COMPILER> -l . <AIX_EXPORTS> <OBJECTS>" "<CMAKE_${lang}_COMPILER> <FLAGS> <CMAKE_${lang}_LINK_FLAGS> -Wl,-bE:<TARGET_IMPLIB> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>") unset(_OBJECTS) diff --git a/Modules/Platform/AIX/ExportImportList b/Modules/Platform/AIX/ExportImportList index 891bce7..5e16fcb 100755 --- a/Modules/Platform/AIX/ExportImportList +++ b/Modules/Platform/AIX/ExportImportList @@ -5,7 +5,7 @@ # This script is internal to CMake and meant only to be # invoked by CMake-generated build systems on AIX. -usage='usage: ExportImportList -o <out-file> [-l <lib>] [-n] [--] <objects>...' +usage='usage: ExportImportList -o <out-file> -c <compiler> [-l <lib>] [-n] [--] <objects>...' die() { echo "$@" 1>&2; exit 1 @@ -15,11 +15,13 @@ die() { out='' lib='' no_objects='' +compiler='' while test "$#" != 0; do case "$1" in -l) shift; lib="$1" ;; -o) shift; out="$1" ;; -n) no_objects='1' ;; + -c) shift; compiler="$1" ;; --) shift; break ;; -*) die "$usage" ;; *) break ;; @@ -27,27 +29,47 @@ while test "$#" != 0; do shift done test -n "$out" || die "$usage" +# We need the compiler executable to resolve where the ibm-llvm-nm executable is +test -n "$compiler" || die "$usage" # Build a temporary file that atomically replaces the output later. out_tmp="$out.tmp$$" trap 'rm -f "$out_tmp"' EXIT INT TERM > "$out_tmp" +# If IPA was enabled and a compiler from the IBMClang family is used, then +# the object files contain LLVM bitcode[0] rather than XCOFF objects and so +# need to be handled differently. +# +# [0]: https://www.ibm.com/docs/en/openxl-c-and-cpp-aix/17.1.0?topic=compatibility-link-time-optimization-lto +NM="$(dirname "$compiler")/../libexec/ibm-llvm-nm" + +function IsBitcode { + # N4 = first 4 bytes, -tx = output in hexadecimal, -An = don't display offset + # cut: trim off the preceding whitespace where the offset would be + # 4243code is the hexadecimal magic number for LLVM bitcode + [ "$(od -N4 -tx -An $1 | cut -d ' ' -f 2)" == "4243c0de" ]; +} + # Collect symbols exported from all object files. if test -z "$no_objects"; then for f in "$@"; do - dump -tov -X 32_64 "$f" | - awk ' - BEGIN { - V["EXPORTED"]=" export" - V["PROTECTED"]=" protected" - } - /^\[[0-9]+\]\tm +[^ ]+ +\.(text|data|bss) +[^ ]+ +(extern|weak) +(EXPORTED|PROTECTED| ) / { - if (!match($NF,/^(\.|__sinit|__sterm|__[0-9]+__)/)) { - print $NF V[$(NF-1)] + if IsBitcode "$f"; then + "$NM" "$f" --defined-only --extern-only --just-symbol-name 2>/dev/null + else + dump -tov -X 32_64 "$f" | + awk ' + BEGIN { + V["EXPORTED"]=" export" + V["PROTECTED"]=" protected" + } + /^\[[0-9]+\]\tm +[^ ]+ +\.(text|data|bss) +[^ ]+ +(extern|weak) +(EXPORTED|PROTECTED| ) / { + if (!match($NF,/^(\.|__sinit|__sterm|__[0-9]+__)/)) { + print $NF V[$(NF-1)] + } } - } - ' + ' + fi done >> "$out_tmp" fi diff --git a/Modules/Platform/Android-Clang.cmake b/Modules/Platform/Android-Clang.cmake index 3a279ca..aaaae9b 100644 --- a/Modules/Platform/Android-Clang.cmake +++ b/Modules/Platform/Android-Clang.cmake @@ -77,7 +77,9 @@ macro(__android_compiler_clang lang) if(CMAKE_ANDROID_NDK_TOOLCHAIN_UNIFIED) string(APPEND CMAKE_${lang}_COMPILER_TARGET "${CMAKE_SYSTEM_VERSION}") endif() - list(APPEND CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND "--target=${CMAKE_${lang}_COMPILER_TARGET}") + if("${lang}" STREQUAL "CXX") + list(APPEND CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND "--target=${CMAKE_${lang}_COMPILER_TARGET}") + endif() endif() if(CMAKE_GENERATOR MATCHES "Visual Studio") set(_ANDROID_STL_NOSTDLIBXX 1) diff --git a/Modules/Platform/Android-Determine.cmake b/Modules/Platform/Android-Determine.cmake index a4e9574..715f68b 100644 --- a/Modules/Platform/Android-Determine.cmake +++ b/Modules/Platform/Android-Determine.cmake @@ -70,7 +70,7 @@ if(CMAKE_GENERATOR MATCHES "Visual Studio") endif() endif() if(VCXPROJ_INSPECT_RESULT) - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log + message(CONFIGURE_LOG "Determining the sysroot for the Android NDK failed. The output was: ${VCXPROJ_INSPECT_RESULT} @@ -78,7 +78,7 @@ ${VCXPROJ_INSPECT_OUTPUT} ") else() - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log + message(CONFIGURE_LOG "Determining the sysroot for the Android NDK succeeded. The output was: ${VCXPROJ_INSPECT_RESULT} diff --git a/Modules/Platform/Android.cmake b/Modules/Platform/Android.cmake index 6944e32..0530988 100644 --- a/Modules/Platform/Android.cmake +++ b/Modules/Platform/Android.cmake @@ -5,6 +5,7 @@ if(CMAKE_ANDROID_NDK) endif() include(Platform/Linux) +unset(LINUX) set(ANDROID 1) @@ -13,6 +14,12 @@ if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Android") return() endif() +# NDK organizes API level specific libraries in numbered subdirectories. To +# avoid incorrect inclusion of libraries below the targeted API level, disable +# architecture specific path suffixes by default. +set_property(GLOBAL PROPERTY FIND_LIBRARY_USE_LIB32_PATHS OFF) +set_property(GLOBAL PROPERTY FIND_LIBRARY_USE_LIB64_PATHS OFF) + # Conventionally Android does not use versioned soname # But in modern versions it is acceptable if(NOT DEFINED CMAKE_PLATFORM_NO_VERSIONED_SONAME) @@ -32,6 +39,8 @@ endif() # Commonly used Android toolchain files that pre-date CMake upstream support # set CMAKE_SYSTEM_VERSION to 1. Avoid interfering with them. if(CMAKE_SYSTEM_VERSION EQUAL 1) + # The NDK legacy toolchain file provides its version number. + set(CMAKE_ANDROID_NDK_VERSION ${ANDROID_NDK_MAJOR}.${ANDROID_NDK_MINOR}) return() endif() diff --git a/Modules/Platform/CYGWIN-GNU.cmake b/Modules/Platform/CYGWIN-GNU.cmake index b81bd4d..ef64012 100644 --- a/Modules/Platform/CYGWIN-GNU.cmake +++ b/Modules/Platform/CYGWIN-GNU.cmake @@ -14,6 +14,34 @@ string(APPEND CMAKE_EXE_LINKER_FLAGS_INIT " -Wl,--enable-auto-import") set(CMAKE_GNULD_IMAGE_VERSION "-Wl,--major-image-version,<TARGET_VERSION_MAJOR>,--minor-image-version,<TARGET_VERSION_MINOR>") set(CMAKE_GENERATOR_RC windres) + + +# Features for LINK_LIBRARY generator expression +## check linker capabilities +if(NOT DEFINED _CMAKE_LINKER_PUSHPOP_STATE_SUPPORTED) + execute_process(COMMAND "${CMAKE_LINKER}" --help + OUTPUT_VARIABLE __linker_help + ERROR_VARIABLE __linker_help) + if(__linker_help MATCHES "--push-state" AND __linker_help MATCHES "--pop-state") + set(_CMAKE_LINKER_PUSHPOP_STATE_SUPPORTED TRUE CACHE INTERNAL "linker supports push/pop state") + else() + set(_CMAKE_LINKER_PUSHPOP_STATE_SUPPORTED FALSE CACHE INTERNAL "linker supports push/pop state") + endif() + unset(__linker_help) +endif() +## WHOLE_ARCHIVE: Force loading all members of an archive +if(_CMAKE_LINKER_PUSHPOP_STATE_SUPPORTED) + set(CMAKE_LINK_LIBRARY_USING_WHOLE_ARCHIVE "LINKER:--push-state,--whole-archive" + "<LINK_ITEM>" + "LINKER:--pop-state") +else() + set(CMAKE_LINK_LIBRARY_USING_WHOLE_ARCHIVE "LINKER:--whole-archive" + "<LINK_ITEM>" + "LINKER:--no-whole-archive") +endif() +set(CMAKE_LINK_LIBRARY_USING_WHOLE_ARCHIVE_SUPPORTED TRUE) + + macro(__cygwin_compiler_gnu lang) # Binary link rules. set(CMAKE_${lang}_CREATE_SHARED_MODULE diff --git a/Modules/Platform/CYGWIN.cmake b/Modules/Platform/CYGWIN.cmake index fc4ea2e..0b64496 100644 --- a/Modules/Platform/CYGWIN.cmake +++ b/Modules/Platform/CYGWIN.cmake @@ -1,48 +1,3 @@ -if("${CMAKE_MINIMUM_REQUIRED_VERSION}" VERSION_LESS "2.8.3.20101214" AND NOT MSYS) - set(__USE_CMAKE_LEGACY_CYGWIN_WIN32 1) -endif() -if(NOT DEFINED WIN32 AND NOT MSYS) - set(WIN32 0) - if(DEFINED __USE_CMAKE_LEGACY_CYGWIN_WIN32) - if(NOT DEFINED CMAKE_LEGACY_CYGWIN_WIN32 - AND DEFINED ENV{CMAKE_LEGACY_CYGWIN_WIN32}) - set(CMAKE_LEGACY_CYGWIN_WIN32 $ENV{CMAKE_LEGACY_CYGWIN_WIN32}) - endif() - if(CMAKE_LEGACY_CYGWIN_WIN32) - message(STATUS "Defining WIN32 under Cygwin due to CMAKE_LEGACY_CYGWIN_WIN32") - set(WIN32 1) - elseif("x${CMAKE_LEGACY_CYGWIN_WIN32}" STREQUAL "x") - message(WARNING "CMake no longer defines WIN32 on Cygwin!" - "\n" - "(1) If you are just trying to build this project, ignore this warning " - "or quiet it by setting CMAKE_LEGACY_CYGWIN_WIN32=0 in your environment or " - "in the CMake cache. " - "If later configuration or build errors occur then this project may " - "have been written under the assumption that Cygwin is WIN32. " - "In that case, set CMAKE_LEGACY_CYGWIN_WIN32=1 instead." - "\n" - "(2) If you are developing this project, add the line\n" - " set(CMAKE_LEGACY_CYGWIN_WIN32 0) # Remove when CMake >= 2.8.4 is required\n" - "at the top of your top-level CMakeLists.txt file or set the minimum " - "required version of CMake to 2.8.4 or higher. " - "Then teach your project to build on Cygwin without WIN32.") - endif() - elseif(DEFINED CMAKE_LEGACY_CYGWIN_WIN32) - message(AUTHOR_WARNING "CMAKE_LEGACY_CYGWIN_WIN32 ignored because\n" - " cmake_minimum_required(VERSION ${CMAKE_MINIMUM_REQUIRED_VERSION})\n" - "is at least 2.8.4.") - endif() -endif() -if(DEFINED __USE_CMAKE_LEGACY_CYGWIN_WIN32) - # Pass WIN32 legacy setting to scripts. - if(WIN32) - set(ENV{CMAKE_LEGACY_CYGWIN_WIN32} 1) - else() - set(ENV{CMAKE_LEGACY_CYGWIN_WIN32} 0) - endif() - unset(__USE_CMAKE_LEGACY_CYGWIN_WIN32) -endif() - set(CYGWIN 1) set(CMAKE_SHARED_LIBRARY_PREFIX "cyg") diff --git a/Modules/Platform/CrayLinuxEnvironment.cmake b/Modules/Platform/CrayLinuxEnvironment.cmake index f2aaf3f..b982b3f 100644 --- a/Modules/Platform/CrayLinuxEnvironment.cmake +++ b/Modules/Platform/CrayLinuxEnvironment.cmake @@ -68,6 +68,7 @@ if (NOT CMAKE_FIND_NO_INSTALL_PREFIX) ) endif() endif() +_cmake_record_install_prefix() list(APPEND CMAKE_SYSTEM_INCLUDE_PATH $ENV{SYSROOT_DIR}/usr/include/X11 diff --git a/Modules/Platform/DOS-OpenWatcom-C.cmake b/Modules/Platform/DOS-OpenWatcom-C.cmake index cf71c84..c6f65c0 100644 --- a/Modules/Platform/DOS-OpenWatcom-C.cmake +++ b/Modules/Platform/DOS-OpenWatcom-C.cmake @@ -1 +1,2 @@ include(Platform/DOS-OpenWatcom) +__dos_open_watcom(C) diff --git a/Modules/Platform/DOS-OpenWatcom-CXX.cmake b/Modules/Platform/DOS-OpenWatcom-CXX.cmake index cf71c84..90d6407 100644 --- a/Modules/Platform/DOS-OpenWatcom-CXX.cmake +++ b/Modules/Platform/DOS-OpenWatcom-CXX.cmake @@ -1 +1,2 @@ include(Platform/DOS-OpenWatcom) +__dos_open_watcom(CXX) diff --git a/Modules/Platform/DOS-OpenWatcom.cmake b/Modules/Platform/DOS-OpenWatcom.cmake index 54c452e..11a854c 100644 --- a/Modules/Platform/DOS-OpenWatcom.cmake +++ b/Modules/Platform/DOS-OpenWatcom.cmake @@ -20,9 +20,8 @@ set(CMAKE_SHARED_LIBRARY_C_FLAGS "-bd") # ... while this is a space separated st string(APPEND CMAKE_C_FLAGS_INIT " -bt=dos") string(APPEND CMAKE_CXX_FLAGS_INIT " -bt=dos -xs") -if(NOT CMAKE_C_STANDARD_INCLUDE_DIRECTORIES) - set(CMAKE_C_STANDARD_INCLUDE_DIRECTORIES $ENV{WATCOM}/h) -endif() -if(NOT CMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES) - set(CMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES $ENV{WATCOM}/h) -endif() +macro(__dos_open_watcom lang) + if(NOT CMAKE_${lang}_STANDARD_INCLUDE_DIRECTORIES) + set(CMAKE_${lang}_STANDARD_INCLUDE_DIRECTORIES $ENV{WATCOM}/h) + endif() +endmacro() diff --git a/Modules/Platform/Darwin.cmake b/Modules/Platform/Darwin.cmake index 839dc81..ac2478b 100644 --- a/Modules/Platform/Darwin.cmake +++ b/Modules/Platform/Darwin.cmake @@ -108,6 +108,33 @@ foreach(lang C CXX Fortran OBJC OBJCXX) set(CMAKE_${lang}_FRAMEWORK_SEARCH_FLAG -F) endforeach() +# Defines LINK_LIBRARY features for frameworks +set(CMAKE_LINK_LIBRARY_USING_FRAMEWORK "LINKER:-framework,<LIBRARY>") +set(CMAKE_LINK_LIBRARY_USING_FRAMEWORK_SUPPORTED TRUE) + +set(CMAKE_LINK_LIBRARY_USING_NEEDED_FRAMEWORK "LINKER:-needed_framework,<LIBRARY>") +set(CMAKE_LINK_LIBRARY_USING_NEEDED_FRAMEWORK_SUPPORTED TRUE) + +set(CMAKE_LINK_LIBRARY_USING_REEXPORT_FRAMEWORK "LINKER:-reexport_framework,<LIBRARY>") +set(CMAKE_LINK_LIBRARY_USING_REEXPORT_FRAMEWORK_SUPPORTED TRUE) + +set(CMAKE_LINK_LIBRARY_USING_WEAK_FRAMEWORK "LINKER:-weak_framework,<LIBRARY>") +set(CMAKE_LINK_LIBRARY_USING_WEAK_FRAMEWORK_SUPPORTED TRUE) + +# Defines LINK_LIBRARY features for libraries +set(CMAKE_LINK_LIBRARY_USING_NEEDED_LIBRARY "PATH{LINKER:-needed_library <LIBRARY>}NAME{LINKER:-needed-l<LIBRARY>}") +set(CMAKE_LINK_LIBRARY_USING_NEEDED_LIBRARY_SUPPORTED TRUE) + +set(CMAKE_LINK_LIBRARY_USING_REEXPORT_LIBRARY "PATH{LINKER:-reexport_library <LIBRARY>}NAME{LINKER:-reexport-l<LIBRARY>}") +set(CMAKE_LINK_LIBRARY_USING_REEXPORT_LIBRARY_SUPPORTED TRUE) + +set(CMAKE_LINK_LIBRARY_USING_WEAK_LIBRARY "PATH{LINKER:-weak_library <LIBRARY>}NAME{LINKER:-weak-l<LIBRARY>}") +set(CMAKE_LINK_LIBRARY_USING_WEAK_LIBRARY_SUPPORTED TRUE) + +# Defines LINK_LIBRARY feature to Force loading of all members of an archive +set(CMAKE_LINK_LIBRARY_USING_WHOLE_ARCHIVE "LINKER:-force_load <LIB_ITEM>") +set(CMAKE_LINK_LIBRARY_USING_WHOLE_ARCHIVE_SUPPORTED TRUE) + # default to searching for frameworks first if(NOT DEFINED CMAKE_FIND_FRAMEWORK) set(CMAKE_FIND_FRAMEWORK FIRST) diff --git a/Modules/Platform/DragonFly.cmake b/Modules/Platform/DragonFly.cmake index 12e5f3c..994ba79 100644 --- a/Modules/Platform/DragonFly.cmake +++ b/Modules/Platform/DragonFly.cmake @@ -3,6 +3,7 @@ # see http://archive.netbsd.se/?ml=dfbsd-users&a=2007-07&m=4678361 include(Platform/FreeBSD) +set(BSD "DragonFlyBSD") # DragonFly BSD requires -z origin to enable $ORIGIN expansion in RPATH. # This is not required for FreeBSD since 10.2-RELEASE. diff --git a/Modules/Platform/FreeBSD.cmake b/Modules/Platform/FreeBSD.cmake index 4a4c00d..9cd9399 100644 --- a/Modules/Platform/FreeBSD.cmake +++ b/Modules/Platform/FreeBSD.cmake @@ -1,3 +1,4 @@ +set(BSD "FreeBSD") set(CMAKE_DL_LIBS "") set(CMAKE_C_COMPILE_OPTIONS_PIC "-fPIC") set(CMAKE_C_COMPILE_OPTIONS_PIE "-fPIE") @@ -26,4 +27,38 @@ foreach(type SHARED_LIBRARY SHARED_MODULE EXE) set(CMAKE_${type}_LINK_DYNAMIC_C_FLAGS "-Wl,-Bdynamic") endforeach() + +# Features for LINK_LIBRARY generator expression +## check linker capabilities +if(NOT DEFINED _CMAKE_LINKER_PUSHPOP_STATE_SUPPORTED) + execute_process(COMMAND "${CMAKE_LINKER}" --help + OUTPUT_VARIABLE __linker_help + ERROR_VARIABLE __linker_help) + if(__linker_help MATCHES "--push-state" AND __linker_help MATCHES "--pop-state") + set(_CMAKE_LINKER_PUSHPOP_STATE_SUPPORTED TRUE CACHE INTERNAL "linker supports push/pop state") + else() + set(_CMAKE_LINKER_PUSHPOP_STATE_SUPPORTED FALSE CACHE INTERNAL "linker supports push/pop state") + endif() + unset(__linker_help) +endif() +## WHOLE_ARCHIVE: Force loading all members of an archive +if(_CMAKE_LINKER_PUSHPOP_STATE_SUPPORTED) + set(CMAKE_LINK_LIBRARY_USING_WHOLE_ARCHIVE "LINKER:--push-state,--whole-archive" + "<LINK_ITEM>" + "LINKER:--pop-state") +else() + set(CMAKE_LINK_LIBRARY_USING_WHOLE_ARCHIVE "LINKER:--whole-archive" + "<LINK_ITEM>" + "LINKER:--no-whole-archive") +endif() +set(CMAKE_LINK_LIBRARY_USING_WHOLE_ARCHIVE_SUPPORTED TRUE) + + +# Features for LINK_GROUP generator expression +## RESCAN: request the linker to rescan static libraries until there is +## no pending undefined symbols +set(CMAKE_LINK_GROUP_USING_RESCAN "LINKER:--start-group" "LINKER:--end-group") +set(CMAKE_LINK_GROUP_USING_RESCAN_SUPPORTED TRUE) + + include(Platform/UnixPaths) diff --git a/Modules/Platform/GHS-MULTI.cmake b/Modules/Platform/GHS-MULTI.cmake index 60a15c4..5b28f29 100644 --- a/Modules/Platform/GHS-MULTI.cmake +++ b/Modules/Platform/GHS-MULTI.cmake @@ -13,5 +13,3 @@ set(GHSMULTI 1) set(CMAKE_FIND_LIBRARY_PREFIXES "") set(CMAKE_FIND_LIBRARY_SUFFIXES ".a") - -include(Platform/WindowsPaths) diff --git a/Modules/Platform/Linux-IntelLLVM.cmake b/Modules/Platform/Linux-IntelLLVM.cmake index 1363b44..992f80e 100644 --- a/Modules/Platform/Linux-IntelLLVM.cmake +++ b/Modules/Platform/Linux-IntelLLVM.cmake @@ -8,18 +8,6 @@ if(__LINUX_COMPILER_INTEL_LLVM) endif() set(__LINUX_COMPILER_INTEL_LLVM 1) -if(NOT XIAR) - set(_intel_xiar_hints) - foreach(lang C CXX Fortran) - if(IS_ABSOLUTE "${CMAKE_${lang}_COMPILER}") - get_filename_component(_hint "${CMAKE_${lang}_COMPILER}" PATH) - list(APPEND _intel_xiar_hints ${_hint}) - endif() - endforeach() - find_program(XIAR NAMES xiar HINTS ${_intel_xiar_hints}) - mark_as_advanced(XIAR) -endif() - macro(__linux_compiler_intel_llvm lang) set(CMAKE_${lang}_COMPILE_OPTIONS_PIC "-fPIC") set(CMAKE_${lang}_COMPILE_OPTIONS_PIE "-fPIE") @@ -37,19 +25,5 @@ macro(__linux_compiler_intel_llvm lang) set(CMAKE_${lang}_LINKER_WRAPPER_FLAG "-Wl,") set(CMAKE_${lang}_LINKER_WRAPPER_FLAG_SEP ",") - set(_CMAKE_${lang}_IPO_SUPPORTED_BY_CMAKE YES) - - if(XIAR) - # INTERPROCEDURAL_OPTIMIZATION - set(CMAKE_${lang}_COMPILE_OPTIONS_IPO -ipo) - set(CMAKE_${lang}_CREATE_STATIC_LIBRARY_IPO - "${XIAR} cr <TARGET> <LINK_FLAGS> <OBJECTS> " - "${XIAR} -s <TARGET> ") - set(_CMAKE_${lang}_IPO_MAY_BE_SUPPORTED_BY_COMPILER YES) - set(_CMAKE_${lang}_IPO_LEGACY_BEHAVIOR YES) - else() - set(_CMAKE_${lang}_IPO_MAY_BE_SUPPORTED_BY_COMPILER NO) - endif() - set(CMAKE_${lang}_COMPILE_OPTIONS_VISIBILITY "-fvisibility=") endmacro() diff --git a/Modules/Platform/Linux-NVHPC.cmake b/Modules/Platform/Linux-NVHPC.cmake index aad17f1..602b417 100644 --- a/Modules/Platform/Linux-NVHPC.cmake +++ b/Modules/Platform/Linux-NVHPC.cmake @@ -3,13 +3,15 @@ # This module is shared by multiple languages; use include blocker. -if(__LINUX_COMPILER_NVIDIA) - return() -endif() -set(__LINUX_COMPILER_NVIDIA 1) - -include(Platform/Linux-PGI) +include_guard() macro(__linux_compiler_nvhpc lang) - __linux_compiler_pgi(${lang}) + set(CMAKE_${lang}_COMPILE_OPTIONS_PIC "-fPIC") + set(CMAKE_${lang}_COMPILE_OPTIONS_PIE "-fPIE") + set(_CMAKE_${lang}_PIE_MAY_BE_SUPPORTED_BY_LINKER YES) + set(CMAKE_${lang}_LINK_OPTIONS_PIE "-fPIE") + set(CMAKE_${lang}_LINK_OPTIONS_NO_PIE "") + set(CMAKE_SHARED_LIBRARY_${lang}_FLAGS "-fPIC") + set(CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS "-shared") + set(CMAKE_SHARED_LIBRARY_LINK_${lang}_FLAGS "") endmacro() diff --git a/Modules/Platform/Linux-OpenWatcom-C.cmake b/Modules/Platform/Linux-OpenWatcom-C.cmake index 383349a..7236c74 100644 --- a/Modules/Platform/Linux-OpenWatcom-C.cmake +++ b/Modules/Platform/Linux-OpenWatcom-C.cmake @@ -1 +1,2 @@ include(Platform/Linux-OpenWatcom) +__linux_open_watcom(C) diff --git a/Modules/Platform/Linux-OpenWatcom-CXX.cmake b/Modules/Platform/Linux-OpenWatcom-CXX.cmake index 383349a..a5f386b 100644 --- a/Modules/Platform/Linux-OpenWatcom-CXX.cmake +++ b/Modules/Platform/Linux-OpenWatcom-CXX.cmake @@ -1 +1,2 @@ include(Platform/Linux-OpenWatcom) +__linux_open_watcom(CXX) diff --git a/Modules/Platform/Linux-OpenWatcom.cmake b/Modules/Platform/Linux-OpenWatcom.cmake index 5b4e995..731fd3c 100644 --- a/Modules/Platform/Linux-OpenWatcom.cmake +++ b/Modules/Platform/Linux-OpenWatcom.cmake @@ -10,16 +10,25 @@ string(APPEND CMAKE_EXE_LINKER_FLAGS_INIT " system linux opt noextension") string(APPEND CMAKE_MODULE_LINKER_FLAGS_INIT " system linux") string(APPEND CMAKE_SHARED_LINKER_FLAGS_INIT " system linux") +cmake_policy(GET CMP0136 __LINUX_WATCOM_CMP0136) +if(__LINUX_WATCOM_CMP0136 STREQUAL "NEW") + set(CMAKE_WATCOM_RUNTIME_LIBRARY_DEFAULT "SingleThreaded") +else() + set(CMAKE_WATCOM_RUNTIME_LIBRARY_DEFAULT "") +endif() +unset(__LINUX_WATCOM_CMP0136) + # single/multi-threaded /-bm # default is setup for single-threaded libraries string(APPEND CMAKE_C_FLAGS_INIT " -bt=linux") string(APPEND CMAKE_CXX_FLAGS_INIT " -bt=linux -xs") -if(CMAKE_CROSSCOMPILING) - if(NOT CMAKE_C_STANDARD_INCLUDE_DIRECTORIES) - set(CMAKE_C_STANDARD_INCLUDE_DIRECTORIES $ENV{WATCOM}/lh) +macro(__linux_open_watcom lang) + if(CMAKE_CROSSCOMPILING) + if(NOT CMAKE_${lang}_STANDARD_INCLUDE_DIRECTORIES) + set(CMAKE_${lang}_STANDARD_INCLUDE_DIRECTORIES $ENV{WATCOM}/lh) + endif() endif() - if(NOT CMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES) - set(CMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES $ENV{WATCOM}/lh) - endif() -endif() + set(CMAKE_${lang}_COMPILE_OPTIONS_WATCOM_RUNTIME_LIBRARY_SingleThreaded "") + set(CMAKE_${lang}_COMPILE_OPTIONS_WATCOM_RUNTIME_LIBRARY_MultiThreaded -bm) +endmacro() diff --git a/Modules/Platform/Linux.cmake b/Modules/Platform/Linux.cmake index b5d5464..3dc3ca3 100644 --- a/Modules/Platform/Linux.cmake +++ b/Modules/Platform/Linux.cmake @@ -1,3 +1,4 @@ +set(LINUX 1) set(CMAKE_DL_LIBS "dl") set(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG "-Wl,-rpath,") set(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG_SEP ":") @@ -19,6 +20,39 @@ foreach(type SHARED_LIBRARY SHARED_MODULE EXE) set(CMAKE_${type}_LINK_DYNAMIC_C_FLAGS "-Wl,-Bdynamic") endforeach() + +# Features for LINK_LIBRARY generator expression +## check linker capabilities +if(NOT DEFINED _CMAKE_LINKER_PUSHPOP_STATE_SUPPORTED) + execute_process(COMMAND "${CMAKE_LINKER}" --help + OUTPUT_VARIABLE __linker_help + ERROR_VARIABLE __linker_help) + if(__linker_help MATCHES "--push-state" AND __linker_help MATCHES "--pop-state") + set(_CMAKE_LINKER_PUSHPOP_STATE_SUPPORTED TRUE CACHE INTERNAL "linker supports push/pop state") + else() + set(_CMAKE_LINKER_PUSHPOP_STATE_SUPPORTED FALSE CACHE INTERNAL "linker supports push/pop state") + endif() + unset(__linker_help) +endif() +## WHOLE_ARCHIVE: Force loading all members of an archive +if(_CMAKE_LINKER_PUSHPOP_STATE_SUPPORTED) + set(CMAKE_LINK_LIBRARY_USING_WHOLE_ARCHIVE "LINKER:--push-state,--whole-archive" + "<LINK_ITEM>" + "LINKER:--pop-state") +else() + set(CMAKE_LINK_LIBRARY_USING_WHOLE_ARCHIVE "LINKER:--whole-archive" + "<LINK_ITEM>" + "LINKER:--no-whole-archive") +endif() +set(CMAKE_LINK_LIBRARY_USING_WHOLE_ARCHIVE_SUPPORTED TRUE) + +# Features for LINK_GROUP generator expression +## RESCAN: request the linker to rescan static libraries until there is +## no pending undefined symbols +set(CMAKE_LINK_GROUP_USING_RESCAN "LINKER:--start-group" "LINKER:--end-group") +set(CMAKE_LINK_GROUP_USING_RESCAN_SUPPORTED TRUE) + + # Debian policy requires that shared libraries be installed without # executable permission. Fedora policy requires that shared libraries # be installed with the executable permission. Since the native tools @@ -53,7 +87,12 @@ include(Platform/UnixPaths) # Debian has lib32 and lib64 paths only for compatibility so they should not be # searched. -if(NOT CMAKE_CROSSCOMPILING AND EXISTS "/etc/debian_version") - set_property(GLOBAL PROPERTY FIND_LIBRARY_USE_LIB32_PATHS FALSE) - set_property(GLOBAL PROPERTY FIND_LIBRARY_USE_LIB64_PATHS FALSE) +if(NOT CMAKE_CROSSCOMPILING) + if (EXISTS "/etc/debian_version") + set_property(GLOBAL PROPERTY FIND_LIBRARY_USE_LIB32_PATHS FALSE) + set_property(GLOBAL PROPERTY FIND_LIBRARY_USE_LIB64_PATHS FALSE) + endif() + if (EXISTS "/etc/arch-release") + set_property(GLOBAL PROPERTY FIND_LIBRARY_USE_LIB64_PATHS FALSE) + endif() endif() diff --git a/Modules/Platform/NetBSD.cmake b/Modules/Platform/NetBSD.cmake index d99cb4a..52c6594 100644 --- a/Modules/Platform/NetBSD.cmake +++ b/Modules/Platform/NetBSD.cmake @@ -1,3 +1,4 @@ +set(BSD "NetBSD") set(CMAKE_DL_LIBS "") set(CMAKE_C_COMPILE_OPTIONS_PIC "-fPIC") set(CMAKE_C_COMPILE_OPTIONS_PIE "-fPIE") @@ -12,4 +13,38 @@ set(CMAKE_SHARED_LIBRARY_RPATH_LINK_C_FLAG "-Wl,-rpath-link,") set(CMAKE_SHARED_LIBRARY_SONAME_C_FLAG "-Wl,-soname,") set(CMAKE_EXE_EXPORTS_C_FLAG "-Wl,--export-dynamic") + +# Features for LINK_LIBRARY generator expression +## check linker capabilities +if(NOT DEFINED _CMAKE_LINKER_PUSHPOP_STATE_SUPPORTED) + execute_process(COMMAND "${CMAKE_LINKER}" --help + OUTPUT_VARIABLE __linker_help + ERROR_VARIABLE __linker_help) + if(__linker_help MATCHES "--push-state" AND __linker_help MATCHES "--pop-state") + set(_CMAKE_LINKER_PUSHPOP_STATE_SUPPORTED TRUE CACHE INTERNAL "linker supports push/pop state") + else() + set(_CMAKE_LINKER_PUSHPOP_STATE_SUPPORTED FALSE CACHE INTERNAL "linker supports push/pop state") + endif() + unset(__linker_help) +endif() +## WHOLE_ARCHIVE: Force loading all members of an archive +if(_CMAKE_LINKER_PUSHPOP_STATE_SUPPORTED) + set(CMAKE_LINK_LIBRARY_USING_WHOLE_ARCHIVE "LINKER:--push-state,--whole-archive" + "<LINK_ITEM>" + "LINKER:--pop-state") +else() + set(CMAKE_LINK_LIBRARY_USING_WHOLE_ARCHIVE "LINKER:--whole-archive" + "<LINK_ITEM>" + "LINKER:--no-whole-archive") +endif() +set(CMAKE_LINK_LIBRARY_USING_WHOLE_ARCHIVE_SUPPORTED TRUE) + + +# Features for LINK_GROUP generator expression +## RESCAN: request the linker to rescan static libraries until there is +## no pending undefined symbols +set(CMAKE_LINK_GROUP_USING_RESCAN "LINKER:--start-group" "LINKER:--end-group") +set(CMAKE_LINK_GROUP_USING_RESCAN_SUPPORTED TRUE) + + include(Platform/UnixPaths) diff --git a/Modules/Platform/OS2-OpenWatcom-C.cmake b/Modules/Platform/OS2-OpenWatcom-C.cmake index 21a4d9e..a6a6b78 100644 --- a/Modules/Platform/OS2-OpenWatcom-C.cmake +++ b/Modules/Platform/OS2-OpenWatcom-C.cmake @@ -1 +1,2 @@ include(Platform/OS2-OpenWatcom) +__os2_open_watcom(C) diff --git a/Modules/Platform/OS2-OpenWatcom-CXX.cmake b/Modules/Platform/OS2-OpenWatcom-CXX.cmake index 21a4d9e..846bb29 100644 --- a/Modules/Platform/OS2-OpenWatcom-CXX.cmake +++ b/Modules/Platform/OS2-OpenWatcom-CXX.cmake @@ -1 +1,2 @@ include(Platform/OS2-OpenWatcom) +__os2_open_watcom(CXX) diff --git a/Modules/Platform/OS2-OpenWatcom.cmake b/Modules/Platform/OS2-OpenWatcom.cmake index 998fb9f..9abcf28 100644 --- a/Modules/Platform/OS2-OpenWatcom.cmake +++ b/Modules/Platform/OS2-OpenWatcom.cmake @@ -16,20 +16,27 @@ endif() set(CMAKE_C_COMPILE_OPTIONS_DLL "-bd") # Note: This variable is a ';' separated list set(CMAKE_SHARED_LIBRARY_C_FLAGS "-bd") # ... while this is a space separated string. +cmake_policy(GET CMP0136 __OS2_WATCOM_CMP0136) +if(__OS2_WATCOM_CMP0136 STREQUAL "NEW") + set(CMAKE_WATCOM_RUNTIME_LIBRARY_DEFAULT "SingleThreaded") +else() + set(CMAKE_WATCOM_RUNTIME_LIBRARY_DEFAULT "") +endif() +unset(__OS2_WATCOM_CMP0136) + string(APPEND CMAKE_C_FLAGS_INIT " -bt=os2") string(APPEND CMAKE_CXX_FLAGS_INIT " -bt=os2 -xs") -if(NOT CMAKE_C_STANDARD_INCLUDE_DIRECTORIES) - if(DEFINED CMAKE_SYSTEM_PROCESSOR AND CMAKE_SYSTEM_PROCESSOR STREQUAL "I86") - set(CMAKE_C_STANDARD_INCLUDE_DIRECTORIES $ENV{WATCOM}/h $ENV{WATCOM}/h/os21x) - else() - set(CMAKE_C_STANDARD_INCLUDE_DIRECTORIES $ENV{WATCOM}/h $ENV{WATCOM}/h/os2) +macro(__os2_open_watcom lang) + if(NOT CMAKE_${lang}_STANDARD_INCLUDE_DIRECTORIES) + if(DEFINED CMAKE_SYSTEM_PROCESSOR AND CMAKE_SYSTEM_PROCESSOR STREQUAL "I86") + set(CMAKE_${lang}_STANDARD_INCLUDE_DIRECTORIES $ENV{WATCOM}/h $ENV{WATCOM}/h/os21x) + else() + set(CMAKE_${lang}_STANDARD_INCLUDE_DIRECTORIES $ENV{WATCOM}/h $ENV{WATCOM}/h/os2) + endif() endif() -endif() -if(NOT CMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES) - if(DEFINED CMAKE_SYSTEM_PROCESSOR AND CMAKE_SYSTEM_PROCESSOR STREQUAL "I86") - set(CMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES $ENV{WATCOM}/h $ENV{WATCOM}/h/os21x) - else() - set(CMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES $ENV{WATCOM}/h $ENV{WATCOM}/h/os2) - endif() -endif() + set(CMAKE_${lang}_COMPILE_OPTIONS_WATCOM_RUNTIME_LIBRARY_SingleThreaded "") + set(CMAKE_${lang}_COMPILE_OPTIONS_WATCOM_RUNTIME_LIBRARY_SingleThreadedDLL -br) + set(CMAKE_${lang}_COMPILE_OPTIONS_WATCOM_RUNTIME_LIBRARY_MultiThreaded -bm) + set(CMAKE_${lang}_COMPILE_OPTIONS_WATCOM_RUNTIME_LIBRARY_MultiThreadedDLL -bm -br) +endmacro() diff --git a/Modules/Platform/OpenBSD.cmake b/Modules/Platform/OpenBSD.cmake index 97e2a6a..51ea60d 100644 --- a/Modules/Platform/OpenBSD.cmake +++ b/Modules/Platform/OpenBSD.cmake @@ -1,4 +1,5 @@ include(Platform/NetBSD) +set(BSD "OpenBSD") # On OpenBSD, the compile time linker does not share it's configuration with # the runtime linker. This will extract the library search paths from the diff --git a/Modules/Platform/SerenityOS-Clang-ASM.cmake b/Modules/Platform/SerenityOS-Clang-ASM.cmake new file mode 100644 index 0000000..ba1e18c --- /dev/null +++ b/Modules/Platform/SerenityOS-Clang-ASM.cmake @@ -0,0 +1,2 @@ +include(Platform/SerenityOS-GNU) +__serenity_compiler_gnu(ASM) diff --git a/Modules/Platform/SerenityOS-Clang-C.cmake b/Modules/Platform/SerenityOS-Clang-C.cmake new file mode 100644 index 0000000..791a197 --- /dev/null +++ b/Modules/Platform/SerenityOS-Clang-C.cmake @@ -0,0 +1,2 @@ +include(Platform/SerenityOS-GNU) +__serenity_compiler_gnu(C) diff --git a/Modules/Platform/SerenityOS-Clang-CXX.cmake b/Modules/Platform/SerenityOS-Clang-CXX.cmake new file mode 100644 index 0000000..084e319 --- /dev/null +++ b/Modules/Platform/SerenityOS-Clang-CXX.cmake @@ -0,0 +1,2 @@ +include(Platform/SerenityOS-GNU) +__serenity_compiler_gnu(CXX) diff --git a/Modules/Platform/SerenityOS-GNU-ASM.cmake b/Modules/Platform/SerenityOS-GNU-ASM.cmake new file mode 100644 index 0000000..ba1e18c --- /dev/null +++ b/Modules/Platform/SerenityOS-GNU-ASM.cmake @@ -0,0 +1,2 @@ +include(Platform/SerenityOS-GNU) +__serenity_compiler_gnu(ASM) diff --git a/Modules/Platform/SerenityOS-GNU-C.cmake b/Modules/Platform/SerenityOS-GNU-C.cmake new file mode 100644 index 0000000..791a197 --- /dev/null +++ b/Modules/Platform/SerenityOS-GNU-C.cmake @@ -0,0 +1,2 @@ +include(Platform/SerenityOS-GNU) +__serenity_compiler_gnu(C) diff --git a/Modules/Platform/SerenityOS-GNU-CXX.cmake b/Modules/Platform/SerenityOS-GNU-CXX.cmake new file mode 100644 index 0000000..084e319 --- /dev/null +++ b/Modules/Platform/SerenityOS-GNU-CXX.cmake @@ -0,0 +1,2 @@ +include(Platform/SerenityOS-GNU) +__serenity_compiler_gnu(CXX) diff --git a/Modules/Platform/SerenityOS-GNU.cmake b/Modules/Platform/SerenityOS-GNU.cmake new file mode 100644 index 0000000..ed39477 --- /dev/null +++ b/Modules/Platform/SerenityOS-GNU.cmake @@ -0,0 +1,24 @@ +# This module is shared by multiple languages; use include blocker. +include_guard() + +set(CMAKE_EXE_LINKER_FLAGS_INIT "-Wl,--hash-style=gnu,-z,relro,-z,now,-z,noexecstack,-z,separate-code,-z,max-page-size=0x1000") + +macro(__serenity_compiler_gnu lang) + set(CMAKE_SHARED_LIBRARY_RUNTIME_${lang}_FLAG "-Wl,-rpath,") + set(CMAKE_SHARED_LIBRARY_RUNTIME_${lang}_FLAG_SEP ":") + set(CMAKE_SHARED_LIBRARY_RPATH_LINK_${lang}_FLAG "-Wl,-rpath-link,") + set(CMAKE_SHARED_LIBRARY_SONAME_${lang}_FLAG "-Wl,-soname,") + set(CMAKE_EXE_EXPORTS_${lang}_FLAG "-Wl,--export-dynamic") + + set(CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS "-shared -Wl,--hash-style=gnu,-z,relro,-z,now,-z,noexecstack,-z,separate-code") + + # Initialize link type selection flags. These flags are used when + # building a shared library, shared module, or executable that links + # to other libraries to select whether to use the static or shared + # versions of the libraries. + foreach(type SHARED_LIBRARY SHARED_MODULE EXE) + set(CMAKE_${type}_LINK_STATIC_${lang}_FLAGS "-Wl,-Bstatic") + set(CMAKE_${type}_LINK_DYNAMIC_${lang}_FLAGS "-Wl,-Bdynamic") + endforeach() + +endmacro() diff --git a/Modules/Platform/SerenityOS.cmake b/Modules/Platform/SerenityOS.cmake new file mode 100644 index 0000000..dc4f369 --- /dev/null +++ b/Modules/Platform/SerenityOS.cmake @@ -0,0 +1,12 @@ + +set(SERENITYOS 1) + +set(CMAKE_DL_LIBS "") +set(CMAKE_SHARED_LIBRARY_RPATH_ORIGIN_TOKEN "\$ORIGIN") +set(CMAKE_SHARED_LIBRARY_SUFFIX ".so") + +# Shared libraries with no builtin soname may not be linked safely by +# specifying the file path. +set(CMAKE_PLATFORM_USES_PATH_WHEN_NO_SONAME 1) + +include(Platform/UnixPaths) diff --git a/Modules/Platform/SunOS.cmake b/Modules/Platform/SunOS.cmake index 78eccf7..b8a302c 100644 --- a/Modules/Platform/SunOS.cmake +++ b/Modules/Platform/SunOS.cmake @@ -7,6 +7,30 @@ if(CMAKE_SYSTEM MATCHES "SunOS-4") set(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG_SEP ":") endif() + +# Features for LINK_LIBRARY generator expression +## WHOLE_ARCHIVE: Force loading all members of an archive +if (CMAKE_SYSTEM_VERSION VERSION_GREATER "5.10") + set(CMAKE_LINK_LIBRARY_USING_WHOLE_ARCHIVE "LINKER:--whole-archive" + "<LINK_ITEM>" + "LINKER:--no-whole-archive") +else() + set(CMAKE_LINK_LIBRARY_USING_WHOLE_ARCHIVE "LINKER:-z,allextract" + "<LINK_ITEM>" + "LINKER:-z,defaultextract") +endif() +set(CMAKE_LINK_LIBRARY_USING_WHOLE_ARCHIVE_SUPPORTED TRUE) + + +# Features for LINK_GROUP generator expression +if (CMAKE_SYSTEM_VERSION VERSION_GREATER "5.9") + ## RESCAN: request the linker to rescan static libraries until there is + ## no pending undefined symbols + set(CMAKE_LINK_GROUP_USING_RESCAN "LINKER:-z,rescan-start" "LINKER:-z,rescan-end") + set(CMAKE_LINK_GROUP_USING_RESCAN_SUPPORTED TRUE) +endif() + + include(Platform/UnixPaths) list(APPEND CMAKE_SYSTEM_PREFIX_PATH diff --git a/Modules/Platform/UnixPaths.cmake b/Modules/Platform/UnixPaths.cmake index b9381c3..8a0ad23 100644 --- a/Modules/Platform/UnixPaths.cmake +++ b/Modules/Platform/UnixPaths.cmake @@ -44,6 +44,7 @@ if (NOT CMAKE_FIND_NO_INSTALL_PREFIX) ) endif() endif() +_cmake_record_install_prefix() # Non "standard" but common install prefixes list(APPEND CMAKE_SYSTEM_PREFIX_PATH diff --git a/Modules/Platform/Windows-Clang-ASM.cmake b/Modules/Platform/Windows-Clang-ASM.cmake index 345d77d..c22e3b0 100644 --- a/Modules/Platform/Windows-Clang-ASM.cmake +++ b/Modules/Platform/Windows-Clang-ASM.cmake @@ -1,2 +1,7 @@ include(Platform/Windows-Clang) __windows_compiler_clang(ASM) + +set(CMAKE_ASM_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreaded "") +set(CMAKE_ASM_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDLL "") +set(CMAKE_ASM_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDebug "") +set(CMAKE_ASM_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDebugDLL "") diff --git a/Modules/Platform/Windows-Clang-HIP.cmake b/Modules/Platform/Windows-Clang-HIP.cmake new file mode 100644 index 0000000..20879fa --- /dev/null +++ b/Modules/Platform/Windows-Clang-HIP.cmake @@ -0,0 +1,19 @@ +include(Platform/Windows-Clang) +set(_COMPILE_HIP_MSVC " -TP") +__windows_compiler_clang(HIP) + +if("x${CMAKE_HIP_COMPILER_FRONTEND_VARIANT}" STREQUAL "xMSVC") + if((NOT DEFINED CMAKE_DEPENDS_USE_COMPILER OR CMAKE_DEPENDS_USE_COMPILER) + AND CMAKE_GENERATOR MATCHES "Makefiles|WMake" + AND CMAKE_DEPFILE_FLAGS_HIP) + set(CMAKE_HIP_DEPENDS_USE_COMPILER TRUE) + endif() +elseif("x${CMAKE_HIP_COMPILER_FRONTEND_VARIANT}" STREQUAL "xGNU") + if((NOT DEFINED CMAKE_DEPENDS_USE_COMPILER OR CMAKE_DEPENDS_USE_COMPILER) + AND CMAKE_GENERATOR MATCHES "Makefiles|WMake" + AND CMAKE_DEPFILE_FLAGS_HIP) + # dependencies are computed by the compiler itself + set(CMAKE_HIP_DEPFILE_FORMAT gcc) + set(CMAKE_HIP_DEPENDS_USE_COMPILER TRUE) + endif() +endif() diff --git a/Modules/Platform/Windows-Clang.cmake b/Modules/Platform/Windows-Clang.cmake index 4d3de0e..33d271d 100644 --- a/Modules/Platform/Windows-Clang.cmake +++ b/Modules/Platform/Windows-Clang.cmake @@ -39,6 +39,7 @@ macro(__windows_compiler_clang_gnu lang) set(CMAKE_${lang}_LINKER_WRAPPER_FLAG_SEP) set(CMAKE_${lang}_LINKER_MANIFEST_FLAG " -Xlinker /MANIFESTINPUT:") + set(CMAKE_${lang}_COMPILE_OPTIONS_WARNING_AS_ERROR "-Werror") if("${CMAKE_${lang}_SIMULATE_VERSION}" MATCHES "^([0-9]+)\\.([0-9]+)") math(EXPR MSVC_VERSION "${CMAKE_MATCH_1}*100 + ${CMAKE_MATCH_2}") @@ -88,17 +89,27 @@ macro(__windows_compiler_clang_gnu lang) set(CMAKE_${lang}_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDebugDLL -D_DEBUG -D_DLL -D_MT -Xclang --dependent-lib=msvcrtd) if(CMAKE_MSVC_RUNTIME_LIBRARY_DEFAULT) - set(__ADDED_FLAGS "") - set(__ADDED_FLAGS_DEBUG "") + set(_RTL_FLAGS "") + set(_RTL_FLAGS_DEBUG "") else() - set(__ADDED_FLAGS_DEBUG "-D_DEBUG -D_DLL -D_MT -Xclang --dependent-lib=msvcrtd") - set(__ADDED_FLAGS "-D_DLL -D_MT -Xclang --dependent-lib=msvcrt") + set(_RTL_FLAGS_DEBUG " -D_DEBUG -D_DLL -D_MT -Xclang --dependent-lib=msvcrtd") + set(_RTL_FLAGS " -D_DLL -D_MT -Xclang --dependent-lib=msvcrt") endif() - string(APPEND CMAKE_${lang}_FLAGS_DEBUG_INIT " -g -Xclang -gcodeview -O0 ${__ADDED_FLAGS_DEBUG}") - string(APPEND CMAKE_${lang}_FLAGS_MINSIZEREL_INIT " -Os -DNDEBUG ${__ADDED_FLAGS}") - string(APPEND CMAKE_${lang}_FLAGS_RELEASE_INIT " -O3 -DNDEBUG ${__ADDED_FLAGS}") - string(APPEND CMAKE_${lang}_FLAGS_RELWITHDEBINFO_INIT " -O2 -g -DNDEBUG -Xclang -gcodeview ${__ADDED_FLAGS}") + if(CMAKE_MSVC_DEBUG_INFORMATION_FORMAT_DEFAULT) + set(_DBG_FLAGS "") + else() + set(_DBG_FLAGS " -g -Xclang -gcodeview") + endif() + + string(APPEND CMAKE_${lang}_FLAGS_DEBUG_INIT " -O0${_DBG_FLAGS}${_RTL_FLAGS_DEBUG}") + string(APPEND CMAKE_${lang}_FLAGS_MINSIZEREL_INIT " -Os -DNDEBUG${_RTL_FLAGS}") + string(APPEND CMAKE_${lang}_FLAGS_RELEASE_INIT " -O3 -DNDEBUG${_RTL_FLAGS}") + string(APPEND CMAKE_${lang}_FLAGS_RELWITHDEBINFO_INIT " -O2 -DNDEBUG${_DBG_FLAGS}${_RTL_FLAGS}") + + set(CMAKE_${lang}_COMPILE_OPTIONS_MSVC_DEBUG_INFORMATION_FORMAT_Embedded -g -Xclang -gcodeview) + #set(CMAKE_${lang}_COMPILE_OPTIONS_MSVC_DEBUG_INFORMATION_FORMAT_ProgramDatabase) # not supported by Clang + #set(CMAKE_${lang}_COMPILE_OPTIONS_MSVC_DEBUG_INFORMATION_FORMAT_EditAndContinue) # not supported by Clang endif() set(CMAKE_INCLUDE_SYSTEM_FLAG_${lang} "-isystem ") set(CMAKE_${lang}_LINKER_SUPPORTS_PDB ON) @@ -108,11 +119,19 @@ macro(__windows_compiler_clang_gnu lang) set(CMAKE_${lang}_COMPILE_OPTIONS_USE_PCH -Xclang -include-pch -Xclang <PCH_FILE> -Xclang -include -Xclang <PCH_HEADER>) set(CMAKE_${lang}_COMPILE_OPTIONS_CREATE_PCH -Xclang -emit-pch -Xclang -include -Xclang <PCH_HEADER> -x ${__pch_header_${lang}}) - unset(__ADDED_FLAGS) - unset(__ADDED_FLAGS_DEBUG) + unset(_DBG_FLAGS) + unset(_RTL_FLAGS) + unset(_RTL_FLAGS_DEBUG) string(TOLOWER "${CMAKE_BUILD_TYPE}" BUILD_TYPE_LOWER) set(CMAKE_${lang}_STANDARD_LIBRARIES_INIT "-lkernel32 -luser32 -lgdi32 -lwinspool -lshell32 -lole32 -loleaut32 -luuid -lcomdlg32 -ladvapi32 -loldnames") + # Features for LINK_LIBRARY generator expression + if(MSVC_VERSION GREATER "1900") + ## WHOLE_ARCHIVE: Force loading all members of an archive + set(CMAKE_${lang}_LINK_LIBRARY_USING_WHOLE_ARCHIVE "LINKER:/WHOLEARCHIVE:<LIBRARY>") + set(CMAKE_${lang}_LINK_LIBRARY_USING_WHOLE_ARCHIVE_SUPPORTED TRUE) + endif() + enable_language(RC) endmacro() @@ -138,24 +157,36 @@ macro(__enable_llvm_rc_preprocessing clang_option_prefix extra_pp_flags) endif() endmacro() +macro(__verify_same_language_values variable) + foreach(lang "C" "CXX" "HIP") + if(DEFINED CMAKE_${lang}_${variable}) + list(APPEND __LANGUAGE_VALUES_${variable} "${CMAKE_${lang}_${variable}}") + endif() + endforeach() + list(REMOVE_DUPLICATES __LANGUAGE_VALUES_${variable}) + list(LENGTH __LANGUAGE_VALUES_${variable} __NUM_VALUES) + + if(__NUM_VALUES GREATER 1) + message(FATAL_ERROR ${ARGN}) + endif() + unset(__NUM_VALUES) + unset(__LANGUAGE_VALUES_${variable}) +endmacro() if("x${CMAKE_C_SIMULATE_ID}" STREQUAL "xMSVC" - OR "x${CMAKE_CXX_SIMULATE_ID}" STREQUAL "xMSVC") + OR "x${CMAKE_CXX_SIMULATE_ID}" STREQUAL "xMSVC" + OR "x${CMAKE_HIP_SIMULATE_ID}" STREQUAL "xMSVC") - if ( DEFINED CMAKE_C_COMPILER_ID AND DEFINED CMAKE_CXX_COMPILER_ID - AND NOT "x${CMAKE_C_COMPILER_ID}" STREQUAL "x${CMAKE_CXX_COMPILER_ID}") - message(FATAL_ERROR "The current configuration mixes Clang and MSVC or " - "some other CL compatible compiler tool. This is not supported. " - "Use either clang or MSVC as both C and C++ compilers.") - endif() + __verify_same_language_values(COMPILER_ID + "The current configuration mixes Clang and MSVC or " + "some other CL compatible compiler tool. This is not supported. " + "Use either clang or MSVC as both C, C++ and/or HIP compilers.") - if ( DEFINED CMAKE_C_COMPILER_FRONTEND_VARIANT AND DEFINED CMAKE_CXX_COMPILER_FRONTEND_VARIANT - AND NOT "x${CMAKE_C_COMPILER_FRONTEND_VARIANT}" STREQUAL "x${CMAKE_CXX_COMPILER_FRONTEND_VARIANT}") - message(FATAL_ERROR "The current configuration uses the Clang compiler " - "tool with mixed frontend variants, both the GNU and in MSVC CL " - "like variants. This is not supported. Use either clang/clang++ " - "or clang-cl as both C and C++ compilers.") - endif() + __verify_same_language_values(COMPILER_FRONTEND_VARIANT + "The current configuration uses the Clang compiler " + "tool with mixed frontend variants, both the GNU and in MSVC CL " + "like variants. This is not supported. Use either clang/clang++ " + "or clang-cl as both C, C++ and/or HIP compilers.") if(NOT CMAKE_RC_COMPILER_INIT) # Check if rc is already in the path @@ -175,13 +206,18 @@ if("x${CMAKE_C_SIMULATE_ID}" STREQUAL "xMSVC" unset(__RC_COMPILER_PATH CACHE) endif() - if ( "x${CMAKE_CXX_COMPILER_FRONTEND_VARIANT}" STREQUAL "xMSVC" OR "x${CMAKE_C_COMPILER_FRONTEND_VARIANT}" STREQUAL "xMSVC" ) + if ( "x${CMAKE_CXX_COMPILER_FRONTEND_VARIANT}" STREQUAL "xMSVC" + OR "x${CMAKE_C_COMPILER_FRONTEND_VARIANT}" STREQUAL "xMSVC" + OR "x${CMAKE_HIP_COMPILER_FRONTEND_VARIANT}" STREQUAL "xMSVC") + include(Platform/Windows-MSVC) # Set the clang option forwarding prefix for clang-cl usage in the llvm-rc processing stage __enable_llvm_rc_preprocessing("-clang:" "") macro(__windows_compiler_clang_base lang) set(_COMPILE_${lang} "${_COMPILE_${lang}_MSVC}") __windows_compiler_msvc(${lang}) + unset(CMAKE_${lang}_COMPILE_OPTIONS_MSVC_DEBUG_INFORMATION_FORMAT_EditAndContinue) # -ZI not supported by Clang + set(CMAKE_${lang}_COMPILE_OPTIONS_WARNING_AS_ERROR "-WX") set(CMAKE_INCLUDE_SYSTEM_FLAG_${lang} "-imsvc") endmacro() else() @@ -193,6 +229,14 @@ if("x${CMAKE_C_SIMULATE_ID}" STREQUAL "xMSVC" endif() unset(__WINDOWS_CLANG_CMP0091) + cmake_policy(GET CMP0141 __WINDOWS_MSVC_CMP0141) + if(__WINDOWS_MSVC_CMP0141 STREQUAL "NEW") + set(CMAKE_MSVC_DEBUG_INFORMATION_FORMAT_DEFAULT "$<$<CONFIG:Debug,RelWithDebInfo>:Embedded>") + else() + set(CMAKE_MSVC_DEBUG_INFORMATION_FORMAT_DEFAULT "") + endif() + unset(__WINDOWS_MSVC_CMP0141) + set(CMAKE_BUILD_TYPE_INIT Debug) __enable_llvm_rc_preprocessing("" "-x c") diff --git a/Modules/Platform/Windows-GNU.cmake b/Modules/Platform/Windows-GNU.cmake index 51dc146..088b238 100644 --- a/Modules/Platform/Windows-GNU.cmake +++ b/Modules/Platform/Windows-GNU.cmake @@ -44,6 +44,39 @@ if("${_help}" MATCHES "GNU ld .* 2\\.1[1-6]") set(__WINDOWS_GNU_LD_RESPONSE 0) endif() + +# Features for LINK_LIBRARY generator expression +## check linker capabilities +if(NOT DEFINED _CMAKE_LINKER_PUSHPOP_STATE_SUPPORTED) + execute_process(COMMAND "${CMAKE_LINKER}" --help + OUTPUT_VARIABLE __linker_help + ERROR_VARIABLE __linker_help) + if(__linker_help MATCHES "--push-state" AND __linker_help MATCHES "--pop-state") + set(_CMAKE_LINKER_PUSHPOP_STATE_SUPPORTED TRUE CACHE INTERNAL "linker supports push/pop state") + else() + set(_CMAKE_LINKER_PUSHPOP_STATE_SUPPORTED FALSE CACHE INTERNAL "linker supports push/pop state") + endif() + unset(__linker_help) +endif() +## WHOLE_ARCHIVE: Force loading all members of an archive +if(_CMAKE_LINKER_PUSHPOP_STATE_SUPPORTED) + set(CMAKE_LINK_LIBRARY_USING_WHOLE_ARCHIVE "LINKER:--push-state,--whole-archive" + "<LINK_ITEM>" + "LINKER:--pop-state") +else() + set(CMAKE_LINK_LIBRARY_USING_WHOLE_ARCHIVE "LINKER:--whole-archive" + "<LINK_ITEM>" + "LINKER:--no-whole-archive") +endif() +set(CMAKE_LINK_LIBRARY_USING_WHOLE_ARCHIVE_SUPPORTED TRUE) + +# Features for LINK_GROUP generator expression +## RESCAN: request the linker to rescan static libraries until there is +## no pending undefined symbols +set(CMAKE_LINK_GROUP_USING_RESCAN "LINKER:--start-group" "LINKER:--end-group") +set(CMAKE_LINK_GROUP_USING_RESCAN_SUPPORTED TRUE) + + macro(__windows_compiler_gnu lang) # Create archiving rules to support large object file lists for static libraries. @@ -124,7 +157,8 @@ macro(__windows_compiler_gnu lang) endif() if(NOT CMAKE_RC_COMPILER_INIT AND NOT CMAKE_GENERATOR_RC) - set(CMAKE_RC_COMPILER_INIT ${_CMAKE_TOOLCHAIN_PREFIX}windres) + set(_CMAKE_RC_COMPILER_LIST ${_CMAKE_TOOLCHAIN_PREFIX}windres windres) + set(_CMAKE_RC_COMPILER_FALLBACK windres) endif() enable_language(RC) diff --git a/Modules/Platform/Windows-Intel-C.cmake b/Modules/Platform/Windows-Intel-C.cmake index e4d9b93..8ae6852 100644 --- a/Modules/Platform/Windows-Intel-C.cmake +++ b/Modules/Platform/Windows-Intel-C.cmake @@ -19,9 +19,8 @@ if((NOT DEFINED CMAKE_DEPENDS_USE_COMPILER OR CMAKE_DEPENDS_USE_COMPILER) set(CMAKE_C_DEPENDS_USE_COMPILER TRUE) endif() -if("${CMAKE_SOURCE_DIR}${CMAKE_BINARY_DIR}" MATCHES " ") - # The Intel compiler does not properly escape spaces in a depfile. - # Fall back to msvc depfile format. - set(CMAKE_DEPFILE_FLAGS_C "/showIncludes") - set(CMAKE_C_DEPFILE_FORMAT msvc) -endif() +# The Intel compiler does not properly escape spaces in a depfile which can +# occur in source and binary cmake paths as well as external include paths. +# Until Intel fixes this bug, fall back unconditionally to msvc depfile format. +set(CMAKE_DEPFILE_FLAGS_C "/showIncludes") +set(CMAKE_C_DEPFILE_FORMAT msvc) diff --git a/Modules/Platform/Windows-Intel-CXX.cmake b/Modules/Platform/Windows-Intel-CXX.cmake index 6adbb6e..e2fa2af 100644 --- a/Modules/Platform/Windows-Intel-CXX.cmake +++ b/Modules/Platform/Windows-Intel-CXX.cmake @@ -20,9 +20,8 @@ if((NOT DEFINED CMAKE_DEPENDS_USE_COMPILER OR CMAKE_DEPENDS_USE_COMPILER) set(CMAKE_CXX_DEPENDS_USE_COMPILER TRUE) endif() -if("${CMAKE_SOURCE_DIR}${CMAKE_BINARY_DIR}" MATCHES " ") - # The Intel compiler does not properly escape spaces in a depfile. - # Fall back to msvc depfile format. - set(CMAKE_DEPFILE_FLAGS_CXX "/showIncludes") - set(CMAKE_CXX_DEPFILE_FORMAT msvc) -endif() +# The Intel compiler does not properly escape spaces in a depfile which can +# occur in source and binary cmake paths as well as external include paths. +# Until Intel fixes this bug, fall back unconditionally to msvc depfile format. +set(CMAKE_DEPFILE_FLAGS_CXX "/showIncludes") +set(CMAKE_CXX_DEPFILE_FORMAT msvc) diff --git a/Modules/Platform/Windows-Intel-Fortran.cmake b/Modules/Platform/Windows-Intel-Fortran.cmake index e3804fb..c9b70d5 100644 --- a/Modules/Platform/Windows-Intel-Fortran.cmake +++ b/Modules/Platform/Windows-Intel-Fortran.cmake @@ -33,6 +33,8 @@ set(CMAKE_Fortran_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreaded -th set(CMAKE_Fortran_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDLL -threads -libs:dll) set(CMAKE_Fortran_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDebug -threads -libs:static -dbglibs) set(CMAKE_Fortran_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDebugDLL -threads -libs:dll -dbglibs) +set(CMAKE_Fortran_COMPILE_OPTIONS_MSVC_DEBUG_INFORMATION_FORMAT_Embedded -Z7) +set(CMAKE_Fortran_COMPILE_OPTIONS_MSVC_DEBUG_INFORMATION_FORMAT_ProgramDatabase -Zi) # Intel Fortran for Windows supports single-threaded RTL but it is # not implemented by the Visual Studio integration. diff --git a/Modules/Platform/Windows-IntelLLVM-Fortran.cmake b/Modules/Platform/Windows-IntelLLVM-Fortran.cmake index 06d0a00..202ba23 100644 --- a/Modules/Platform/Windows-IntelLLVM-Fortran.cmake +++ b/Modules/Platform/Windows-IntelLLVM-Fortran.cmake @@ -33,6 +33,8 @@ set(CMAKE_Fortran_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreaded -th set(CMAKE_Fortran_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDLL -threads -libs:dll) set(CMAKE_Fortran_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDebug -threads -libs:static -dbglibs) set(CMAKE_Fortran_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDebugDLL -threads -libs:dll -dbglibs) +set(CMAKE_Fortran_COMPILE_OPTIONS_MSVC_DEBUG_INFORMATION_FORMAT_Embedded -Z7) +set(CMAKE_Fortran_COMPILE_OPTIONS_MSVC_DEBUG_INFORMATION_FORMAT_ProgramDatabase -Zi) # Intel Fortran for Windows supports single-threaded RTL but it is # not implemented by the Visual Studio integration. diff --git a/Modules/Platform/Windows-IntelLLVM.cmake b/Modules/Platform/Windows-IntelLLVM.cmake index f24dcdb..43f5874 100644 --- a/Modules/Platform/Windows-IntelLLVM.cmake +++ b/Modules/Platform/Windows-IntelLLVM.cmake @@ -3,26 +3,61 @@ # This module is shared by multiple languages; use include blocker. -if(__WINDOWS_INTEL) +if(__WINDOWS_INTEL_LLVM) return() endif() -set(__WINDOWS_INTEL 1) +set(__WINDOWS_INTEL_LLVM 1) +# Platform/Windows-MSVC adds some linking options icx/ifx do not understand, +# but that need to be passed to the linker. Wrap all the linking options from +# Platform/Windows-MSVC so that the compiler will hand them off to the linker +# without interpreting them. + +# Save original CMAKE_${t}_LINKER_FLAGS_INIT +foreach(t EXE SHARED MODULE STATIC) + set(_saved_cmake_${t}_linker_flags_init ${CMAKE_${t}_LINKER_FLAGS_INIT}) + set(CMAKE_${t}_LINKER_FLAGS_INIT "") +endforeach() include(Platform/Windows-MSVC) +# Wrap linker flags from Windows-MSVC +set(_IntelLLVM_LINKER_WRAPPER_FLAG "/Qoption,link,") +set(_IntelLLVM_LINKER_WRAPPER_FLAG_SEP ",") +foreach(t EXE SHARED MODULE STATIC) + set(_wrapped_linker_flags "") + foreach(flag ${CMAKE_${t}_LINKER_FLAGS_INIT}) + string(STRIP ${flag} flag) + list(APPEND _wrapped_linker_flags "${_IntelLLVM_LINKER_WRAPPER_FLAG}${flag}") + endforeach() + set(CMAKE_${t}_LINKER_FLAGS_INIT "") + list(APPEND CMAKE_${t}_LINKER_FLAGS_INIT + ${_saved_cmake_${t}_linker_flags_init} ${_wrapped_linker_flags}) +endforeach() + macro(__windows_compiler_intel lang) __windows_compiler_msvc(${lang}) - # For DPCPP other offload cases, some link flags need to go to the compiler - # driver and others need to go to the linker. Pass the compiler linking flags - # in CMAKE_${lang}_LINK_FLAGS and linker flags in LINK_FLAGS + set(CMAKE_${lang}_LINKER_WRAPPER_FLAG "${_IntelLLVM_LINKER_WRAPPER_FLAG}") + set(CMAKE_${lang}_LINKER_WRAPPER_FLAG_SEP "${_IntelLLVM_LINKER_WRAPPER_FLAG_SEP}") + set(CMAKE_${lang}_CREATE_WIN32_EXE "${CMAKE_${lang}_LINKER_WRAPPER_FLAG}/subsystem:windows") + set(CMAKE_${lang}_CREATE_CONSOLE_EXE "${CMAKE_${lang}_LINKER_WRAPPER_FLAG}/subsystem:console") + set(CMAKE_LINK_DEF_FILE_FLAG "${CMAKE_${lang}_LINKER_WRAPPER_FLAG}/DEF:") + set(CMAKE_LIBRARY_PATH_FLAG "${CMAKE_${lang}_LINKER_WRAPPER_FLAG}/LIBPATH:") + + # Features for LINK_LIBRARY generator expression + if(MSVC_VERSION GREATER "1900") + ## WHOLE_ARCHIVE: Force loading all members of an archive + set(CMAKE_LINK_LIBRARY_USING_WHOLE_ARCHIVE "LINKER:/WHOLEARCHIVE:<LIBRARY>") + set(CMAKE_LINK_LIBRARY_USING_WHOLE_ARCHIVE_SUPPORTED TRUE) + endif() + set(CMAKE_${lang}_LINK_EXECUTABLE - "${_CMAKE_VS_LINK_EXE}<CMAKE_${lang}_COMPILER> ${CMAKE_CL_NOLOGO} <CMAKE_${lang}_LINK_FLAGS> <OBJECTS> ${CMAKE_START_TEMP_FILE} /link /out:<TARGET> /implib:<TARGET_IMPLIB> /pdb:<TARGET_PDB> /version:<TARGET_VERSION_MAJOR>.<TARGET_VERSION_MINOR>${_PLATFORM_LINK_FLAGS} <LINK_FLAGS> <LINK_LIBRARIES>${CMAKE_END_TEMP_FILE}") + "${_CMAKE_VS_LINK_EXE}<CMAKE_${lang}_COMPILER> ${CMAKE_CL_NOLOGO} <CMAKE_${lang}_LINK_FLAGS> <OBJECTS> ${CMAKE_START_TEMP_FILE} <LINK_FLAGS> <LINK_LIBRARIES> /link /out:<TARGET> /implib:<TARGET_IMPLIB> /pdb:<TARGET_PDB> /version:<TARGET_VERSION_MAJOR>.<TARGET_VERSION_MINOR>${_PLATFORM_LINK_FLAGS} ${CMAKE_END_TEMP_FILE}") set(CMAKE_${lang}_CREATE_SHARED_LIBRARY - "${_CMAKE_VS_LINK_DLL}<CMAKE_${lang}_COMPILER> ${CMAKE_CL_NOLOGO} <CMAKE_${lang}_LINK_FLAGS> <OBJECTS> ${CMAKE_START_TEMP_FILE} -LD -link /out:<TARGET> /implib:<TARGET_IMPLIB> /pdb:<TARGET_PDB> /version:<TARGET_VERSION_MAJOR>.<TARGET_VERSION_MINOR>${_PLATFORM_LINK_FLAGS} <LINK_FLAGS> <LINK_LIBRARIES> ${CMAKE_END_TEMP_FILE}") + "${_CMAKE_VS_LINK_DLL}<CMAKE_${lang}_COMPILER> ${CMAKE_CL_NOLOGO} <CMAKE_${lang}_LINK_FLAGS> <OBJECTS> ${CMAKE_START_TEMP_FILE} -LD <LINK_FLAGS> <LINK_LIBRARIES> -link /out:<TARGET> /implib:<TARGET_IMPLIB> /pdb:<TARGET_PDB> /version:<TARGET_VERSION_MAJOR>.<TARGET_VERSION_MINOR>${_PLATFORM_LINK_FLAGS} ${CMAKE_END_TEMP_FILE}") if (NOT "${lang}" STREQUAL "Fortran" OR CMAKE_${lang}_COMPILER_VERSION VERSION_GREATER_EQUAL 2022.1) # The Fortran driver does not support -fuse-ld=llvm-lib before compiler version 2022.1 set(CMAKE_${lang}_CREATE_STATIC_LIBRARY - "<CMAKE_${lang}_COMPILER> ${CMAKE_CL_NOLOGO} <CMAKE_${lang}_LINK_FLAGS> <OBJECTS> ${CMAKE_START_TEMP_FILE} -fuse-ld=llvm-lib -o <TARGET> -link <LINK_FLAGS> <LINK_LIBRARIES> ${CMAKE_END_TEMP_FILE}") + "<CMAKE_${lang}_COMPILER> ${CMAKE_CL_NOLOGO} <CMAKE_${lang}_LINK_FLAGS> <OBJECTS> ${CMAKE_START_TEMP_FILE} -fuse-ld=llvm-lib -o <TARGET> <LINK_FLAGS> <LINK_LIBRARIES> ${CMAKE_END_TEMP_FILE}") endif() set(CMAKE_DEPFILE_FLAGS_${lang} "-QMD -QMT <DEP_TARGET> -QMF <DEP_FILE>") diff --git a/Modules/Platform/Windows-LLVMFlang-Fortran.cmake b/Modules/Platform/Windows-LLVMFlang-Fortran.cmake new file mode 100644 index 0000000..64dc0da --- /dev/null +++ b/Modules/Platform/Windows-LLVMFlang-Fortran.cmake @@ -0,0 +1,3 @@ +include(Platform/Windows-GNU) +__windows_compiler_gnu(Fortran) +# TODO: MSVC ABI Support diff --git a/Modules/Platform/Windows-MSVC.cmake b/Modules/Platform/Windows-MSVC.cmake index b2cc6f4..8e96bf4 100644 --- a/Modules/Platform/Windows-MSVC.cmake +++ b/Modules/Platform/Windows-MSVC.cmake @@ -331,6 +331,22 @@ else() endif() unset(__WINDOWS_MSVC_CMP0091) +cmake_policy(GET CMP0141 __WINDOWS_MSVC_CMP0141) +if(__WINDOWS_MSVC_CMP0141 STREQUAL "NEW") + set(CMAKE_MSVC_DEBUG_INFORMATION_FORMAT_DEFAULT "$<$<CONFIG:Debug,RelWithDebInfo>:ProgramDatabase>") +else() + set(CMAKE_MSVC_DEBUG_INFORMATION_FORMAT_DEFAULT "") +endif() +unset(__WINDOWS_MSVC_CMP0141) + +# Features for LINK_LIBRARY generator expression +if(MSVC_VERSION GREATER "1900") + ## WHOLE_ARCHIVE: Force loading all members of an archive + set(CMAKE_LINK_LIBRARY_USING_WHOLE_ARCHIVE "/WHOLEARCHIVE:<LIBRARY>") + set(CMAKE_LINK_LIBRARY_USING_WHOLE_ARCHIVE_SUPPORTED TRUE) +endif() + + macro(__windows_compiler_msvc lang) if(NOT MSVC_VERSION LESS 1400) # for 2005 make sure the manifest is put in the dll with mt @@ -432,6 +448,12 @@ macro(__windows_compiler_msvc lang) endif() unset(_cmp0092) + if(CMAKE_MSVC_DEBUG_INFORMATION_FORMAT_DEFAULT) + set(_Zi "") + else() + set(_Zi " /Zi") + endif() + if(CMAKE_VS_PLATFORM_TOOLSET MATCHES "v[0-9]+_clang_.*") # note: MSVC 14 2015 Update 1 sets -fno-ms-compatibility by default, but this does not allow one to compile many projects # that include MS's own headers. CMake itself is affected project too. @@ -442,20 +464,24 @@ macro(__windows_compiler_msvc lang) string(APPEND CMAKE_${lang}_FLAGS_MINSIZEREL_INIT "${_MD} -DNDEBUG") # TODO: Add '-Os' once VS generator maps it properly for Clang else() string(APPEND CMAKE_${lang}_FLAGS_INIT " ${_PLATFORM_DEFINES}${_PLATFORM_DEFINES_${lang}} /D_WINDOWS${_W3}${_FLAGS_${lang}}") - string(APPEND CMAKE_${lang}_FLAGS_DEBUG_INIT "${_MDd} /Zi /Ob0 /Od ${_RTC1}") + string(APPEND CMAKE_${lang}_FLAGS_DEBUG_INIT "${_MDd}${_Zi} /Ob0 /Od ${_RTC1}") string(APPEND CMAKE_${lang}_FLAGS_RELEASE_INIT "${_MD} /O2 /Ob2 /DNDEBUG") - string(APPEND CMAKE_${lang}_FLAGS_RELWITHDEBINFO_INIT "${_MD} /Zi /O2 /Ob1 /DNDEBUG") + string(APPEND CMAKE_${lang}_FLAGS_RELWITHDEBINFO_INIT "${_MD}${_Zi} /O2 /Ob1 /DNDEBUG") string(APPEND CMAKE_${lang}_FLAGS_MINSIZEREL_INIT "${_MD} /O1 /Ob1 /DNDEBUG") endif() unset(_Wall) unset(_W3) unset(_MDd) unset(_MD) + unset(_Zi) set(CMAKE_${lang}_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreaded -MT) set(CMAKE_${lang}_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDLL -MD) set(CMAKE_${lang}_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDebug -MTd) set(CMAKE_${lang}_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDebugDLL -MDd) + set(CMAKE_${lang}_COMPILE_OPTIONS_MSVC_DEBUG_INFORMATION_FORMAT_Embedded -Z7) + set(CMAKE_${lang}_COMPILE_OPTIONS_MSVC_DEBUG_INFORMATION_FORMAT_ProgramDatabase -Zi) + set(CMAKE_${lang}_COMPILE_OPTIONS_MSVC_DEBUG_INFORMATION_FORMAT_EditAndContinue -ZI) endif() set(CMAKE_${lang}_LINKER_SUPPORTS_PDB ON) diff --git a/Modules/Platform/Windows-NVIDIA-CUDA.cmake b/Modules/Platform/Windows-NVIDIA-CUDA.cmake index 6c1699b..326e715 100644 --- a/Modules/Platform/Windows-NVIDIA-CUDA.cmake +++ b/Modules/Platform/Windows-NVIDIA-CUDA.cmake @@ -57,6 +57,12 @@ else() set(_MD "-MD ") endif() +if(CMAKE_MSVC_DEBUG_INFORMATION_FORMAT_DEFAULT) + set(_Zi "") +else() + set(_Zi " -Zi") +endif() + cmake_policy(GET CMP0092 _cmp0092) if(_cmp0092 STREQUAL "NEW") set(_W3 "") @@ -66,11 +72,12 @@ endif() unset(_cmp0092) string(APPEND CMAKE_CUDA_FLAGS_INIT " ${PLATFORM_DEFINES_CUDA} -D_WINDOWS -Xcompiler=\"${_W3}${_FLAGS_CXX}\"") -string(APPEND CMAKE_CUDA_FLAGS_DEBUG_INIT " -Xcompiler=\"${_MDd}-Zi -Ob0 -Od ${_RTC1}\"") +string(APPEND CMAKE_CUDA_FLAGS_DEBUG_INIT " -Xcompiler=\"${_MDd}${_Zi} -Ob0 -Od ${_RTC1}\"") string(APPEND CMAKE_CUDA_FLAGS_RELEASE_INIT " -Xcompiler=\"${_MD}-O2 -Ob2\" -DNDEBUG") -string(APPEND CMAKE_CUDA_FLAGS_RELWITHDEBINFO_INIT " -Xcompiler=\"${_MD}-Zi -O2 -Ob1\" -DNDEBUG") +string(APPEND CMAKE_CUDA_FLAGS_RELWITHDEBINFO_INIT " -Xcompiler=\"${_MD}${_Zi} -O2 -Ob1\" -DNDEBUG") string(APPEND CMAKE_CUDA_FLAGS_MINSIZEREL_INIT " -Xcompiler=\"${_MD}-O1 -Ob1\" -DNDEBUG") unset(_W3) +unset(_Zi) unset(_MDd) unset(_MD) @@ -78,6 +85,9 @@ set(CMAKE_CUDA_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreaded -Xcomp set(CMAKE_CUDA_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDLL -Xcompiler=-MD) set(CMAKE_CUDA_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDebug -Xcompiler=-MTd) set(CMAKE_CUDA_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDebugDLL -Xcompiler=-MDd) +set(CMAKE_CUDA_COMPILE_OPTIONS_MSVC_DEBUG_INFORMATION_FORMAT_Embedded -Xcompiler=-Z7) +set(CMAKE_CUDA_COMPILE_OPTIONS_MSVC_DEBUG_INFORMATION_FORMAT_ProgramDatabase -Xcompiler=-Zi) +set(CMAKE_CUDA_COMPILE_OPTIONS_MSVC_DEBUG_INFORMATION_FORMAT_EditAndContinue -Xcompiler=-ZI) set(CMAKE_CUDA_STANDARD_LIBRARIES_INIT "${CMAKE_C_STANDARD_LIBRARIES_INIT}") diff --git a/Modules/Platform/Windows-OpenWatcom.cmake b/Modules/Platform/Windows-OpenWatcom.cmake index 19bcb97..3e9795e 100644 --- a/Modules/Platform/Windows-OpenWatcom.cmake +++ b/Modules/Platform/Windows-OpenWatcom.cmake @@ -14,22 +14,32 @@ set(CMAKE_SHARED_LIBRARY_C_FLAGS "-bd") # ... while this is a space separated st set(CMAKE_RC_COMPILER "rc" ) -# single/multi-threaded /-bm -# static/DLL run-time libraries /-br -# default is setup for multi-threaded + DLL run-time libraries -string(APPEND CMAKE_C_FLAGS_INIT " -bt=nt -dWIN32 -br -bm") -string(APPEND CMAKE_CXX_FLAGS_INIT " -bt=nt -xs -dWIN32 -br -bm") - -if(CMAKE_CROSSCOMPILING) - if(NOT CMAKE_C_STANDARD_INCLUDE_DIRECTORIES) - set(CMAKE_C_STANDARD_INCLUDE_DIRECTORIES $ENV{WATCOM}/h $ENV{WATCOM}/h/nt) - endif() - if(NOT CMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES) - set(CMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES $ENV{WATCOM}/h $ENV{WATCOM}/h/nt) - endif() +cmake_policy(GET CMP0136 __WINDOWS_WATCOM_CMP0136) +if(__WINDOWS_WATCOM_CMP0136 STREQUAL "NEW") + set(CMAKE_WATCOM_RUNTIME_LIBRARY_DEFAULT "MultiThreadedDLL") + set(_br_bm "") +else() + set(CMAKE_WATCOM_RUNTIME_LIBRARY_DEFAULT "") + set(_br_bm "-br -bm") endif() +string(APPEND CMAKE_C_FLAGS_INIT " -bt=nt -dWIN32 ${_br_bm}") +string(APPEND CMAKE_CXX_FLAGS_INIT " -bt=nt -xs -dWIN32 ${_br_bm}") + +unset(__WINDOWS_WATCOM_CMP0136) +unset(_br_bm) + macro(__windows_open_watcom lang) + if(CMAKE_CROSSCOMPILING) + if(NOT CMAKE_${lang}_STANDARD_INCLUDE_DIRECTORIES) + set(CMAKE_${lang}_STANDARD_INCLUDE_DIRECTORIES $ENV{WATCOM}/h $ENV{WATCOM}/h/nt) + endif() + endif() set(CMAKE_${lang}_CREATE_WIN32_EXE "system nt_win") set(CMAKE_${lang}_CREATE_CONSOLE_EXE "system nt") + + set(CMAKE_${lang}_COMPILE_OPTIONS_WATCOM_RUNTIME_LIBRARY_SingleThreaded "") + set(CMAKE_${lang}_COMPILE_OPTIONS_WATCOM_RUNTIME_LIBRARY_SingleThreadedDLL -br) + set(CMAKE_${lang}_COMPILE_OPTIONS_WATCOM_RUNTIME_LIBRARY_MultiThreaded -bm) + set(CMAKE_${lang}_COMPILE_OPTIONS_WATCOM_RUNTIME_LIBRARY_MultiThreadedDLL -bm -br) endmacro() diff --git a/Modules/Platform/Windows3x-OpenWatcom-C.cmake b/Modules/Platform/Windows3x-OpenWatcom-C.cmake new file mode 100644 index 0000000..68a8af6 --- /dev/null +++ b/Modules/Platform/Windows3x-OpenWatcom-C.cmake @@ -0,0 +1,2 @@ +include(Platform/Windows3x-OpenWatcom) +__windows3x_open_watcom(C) diff --git a/Modules/Platform/Windows3x-OpenWatcom-CXX.cmake b/Modules/Platform/Windows3x-OpenWatcom-CXX.cmake new file mode 100644 index 0000000..182ef11 --- /dev/null +++ b/Modules/Platform/Windows3x-OpenWatcom-CXX.cmake @@ -0,0 +1,2 @@ +include(Platform/Windows3x-OpenWatcom) +__windows3x_open_watcom(CXX) diff --git a/Modules/Platform/Windows3x-OpenWatcom.cmake b/Modules/Platform/Windows3x-OpenWatcom.cmake new file mode 100644 index 0000000..6fcceea --- /dev/null +++ b/Modules/Platform/Windows3x-OpenWatcom.cmake @@ -0,0 +1,33 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + +# This module is shared by multiple languages; use include blocker. +include_guard() + +set(CMAKE_BUILD_TYPE_INIT Debug) + +if(DEFINED CMAKE_SYSTEM_PROCESSOR AND CMAKE_SYSTEM_PROCESSOR STREQUAL "I86") + string(APPEND CMAKE_EXE_LINKER_FLAGS_INIT " system windows") + string(APPEND CMAKE_SHARED_LINKER_FLAGS_INIT " system windows") + string(APPEND CMAKE_MODULE_LINKER_FLAGS_INIT " system windows") +else() + string(APPEND CMAKE_EXE_LINKER_FLAGS_INIT " system win386") + string(APPEND CMAKE_SHARED_LINKER_FLAGS_INIT " system win386") + string(APPEND CMAKE_MODULE_LINKER_FLAGS_INIT " system win386") +endif() + +set(CMAKE_C_COMPILE_OPTIONS_DLL "-bd") # Note: This variable is a ';' separated list +set(CMAKE_SHARED_LIBRARY_C_FLAGS "-bd") # ... while this is a space separated string. + +set(CMAKE_RC_COMPILER "rc") + +set(CMAKE_WATCOM_RUNTIME_LIBRARY_DEFAULT "") + +string(APPEND CMAKE_C_FLAGS_INIT " -bt=windows") +string(APPEND CMAKE_CXX_FLAGS_INIT " -bt=windows -xs") + +macro(__windows3x_open_watcom lang) + if(NOT CMAKE_${lang}_STANDARD_INCLUDE_DIRECTORIES) + set(CMAKE_${lang}_STANDARD_INCLUDE_DIRECTORIES $ENV{WATCOM}/h $ENV{WATCOM}/h/win) + endif() +endmacro() diff --git a/Modules/Platform/Windows3x.cmake b/Modules/Platform/Windows3x.cmake new file mode 100644 index 0000000..856f4b1 --- /dev/null +++ b/Modules/Platform/Windows3x.cmake @@ -0,0 +1,12 @@ +set(CMAKE_STATIC_LIBRARY_PREFIX "") +set(CMAKE_STATIC_LIBRARY_SUFFIX ".lib") +set(CMAKE_SHARED_LIBRARY_PREFIX "") +set(CMAKE_SHARED_LIBRARY_SUFFIX ".dll") +set(CMAKE_IMPORT_LIBRARY_PREFIX "") +set(CMAKE_IMPORT_LIBRARY_SUFFIX ".lib") +set(CMAKE_EXECUTABLE_SUFFIX ".exe") +set(CMAKE_LINK_LIBRARY_SUFFIX ".lib") +set(CMAKE_DL_LIBS "") + +set(CMAKE_FIND_LIBRARY_PREFIXES "") +set(CMAKE_FIND_LIBRARY_SUFFIXES ".lib") diff --git a/Modules/Platform/WindowsPaths.cmake b/Modules/Platform/WindowsPaths.cmake index b9e2f17..de93338 100644 --- a/Modules/Platform/WindowsPaths.cmake +++ b/Modules/Platform/WindowsPaths.cmake @@ -67,6 +67,7 @@ if (NOT CMAKE_FIND_NO_INSTALL_PREFIX) ) endif() endif() +_cmake_record_install_prefix() if(CMAKE_CROSSCOMPILING AND NOT CMAKE_HOST_SYSTEM_NAME MATCHES "Windows") # MinGW (useful when cross compiling from linux with CMAKE_FIND_ROOT_PATH set) diff --git a/Modules/Platform/kFreeBSD.cmake b/Modules/Platform/kFreeBSD.cmake index c1db259..09c240d 100644 --- a/Modules/Platform/kFreeBSD.cmake +++ b/Modules/Platform/kFreeBSD.cmake @@ -1,4 +1,5 @@ -# kFreeBSD looks just like Linux. +# kFreeBSD is a Debian GNU distribution with a kernel from FreeBSD, +# and should be marked as LINUX include(Platform/Linux) set(CMAKE_LIBRARY_ARCHITECTURE_REGEX "[a-z0-9_]+(-[a-z0-9_]+)?-kfreebsd-gnu[a-z0-9_]*") diff --git a/Modules/ProcessorCount.cmake b/Modules/ProcessorCount.cmake index bda23ab..47e266d 100644 --- a/Modules/ProcessorCount.cmake +++ b/Modules/ProcessorCount.cmake @@ -22,9 +22,17 @@ This function is guaranteed to return a positive integer (>=1) if it succeeds. It returns 0 if there's a problem determining the processor count. +More generally accurate physical CPU count can be obtained via +:command:`cmake_host_system_information`: + +.. code-block:: cmake + + cmake_host_system_information(RESULT N + QUERY NUMBER_OF_PHYSICAL_CORES) + Example use, in a ctest -S dashboard script: -:: +.. code-block:: cmake include(ProcessorCount) ProcessorCount(N) @@ -33,8 +41,6 @@ Example use, in a ctest -S dashboard script: set(ctest_test_args ${ctest_test_args} PARALLEL_LEVEL ${N}) endif() - - This function is intended to offer an approximation of the value of the number of compute cores available on the current machine, such that you may use that value for parallel building and parallel diff --git a/Modules/SystemInformation.cmake b/Modules/SystemInformation.cmake index 5ecc39a..97f3856 100644 --- a/Modules/SystemInformation.cmake +++ b/Modules/SystemInformation.cmake @@ -5,8 +5,8 @@ cmake_minimum_required(VERSION ${CMAKE_VERSION}) project(DumpInformation) -# first get the standard information for th platform -include_directories("This does not exists") +# first get the standard information for the platform +include_directories("This does not exist") get_directory_property(incl INCLUDE_DIRECTORIES) set_directory_properties(PROPERTIES INCLUDE_DIRECTORIES "${DumpInformation_BINARY_DIR};${DumpInformation_SOURCE_DIR}") @@ -83,8 +83,6 @@ macro(DUMP_FILE THE_FILE) endmacro() DUMP_FILE("../CMakeCache.txt") -DUMP_FILE("../CMakeFiles/CMakeOutput.log") -DUMP_FILE("../CMakeFiles/CMakeError.log") DUMP_FILE("../CMakeFiles/CMakeSystem.cmake") foreach (EXTRA_FILE ${EXTRA_DUMP_FILES}) diff --git a/Modules/TestBigEndian.cmake b/Modules/TestBigEndian.cmake index ea8ca73..12b6816 100644 --- a/Modules/TestBigEndian.cmake +++ b/Modules/TestBigEndian.cmake @@ -77,21 +77,16 @@ macro(__TEST_BIG_ENDIAN_LEGACY_IMPL VARIABLE) endif() if(_test_language STREQUAL "CXX") - set(_test_file "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/TestEndianess.cpp") + set(_test_file TestEndianess.cpp) else() - set(_test_file "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/TestEndianess.c") + set(_test_file TestEndianess.c) endif() - configure_file("${CMAKE_ROOT}/Modules/TestEndianess.c.in" - ${_test_file} - @ONLY) - - file(READ ${_test_file} TEST_ENDIANESS_FILE_CONTENT) + file(READ "${CMAKE_ROOT}/Modules/TestEndianess.c.in" TEST_ENDIANESS_FILE_CONTENT) + string(CONFIGURE "${TEST_ENDIANESS_FILE_CONTENT}" TEST_ENDIANESS_FILE_CONTENT @ONLY) try_compile(HAVE_${VARIABLE} - "${CMAKE_BINARY_DIR}" - ${_test_file} - OUTPUT_VARIABLE OUTPUT + SOURCE_FROM_VAR "${_test_file}" TEST_ENDIANESS_FILE_CONTENT COPY_FILE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/TestEndianess.bin" ) if(HAVE_${VARIABLE}) @@ -129,14 +124,8 @@ macro(__TEST_BIG_ENDIAN_LEGACY_IMPL VARIABLE) message(CHECK_FAIL "TEST_BIG_ENDIAN found no result!") message(SEND_ERROR "TEST_BIG_ENDIAN found no result!") endif() - - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log - "Determining if the system is big endian passed with the following output:\n${OUTPUT}\nTestEndianess.c:\n${TEST_ENDIANESS_FILE_CONTENT}\n\n") - else() message(CHECK_FAIL "failed") - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log - "Determining if the system is big endian failed with the following output:\n${OUTPUT}\nTestEndianess.c:\n${TEST_ENDIANESS_FILE_CONTENT}\n\n") set(${VARIABLE}) endif() endif() diff --git a/Modules/TestCXXAcceptsFlag.cmake b/Modules/TestCXXAcceptsFlag.cmake index ce505f3..023d6ba 100644 --- a/Modules/TestCXXAcceptsFlag.cmake +++ b/Modules/TestCXXAcceptsFlag.cmake @@ -25,20 +25,13 @@ macro(CHECK_CXX_ACCEPTS_FLAG FLAGS VARIABLE) if(NOT DEFINED ${VARIABLE}) message(CHECK_START "Checking to see if CXX compiler accepts flag ${FLAGS}") try_compile(${VARIABLE} - ${CMAKE_BINARY_DIR} - ${CMAKE_ROOT}/Modules/DummyCXXFile.cxx + SOURCES ${CMAKE_ROOT}/Modules/DummyCXXFile.cxx CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${FLAGS} - OUTPUT_VARIABLE OUTPUT) + ) if(${VARIABLE}) message(CHECK_PASS "yes") - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log - "Determining if the CXX compiler accepts the flag ${FLAGS} passed with " - "the following output:\n${OUTPUT}\n\n") else() message(CHECK_FAIL "no") - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log - "Determining if the CXX compiler accepts the flag ${FLAGS} failed with " - "the following output:\n${OUTPUT}\n\n") endif() endif() endmacro() diff --git a/Modules/TestForANSIForScope.cmake b/Modules/TestForANSIForScope.cmake index 0f2dc01..b1a12cf 100644 --- a/Modules/TestForANSIForScope.cmake +++ b/Modules/TestForANSIForScope.cmake @@ -17,23 +17,17 @@ for-init-statement to the loop body. if(NOT DEFINED CMAKE_ANSI_FOR_SCOPE) message(CHECK_START "Check for ANSI scope") - try_compile(CMAKE_ANSI_FOR_SCOPE ${CMAKE_BINARY_DIR} - ${CMAKE_ROOT}/Modules/TestForAnsiForScope.cxx - OUTPUT_VARIABLE OUTPUT) + try_compile(CMAKE_ANSI_FOR_SCOPE + SOURCES ${CMAKE_ROOT}/Modules/TestForAnsiForScope.cxx + ) if (CMAKE_ANSI_FOR_SCOPE) message(CHECK_PASS "found") set (CMAKE_NO_ANSI_FOR_SCOPE 0 CACHE INTERNAL "Does the compiler support ansi for scope.") - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log - "Determining if the CXX compiler understands ansi for scopes passed with " - "the following output:\n${OUTPUT}\n\n") else () message(CHECK_FAIL "not found") set (CMAKE_NO_ANSI_FOR_SCOPE 1 CACHE INTERNAL "Does the compiler support ansi for scope.") - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log - "Determining if the CXX compiler understands ansi for scopes failed with " - "the following output:\n${OUTPUT}\n\n") endif () endif() diff --git a/Modules/TestForANSIStreamHeaders.cxx b/Modules/TestForANSIStreamHeaders.cxx index d314d58..0ae9723 100644 --- a/Modules/TestForANSIStreamHeaders.cxx +++ b/Modules/TestForANSIStreamHeaders.cxx @@ -1,6 +1,6 @@ #include <iostream> -int main(int, char* []) +int main(int, char*[]) { return 0; } diff --git a/Modules/TestForAnsiForScope.cxx b/Modules/TestForAnsiForScope.cxx index 4bc2c67..1632cae 100644 --- a/Modules/TestForAnsiForScope.cxx +++ b/Modules/TestForAnsiForScope.cxx @@ -1,4 +1,4 @@ -int main(int, char* []) +int main(int, char*[]) { int i; for (int i = 0; i < 1; ++i) diff --git a/Modules/TestForSSTREAM.cmake b/Modules/TestForSSTREAM.cmake index 545b7ec..e2cc5b0 100644 --- a/Modules/TestForSSTREAM.cmake +++ b/Modules/TestForSSTREAM.cmake @@ -16,23 +16,17 @@ check if the compiler supports the standard ANSI sstream header if(NOT DEFINED CMAKE_HAS_ANSI_STRING_STREAM) message(CHECK_START "Check for sstream") - try_compile(CMAKE_HAS_ANSI_STRING_STREAM ${CMAKE_BINARY_DIR} - ${CMAKE_ROOT}/Modules/TestForSSTREAM.cxx - OUTPUT_VARIABLE OUTPUT) + try_compile(CMAKE_HAS_ANSI_STRING_STREAM + SOURCES ${CMAKE_ROOT}/Modules/TestForSSTREAM.cxx + ) if (CMAKE_HAS_ANSI_STRING_STREAM) message(CHECK_PASS "found") set (CMAKE_NO_ANSI_STRING_STREAM 0 CACHE INTERNAL "Does the compiler support sstream") - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log - "Determining if the CXX compiler has sstream passed with " - "the following output:\n${OUTPUT}\n\n") else () message(CHECK_FAIL "not found") set (CMAKE_NO_ANSI_STRING_STREAM 1 CACHE INTERNAL "Does the compiler support sstream") - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log - "Determining if the CXX compiler has sstream failed with " - "the following output:\n${OUTPUT}\n\n") endif () endif() diff --git a/Modules/TestForSSTREAM.cxx b/Modules/TestForSSTREAM.cxx index 83a75e4..59f13a3 100644 --- a/Modules/TestForSSTREAM.cxx +++ b/Modules/TestForSSTREAM.cxx @@ -1,5 +1,5 @@ #include <sstream> -int main(int, char* []) +int main(int, char*[]) { std::ostringstream os; os << "12345"; diff --git a/Modules/TestForSTDNamespace.cmake b/Modules/TestForSTDNamespace.cmake index d101c83..61e922d 100644 --- a/Modules/TestForSTDNamespace.cmake +++ b/Modules/TestForSTDNamespace.cmake @@ -16,23 +16,17 @@ check if the compiler supports std:: on stl classes if(NOT DEFINED CMAKE_STD_NAMESPACE) message(CHECK_START "Check for STD namespace") - try_compile(CMAKE_STD_NAMESPACE ${CMAKE_BINARY_DIR} - ${CMAKE_ROOT}/Modules/TestForSTDNamespace.cxx - OUTPUT_VARIABLE OUTPUT) + try_compile(CMAKE_STD_NAMESPACE + SOURCES ${CMAKE_ROOT}/Modules/TestForSTDNamespace.cxx + ) if (CMAKE_STD_NAMESPACE) message(CHECK_PASS "found") set (CMAKE_NO_STD_NAMESPACE 0 CACHE INTERNAL "Does the compiler support std::.") - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log - "Determining if the CXX compiler has std namespace passed with " - "the following output:\n${OUTPUT}\n\n") else () message(CHECK_FAIL "not found") set (CMAKE_NO_STD_NAMESPACE 1 CACHE INTERNAL "Does the compiler support std::.") - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log - "Determining if the CXX compiler has std namespace failed with " - "the following output:\n${OUTPUT}\n\n") endif () endif() diff --git a/Modules/TestForSTDNamespace.cxx b/Modules/TestForSTDNamespace.cxx index 62951ff..b537d44 100644 --- a/Modules/TestForSTDNamespace.cxx +++ b/Modules/TestForSTDNamespace.cxx @@ -1,5 +1,5 @@ #include <list> -int main(int, char* []) +int main(int, char*[]) { std::list<int>(); return 0; diff --git a/Modules/UseJava.cmake b/Modules/UseJava.cmake index ef63ac3..54a8cf7 100644 --- a/Modules/UseJava.cmake +++ b/Modules/UseJava.cmake @@ -7,7 +7,7 @@ UseJava This file provides support for ``Java``. It is assumed that :module:`FindJava` has already been loaded. See :module:`FindJava` for -information on how to load Java into your ``CMake`` project. +information on how to load Java into your CMake project. Synopsis ^^^^^^^^ @@ -294,7 +294,7 @@ Header Generation .. deprecated:: 3.11 This command will no longer be supported starting with version 10 of the JDK - due to the `suppression of javah tool <http://openjdk.java.net/jeps/313>`_. + due to the `suppression of javah tool <https://openjdk.java.net/jeps/313>`_. The :ref:`add_jar(GENERATE_NATIVE_HEADERS) <add_jar>` command should be used instead. diff --git a/Modules/UseSWIG.cmake b/Modules/UseSWIG.cmake index 35b1704..ca16bc2 100644 --- a/Modules/UseSWIG.cmake +++ b/Modules/UseSWIG.cmake @@ -8,7 +8,14 @@ UseSWIG This file provides support for ``SWIG``. It is assumed that :module:`FindSWIG` module has already been loaded. -Defines the following command for use with ``SWIG``: +.. only:: html + + .. contents:: + +CMake Commands +^^^^^^^^^^^^^^ + +The following command is defined for use with ``SWIG``: .. command:: swig_add_library @@ -125,20 +132,8 @@ Defines the following command for use with ``SWIG``: to prevent interference between targets or losing other important files, each target should have its own dedicated output directory. -.. command:: swig_link_libraries - - Link libraries to swig module:: - - swig_link_libraries(<name> <item>...) - - This command has same capabilities as :command:`target_link_libraries` - command. - - .. note:: - - If variable ``UseSWIG_TARGET_NAME_PREFERENCE`` is set to ``STANDARD``, this - command is deprecated and :command:`target_link_libraries` command must be - used instead. +Properties on Source Files +^^^^^^^^^^^^^^^^^^^^^^^^^^ Source file properties on module files **must** be set before the invocation of the ``swig_add_library`` command to specify special behavior of SWIG and @@ -233,6 +228,9 @@ ensure generated files will receive the required settings. other ways to define output file directory applies (see ``OUTFILE_DIR`` option of ``swig_add_library()`` command). +Properties on Targets +^^^^^^^^^^^^^^^^^^^^^ + Target library properties can be set to apply same configuration to all SWIG input files. @@ -271,6 +269,9 @@ input files. Add dependencies to all SWIG input files. +Read-only Target Properties +""""""""""""""""""""""""""" + The following target properties are output properties and can be used to get information about support files generated by ``SWIG`` interface compilation. @@ -303,6 +304,9 @@ information about support files generated by ``SWIG`` interface compilation. When source property ``OUTPUT_DIR`` is defined, multiple directories can be specified as part of ``SWIG_SUPPORT_FILES_DIRECTORY``. +CMake Variables +^^^^^^^^^^^^^^^ + Some variables can be set to customize the behavior of ``swig_add_library`` as well as ``SWIG``: @@ -361,6 +365,34 @@ as well as ``SWIG``: .. versionadded:: 3.22 Added the support of :ref:`Visual Studio Generators`. +Deprecated Commands +^^^^^^^^^^^^^^^^^^^ + +.. command:: swig_link_libraries + + .. deprecated:: 3.13 + Use :command:`target_link_libraries` with the standard target name, + or with ``${SWIG_MODULE_<name>_REAL_NAME}`` for legacy target naming. + + Link libraries to swig module:: + + swig_link_libraries(<name> <item>...) + + This command has same capabilities as :command:`target_link_libraries` + command. + + .. note:: + When policy :policy:`CMP0078` is set to ``NEW``, + :command:`swig_add_library` creates a standard target with the + specified ``<name>`` and :command:`target_link_libraries` must be used + instead of this command. + + With the legacy behavior (when :policy:`CMP0078` is set to ``OLD`` and + the ``UseSWIG_TARGET_NAME_PREFERENCE`` variable is set to ``"LEGACY"``, + or in CMake versions prior to 3.12), it is preferable to use + ``target_link_libraries(${SWIG_MODULE_<name>_REAL_NAME} ...)`` + instead of this command. + #]=======================================================================] cmake_policy(PUSH) @@ -377,6 +409,8 @@ set(SWIG_EXTRA_LIBRARIES "") set(SWIG_PYTHON_EXTRA_FILE_EXTENSIONS ".py") set(SWIG_JAVA_EXTRA_FILE_EXTENSIONS ".java" "JNI.java") set(SWIG_CSHARP_EXTRA_FILE_EXTENSIONS ".cs" "PINVOKE.cs") +set(SWIG_PERL_EXTRA_FILE_EXTENSIONS ".pm") +set(SWIG_PERL5_EXTRA_FILE_EXTENSIONS ".pm") set(SWIG_MANAGE_SUPPORT_FILES_SCRIPT "${CMAKE_CURRENT_LIST_DIR}/UseSWIG/ManageSupportFiles.cmake") @@ -413,8 +447,8 @@ macro(SWIG_MODULE_INITIALIZE name language) endif() if(SWIG_MODULE_${name}_LANGUAGE STREQUAL "UNKNOWN") message(FATAL_ERROR "SWIG Error: Language \"${language}\" not found") - elseif(SWIG_MODULE_${name}_LANGUAGE STREQUAL "PERL" AND - NOT "-shadow" IN_LIST SWIG_MODULE_${name}_EXTRA_FLAGS) + elseif((SWIG_MODULE_${name}_LANGUAGE STREQUAL "PERL" OR SWIG_MODULE_${name}_LANGUAGE STREQUAL "PERL5") + AND NOT "-shadow" IN_LIST SWIG_MODULE_${name}_EXTRA_FLAGS) list(APPEND SWIG_MODULE_${name}_EXTRA_FLAGS "-shadow") endif() endmacro() @@ -970,7 +1004,7 @@ function(SWIG_ADD_LIBRARY name) if (APPLE) set_target_properties (${target_name} PROPERTIES SUFFIX ".bundle") endif () - elseif (swig_lowercase_language STREQUAL "perl") + elseif (swig_lowercase_language STREQUAL "perl" OR swig_lowercase_language STREQUAL "perl5") # assume empty prefix because we expect the module to be dynamically loaded set_target_properties (${target_name} PROPERTIES PREFIX "") if (APPLE) @@ -989,6 +1023,9 @@ function(SWIG_ADD_LIBRARY name) endif() set_target_properties (${target_name} PROPERTIES PREFIX "") endif() + if (APPLE) + set_target_properties (${target_name} PROPERTIES SUFFIX ".dylib") + endif () else() # assume empty prefix because we expect the module to be dynamically loaded set_target_properties (${target_name} PROPERTIES PREFIX "") diff --git a/Modules/UsewxWidgets.cmake b/Modules/UsewxWidgets.cmake index eed0410..b428a61 100644 --- a/Modules/UsewxWidgets.cmake +++ b/Modules/UsewxWidgets.cmake @@ -38,18 +38,6 @@ AUTHOR Jan Woetzel <jw -at- mip.informatik.uni-kiel.de> #]=======================================================================] -# debug message and logging. -# comment these out for distribution -if (NOT LOGFILE ) - # set(LOGFILE "${PROJECT_BINARY_DIR}/CMakeOutput.log") -endif () -macro(MSG _MSG) - # file(APPEND ${LOGFILE} "${CMAKE_CURRENT_LIST_FILE}(${CMAKE_CURRENT_LIST_LINE}): ${_MSG}\n") - # message(STATUS "${CMAKE_CURRENT_LIST_FILE}(${CMAKE_CURRENT_LIST_LINE}): ${_MSG}") -endmacro() - - -MSG("wxWidgets_FOUND=${wxWidgets_FOUND}") if (wxWidgets_FOUND) if (wxWidgets_INCLUDE_DIRS) if(wxWidgets_INCLUDE_DIRS_NO_SYSTEM) @@ -57,45 +45,28 @@ if (wxWidgets_FOUND) else() include_directories(SYSTEM ${wxWidgets_INCLUDE_DIRS}) endif() - MSG("wxWidgets_INCLUDE_DIRS=${wxWidgets_INCLUDE_DIRS}") endif() if (wxWidgets_LIBRARY_DIRS) link_directories(${wxWidgets_LIBRARY_DIRS}) - MSG("wxWidgets_LIBRARY_DIRS=${wxWidgets_LIBRARY_DIRS}") endif() if (wxWidgets_DEFINITIONS) set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS ${wxWidgets_DEFINITIONS}) - MSG("wxWidgets_DEFINITIONS=${wxWidgets_DEFINITIONS}") endif() if (wxWidgets_DEFINITIONS_DEBUG) set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS_DEBUG ${wxWidgets_DEFINITIONS_DEBUG}) - MSG("wxWidgets_DEFINITIONS_DEBUG=${wxWidgets_DEFINITIONS_DEBUG}") endif() if (wxWidgets_CXX_FLAGS) # Flags are expected to be a string here, not a list. string(REPLACE ";" " " wxWidgets_CXX_FLAGS_str "${wxWidgets_CXX_FLAGS}") string(APPEND CMAKE_CXX_FLAGS " ${wxWidgets_CXX_FLAGS_str}") - MSG("wxWidgets_CXX_FLAGS=${wxWidgets_CXX_FLAGS_str}") unset(wxWidgets_CXX_FLAGS_str) endif() - - # DEPRECATED JW - # just for backward compatibility: add deps to all targets - # library projects better use advanced find_package(wxWidgets) directly. - #if(wxWidgets_LIBRARIES) - # link_libraries(${wxWidgets_LIBRARIES}) - # # BUG: str too long: MSG("wxWidgets_LIBRARIES=${wxWidgets_LIBRARIES}") - # if(LOGFILE) - # file(APPEND ${LOGFILE} "${CMAKE_CURRENT_LIST_FILE}(${CMAKE_CURRENT_LIST_LINE}): ${wxWidgets_LIBRARIES}\n") - # endif() - #endif() - else () message("wxWidgets requested but not found.") endif() diff --git a/Modules/WriteBasicConfigVersionFile.cmake b/Modules/WriteBasicConfigVersionFile.cmake index 45f9e58..1c5ecd5 100644 --- a/Modules/WriteBasicConfigVersionFile.cmake +++ b/Modules/WriteBasicConfigVersionFile.cmake @@ -46,6 +46,21 @@ function(WRITE_BASIC_CONFIG_VERSION_FILE _filename) endif() endif() + if(NOT CVF_ARCH_INDEPENDENT) + set(CVF_ARCH_INDEPENDENT_CHECK " +# if the installed or the using project don't have CMAKE_SIZEOF_VOID_P set, ignore it: +if(CMAKE_SIZEOF_VOID_P STREQUAL \"\" OR \"${CMAKE_SIZEOF_VOID_P}\" STREQUAL \"\") + return() +endif() + +# check that the installed version has the same 32/64bit-ness as the one which is currently searching: +if(NOT CMAKE_SIZEOF_VOID_P STREQUAL \"${CMAKE_SIZEOF_VOID_P}\") + math(EXPR installedBits \"${CMAKE_SIZEOF_VOID_P} * 8\") + set(PACKAGE_VERSION \"\${PACKAGE_VERSION} (\${installedBits}bit)\") + set(PACKAGE_VERSION_UNSUITABLE TRUE) +endif()") + endif() + configure_file("${versionTemplateFile}" "${_filename}" @ONLY) endfunction() |