diff options
Diffstat (limited to 'Modules')
48 files changed, 1111 insertions, 111 deletions
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/CMakeDetermineCUDACompiler.cmake b/Modules/CMakeDetermineCUDACompiler.cmake index 2649441..66020e8 100644 --- a/Modules/CMakeDetermineCUDACompiler.cmake +++ b/Modules/CMakeDetermineCUDACompiler.cmake @@ -249,7 +249,8 @@ if(NOT CMAKE_CUDA_COMPILER_ID_RUN) set(CMAKE_CUDA_COMPILER_TOOLKIT_VERSION "${CMAKE_MATCH_1}") endif() - # Make the all and all-major architecture information available. + # Make the all, all-major, and native architecture information available. + # FIXME(#23161): Defer architecture detection until compiler testing. include(${CMAKE_ROOT}/Modules/CUDA/architectures.cmake) endif() @@ -259,11 +260,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,6 +273,7 @@ if(NOT CMAKE_CUDA_COMPILER_ID_RUN) endif() endif() + # FIXME(#23161): Defer architecture testing until compiler testing. 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. @@ -289,6 +291,17 @@ if(NOT CMAKE_CUDA_COMPILER_ID_RUN) set(architectures_test ${CMAKE_CUDA_ARCHITECTURES_ALL_MAJOR}) endif() endif() + elseif(CMAKE_CUDA_ARCHITECTURES STREQUAL "native") + # For sufficiently new NVCC we can just use the 'native' value directly. + # For VS we don't test since we can't find nvcc this early (see #23161). + if(CMAKE_CUDA_COMPILER_ID STREQUAL "NVIDIA" AND CMAKE_CUDA_COMPILER_TOOLKIT_VERSION VERSION_GREATER_EQUAL 11.6) + 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() + set(architectures_test ${_CUDA_ARCHITECTURES_NATIVE}) + endif() elseif(CMAKE_CUDA_ARCHITECTURES OR "${CMAKE_CUDA_ARCHITECTURES}" STREQUAL "") # Explicit architectures. Test them during detection. set(architectures_explicit TRUE) @@ -346,6 +359,7 @@ if(NOT CMAKE_CUDA_COMPILER_ID_RUN) # We now know the version, so make the architecture variables available. set(CMAKE_CUDA_COMPILER_TOOLKIT_VERSION ${CMAKE_CUDA_COMPILER_VERSION}) + # FIXME(#23161): Defer architecture detection until compiler testing. include(${CMAKE_ROOT}/Modules/CUDA/architectures.cmake) endif() @@ -633,7 +647,7 @@ 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)$") +elseif(CMAKE_CUDA_ARCHITECTURES AND NOT "${architectures_tested}" MATCHES "^(all|all-major|native)$") # Sort since order mustn't matter. list(SORT architectures_detected) list(SORT architectures_tested) diff --git a/Modules/CMakeDetermineCompiler.cmake b/Modules/CMakeDetermineCompiler.cmake index aec86d9..ec2a865 100644 --- a/Modules/CMakeDetermineCompiler.cmake +++ b/Modules/CMakeDetermineCompiler.cmake @@ -119,9 +119,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..82a6d21 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. diff --git a/Modules/CMakeDetermineCompilerId.cmake b/Modules/CMakeDetermineCompilerId.cmake index 5670509..a90fa5d 100644 --- a/Modules/CMakeDetermineCompilerId.cmake +++ b/Modules/CMakeDetermineCompilerId.cmake @@ -495,7 +495,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)$") + if(CMAKE_CUDA_ARCHITECTURES AND NOT CMAKE_CUDA_ARCHITECTURES MATCHES "^(all|all-major|native)$") foreach(arch ${CMAKE_CUDA_ARCHITECTURES}) string(REGEX MATCH "[0-9]+" arch_name "${arch}") string(APPEND cuda_codegen "compute_${arch_name},sm_${arch_name};") @@ -841,15 +841,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 \\\"") diff --git a/Modules/CMakeGenericSystem.cmake b/Modules/CMakeGenericSystem.cmake index 649b6f7..e2925dc 100644 --- a/Modules/CMakeGenericSystem.cmake +++ b/Modules/CMakeGenericSystem.cmake @@ -24,6 +24,12 @@ set(CMAKE_DL_LIBS "dl") set(CMAKE_FIND_LIBRARY_PREFIXES "lib") set(CMAKE_FIND_LIBRARY_SUFFIXES ".so" ".a") +# 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) + set(CMAKE_AUTOGEN_ORIGIN_DEPENDS ON) set(CMAKE_AUTOMOC_COMPILER_PREDEFINES ON) if(NOT DEFINED CMAKE_AUTOMOC_PATH_PREFIX) @@ -41,11 +47,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/CMakePlatformId.h.in b/Modules/CMakePlatformId.h.in index 59195f8..06f5ecd 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,12 @@ # define ARCHITECTURE_ID "" # endif +# elif defined(__ADSPSHARC__) +# define ARCHITECTURE_ID "SHARC" + +# elif defined(__ADSPBLACKFIN__) +# define ARCHITECTURE_ID "Blackfin" + #else # define ARCHITECTURE_ID #endif diff --git a/Modules/CMakeTestCUDACompiler.cmake b/Modules/CMakeTestCUDACompiler.cmake index 25a3653..ea07482 100644 --- a/Modules/CMakeTestCUDACompiler.cmake +++ b/Modules/CMakeTestCUDACompiler.cmake @@ -21,6 +21,51 @@ 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) + 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}") + file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.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 diff --git a/Modules/CPack.cmake b/Modules/CPack.cmake index 6650f7c..40cfde4 100644 --- a/Modules/CPack.cmake +++ b/Modules/CPack.cmake @@ -304,14 +304,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 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -806,8 +817,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/CUDA/architectures.cmake b/Modules/CUDA/architectures.cmake index fa3a5a1..9b1f2b5 100644 --- a/Modules/CUDA/architectures.cmake +++ b/Modules/CUDA/architectures.cmake @@ -44,3 +44,63 @@ 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() + +# FIXME(#23161): Detect architectures early since we test them during +# compiler detection. We already have code to detect them later during +# compiler testing, so we should not need to do this here. +if(NOT CMAKE_GENERATOR MATCHES "Visual Studio") + set(_CUDA_ARCHS_EXE "${CMAKE_PLATFORM_INFO_DIR}/CMakeDetermineCUDACompilerArchs.bin") + execute_process( + COMMAND "${_CUDA_NVCC_EXECUTABLE}" -o "${_CUDA_ARCHS_EXE}" --cudart=static "${CMAKE_ROOT}/Modules/CMakeCUDACompilerABI.cu" + RESULT_VARIABLE _CUDA_ARCHS_RESULT + OUTPUT_VARIABLE _CUDA_ARCHS_OUTPUT + ERROR_VARIABLE _CUDA_ARCHS_OUTPUT + ) + if(_CUDA_ARCHS_RESULT EQUAL 0) + execute_process( + COMMAND "${_CUDA_ARCHS_EXE}" + RESULT_VARIABLE _CUDA_ARCHS_RESULT + OUTPUT_VARIABLE _CUDA_ARCHS_OUTPUT + ERROR_VARIABLE _CUDA_ARCHS_OUTPUT + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + endif() + 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(_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 _CUDA_ARCHITECTURES_NATIVE ${_CUDA_ARCH}) + endforeach() + unset(_CUDA_ARCH) + unset(_CUDA_ARCH_MIN) + unset(_CUDA_ARCH_MAX) + else() + set(_CUDA_ARCHITECTURES_NATIVE "${_CUDA_ARCHS_OUTPUT}") + endif() + list(REMOVE_DUPLICATES _CUDA_ARCHITECTURES_NATIVE) + 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}") + file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log + "Detecting the CUDA native architecture(s) failed with " + "the following output:\n${_CUDA_ARCHS_OUTPUT}\n\n") + set(_CUDA_ARCHS_OUTPUT "") + endif() + unset(_CUDA_ARCHS_EXE) + unset(_CUDA_ARCHS_RESULT) + unset(_CUDA_ARCHS_OUTPUT) +endif() 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.cmake b/Modules/Compiler/Clang.cmake index f885eb0..df115d3 100644 --- a/Modules/Compiler/Clang.cmake +++ b/Modules/Compiler/Clang.cmake @@ -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() diff --git a/Modules/Compiler/GNU.cmake b/Modules/Compiler/GNU.cmake index 928e726..2eef532 100644 --- a/Modules/Compiler/GNU.cmake +++ b/Modules/Compiler/GNU.cmake @@ -119,4 +119,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/SunPro-C.cmake b/Modules/Compiler/SunPro-C.cmake index c98656f..7a406ac 100644 --- a/Modules/Compiler/SunPro-C.cmake +++ b/Modules/Compiler/SunPro-C.cmake @@ -33,8 +33,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/ExternalProject.cmake b/Modules/ExternalProject.cmake index 7f16fdc..42cb7a0 100644 --- a/Modules/ExternalProject.cmake +++ b/Modules/ExternalProject.cmake @@ -353,6 +353,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 diff --git a/Modules/ExternalProject/gitupdate.cmake.in b/Modules/ExternalProject/gitupdate.cmake.in index 0de2372..7896f62 100644 --- a/Modules/ExternalProject/gitupdate.cmake.in +++ b/Modules/ExternalProject/gitupdate.cmake.in @@ -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@" for-each-ref "--format=%(upstream:short)" "${current_branch}" WORKING_DIRECTORY "@work_dir@" OUTPUT_VARIABLE upstream_branch OUTPUT_STRIP_TRAILING_WHITESPACE diff --git a/Modules/FindBLAS.cmake b/Modules/FindBLAS.cmake index e3bf8f9..7a381af 100644 --- a/Modules/FindBLAS.cmake +++ b/Modules/FindBLAS.cmake @@ -273,8 +273,8 @@ endif() include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) if(BLA_PREFER_PKGCONFIG) - find_package(PkgConfig) - pkg_check_modules(PKGC_BLAS blas) + find_package(PkgConfig QUIET) + pkg_check_modules(PKGC_BLAS QUIET blas) if(PKGC_BLAS_FOUND) set(BLAS_FOUND ${PKGC_BLAS_FOUND}) set(BLAS_LIBRARIES "${PKGC_BLAS_LINK_LIBRARIES}") diff --git a/Modules/FindGLUT.cmake b/Modules/FindGLUT.cmake index fe274de..43041c5 100644 --- a/Modules/FindGLUT.cmake +++ b/Modules/FindGLUT.cmake @@ -94,9 +94,12 @@ function(_add_glut_target_simple) IMPORTED_LOCATION "${GLUT_glut_LIBRARY}") endfunction() -find_package(PkgConfig) +find_package(PkgConfig QUIET) if(PKG_CONFIG_FOUND) - pkg_check_modules(GLUT glut) + pkg_check_modules(GLUT QUIET glut) + if(NOT GLUT_FOUND) + pkg_check_modules(GLUT QUIET freeglut) + endif() if(GLUT_FOUND) # GLUT_INCLUDE_DIRS is now the official result variable, but # older versions of CMake only provided GLUT_INCLUDE_DIR. @@ -111,7 +114,7 @@ if(WIN32) find_path( GLUT_INCLUDE_DIR NAMES GL/glut.h PATHS ${GLUT_ROOT_PATH}/include ) 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 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/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..46ad015 100644 --- a/Modules/FindHDF5.cmake +++ b/Modules/FindHDF5.cmake @@ -555,8 +555,8 @@ if(NOT HDF5_FOUND AND NOT HDF5_NO_FIND_PACKAGE_CONFIG_FILE) endif() if( _hdf5_lang_location ) set(HDF5_${_lang}_LIBRARY ${_hdf5_lang_location}) - list(APPEND HDF5_LIBRARIES ${HDF5_${_lang}_TARGET}${_suffix}) - set(HDF5_${_lang}_LIBRARIES ${HDF5_${_lang}_TARGET}${_suffix}) + list(APPEND HDF5_LIBRARIES ${HDF5_${_lang}_LIBRARY}) + set(HDF5_${_lang}_LIBRARIES ${HDF5_${_lang}_LIBRARY}) set(HDF5_${_lang}_FOUND TRUE) endif() if(HDF5_FIND_HL) @@ -569,8 +569,8 @@ if(NOT HDF5_FOUND AND NOT HDF5_NO_FIND_PACKAGE_CONFIG_FILE) endif() if( _hdf5_lang_hl_location ) set(HDF5_${_lang}_HL_LIBRARY ${_hdf5_lang_hl_location}) - list(APPEND HDF5_HL_LIBRARIES ${HDF5_${_lang}_HL_TARGET}${_suffix}) - set(HDF5_${_lang}_HL_LIBRARIES ${HDF5_${_lang}_HL_TARGET}${_suffix}) + list(APPEND HDF5_HL_LIBRARIES ${HDF5_${_lang}_HL_LIBRARY}) + set(HDF5_${_lang}_HL_LIBRARIES ${HDF5_${_lang}_HL_LIBRARY}) set(HDF5_HL_FOUND TRUE) endif() unset(_hdf5_lang_hl_location) diff --git a/Modules/FindJNI.cmake b/Modules/FindJNI.cmake index e4f60b3..96f136a 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_ANDROID_API 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_ANDROID_API 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 @@ -328,10 +417,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) @@ -350,11 +448,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 @@ -364,11 +497,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) @@ -378,12 +550,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 @@ -393,13 +588,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/FindLAPACK.cmake b/Modules/FindLAPACK.cmake index 5540965..50d4ebd 100644 --- a/Modules/FindLAPACK.cmake +++ b/Modules/FindLAPACK.cmake @@ -278,8 +278,8 @@ endif() # Search with pkg-config if specified if(BLA_PREFER_PKGCONFIG) - find_package(PkgConfig) - pkg_check_modules(PKGC_LAPACK lapack) + find_package(PkgConfig QUIET) + pkg_check_modules(PKGC_LAPACK QUIET lapack) if(PKGC_LAPACK_FOUND) set(LAPACK_FOUND TRUE) set(LAPACK_LIBRARIES "${PKGC_LAPACK_LINK_LIBRARIES}") diff --git a/Modules/FindMatlab.cmake b/Modules/FindMatlab.cmake index 17c1fa1..48ef5eb 100644 --- a/Modules/FindMatlab.cmake +++ b/Modules/FindMatlab.cmake @@ -769,6 +769,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,21 +790,57 @@ 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() - return() + 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 successful, read back the log @@ -928,6 +968,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 +991,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 +1020,7 @@ endfunction() [LINK_TO target1 target2 ...] [R2017b | R2018a] [EXCLUDE_FROM_ALL] + [NO_IMPLICIT_LINK_TO_MATLAB_LIBRARIES] [...] ) @@ -978,7 +1030,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 +1067,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 +1099,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) @@ -1112,16 +1171,19 @@ function(matlab_add_mex) target_include_directories(${${prefix}_NAME} 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 "" 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/FindZLIB.cmake b/Modules/FindZLIB.cmake index 5778b03..4af842a 100644 --- a/Modules/FindZLIB.cmake +++ b/Modules/FindZLIB.cmake @@ -53,6 +53,11 @@ 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``. + #]=======================================================================] set(_ZLIB_SEARCHES) @@ -72,8 +77,8 @@ 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) +set(ZLIB_NAMES z zlib zdll zlib1 zlibstatic zlibstat zlibvc) +set(ZLIB_NAMES_DEBUG zd zlibd zdlld zlibd1 zlib1d zlibstaticd zlibstatd zlibvcd) # Try each search configuration. foreach(search ${_ZLIB_SEARCHES}) @@ -82,11 +87,26 @@ endforeach() # Allow ZLIB_LIBRARY to be set manually, as the location of the zlib library if(NOT ZLIB_LIBRARY) + # Support preference of static libs by adjusting CMAKE_FIND_LIBRARY_SUFFIXES + if(ZLIB_USE_STATIC_LIBS) + set(_zlib_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES}) + 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(ZLIB_USE_STATIC_LIBS) + set(CMAKE_FIND_LIBRARY_SUFFIXES ${_zlib_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES}) + endif() + include(${CMAKE_CURRENT_LIST_DIR}/SelectLibraryConfigurations.cmake) select_library_configurations(ZLIB) endif() diff --git a/Modules/FindwxWidgets.cmake b/Modules/FindwxWidgets.cmake index 63af9b6..f7996ba 100644 --- a/Modules/FindwxWidgets.cmake +++ b/Modules/FindwxWidgets.cmake @@ -218,7 +218,7 @@ endif() #===================================================================== # Determine whether unix or win32 paths should be used #===================================================================== -if(WIN32 AND NOT CYGWIN AND NOT MSYS AND NOT CMAKE_CROSSCOMPILING) +if(WIN32 AND NOT CYGWIN AND NOT MSYS AND NOT MINGW AND NOT CMAKE_CROSSCOMPILING) set(wxWidgets_FIND_STYLE "win32") else() set(wxWidgets_FIND_STYLE "unix") diff --git a/Modules/Internal/CPack/CPackRPM.cmake b/Modules/Internal/CPack/CPackRPM.cmake index c72bf6d..cd631b8 100644 --- a/Modules/Internal/CPack/CPackRPM.cmake +++ b/Modules/Internal/CPack/CPackRPM.cmake @@ -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() 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/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/Darwin.cmake b/Modules/Platform/Darwin.cmake index 839dc81..ec88a37 100644 --- a/Modules/Platform/Darwin.cmake +++ b/Modules/Platform/Darwin.cmake @@ -103,11 +103,38 @@ foreach(lang C CXX Fortran OBJC OBJCXX) set(CMAKE_${lang}_CREATE_MACOSX_FRAMEWORK "<CMAKE_${lang}_COMPILER> <LANGUAGE_COMPILE_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS> <LINK_FLAGS> -o <TARGET> <SONAME_FLAG> <TARGET_INSTALLNAME_DIR><TARGET_SONAME> <OBJECTS> <LINK_LIBRARIES>") - # Set default framework search path flag for languages known to use a - # preprocessor that may find headers in frameworks. - set(CMAKE_${lang}_FRAMEWORK_SEARCH_FLAG -F) +# Set default framework search path flag for languages known to use a +# preprocessor that may find headers in frameworks. +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<LIB_ITEM>}") +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<LIB_ITEM>}") +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<LIB_ITEM>}") +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/FreeBSD.cmake b/Modules/Platform/FreeBSD.cmake index 4a4c00d..bd5a786 100644 --- a/Modules/Platform/FreeBSD.cmake +++ b/Modules/Platform/FreeBSD.cmake @@ -26,4 +26,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.cmake b/Modules/Platform/Linux.cmake index b5d5464..a7e58ab 100644 --- a/Modules/Platform/Linux.cmake +++ b/Modules/Platform/Linux.cmake @@ -19,6 +19,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 diff --git a/Modules/Platform/NetBSD.cmake b/Modules/Platform/NetBSD.cmake index d99cb4a..ab85923 100644 --- a/Modules/Platform/NetBSD.cmake +++ b/Modules/Platform/NetBSD.cmake @@ -12,4 +12,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/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/Windows-Clang.cmake b/Modules/Platform/Windows-Clang.cmake index e7e975d..7600c8d 100644 --- a/Modules/Platform/Windows-Clang.cmake +++ b/Modules/Platform/Windows-Clang.cmake @@ -113,6 +113,13 @@ macro(__windows_compiler_clang_gnu lang) 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() diff --git a/Modules/Platform/Windows-GNU.cmake b/Modules/Platform/Windows-GNU.cmake index 51dc146..b464169 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. diff --git a/Modules/Platform/Windows-MSVC.cmake b/Modules/Platform/Windows-MSVC.cmake index b2cc6f4..e74ec9e 100644 --- a/Modules/Platform/Windows-MSVC.cmake +++ b/Modules/Platform/Windows-MSVC.cmake @@ -331,6 +331,15 @@ else() endif() unset(__WINDOWS_MSVC_CMP0091) + +# 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 |