diff options
Diffstat (limited to 'Modules')
137 files changed, 4484 insertions, 1172 deletions
diff --git a/Modules/CMakeASMInformation.cmake b/Modules/CMakeASMInformation.cmake index 125c4e3..6b73730 100644 --- a/Modules/CMakeASMInformation.cmake +++ b/Modules/CMakeASMInformation.cmake @@ -29,15 +29,15 @@ if(NOT _INCLUDED_FILE) endif() if(CMAKE_SYSTEM_PROCESSOR) - include(Platform/${CMAKE_SYSTEM_NAME}-${CMAKE_ASM${ASM_DIALECT}_COMPILER_ID}-ASM${ASM_DIALECT}-${CMAKE_SYSTEM_PROCESSOR} OPTIONAL RESULT_VARIABLE _INCLUDED_FILE) + include(Platform/${CMAKE_EFFECTIVE_SYSTEM_NAME}-${CMAKE_ASM${ASM_DIALECT}_COMPILER_ID}-ASM${ASM_DIALECT}-${CMAKE_SYSTEM_PROCESSOR} OPTIONAL RESULT_VARIABLE _INCLUDED_FILE) if(NOT _INCLUDED_FILE) - include(Platform/${CMAKE_SYSTEM_NAME}-${CMAKE_BASE_NAME}-${CMAKE_SYSTEM_PROCESSOR} OPTIONAL) + include(Platform/${CMAKE_EFFECTIVE_SYSTEM_NAME}-${CMAKE_BASE_NAME}-${CMAKE_SYSTEM_PROCESSOR} OPTIONAL) endif() endif() -include(Platform/${CMAKE_SYSTEM_NAME}-${CMAKE_ASM${ASM_DIALECT}_COMPILER_ID}-ASM${ASM_DIALECT} OPTIONAL RESULT_VARIABLE _INCLUDED_FILE) +include(Platform/${CMAKE_EFFECTIVE_SYSTEM_NAME}-${CMAKE_ASM${ASM_DIALECT}_COMPILER_ID}-ASM${ASM_DIALECT} OPTIONAL RESULT_VARIABLE _INCLUDED_FILE) if(NOT _INCLUDED_FILE) - include(Platform/${CMAKE_SYSTEM_NAME}-${CMAKE_BASE_NAME} OPTIONAL) + include(Platform/${CMAKE_EFFECTIVE_SYSTEM_NAME}-${CMAKE_BASE_NAME} OPTIONAL) endif() # This should be included before the _INIT variables are diff --git a/Modules/CMakeCInformation.cmake b/Modules/CMakeCInformation.cmake index 1e46cac..df43559 100644 --- a/Modules/CMakeCInformation.cmake +++ b/Modules/CMakeCInformation.cmake @@ -35,21 +35,21 @@ endif() # load a hardware specific file, mostly useful for embedded compilers if(CMAKE_SYSTEM_PROCESSOR) if(CMAKE_C_COMPILER_ID) - include(Platform/${CMAKE_SYSTEM_NAME}-${CMAKE_C_COMPILER_ID}-C-${CMAKE_SYSTEM_PROCESSOR} OPTIONAL RESULT_VARIABLE _INCLUDED_FILE) + include(Platform/${CMAKE_EFFECTIVE_SYSTEM_NAME}-${CMAKE_C_COMPILER_ID}-C-${CMAKE_SYSTEM_PROCESSOR} OPTIONAL RESULT_VARIABLE _INCLUDED_FILE) endif() if (NOT _INCLUDED_FILE) - include(Platform/${CMAKE_SYSTEM_NAME}-${CMAKE_BASE_NAME}-${CMAKE_SYSTEM_PROCESSOR} OPTIONAL) + include(Platform/${CMAKE_EFFECTIVE_SYSTEM_NAME}-${CMAKE_BASE_NAME}-${CMAKE_SYSTEM_PROCESSOR} OPTIONAL) endif () endif() # load the system- and compiler specific files if(CMAKE_C_COMPILER_ID) - include(Platform/${CMAKE_SYSTEM_NAME}-${CMAKE_C_COMPILER_ID}-C + include(Platform/${CMAKE_EFFECTIVE_SYSTEM_NAME}-${CMAKE_C_COMPILER_ID}-C OPTIONAL RESULT_VARIABLE _INCLUDED_FILE) endif() if (NOT _INCLUDED_FILE) - include(Platform/${CMAKE_SYSTEM_NAME}-${CMAKE_BASE_NAME} + include(Platform/${CMAKE_EFFECTIVE_SYSTEM_NAME}-${CMAKE_BASE_NAME} OPTIONAL RESULT_VARIABLE _INCLUDED_FILE) endif () diff --git a/Modules/CMakeCUDACompiler.cmake.in b/Modules/CMakeCUDACompiler.cmake.in index f524e5f..9761d8c 100644 --- a/Modules/CMakeCUDACompiler.cmake.in +++ b/Modules/CMakeCUDACompiler.cmake.in @@ -11,6 +11,7 @@ set(CMAKE_CUDA_SIMULATE_VERSION "@CMAKE_CUDA_SIMULATE_VERSION@") set(CMAKE_CUDA_COMPILER_ENV_VAR "CUDACXX") set(CMAKE_CUDA_HOST_COMPILER_ENV_VAR "CUDAHOSTCXX") +set(CMAKE_CUDA_COMPILER_LOADED 1) set(CMAKE_CUDA_COMPILER_ID_RUN 1) set(CMAKE_CUDA_SOURCE_FILE_EXTENSIONS cu) set(CMAKE_CUDA_LINKER_PREFERENCE 15) diff --git a/Modules/CMakeCUDACompilerId.cu.in b/Modules/CMakeCUDACompilerId.cu.in index 018bab7..6eda924 100644 --- a/Modules/CMakeCUDACompilerId.cu.in +++ b/Modules/CMakeCUDACompilerId.cu.in @@ -17,7 +17,9 @@ char const* info_simulate = "INFO" ":" "simulate[" SIMULATE_ID "]"; @CMAKE_CUDA_COMPILER_ID_ERROR_FOR_TEST@ const char* info_language_dialect_default = "INFO" ":" "dialect_default[" -#if __cplusplus > 201402L +#if __cplusplus > 201703L + "20" +#elif __cplusplus >= 201703L "17" #elif __cplusplus >= 201402L "14" diff --git a/Modules/CMakeCUDAInformation.cmake b/Modules/CMakeCUDAInformation.cmake index 167e177..479493b 100644 --- a/Modules/CMakeCUDAInformation.cmake +++ b/Modules/CMakeCUDAInformation.cmake @@ -17,9 +17,9 @@ endif() if(CMAKE_CUDA_COMPILER_ID) # load a hardware specific file, mostly useful for embedded compilers if(CMAKE_SYSTEM_PROCESSOR) - include(Platform/${CMAKE_SYSTEM_NAME}-${CMAKE_CUDA_COMPILER_ID}-CUDA-${CMAKE_SYSTEM_PROCESSOR} OPTIONAL) + include(Platform/${CMAKE_EFFECTIVE_SYSTEM_NAME}-${CMAKE_CUDA_COMPILER_ID}-CUDA-${CMAKE_SYSTEM_PROCESSOR} OPTIONAL) endif() - include(Platform/${CMAKE_SYSTEM_NAME}-${CMAKE_CUDA_COMPILER_ID}-CUDA OPTIONAL) + include(Platform/${CMAKE_EFFECTIVE_SYSTEM_NAME}-${CMAKE_CUDA_COMPILER_ID}-CUDA OPTIONAL) endif() @@ -177,17 +177,31 @@ else() set(_CMAKE_CUDA_EXTRA_DEVICE_LINK_FLAGS "") endif() +# Add implicit host link directories that contain device libraries +# to the device link line. +set(__IMPLICT_DLINK_DIRS ${CMAKE_CUDA_IMPLICIT_LINK_DIRECTORIES}) +if(__IMPLICT_DLINK_DIRS) + list(REMOVE_ITEM __IMPLICT_DLINK_DIRS ${CMAKE_CUDA_HOST_IMPLICIT_LINK_DIRECTORIES}) +endif() +set(__IMPLICT_DLINK_FLAGS ) +foreach(dir ${__IMPLICT_DLINK_DIRS}) + if(EXISTS "${dir}/libcublas_device.a") + string(APPEND __IMPLICT_DLINK_FLAGS " -L\"${dir}\"") + endif() +endforeach() +unset(__IMPLICT_DLINK_DIRS) #These are used when linking relocatable (dc) cuda code if(NOT CMAKE_CUDA_DEVICE_LINK_LIBRARY) set(CMAKE_CUDA_DEVICE_LINK_LIBRARY - "<CMAKE_CUDA_COMPILER> ${CMAKE_CUDA_HOST_FLAGS} <CMAKE_CUDA_LINK_FLAGS> <LANGUAGE_COMPILE_FLAGS> ${CMAKE_CUDA_COMPILE_OPTIONS_PIC} ${_CMAKE_CUDA_EXTRA_DEVICE_LINK_FLAGS} -shared -dlink <OBJECTS> -o <TARGET> <LINK_LIBRARIES>") + "<CMAKE_CUDA_COMPILER> ${CMAKE_CUDA_HOST_FLAGS} <CMAKE_CUDA_LINK_FLAGS> <LANGUAGE_COMPILE_FLAGS> ${CMAKE_CUDA_COMPILE_OPTIONS_PIC} ${_CMAKE_CUDA_EXTRA_DEVICE_LINK_FLAGS} -shared -dlink <OBJECTS> -o <TARGET> <LINK_LIBRARIES>${__IMPLICT_DLINK_FLAGS}") endif() if(NOT CMAKE_CUDA_DEVICE_LINK_EXECUTABLE) set(CMAKE_CUDA_DEVICE_LINK_EXECUTABLE - "<CMAKE_CUDA_COMPILER> ${CMAKE_CUDA_HOST_FLAGS} <FLAGS> <CMAKE_CUDA_LINK_FLAGS> ${CMAKE_CUDA_COMPILE_OPTIONS_PIC} ${_CMAKE_CUDA_EXTRA_DEVICE_LINK_FLAGS} -shared -dlink <OBJECTS> -o <TARGET> <LINK_LIBRARIES>") + "<CMAKE_CUDA_COMPILER> ${CMAKE_CUDA_HOST_FLAGS} <FLAGS> <CMAKE_CUDA_LINK_FLAGS> ${CMAKE_CUDA_COMPILE_OPTIONS_PIC} ${_CMAKE_CUDA_EXTRA_DEVICE_LINK_FLAGS} -shared -dlink <OBJECTS> -o <TARGET> <LINK_LIBRARIES>${__IMPLICT_DLINK_FLAGS}") endif() unset(_CMAKE_CUDA_EXTRA_DEVICE_LINK_FLAGS) +unset(__IMPLICT_DLINK_FLAGS) set(CMAKE_CUDA_INFORMATION_LOADED 1) diff --git a/Modules/CMakeCXXCompiler.cmake.in b/Modules/CMakeCXXCompiler.cmake.in index df57a4f..974886d 100644 --- a/Modules/CMakeCXXCompiler.cmake.in +++ b/Modules/CMakeCXXCompiler.cmake.in @@ -10,6 +10,7 @@ set(CMAKE_CXX98_COMPILE_FEATURES "@CMAKE_CXX98_COMPILE_FEATURES@") set(CMAKE_CXX11_COMPILE_FEATURES "@CMAKE_CXX11_COMPILE_FEATURES@") set(CMAKE_CXX14_COMPILE_FEATURES "@CMAKE_CXX14_COMPILE_FEATURES@") set(CMAKE_CXX17_COMPILE_FEATURES "@CMAKE_CXX17_COMPILE_FEATURES@") +set(CMAKE_CXX20_COMPILE_FEATURES "@CMAKE_CXX20_COMPILE_FEATURES@") set(CMAKE_CXX_PLATFORM_ID "@CMAKE_CXX_PLATFORM_ID@") set(CMAKE_CXX_SIMULATE_ID "@CMAKE_CXX_SIMULATE_ID@") diff --git a/Modules/CMakeCXXCompilerId.cpp.in b/Modules/CMakeCXXCompilerId.cpp.in index 4cb2267..34639b4 100644 --- a/Modules/CMakeCXXCompilerId.cpp.in +++ b/Modules/CMakeCXXCompilerId.cpp.in @@ -34,7 +34,9 @@ char const *info_cray = "INFO" ":" "compiler_wrapper[CrayPrgEnv]"; #endif const char* info_language_dialect_default = "INFO" ":" "dialect_default[" -#if CXX_STD > 201402L +#if CXX_STD > 201703L + "20" +#elif CXX_STD >= 201703L "17" #elif CXX_STD >= 201402L "14" diff --git a/Modules/CMakeCXXInformation.cmake b/Modules/CMakeCXXInformation.cmake index 9ac9560..2975874 100644 --- a/Modules/CMakeCXXInformation.cmake +++ b/Modules/CMakeCXXInformation.cmake @@ -36,19 +36,19 @@ endif() # load a hardware specific file, mostly useful for embedded compilers if(CMAKE_SYSTEM_PROCESSOR) if(CMAKE_CXX_COMPILER_ID) - include(Platform/${CMAKE_SYSTEM_NAME}-${CMAKE_CXX_COMPILER_ID}-CXX-${CMAKE_SYSTEM_PROCESSOR} OPTIONAL RESULT_VARIABLE _INCLUDED_FILE) + include(Platform/${CMAKE_EFFECTIVE_SYSTEM_NAME}-${CMAKE_CXX_COMPILER_ID}-CXX-${CMAKE_SYSTEM_PROCESSOR} OPTIONAL RESULT_VARIABLE _INCLUDED_FILE) endif() if (NOT _INCLUDED_FILE) - include(Platform/${CMAKE_SYSTEM_NAME}-${CMAKE_BASE_NAME}-${CMAKE_SYSTEM_PROCESSOR} OPTIONAL) + include(Platform/${CMAKE_EFFECTIVE_SYSTEM_NAME}-${CMAKE_BASE_NAME}-${CMAKE_SYSTEM_PROCESSOR} OPTIONAL) endif () endif() # load the system- and compiler specific files if(CMAKE_CXX_COMPILER_ID) - include(Platform/${CMAKE_SYSTEM_NAME}-${CMAKE_CXX_COMPILER_ID}-CXX OPTIONAL RESULT_VARIABLE _INCLUDED_FILE) + include(Platform/${CMAKE_EFFECTIVE_SYSTEM_NAME}-${CMAKE_CXX_COMPILER_ID}-CXX OPTIONAL RESULT_VARIABLE _INCLUDED_FILE) endif() if (NOT _INCLUDED_FILE) - include(Platform/${CMAKE_SYSTEM_NAME}-${CMAKE_BASE_NAME} OPTIONAL + include(Platform/${CMAKE_EFFECTIVE_SYSTEM_NAME}-${CMAKE_BASE_NAME} OPTIONAL RESULT_VARIABLE _INCLUDED_FILE) endif () diff --git a/Modules/CMakeDetermineCSharpCompiler.cmake b/Modules/CMakeDetermineCSharpCompiler.cmake index eb825a5..5802b15 100644 --- a/Modules/CMakeDetermineCSharpCompiler.cmake +++ b/Modules/CMakeDetermineCSharpCompiler.cmake @@ -1,7 +1,7 @@ # Distributed under the OSI-approved BSD 3-Clause License. See accompanying # file Copyright.txt or https://cmake.org/licensing for details. -if(NOT ${CMAKE_GENERATOR} MATCHES "Visual Studio ([^89]|[89][0-9])") +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.") endif() diff --git a/Modules/CMakeDetermineCUDACompiler.cmake b/Modules/CMakeDetermineCUDACompiler.cmake index f5a3ebd..113b520 100644 --- a/Modules/CMakeDetermineCUDACompiler.cmake +++ b/Modules/CMakeDetermineCUDACompiler.cmake @@ -6,7 +6,7 @@ include(${CMAKE_ROOT}/Modules//CMakeParseImplicitLinkInfo.cmake) if( NOT ( ("${CMAKE_GENERATOR}" MATCHES "Make") OR ("${CMAKE_GENERATOR}" MATCHES "Ninja") OR - ("${CMAKE_GENERATOR}" MATCHES "Visual Studio (1|[89][0-9])") ) ) + ("${CMAKE_GENERATOR}" MATCHES "Visual Studio (1|[9][0-9])") ) ) message(FATAL_ERROR "CUDA language not currently supported by \"${CMAKE_GENERATOR}\" generator") endif() @@ -40,7 +40,6 @@ else() endif() #Allow the user to specify a host compiler -set(CMAKE_CUDA_HOST_COMPILER "" CACHE FILEPATH "Host compiler to be used by nvcc") if(NOT $ENV{CUDAHOSTCXX} STREQUAL "") get_filename_component(CMAKE_CUDA_HOST_COMPILER $ENV{CUDAHOSTCXX} PROGRAM) if(NOT EXISTS ${CMAKE_CUDA_HOST_COMPILER}) diff --git a/Modules/CMakeDetermineCompileFeatures.cmake b/Modules/CMakeDetermineCompileFeatures.cmake index 3ed92be..01a81a1 100644 --- a/Modules/CMakeDetermineCompileFeatures.cmake +++ b/Modules/CMakeDetermineCompileFeatures.cmake @@ -49,6 +49,7 @@ function(cmake_determine_compile_features lang) set(CMAKE_CXX11_COMPILE_FEATURES) set(CMAKE_CXX14_COMPILE_FEATURES) set(CMAKE_CXX17_COMPILE_FEATURES) + set(CMAKE_CXX20_COMPILE_FEATURES) include("${CMAKE_ROOT}/Modules/Internal/FeatureTesting.cmake") @@ -59,6 +60,9 @@ function(cmake_determine_compile_features lang) return() endif() + if (CMAKE_CXX17_COMPILE_FEATURES AND CMAKE_CXX20_COMPILE_FEATURES) + list(REMOVE_ITEM CMAKE_CXX20_COMPILE_FEATURES ${CMAKE_CXX17_COMPILE_FEATURES}) + endif() if (CMAKE_CXX14_COMPILE_FEATURES AND CMAKE_CXX17_COMPILE_FEATURES) list(REMOVE_ITEM CMAKE_CXX17_COMPILE_FEATURES ${CMAKE_CXX14_COMPILE_FEATURES}) endif() @@ -75,6 +79,7 @@ function(cmake_determine_compile_features lang) ${CMAKE_CXX11_COMPILE_FEATURES} ${CMAKE_CXX14_COMPILE_FEATURES} ${CMAKE_CXX17_COMPILE_FEATURES} + ${CMAKE_CXX20_COMPILE_FEATURES} ) endif() @@ -83,6 +88,7 @@ function(cmake_determine_compile_features lang) set(CMAKE_CXX11_COMPILE_FEATURES ${CMAKE_CXX11_COMPILE_FEATURES} PARENT_SCOPE) set(CMAKE_CXX14_COMPILE_FEATURES ${CMAKE_CXX14_COMPILE_FEATURES} PARENT_SCOPE) set(CMAKE_CXX17_COMPILE_FEATURES ${CMAKE_CXX17_COMPILE_FEATURES} PARENT_SCOPE) + set(CMAKE_CXX20_COMPILE_FEATURES ${CMAKE_CXX20_COMPILE_FEATURES} PARENT_SCOPE) message(STATUS "Detecting ${lang} compile features - done") endif() diff --git a/Modules/CMakeDetermineCompilerId.cmake b/Modules/CMakeDetermineCompilerId.cmake index 15c304c..ea5465a 100644 --- a/Modules/CMakeDetermineCompilerId.cmake +++ b/Modules/CMakeDetermineCompilerId.cmake @@ -52,6 +52,22 @@ function(CMAKE_DETERMINE_COMPILER_ID lang flagvar src) endforeach() endif() + # CUDA < 7.5 is missing version macros + if(lang STREQUAL "CUDA" + AND CMAKE_${lang}_COMPILER_ID STREQUAL "NVIDIA" + AND NOT CMAKE_${lang}_COMPILER_VERSION) + execute_process( + COMMAND "${CMAKE_${lang}_COMPILER}" + --version + OUTPUT_VARIABLE output ERROR_VARIABLE output + RESULT_VARIABLE result + TIMEOUT 10 + ) + if(output MATCHES [=[ V([0-9]+)\.([0-9]+)\.([0-9]+)]=]) + set(CMAKE_${lang}_COMPILER_VERSION "${CMAKE_MATCH_1}.${CMAKE_MATCH_2}.${CMAKE_MATCH_3}") + endif() + endif() + if (COMPILER_QNXNTO AND CMAKE_${lang}_COMPILER_ID STREQUAL "GNU") execute_process( COMMAND "${CMAKE_${lang}_COMPILER}" diff --git a/Modules/CMakeDetermineFortranCompiler.cmake b/Modules/CMakeDetermineFortranCompiler.cmake index cf502f6..5ddd64f 100644 --- a/Modules/CMakeDetermineFortranCompiler.cmake +++ b/Modules/CMakeDetermineFortranCompiler.cmake @@ -66,12 +66,20 @@ else() # The order is 95 or newer compilers first, then 90, # then 77 or older compilers, gnu is always last in the group, # so if you paid for a compiler it is picked by default. - set(CMAKE_Fortran_COMPILER_LIST - ftn - ifort ifc af95 af90 efc f95 pathf2003 pathf95 pgf95 pgfortran lf95 xlf95 - fort flang gfortran gfortran-4 g95 f90 pathf90 pgf90 xlf90 epcf90 fort77 - frt pgf77 xlf fl32 af77 g77 f77 nag - ) + if(CMAKE_HOST_WIN32) + set(CMAKE_Fortran_COMPILER_LIST + ifort pgf95 pgfortran lf95 fort + flang gfortran gfortran-4 g95 f90 pgf90 + pgf77 g77 f77 nag + ) + else() + set(CMAKE_Fortran_COMPILER_LIST + ftn + ifort ifc efc pgf95 pgfortran lf95 xlf95 fort + flang gfortran gfortran-4 g95 f90 pgf90 + frt pgf77 xlf g77 f77 nag + ) + endif() # Vendor-specific compiler names. set(_Fortran_COMPILER_NAMES_GNU gfortran gfortran-4 g95 g77) diff --git a/Modules/CMakeFindBinUtils.cmake b/Modules/CMakeFindBinUtils.cmake index ece0547..1b6823c 100644 --- a/Modules/CMakeFindBinUtils.cmake +++ b/Modules/CMakeFindBinUtils.cmake @@ -19,6 +19,25 @@ # on UNIX, cygwin and mingw +if(CMAKE_LINKER) + # we only get here if CMAKE_LINKER was specified using -D or a pre-made CMakeCache.txt + # (e.g. via ctest) or set in CMAKE_TOOLCHAIN_FILE + # find the linker in the PATH if necessary + get_filename_component(_CMAKE_USER_LINKER_PATH "${CMAKE_LINKER}" PATH) + if(NOT _CMAKE_USER_LINKER_PATH) + find_program(CMAKE_LINKER_WITH_PATH NAMES ${CMAKE_LINKER} HINTS ${_CMAKE_TOOLCHAIN_LOCATION}) + if(CMAKE_LINKER_WITH_PATH) + set(CMAKE_LINKER ${CMAKE_LINKER_WITH_PATH}) + get_property(_CMAKE_LINKER_CACHED CACHE CMAKE_LINKER PROPERTY TYPE) + if(_CMAKE_LINKER_CACHED) + set(CMAKE_LINKER "${CMAKE_LINKER}" CACHE STRING "Default Linker" FORCE) + endif() + unset(_CMAKE_LINKER_CACHED) + endif() + unset(CMAKE_LINKER_WITH_PATH CACHE) + endif() +endif() + # if it's the MS C/CXX compiler, search for link if("x${CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_SIMULATE_ID}" STREQUAL "xMSVC" OR "x${CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_ID}" STREQUAL "xMSVC" diff --git a/Modules/CMakeFindPackageMode.cmake b/Modules/CMakeFindPackageMode.cmake index 7c41d49..ec3652c 100644 --- a/Modules/CMakeFindPackageMode.cmake +++ b/Modules/CMakeFindPackageMode.cmake @@ -65,6 +65,8 @@ if("${CMAKE_SYSTEM_NAME}" MATCHES Darwin AND "${COMPILER_ID}" MATCHES GNU) set(CMAKE_${LANGUAGE}_OSX_DEPLOYMENT_TARGET_FLAG "") endif() +include(CMakeSystemSpecificInitialize) + # Also load the system specific file, which sets up e.g. the search paths. # This makes the FIND_XXX() calls work much better include(CMakeSystemSpecificInformation) diff --git a/Modules/CMakeFortranCompiler.cmake.in b/Modules/CMakeFortranCompiler.cmake.in index 2e34cbb..9b951fc 100644 --- a/Modules/CMakeFortranCompiler.cmake.in +++ b/Modules/CMakeFortranCompiler.cmake.in @@ -31,7 +31,7 @@ if(CMAKE_COMPILER_IS_MINGW) set(MINGW 1) endif() set(CMAKE_Fortran_COMPILER_ID_RUN 1) -set(CMAKE_Fortran_SOURCE_FILE_EXTENSIONS f;F;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) 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/CMakeFortranInformation.cmake b/Modules/CMakeFortranInformation.cmake index 5f028e4..cceac83 100644 --- a/Modules/CMakeFortranInformation.cmake +++ b/Modules/CMakeFortranInformation.cmake @@ -22,10 +22,10 @@ if(CMAKE_COMPILER_IS_GNUG77) set(CMAKE_BASE_NAME g77) endif() if(CMAKE_Fortran_COMPILER_ID) - include(Platform/${CMAKE_SYSTEM_NAME}-${CMAKE_Fortran_COMPILER_ID}-Fortran OPTIONAL RESULT_VARIABLE _INCLUDED_FILE) + include(Platform/${CMAKE_EFFECTIVE_SYSTEM_NAME}-${CMAKE_Fortran_COMPILER_ID}-Fortran OPTIONAL RESULT_VARIABLE _INCLUDED_FILE) endif() if (NOT _INCLUDED_FILE) - include(Platform/${CMAKE_SYSTEM_NAME}-${CMAKE_BASE_NAME} OPTIONAL + include(Platform/${CMAKE_EFFECTIVE_SYSTEM_NAME}-${CMAKE_BASE_NAME} OPTIONAL RESULT_VARIABLE _INCLUDED_FILE) endif () diff --git a/Modules/CMakeLanguageInformation.cmake b/Modules/CMakeLanguageInformation.cmake index 18c8624..674ab86 100644 --- a/Modules/CMakeLanguageInformation.cmake +++ b/Modules/CMakeLanguageInformation.cmake @@ -9,10 +9,10 @@ macro(__cmake_include_compiler_wrapper lang) set(_INCLUDED_WRAPPER_FILE 0) if (CMAKE_${lang}_COMPILER_ID) - include(Platform/${CMAKE_SYSTEM_NAME}-${CMAKE_${lang}_COMPILER_WRAPPER}-${CMAKE_${lang}_COMPILER_ID}-${lang} OPTIONAL RESULT_VARIABLE _INCLUDED_WRAPPER_FILE) + include(Platform/${CMAKE_EFFECTIVE_SYSTEM_NAME}-${CMAKE_${lang}_COMPILER_WRAPPER}-${CMAKE_${lang}_COMPILER_ID}-${lang} OPTIONAL RESULT_VARIABLE _INCLUDED_WRAPPER_FILE) endif() if (NOT _INCLUDED_WRAPPER_FILE) - include(Platform/${CMAKE_SYSTEM_NAME}-${CMAKE_${lang}_COMPILER_WRAPPER}-${lang} OPTIONAL RESULT_VARIABLE _INCLUDED_WRAPPER_FILE) + include(Platform/${CMAKE_EFFECTIVE_SYSTEM_NAME}-${CMAKE_${lang}_COMPILER_WRAPPER}-${lang} OPTIONAL RESULT_VARIABLE _INCLUDED_WRAPPER_FILE) endif () # No platform - wrapper - lang information so maybe there's just wrapper - lang information diff --git a/Modules/CMakeSwiftInformation.cmake b/Modules/CMakeSwiftInformation.cmake index d9b408d..07ba6d0 100644 --- a/Modules/CMakeSwiftInformation.cmake +++ b/Modules/CMakeSwiftInformation.cmake @@ -14,9 +14,9 @@ endif() if(CMAKE_Swift_COMPILER_ID) # load a hardware specific file, mostly useful for embedded compilers if(CMAKE_SYSTEM_PROCESSOR) - include(Platform/${CMAKE_SYSTEM_NAME}-${CMAKE_Swift_COMPILER_ID}-Swift-${CMAKE_SYSTEM_PROCESSOR} OPTIONAL) + include(Platform/${CMAKE_EFFECTIVE_SYSTEM_NAME}-${CMAKE_Swift_COMPILER_ID}-Swift-${CMAKE_SYSTEM_PROCESSOR} OPTIONAL) endif() - include(Platform/${CMAKE_SYSTEM_NAME}-${CMAKE_Swift_COMPILER_ID}-Swift OPTIONAL) + include(Platform/${CMAKE_EFFECTIVE_SYSTEM_NAME}-${CMAKE_Swift_COMPILER_ID}-Swift OPTIONAL) endif() # for most systems a module is the same as a shared library diff --git a/Modules/CMakeSystemSpecificInitialize.cmake b/Modules/CMakeSystemSpecificInitialize.cmake index 6200e9c..de4d7f5 100644 --- a/Modules/CMakeSystemSpecificInitialize.cmake +++ b/Modules/CMakeSystemSpecificInitialize.cmake @@ -5,6 +5,19 @@ # This file is included by cmGlobalGenerator::EnableLanguage. # It is included before the compiler has been determined. +# The CMAKE_EFFECTIVE_SYSTEM_NAME is used to load compiler and compiler +# wrapper configuration files. By default it equals to CMAKE_SYSTEM_NAME +# but could be overridden in the ${CMAKE_SYSTEM_NAME}-Initialize files. +# +# It is useful to share the same aforementioned configuration files and +# avoids duplicating them in case of tightly related platforms. +# +# An example are the platforms supported by Xcode (macOS, iOS, tvOS, +# and watchOS). For all of those the CMAKE_EFFECTIVE_SYSTEM_NAME is +# set to Apple which results in using +# Platfom/Apple-AppleClang-CXX.cmake for the Apple C++ compiler. +set(CMAKE_EFFECTIVE_SYSTEM_NAME "${CMAKE_SYSTEM_NAME}") + include(Platform/${CMAKE_SYSTEM_NAME}-Initialize OPTIONAL) set(CMAKE_SYSTEM_SPECIFIC_INITIALIZE_LOADED 1) diff --git a/Modules/CMakeTestCSharpCompiler.cmake b/Modules/CMakeTestCSharpCompiler.cmake index f3b95fd..6715c30 100644 --- a/Modules/CMakeTestCSharpCompiler.cmake +++ b/Modules/CMakeTestCSharpCompiler.cmake @@ -15,7 +15,7 @@ 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 that selected C# compiler can actually compile +# determine that the selected C# compiler can actually compile # and link the most basic of programs. If not, a fatal error # is set and cmake stops processing commands and will not generate # any makefiles or projects. diff --git a/Modules/CMakeTestCUDACompiler.cmake b/Modules/CMakeTestCUDACompiler.cmake index df5ec72..f0454da 100644 --- a/Modules/CMakeTestCUDACompiler.cmake +++ b/Modules/CMakeTestCUDACompiler.cmake @@ -15,7 +15,7 @@ include(CMakeTestCompilerCommon) unset(CMAKE_CUDA_COMPILER_WORKS CACHE) # This file is used by EnableLanguage in cmGlobalGenerator to -# determine that that selected cuda compiler can actually compile +# determine that the selected cuda compiler can actually compile # and link the most basic of programs. If not, a fatal error # is set and cmake stops processing commands and will not generate # any makefiles or projects. diff --git a/Modules/CMakeTestCXXCompiler.cmake b/Modules/CMakeTestCXXCompiler.cmake index 7b80dc0..e4d49ae 100644 --- a/Modules/CMakeTestCXXCompiler.cmake +++ b/Modules/CMakeTestCXXCompiler.cmake @@ -16,7 +16,7 @@ include(CMakeTestCompilerCommon) unset(CMAKE_CXX_COMPILER_WORKS CACHE) # This file is used by EnableLanguage in cmGlobalGenerator to -# determine that that selected C++ compiler can actually compile +# determine that the selected C++ compiler can actually compile # and link the most basic of programs. If not, a fatal error # is set and cmake stops processing commands and will not generate # any makefiles or projects. diff --git a/Modules/CMakeTestFortranCompiler.cmake b/Modules/CMakeTestFortranCompiler.cmake index 3c150a8..e9860e9 100644 --- a/Modules/CMakeTestFortranCompiler.cmake +++ b/Modules/CMakeTestFortranCompiler.cmake @@ -16,7 +16,7 @@ include(CMakeTestCompilerCommon) unset(CMAKE_Fortran_COMPILER_WORKS CACHE) # This file is used by EnableLanguage in cmGlobalGenerator to -# determine that that selected Fortran compiler can actually compile +# determine that the selected Fortran compiler can actually compile # and link the most basic of programs. If not, a fatal error # is set and cmake stops processing commands and will not generate # any makefiles or projects. diff --git a/Modules/CMakeTestJavaCompiler.cmake b/Modules/CMakeTestJavaCompiler.cmake index 23fdbdc..3c33573 100644 --- a/Modules/CMakeTestJavaCompiler.cmake +++ b/Modules/CMakeTestJavaCompiler.cmake @@ -3,7 +3,7 @@ # This file is used by EnableLanguage in cmGlobalGenerator to -# determine that that selected Fortran compiler can actually compile +# determine that the selected Fortran compiler can actually compile # and link the most basic of programs. If not, a fatal error # is set and cmake stops processing commands and will not generate # any makefiles or projects. diff --git a/Modules/CMakeTestRCCompiler.cmake b/Modules/CMakeTestRCCompiler.cmake index c510d3a..3123a6c 100644 --- a/Modules/CMakeTestRCCompiler.cmake +++ b/Modules/CMakeTestRCCompiler.cmake @@ -3,7 +3,7 @@ # This file is used by EnableLanguage in cmGlobalGenerator to -# determine that that selected RC compiler can actually compile +# determine that the selected RC compiler can actually compile # and link the most basic of programs. If not, a fatal error # is set and cmake stops processing commands and will not generate # any makefiles or projects. diff --git a/Modules/CMakeTestSwiftCompiler.cmake b/Modules/CMakeTestSwiftCompiler.cmake index bcd5c33..858c1be 100644 --- a/Modules/CMakeTestSwiftCompiler.cmake +++ b/Modules/CMakeTestSwiftCompiler.cmake @@ -16,7 +16,7 @@ include(CMakeTestCompilerCommon) unset(CMAKE_Swift_COMPILER_WORKS CACHE) # This file is used by EnableLanguage in cmGlobalGenerator to -# determine that that selected C++ compiler can actually compile +# determine that the selected C++ compiler can actually compile # and link the most basic of programs. If not, a fatal error # is set and cmake stops processing commands and will not generate # any makefiles or projects. diff --git a/Modules/CPack.NuGet.nuspec.in b/Modules/CPack.NuGet.nuspec.in new file mode 100644 index 0000000..b7beb5d --- /dev/null +++ b/Modules/CPack.NuGet.nuspec.in @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="utf-8"?> +<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd"> + <metadata> + <!-- Required elements--> + <id>@CPACK_NUGET_PACKAGE_NAME@</id> + <version>@CPACK_NUGET_PACKAGE_VERSION@</version> + <description>@CPACK_NUGET_PACKAGE_DESCRIPTION@</description> + <authors>@CPACK_NUGET_PACKAGE_AUTHORS@</authors> + + <!-- Optional elements --> + @_CPACK_NUGET_TITLE_TAG@ + @_CPACK_NUGET_OWNERS_TAG@ + @_CPACK_NUGET_PROJECTURL_TAG@ + @_CPACK_NUGET_LICENSEURL_TAG@ + @_CPACK_NUGET_ICONURL_TAG@ + @_CPACK_NUGET_REQUIRELICENSEACCEPTANCE_TAG@ + @_CPACK_NUGET_SUMMARY_TAG@ + @_CPACK_NUGET_RELEASENOTES_TAG@ + @_CPACK_NUGET_COPYRIGHT_TAG@ + @_CPACK_NUGET_TAGS_TAG@ + @_CPACK_NUGET_DEPENDENCIES_TAG@ + </metadata> + @_CPACK_NUGET_FILES_TAG@ +</package> diff --git a/Modules/CPack.cmake b/Modules/CPack.cmake index 9216fc9..8070869 100644 --- a/Modules/CPack.cmake +++ b/Modules/CPack.cmake @@ -1,299 +1,342 @@ # Distributed under the OSI-approved BSD 3-Clause License. See accompanying # file Copyright.txt or https://cmake.org/licensing for details. -#.rst: -# CPack -# ----- -# -# Build binary and source package installers. -# -# Variables common to all CPack generators -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -# -# The -# CPack module generates binary and source installers in a variety of -# formats using the cpack program. Inclusion of the CPack module adds -# two new targets to the resulting makefiles, package and -# package_source, which build the binary and source installers, -# respectively. The generated binary installers contain everything -# installed via CMake's INSTALL command (and the deprecated -# INSTALL_FILES, INSTALL_PROGRAMS, and INSTALL_TARGETS commands). -# -# For certain kinds of binary installers (including the graphical -# installers on Mac OS X and Windows), CPack generates installers that -# allow users to select individual application components to install. -# See CPackComponent module for that. -# -# The CPACK_GENERATOR variable has different meanings in different -# contexts. In your CMakeLists.txt file, CPACK_GENERATOR is a *list of -# generators*: when run with no other arguments, CPack will iterate over -# that list and produce one package for each generator. In a -# CPACK_PROJECT_CONFIG_FILE, though, CPACK_GENERATOR is a *string naming -# a single generator*. If you need per-cpack- generator logic to -# control *other* cpack settings, then you need a -# CPACK_PROJECT_CONFIG_FILE. -# -# The CMake source tree itself contains a CPACK_PROJECT_CONFIG_FILE. -# See the top level file CMakeCPackOptions.cmake.in for an example. -# -# If set, the CPACK_PROJECT_CONFIG_FILE is included automatically on a -# per-generator basis. It only need contain overrides. -# -# Here's how it works: -# -# * cpack runs -# * it includes CPackConfig.cmake -# * it iterates over the generators listed in that file's -# CPACK_GENERATOR list variable (unless told to use just a -# specific one via -G on the command line...) -# * foreach generator, it then -# -# - sets CPACK_GENERATOR to the one currently being iterated -# - includes the CPACK_PROJECT_CONFIG_FILE -# - produces the package for that generator -# -# This is the key: For each generator listed in CPACK_GENERATOR in -# CPackConfig.cmake, cpack will *reset* CPACK_GENERATOR internally to -# *the one currently being used* and then include the -# CPACK_PROJECT_CONFIG_FILE. -# -# Before including this CPack module in your CMakeLists.txt file, there -# are a variety of variables that can be set to customize the resulting -# installers. The most commonly-used variables are: -# -# .. variable:: CPACK_PACKAGE_NAME -# -# The name of the package (or application). If not specified, defaults to -# the project name. -# -# .. variable:: CPACK_PACKAGE_VENDOR -# -# The name of the package vendor. (e.g., "Kitware"). Default is "Humanity". -# -# .. variable:: CPACK_PACKAGE_DIRECTORY -# -# The directory in which CPack is doing its packaging. If it is not set -# then this will default (internally) to the build dir. This variable may -# be defined in CPack config file or from the cpack command line option -# "-B". If set the command line option override the value found in the -# config file. -# -# .. variable:: CPACK_PACKAGE_VERSION_MAJOR -# -# Package major Version. Default value is 0. -# -# .. variable:: CPACK_PACKAGE_VERSION_MINOR -# -# Package minor Version. Default value is 1. -# -# .. variable:: CPACK_PACKAGE_VERSION_PATCH -# -# Package patch Version. Default value is 1. -# -# .. variable:: CPACK_PACKAGE_DESCRIPTION_FILE -# -# A text file used to describe the project. Used, for example, the -# introduction screen of a CPack-generated Windows installer to describe -# the project. -# -# .. variable:: CPACK_PACKAGE_DESCRIPTION_SUMMARY -# -# Short description of the project (only a few words). Default value is:: -# -# ${PROJECT_DESCRIPTION} -# -# if DESCRIPTION has given to the project() call or -# CMake generated string with PROJECT_NAME otherwise. -# -# .. variable:: CPACK_PACKAGE_FILE_NAME -# -# The name of the package file to generate, not including the -# extension. For example, cmake-2.6.1-Linux-i686. The default value is:: -# -# ${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}-${CPACK_SYSTEM_NAME}. -# -# .. variable:: CPACK_PACKAGE_INSTALL_DIRECTORY -# -# Installation directory on the target system. This may be used by some -# CPack generators like NSIS to create an installation directory e.g., -# "CMake 2.5" below the installation prefix. All installed element will be -# put inside this directory. -# -# .. variable:: CPACK_PACKAGE_ICON -# -# A branding image that will be displayed inside the installer (used by GUI -# installers). -# -# .. variable:: CPACK_PACKAGE_CHECKSUM -# -# An algorithm that will be used to generate additional file with checksum -# of the package. Output file name will be:: -# -# ${CPACK_PACKAGE_FILE_NAME}.${CPACK_PACKAGE_CHECKSUM} -# -# Supported algorithms are those listed by the -# :ref:`string(\<HASH\>) <Supported Hash Algorithms>` -# command. -# -# .. variable:: CPACK_PROJECT_CONFIG_FILE -# -# CPack-time project CPack configuration file. This file included at cpack -# time, once per generator after CPack has set CPACK_GENERATOR to the -# actual generator being used. It allows per-generator setting of CPACK_* -# variables at cpack time. -# -# .. variable:: CPACK_RESOURCE_FILE_LICENSE -# -# License to be embedded in the installer. It will typically be displayed -# 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 installed file but is used by some CPack generators -# like NSIS. 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 INSTALL -# command in your CMakeLists.txt. -# -# .. variable:: CPACK_RESOURCE_FILE_README -# -# ReadMe file to be embedded in the installer. It typically describes in -# some detail the purpose of the project during the installation. Not all -# CPack generators uses this file. -# -# .. variable:: CPACK_RESOURCE_FILE_WELCOME -# -# Welcome file to be embedded in the installer. It welcomes users to this -# installer. Typically used in the graphical installers on Windows and Mac -# OS X. -# -# .. variable:: CPACK_MONOLITHIC_INSTALL -# -# Disables the component-based installation mechanism. When set the -# component specification is ignored and all installed items are put in a -# single "MONOLITHIC" package. Some CPack generators do monolithic -# packaging by default and may be asked to do component packaging by -# setting CPACK_<GENNAME>_COMPONENT_INSTALL to 1/TRUE. -# -# .. variable:: CPACK_GENERATOR -# -# List of CPack generators to use. If not specified, CPack will create a -# set of options CPACK_BINARY_<GENNAME> (e.g., CPACK_BINARY_NSIS) allowing -# the user to enable/disable individual generators. This variable may be -# used on the command line as well as in:: -# -# cpack -D CPACK_GENERATOR="ZIP;TGZ" /path/to/build/tree -# -# .. variable:: CPACK_OUTPUT_CONFIG_FILE -# -# The name of the CPack binary configuration file. This file is the CPack -# configuration generated by the CPack module for binary -# installers. Defaults to CPackConfig.cmake. -# -# .. variable:: CPACK_PACKAGE_EXECUTABLES -# -# 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 -# NSIS, WIX and OSXX11 do). -# -# .. variable:: CPACK_STRIP_FILES -# -# List of files to be stripped. Starting with CMake 2.6.0 CPACK_STRIP_FILES -# will be a boolean variable which enables stripping of all files (a list -# of files evaluates to TRUE in CMake, so this change is compatible). -# -# .. variable:: CPACK_VERBATIM_VARIABLES -# -# If set to TRUE, values of variables prefixed with CPACK_ will be escaped -# before being written to the configuration files, so that the cpack program -# receives them exactly as they were specified. If not, characters like quotes -# and backslashes can cause parsing errors or alter the value received by the -# cpack program. Defaults to FALSE for backwards compatibility. -# -# * Mandatory : NO -# * Default : FALSE -# -# The following CPack variables are specific to source packages, and -# will not affect binary packages: -# -# .. variable:: CPACK_SOURCE_PACKAGE_FILE_NAME -# -# The name of the source package. For example cmake-2.6.1. -# -# .. variable:: CPACK_SOURCE_STRIP_FILES -# -# List of files in the source tree that will be stripped. Starting with -# CMake 2.6.0 CPACK_SOURCE_STRIP_FILES will be a boolean variable which -# enables stripping of all files (a list of files evaluates to TRUE in -# CMake, so this change is compatible). -# -# .. variable:: CPACK_SOURCE_GENERATOR -# -# List of generators used for the source packages. As with CPACK_GENERATOR, -# if this is not specified then CPack will create a set of options (e.g., -# CPACK_SOURCE_ZIP) allowing users to select which packages will be -# generated. -# -# .. variable:: CPACK_SOURCE_OUTPUT_CONFIG_FILE -# -# The name of the CPack source configuration file. This file is the CPack -# configuration generated by the CPack module for source -# installers. Defaults to CPackSourceConfig.cmake. -# -# .. variable:: CPACK_SOURCE_IGNORE_FILES -# -# Pattern of files in the source tree that won't be packaged when building -# a source package. This is a list of regular expression patterns (that -# must be properly escaped), e.g., -# /CVS/;/\\.svn/;\\.swp$;\\.#;/#;.*~;cscope.* -# -# The following variables are for advanced uses of CPack: -# -# .. variable:: CPACK_CMAKE_GENERATOR -# -# What CMake generator should be used if the project is CMake -# project. Defaults to the value of CMAKE_GENERATOR few users will want to -# change this setting. -# -# .. variable:: CPACK_INSTALL_CMAKE_PROJECTS -# -# List of four values that specify what project to install. The four values -# are: Build directory, Project Name, Project Component, Directory. If -# omitted, CPack will build an installer that installs everything. -# -# .. variable:: CPACK_SYSTEM_NAME -# -# System name, defaults to the value of ${CMAKE_SYSTEM_NAME}, except on -# Windows where it will be "win32" or "win64". -# -# .. variable:: CPACK_PACKAGE_VERSION -# -# Package full version, used internally. By default, this is built from -# CPACK_PACKAGE_VERSION_MAJOR, CPACK_PACKAGE_VERSION_MINOR, and -# CPACK_PACKAGE_VERSION_PATCH. -# -# .. variable:: CPACK_TOPLEVEL_TAG -# -# Directory for the installed files. -# -# .. variable:: CPACK_INSTALL_COMMANDS -# -# Extra commands to install components. -# -# .. variable:: CPACK_INSTALLED_DIRECTORIES -# -# Extra directories to install. -# -# .. variable:: CPACK_PACKAGE_INSTALL_REGISTRY_KEY -# -# Registry key used when installing this project. This is only used by -# installer for Windows. The default value is based on the installation -# directory. -# -# .. variable:: CPACK_CREATE_DESKTOP_LINKS -# -# List of desktop links to create. -# Each desktop link requires a corresponding start menu shortcut -# as created by :variable:`CPACK_PACKAGE_EXECUTABLES`. +#[=======================================================================[.rst: +CPack +----- + +Build binary and source package installers. + +Variables common to all CPack generators +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The CPack module generates binary and source installers in a variety of +formats using the cpack program. Inclusion of the CPack module adds +two new build targets, ``package`` and ``package_source``, which build +the binary and source installers respectively. The generated binary +installers contain everything installed via CMake's :command:`install` +command (and the deprecated :command:`install_files`, +:command:`install_programs` and :command:`install_targets` commands). + +For certain kinds of binary installers (including the graphical +installers on Mac OS X and Windows), CPack generates installers that +allow users to select individual application components to install. +See :module:`CPackComponent` module for further details. + +The :variable:`CPACK_GENERATOR` variable has different meanings in different +contexts. In a ``CMakeLists.txt`` file, :variable:`CPACK_GENERATOR` is a +*list of generators*: and when :manual:`cpack <cpack(1)>` is run with no other +arguments, it will iterate over that list and produce one package for each +generator. In a :variable:`CPACK_PROJECT_CONFIG_FILE`, +:variable:`CPACK_GENERATOR` is a *string naming a single generator*. If you +need per-cpack-generator logic to control *other* cpack settings, then you +need a :variable:`CPACK_PROJECT_CONFIG_FILE`. + +The CMake source tree itself contains a :variable:`CPACK_PROJECT_CONFIG_FILE`. +See the top level file ``CMakeCPackOptions.cmake.in`` for an example. + +If set, the :variable:`CPACK_PROJECT_CONFIG_FILE` is included automatically +on a per-generator basis. It only need contain overrides. + +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`` + input file. +* foreach generator, it then + + - sets :variable:`CPACK_GENERATOR` to the one currently being iterated + - includes the :variable:`CPACK_PROJECT_CONFIG_FILE` + - produces the package for that generator + +This is the key: For each generator listed in :variable:`CPACK_GENERATOR` in +``CPackConfig.cmake``, cpack will *reset* :variable:`CPACK_GENERATOR` +internally to *the one currently being used* and then include the +:variable:`CPACK_PROJECT_CONFIG_FILE`. + +Before including this CPack module in your ``CMakeLists.txt`` file, there +are a variety of variables that can be set to customize the resulting +installers. The most commonly-used variables are: + +.. variable:: CPACK_PACKAGE_NAME + + The name of the package (or application). If not specified, it defaults to + the project name. + +.. variable:: CPACK_PACKAGE_VENDOR + + The name of the package vendor. (e.g., "Kitware"). The default is "Humanity". + +.. variable:: CPACK_PACKAGE_DIRECTORY + + The directory in which CPack is doing its packaging. If it is not set + then this will default (internally) to the build dir. This variable may + be defined in a CPack config file or from the :manual:`cpack <cpack(1)>` + command line option ``-B``. If set, the command line option overrides the + value found in the config file. + +.. variable:: CPACK_PACKAGE_VERSION_MAJOR + + Package major version. This variable will always be set, but its default + value depends on whether or not version details were given to the + :command:`project` command in the top level CMakeLists.txt file. If version + details were given, the default value will be + :variable:`CMAKE_PROJECT_VERSION_MAJOR`. If no version details were given, + a default version of 0.1.1 will be assumed, leading to + ``CPACK_PACKAGE_VERSION_MAJOR`` having a default value of 0. + +.. variable:: CPACK_PACKAGE_VERSION_MINOR + + Package minor version. The default value is determined based on whether or + not version details were given to the :command:`project` command in the top + level CMakeLists.txt file. If version details were given, the default + value will be :variable:`CMAKE_PROJECT_VERSION_MINOR`, but if no minor + version component was specified then ``CPACK_PACKAGE_VERSION_MINOR`` will be + left unset. If no project version was given at all, a default version of + 0.1.1 will be assumed, leading to ``CPACK_PACKAGE_VERSION_MINOR`` having a + default value of 1. + +.. variable:: CPACK_PACKAGE_VERSION_PATCH + + Package patch version. The default value is determined based on whether or + not version details were given to the :command:`project` command in the top + level CMakeLists.txt file. If version details were given, the default + value will be :variable:`CMAKE_PROJECT_VERSION_PATCH`, but if no patch + version component was specified then ``CPACK_PACKAGE_VERSION_PATCH`` will be + left unset. If no project version was given at all, a default version of + 0.1.1 will be assumed, leading to ``CPACK_PACKAGE_VERSION_PATCH`` having a + default value of 1. + +.. variable:: CPACK_PACKAGE_DESCRIPTION + + A description of the project, used in places such as the introduction + screen of CPack-generated Windows installers. If not set, the value of + this variable is populated from the file named by + :variable:`CPACK_PACKAGE_DESCRIPTION_FILE`. + +.. variable:: CPACK_PACKAGE_DESCRIPTION_FILE + + A text file used to describe the project when + :variable:`CPACK_PACKAGE_DESCRIPTION` is not explicitly set. The default + value for ``CPACK_PACKAGE_DESCRIPTION_FILE`` points to a built-in template + file ``Templates/CPack.GenericDescription.txt``. + +.. variable:: CPACK_PACKAGE_DESCRIPTION_SUMMARY + + Short description of the project (only a few words). If the + :variable:`CMAKE_PROJECT_DESCRIPTION` variable is set, it is used as the + default value, otherwise the default will be a string generated by CMake + based on :variable:`CMAKE_PROJECT_NAME`. + +.. variable:: CPACK_PACKAGE_HOMEPAGE_URL + + Project homepage URL. The default value is taken from the + :variable:`CMAKE_PROJECT_HOMEPAGE_URL` variable, which is set by the top + level :command:`project` command, or else the default will be empty if no + URL was provided to :command:`project`. + +.. variable:: CPACK_PACKAGE_FILE_NAME + + The name of the package file to generate, not including the + extension. For example, ``cmake-2.6.1-Linux-i686``. The default value + is:: + + ${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}-${CPACK_SYSTEM_NAME} + +.. variable:: CPACK_PACKAGE_INSTALL_DIRECTORY + + Installation directory on the target system. This may be used by some + CPack generators like NSIS to create an installation directory e.g., + "CMake 2.5" below the installation prefix. All installed elements will be + put inside this directory. + +.. variable:: CPACK_PACKAGE_ICON + + A branding image that will be displayed inside the installer (used by GUI + installers). + +.. variable:: CPACK_PACKAGE_CHECKSUM + + An algorithm that will be used to generate an additional file with the + checksum of the package. The output file name will be:: + + ${CPACK_PACKAGE_FILE_NAME}.${CPACK_PACKAGE_CHECKSUM} + + Supported algorithms are those listed by the + :ref:`string(\<HASH\>) <Supported Hash Algorithms>` command. + +.. variable:: CPACK_PROJECT_CONFIG_FILE + + CPack-time project CPack configuration file. This file is included at cpack + time, once per generator after CPack has set :variable:`CPACK_GENERATOR` + to the actual generator being used. It allows per-generator setting of + ``CPACK_*`` variables at cpack time. + +.. variable:: CPACK_RESOURCE_FILE_LICENSE + + License to be embedded in the installer. It will typically be displayed + 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 + one) along with your project, you must add an appropriate CMake + :command:`install` command in your ``CMakeLists.txt``. + +.. variable:: CPACK_RESOURCE_FILE_README + + ReadMe file to be embedded in the installer. It typically describes in + some detail the purpose of the project during the installation. Not all + CPack generators use this file. + +.. variable:: CPACK_RESOURCE_FILE_WELCOME + + Welcome file to be embedded in the installer. It welcomes users to this + installer. Typically used in the graphical installers on Windows and Mac + OS X. + +.. variable:: CPACK_MONOLITHIC_INSTALL + + Disables the component-based installation mechanism. When set, the + component specification is ignored and all installed items are put in a + single "MONOLITHIC" package. Some CPack generators do monolithic + packaging by default and may be asked to do component packaging by + setting ``CPACK_<GENNAME>_COMPONENT_INSTALL`` to ``TRUE``. + +.. variable:: CPACK_GENERATOR + + 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. + +.. variable:: CPACK_OUTPUT_CONFIG_FILE + + The name of the CPack binary configuration file. This file is the CPack + configuration generated by the CPack module for binary installers. + Defaults to ``CPackConfig.cmake``. + +.. variable:: CPACK_PACKAGE_EXECUTABLES + + 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 + NSIS, WIX and OSXX11 do). + +.. variable:: CPACK_STRIP_FILES + + List of files to be stripped. Starting with CMake 2.6.0, + ``CPACK_STRIP_FILES`` will be a boolean variable which enables + stripping of all files (a list of files evaluates to ``TRUE`` in CMake, + so this change is compatible). + +.. variable:: CPACK_VERBATIM_VARIABLES + + If set to ``TRUE``, values of variables prefixed with ``CPACK_`` will be + escaped before being written to the configuration files, so that the cpack + program receives them exactly as they were specified. If not, characters + like quotes and backslashes can cause parsing errors or alter the value + received by the cpack program. Defaults to ``FALSE`` for backwards + compatibility. + +The following CPack variables are specific to source packages, and +will not affect binary packages: + +.. variable:: CPACK_SOURCE_PACKAGE_FILE_NAME + + The name of the source package. For example ``cmake-2.6.1``. + +.. variable:: CPACK_SOURCE_STRIP_FILES + + List of files in the source tree that will be stripped. Starting with + CMake 2.6.0, ``CPACK_SOURCE_STRIP_FILES`` will be a boolean + variable which enables stripping of all files (a list of files evaluates + to ``TRUE`` in CMake, so this change is compatible). + +.. variable:: CPACK_SOURCE_GENERATOR + + List of generators used for the source packages. As with + :variable:`CPACK_GENERATOR`, if this is not specified then CPack will + create a set of options (e.g. ``CPACK_SOURCE_ZIP``) allowing + users to select which packages will be generated. + +.. variable:: CPACK_SOURCE_OUTPUT_CONFIG_FILE + + The name of the CPack source configuration file. This file is the CPack + configuration generated by the CPack module for source installers. + Defaults to ``CPackSourceConfig.cmake``. + +.. variable:: CPACK_SOURCE_IGNORE_FILES + + Pattern of files in the source tree that won't be packaged when building + a source package. This is a list of regular expression patterns (that + must be properly escaped), e.g., + ``/CVS/;/\\.svn/;\\.swp$;\\.#;/#;.*~;cscope.*`` + +The following variables are for advanced uses of CPack: + +.. variable:: CPACK_CMAKE_GENERATOR + + What CMake generator should be used if the project is a CMake + project. Defaults to the value of :variable:`CMAKE_GENERATOR`. Few users + will want to change this setting. + +.. variable:: CPACK_INSTALL_CMAKE_PROJECTS + + List of four values that specify what project to install. The four values + are: Build directory, Project Name, Project Component, Directory. If + omitted, CPack will build an installer that installs everything. + +.. variable:: CPACK_SYSTEM_NAME + + System name, defaults to the value of :variable:`CMAKE_SYSTEM_NAME`, + except on Windows where it will be ``win32`` or ``win64``. + +.. variable:: CPACK_PACKAGE_VERSION + + Package full version, used internally. By default, this is built from + :variable:`CPACK_PACKAGE_VERSION_MAJOR`, + :variable:`CPACK_PACKAGE_VERSION_MINOR`, and + :variable:`CPACK_PACKAGE_VERSION_PATCH`. + +.. variable:: CPACK_TOPLEVEL_TAG + + Directory for the installed files. + +.. variable:: CPACK_INSTALL_COMMANDS + + Extra commands to install components. + +.. variable:: CPACK_INSTALLED_DIRECTORIES + + Extra directories to install. + +.. variable:: CPACK_PACKAGE_INSTALL_REGISTRY_KEY + + Registry key used when installing this project. This is only used by + installers for Windows. The default value is based on the installation + directory. + +.. variable:: CPACK_CREATE_DESKTOP_LINKS + + List of desktop links to create. Each desktop link requires a + corresponding start menu shortcut as created by + :variable:`CPACK_PACKAGE_EXECUTABLES`. + +.. variable:: CPACK_BINARY_<GENNAME> + + CPack generated options for binary generators. The ``CPack.cmake`` module + 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. + +#]=======================================================================] # Define this var in order to avoid (or warn) concerning multiple inclusion if(CPack_CMake_INCLUDED) @@ -360,11 +403,28 @@ endfunction() # Set the package name _cpack_set_default(CPACK_PACKAGE_NAME "${CMAKE_PROJECT_NAME}") -_cpack_set_default(CPACK_PACKAGE_VERSION_MAJOR "0") -_cpack_set_default(CPACK_PACKAGE_VERSION_MINOR "1") -_cpack_set_default(CPACK_PACKAGE_VERSION_PATCH "1") -_cpack_set_default(CPACK_PACKAGE_VERSION - "${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}") +if(CMAKE_PROJECT_VERSION_MAJOR) + _cpack_set_default(CPACK_PACKAGE_VERSION_MAJOR "${CMAKE_PROJECT_VERSION_MAJOR}") + if(CMAKE_PROJECT_VERSION_MINOR) + _cpack_set_default(CPACK_PACKAGE_VERSION_MINOR "${CMAKE_PROJECT_VERSION_MINOR}") + if(CMAKE_PROJECT_VERSION_PATCH) + _cpack_set_default(CPACK_PACKAGE_VERSION_PATCH "${CMAKE_PROJECT_VERSION_PATCH}") + _cpack_set_default(CPACK_PACKAGE_VERSION + "${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}") + else() + _cpack_set_default(CPACK_PACKAGE_VERSION + "${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}") + endif() + else() + _cpack_set_default(CPACK_PACKAGE_VERSION "${CPACK_PACKAGE_VERSION_MAJOR}") + endif() +else() + _cpack_set_default(CPACK_PACKAGE_VERSION_MAJOR "0") + _cpack_set_default(CPACK_PACKAGE_VERSION_MINOR "1") + _cpack_set_default(CPACK_PACKAGE_VERSION_PATCH "1") + _cpack_set_default(CPACK_PACKAGE_VERSION + "${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}") +endif() _cpack_set_default(CPACK_PACKAGE_VENDOR "Humanity") if(CMAKE_PROJECT_DESCRIPTION) _cpack_set_default(CPACK_PACKAGE_DESCRIPTION_SUMMARY @@ -373,6 +433,10 @@ else() _cpack_set_default(CPACK_PACKAGE_DESCRIPTION_SUMMARY "${CMAKE_PROJECT_NAME} built using CMake") endif() +if(CMAKE_PROJECT_HOMEPAGE_URL) + _cpack_set_default(CPACK_PACKAGE_HOMEPAGE_URL + "${CMAKE_PROJECT_HOMEPAGE_URL}") +endif() _cpack_set_default(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_ROOT}/Templates/CPack.GenericDescription.txt") @@ -453,16 +517,9 @@ macro(cpack_optional_append _list _cond _item) endif() endmacro() -#.rst: -# .. variable:: CPACK_BINARY_<GENNAME> -# -# CPack generated options for binary generators. The CPack.cmake module -# generates (when CPACK_GENERATOR is not set) a set of CMake options (see -# CMake option command) which may then be used to select the CPack -# generator(s) to be used when launching the package target. -# -# Provide options to choose generators we might check here if the required -# tools for the generates exist and set the defaults according to the results +# Provide options to choose generators we might check here if the required +# tools for the generators exist and set the defaults according to the +# results. if(NOT CPACK_GENERATOR) if(UNIX) if(CYGWIN) @@ -487,10 +544,11 @@ if(NOT CPACK_GENERATOR) option(CPACK_BINARY_TXZ "Enable to build TXZ packages" OFF) endif() else() - option(CPACK_BINARY_7Z "Enable to build 7-Zip packages" OFF) - option(CPACK_BINARY_NSIS "Enable to build NSIS packages" ON) - option(CPACK_BINARY_WIX "Enable to build WiX packages" OFF) - option(CPACK_BINARY_ZIP "Enable to build ZIP packages" OFF) + option(CPACK_BINARY_7Z "Enable to build 7-Zip packages" OFF) + option(CPACK_BINARY_NSIS "Enable to build NSIS packages" ON) + option(CPACK_BINARY_NUGET "Enable to build NuGet packages" OFF) + option(CPACK_BINARY_WIX "Enable to build WiX packages" OFF) + option(CPACK_BINARY_ZIP "Enable to build ZIP packages" OFF) endif() option(CPACK_BINARY_IFW "Enable to build IFW packages" OFF) @@ -502,6 +560,7 @@ if(NOT CPACK_GENERATOR) cpack_optional_append(CPACK_GENERATOR CPACK_BINARY_FREEBSD FREEBSD) 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_OSXX11 OSXX11) cpack_optional_append(CPACK_GENERATOR CPACK_BINARY_PACKAGEMAKER PackageMaker) cpack_optional_append(CPACK_GENERATOR CPACK_BINARY_PRODUCTBUILD productbuild) @@ -554,6 +613,7 @@ mark_as_advanced( CPACK_BINARY_FREEBSD CPACK_BINARY_IFW CPACK_BINARY_NSIS + CPACK_BINARY_NUGET CPACK_BINARY_OSXX11 CPACK_BINARY_PACKAGEMAKER CPACK_BINARY_PRODUCTBUILD diff --git a/Modules/CPackDeb.cmake b/Modules/CPackDeb.cmake index 35447c9..067e290 100644 --- a/Modules/CPackDeb.cmake +++ b/Modules/CPackDeb.cmake @@ -29,8 +29,8 @@ # Here are some CPackDeb wiki resources that are here for historic reasons and # are no longer maintained but may still prove useful: # -# - https://cmake.org/Wiki/CMake:CPackConfiguration -# - https://cmake.org/Wiki/CMake:CPackPackageGenerators#DEB_.28UNIX_only.29 +# - https://gitlab.kitware.com/cmake/community/wikis/doc/cpack/Configuration +# - https://gitlab.kitware.com/cmake/community/wikis/doc/cpack/PackageGenerators#deb-unix-only # # List of CPackDEB specific variables: # @@ -254,7 +254,7 @@ # upstream documentation or information may be found. # # * Mandatory : NO -# * Default : - +# * Default : :variable:`CMAKE_PROJECT_HOMEPAGE_URL` # # .. note:: # @@ -278,7 +278,7 @@ # You may need set :variable:`CMAKE_INSTALL_RPATH` to an appropriate value # if you use this feature, because if you don't :code:`dpkg-shlibdeps` # may fail to find your own shared libs. -# See https://cmake.org/Wiki/CMake_RPATH_handling. +# See https://gitlab.kitware.com/cmake/community/wikis/doc/cmake/RPATH-handling # # .. variable:: CPACK_DEBIAN_PACKAGE_DEBUG # @@ -914,6 +914,11 @@ function(cpack_deb_prepare_package_vars) endif() endif() + # Homepage: (optional) + if(NOT CPACK_DEBIAN_PACKAGE_HOMEPAGE AND CMAKE_PROJECT_HOMEPAGE_URL) + set(CPACK_DEBIAN_PACKAGE_HOMEPAGE "${CMAKE_PROJECT_HOMEPAGE_URL}") + endif() + # Section: (recommended) if(NOT CPACK_DEBIAN_PACKAGE_SECTION) set(CPACK_DEBIAN_PACKAGE_SECTION "devel") diff --git a/Modules/CPackFreeBSD.cmake b/Modules/CPackFreeBSD.cmake index 7fec78a..b681d4f 100644 --- a/Modules/CPackFreeBSD.cmake +++ b/Modules/CPackFreeBSD.cmake @@ -80,7 +80,8 @@ the RPM information (e.g. package license). * Mandatory: YES * Default: - - :variable:`CPACK_DEBIAN_PACKAGE_HOMEPAGE` (this may be set already + - :variable:`CMAKE_PROJECT_HOMEPAGE_URL`, or if that is not set, + :variable:`CPACK_DEBIAN_PACKAGE_HOMEPAGE` (this may be set already for Debian packaging, so we may as well re-use it). .. variable:: CPACK_FREEBSD_PACKAGE_LICENSE @@ -208,6 +209,7 @@ _cpack_freebsd_fallback_var("CPACK_FREEBSD_PACKAGE_DESCRIPTION" # There's really only one homepage for a project, so # re-use the Debian setting if it's there. _cpack_freebsd_fallback_var("CPACK_FREEBSD_PACKAGE_WWW" + "CMAKE_PROJECT_HOMEPAGE_URL" "CPACK_DEBIAN_PACKAGE_HOMEPAGE" "_cpack_freebsd_fallback_www" ) diff --git a/Modules/CPackNSIS.cmake b/Modules/CPackNSIS.cmake index 18d1871..5bc4395 100644 --- a/Modules/CPackNSIS.cmake +++ b/Modules/CPackNSIS.cmake @@ -126,7 +126,7 @@ # .. variable:: CPACK_NSIS_MENU_LINKS # # Specify links in [application] menu. This should contain a list of pair -# "link" "link name". The link may be an URL or a path relative to +# "link" "link name". The link may be a URL or a path relative to # installation prefix. Like:: # # set(CPACK_NSIS_MENU_LINKS diff --git a/Modules/CPackNuGet.cmake b/Modules/CPackNuGet.cmake new file mode 100644 index 0000000..29d4296 --- /dev/null +++ b/Modules/CPackNuGet.cmake @@ -0,0 +1,556 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + +#[=======================================================================[.rst: +CPackNuGet +---------- + +When build a NuGet pacakge there is no direct way to control an output +filename due a lack of the corresponding CLI option of NuGet, so there +is no ``CPACK_NUGET_PACKAGE_FILENAME`` variable. To form the output filename +NuGet uses the package name and the version according to its built-in rules. + +Also, be aware that including a top level directory +(``CPACK_INCLUDE_TOPLEVEL_DIRECTORY``) is ignored by this generator. + + +Variables specific to CPack NuGet generator +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +CPackNuGet may be used to create NuGet packages using :module:`CPack`. +CPackNuGet is a :module:`CPack` generator thus it uses the ``CPACK_XXX`` +variables used by :module:`CPack`. + +CPackNuGet has specific features which are controlled by the specifics +:code:`CPACK_NUGET_XXX` variables. In the "one per group" mode +(see :variable:`CPACK_COMPONENTS_GROUPING`), ``<compName>`` placeholder +in the variables below would contain a group name (uppercased and turned into +a "C" identifier). + +List of CPackNuGet specific variables: + +.. variable:: CPACK_NUGET_COMPONENT_INSTALL + + Enable component packaging for CPackNuGet + + * Mandatory : NO + * Default : OFF + +.. variable:: CPACK_NUGET_PACKAGE_NAME + CPACK_NUGET_<compName>_PACKAGE_NAME + + The NUGET package name. + + * Mandatory : YES + * Default : :variable:`CPACK_PACKAGE_NAME` + +.. variable:: CPACK_NUGET_PACKAGE_VERSION + CPACK_NUGET_<compName>_PACKAGE_VERSION + + The NuGet package version. + + * Mandatory : YES + * Default : :variable:`CPACK_PACKAGE_VERSION` + +.. variable:: CPACK_NUGET_PACKAGE_DESCRIPTION + CPACK_NUGET_<compName>_PACKAGE_DESCRIPTION + + A long description of the package for UI display. + + * Mandatory : YES + * Default : + - :variable:`CPACK_COMPONENT_<compName>_DESCRIPTION`, + - ``CPACK_COMPONENT_GROUP_<groupName>_DESCRIPTION``, + - :variable:`CPACK_PACKAGE_DESCRIPTION` + + .. variable:: CPACK_NUGET_PACKAGE_AUTHORS + CPACK_NUGET_<compName>_PACKAGE_AUTHORS + + A comma-separated list of packages authors, matching the profile names + on nuget.org_. These are displayed in the NuGet Gallery on + nuget.org_ and are used to cross-reference packages by the same + authors. + + * Mandatory : YES + * Default : :variable:`CPACK_PACKAGE_VENDOR` + +.. variable:: CPACK_NUGET_PACKAGE_TITLE + CPACK_NUGET_<compName>_PACKAGE_TITLE + + A human-friendly title of the package, typically used in UI displays + as on nuget.org_ and the Package Manager in Visual Studio. If not + specified, the package ID is used. + + * Mandatory : NO + * Default : + - :variable:`CPACK_COMPONENT_<compName>_DISPLAY_NAME`, + - ``CPACK_COMPONENT_GROUP_<groupName>_DISPLAY_NAME`` + +.. variable:: CPACK_NUGET_PACKAGE_OWNERS + CPACK_NUGET_<compName>_PACKAGE_OWNERS + + A comma-separated list of the package creators using profile names + on nuget.org_. This is often the same list as in authors, + and is ignored when uploading the package to nuget.org_. + + * Mandatory : NO + * Default : - + +.. variable:: CPACK_NUGET_PACKAGE_HOMEPAGE_URL + CPACK_NUGET_<compName>_PACKAGE_HOMEPAGE_URL + + A URL for the package's home page, often shown in UI displays as well + as nuget.org_. + + * Mandatory : NO + * Default : :variable:`CPACK_PACKAGE_HOMEPAGE_URL` + +.. variable:: CPACK_NUGET_PACKAGE_LICENSEURL + CPACK_NUGET_<compName>_PACKAGE_LICENSEURL + + A URL for the package's license, often shown in UI displays as well + as nuget.org_. + + * Mandatory : NO + * Default : - + +.. variable:: CPACK_NUGET_PACKAGE_ICONURL + CPACK_NUGET_<compName>_PACKAGE_ICONURL + + A URL for a 64x64 image with transparency background to use as the + icon for the package in UI display. + + * Mandatory : NO + * Default : - + +.. variable:: CPACK_NUGET_PACKAGE_DESCRIPTION_SUMMARY + CPACK_NUGET_<compName>_PACKAGE_DESCRIPTION_SUMMARY + + A short description of the package for UI display. If omitted, a + truncated version of description is used. + + * Mandatory : NO + * Default : :variable:`CPACK_PACKAGE_DESCRIPTION_SUMMARY` + +.. variable:: CPACK_NUGET_PACKAGE_RELEASE_NOTES + CPACK_NUGET_<compName>_PACKAGE_RELEASE_NOTES + + A description of the changes made in this release of the package, + often used in UI like the Updates tab of the Visual Studio Package + Manager in place of the package description. + + * Mandatory : NO + * Default : - + +.. variable:: CPACK_NUGET_PACKAGE_COPYRIGHT + CPACK_NUGET_<compName>_PACKAGE_COPYRIGHT + + Copyright details for the package. + + * Mandatory : NO + * Default : - + +.. variable:: CPACK_NUGET_PACKAGE_TAGS + CPACK_NUGET_<compName>_PACKAGE_TAGS + + A space-delimited list of tags and keywords that describe the + package and aid discoverability of packages through search and + filtering. + + * Mandatory : NO + * Default : - + +.. variable:: CPACK_NUGET_PACKAGE_DEPENDENCIES + CPACK_NUGET_<compName>_PACKAGE_DEPENDENCIES + + A list of package dependencies. + + * Mandatory : NO + * Default : - + +.. variable:: CPACK_NUGET_PACKAGE_DEPENDENCIES_<dependency>_VERSION + CPACK_NUGET_<compName>_PACKAGE_DEPENDENCIES_<dependency>_VERSION + + A `version specification`_ for the particular dependency, where + ``<dependency>`` is an item of the dependency list (see above) + transformed with ``MAKE_C_IDENTIFIER`` function of :command:`string` + command. + + * Mandatory : NO + * Default : - + +.. variable:: CPACK_NUGET_PACKAGE_DEBUG + + Enable debug messages while executing ``CPackNuGet.cmake``. + + * Mandatory : NO + * Default : OFF + + +.. _nuget.org: http://nuget.org +.. _version specification: https://docs.microsoft.com/en-us/nuget/reference/package-versioning#version-ranges-and-wildcards + +.. NuGet spec docs https://docs.microsoft.com/en-us/nuget/reference/nuspec + +#]=======================================================================] + +# Author: Alex Turbov + +if(CMAKE_BINARY_DIR) + message(FATAL_ERROR "CPackNuGet.cmake may only be used by CPack internally.") +endif() + +function(_cpack_nuget_debug) + if(CPACK_NUGET_PACKAGE_DEBUG) + message("CPackNuGet:Debug: " ${ARGN}) + endif() +endfunction() + +function(_cpack_nuget_debug_var NAME) + if(CPACK_NUGET_PACKAGE_DEBUG) + message("CPackNuGet:Debug: ${NAME}=`${${NAME}}`") + endif() +endfunction() + +function(_cpack_nuget_variable_fallback OUTPUT_VAR_NAME NUGET_VAR_NAME) + if(ARGN) + list(JOIN ARGN "`, `" _va_args) + set(_va_args ", ARGN: `${_va_args}`") + endif() + _cpack_nuget_debug( + "_cpack_nuget_variable_fallback: " + "OUTPUT_VAR_NAME=`${OUTPUT_VAR_NAME}`, " + "NUGET_VAR_NAME=`${NUGET_VAR_NAME}`" + "${_va_args}" + ) + + set(_options USE_CDATA) + set(_one_value_args LIST_GLUE) + set(_multi_value_args FALLBACK_VARS) + cmake_parse_arguments(PARSE_ARGV 0 _args "${_options}" "${_one_value_args}" "${_multi_value_args}") + + if(CPACK_NUGET_PACKAGE_COMPONENT) + string( + TOUPPER "${CPACK_NUGET_PACKAGE_COMPONENT}" + CPACK_NUGET_PACKAGE_COMPONENT_UPPER + ) + endif() + + if(CPACK_NUGET_PACKAGE_COMPONENT + AND CPACK_NUGET_${CPACK_NUGET_PACKAGE_COMPONENT}_PACKAGE_${NUGET_VAR_NAME} + ) + set( + _result + "${CPACK_NUGET_${CPACK_NUGET_PACKAGE_COMPONENT}_PACKAGE_${NUGET_VAR_NAME}}" + ) + _cpack_nuget_debug( + " CPACK_NUGET_${CPACK_NUGET_PACKAGE_COMPONENT}_PACKAGE_${NUGET_VAR_NAME}: " + "OUTPUT_VAR_NAME->${OUTPUT_VAR_NAME}=`${_result}`" + ) + + elseif(CPACK_NUGET_PACKAGE_COMPONENT_UPPER + AND CPACK_NUGET_${CPACK_NUGET_PACKAGE_COMPONENT_UPPER}_PACKAGE_${NUGET_VAR_NAME} + ) + set( + _result + "${CPACK_NUGET_${CPACK_NUGET_PACKAGE_COMPONENT_UPPER}_PACKAGE_${NUGET_VAR_NAME}}" + ) + _cpack_nuget_debug( + " CPACK_NUGET_${CPACK_NUGET_PACKAGE_COMPONENT_UPPER}_PACKAGE_${NUGET_VAR_NAME}: " + "OUTPUT_VAR_NAME->${OUTPUT_VAR_NAME}=`${_result}`" + ) + + elseif(CPACK_NUGET_PACKAGE_${NUGET_VAR_NAME}) + set(_result "${CPACK_NUGET_PACKAGE_${NUGET_VAR_NAME}}") + _cpack_nuget_debug( + " CPACK_NUGET_PACKAGE_${NUGET_VAR_NAME}: " + "OUTPUT_VAR_NAME->${OUTPUT_VAR_NAME}=`${_result}`" + ) + + else() + foreach(_var IN LISTS _args_FALLBACK_VARS) + _cpack_nuget_debug(" Fallback: ${_var} ...") + if(${_var}) + _cpack_nuget_debug(" ${_var}=`${${_var}}`") + set(_result "${${_var}}") + _cpack_nuget_debug( + " ${_var}: OUTPUT_VAR_NAME->${OUTPUT_VAR_NAME}=`${_result}`" + ) + break() + endif() + endforeach() + endif() + + if(_result) + if(_args_USE_CDATA) + set(_value_before "<![CDATA[") + set(_value_after "]]>") + endif() + + list(LENGTH _result _result_len) + if(_result_len GREATER 1 AND _args_LIST_GLUE) + list(JOIN _result "${_args_LIST_GLUE}" _result) + endif() + + set(${OUTPUT_VAR_NAME} "${_value_before}${_result}${_value_after}" PARENT_SCOPE) + endif() + +endfunction() + +function(_cpack_nuget_variable_fallback_and_wrap_into_element ELEMENT NUGET_VAR_NAME) + set(_options) + set(_one_value_args) + set(_multi_value_args FALLBACK_VARS) + cmake_parse_arguments(PARSE_ARGV 0 _args "${_options}" "${_one_value_args}" "${_multi_value_args}") + + _cpack_nuget_variable_fallback(_value ${NUGET_VAR_NAME} ${ARGN} USE_CDATA) + + if(_value) + string(TOUPPER "${ELEMENT}" _ELEMENT_UP) + set( + _CPACK_NUGET_${_ELEMENT_UP}_TAG + "<${ELEMENT}>${_value}</${ELEMENT}>" + PARENT_SCOPE + ) + endif() +endfunction() + +# Print some debug info +_cpack_nuget_debug("---[CPack NuGet Input Variables]---") +_cpack_nuget_debug_var(CPACK_PACKAGE_NAME) +_cpack_nuget_debug_var(CPACK_PACKAGE_VERSION) +_cpack_nuget_debug_var(CPACK_TOPLEVEL_TAG) +_cpack_nuget_debug_var(CPACK_TOPLEVEL_DIRECTORY) +_cpack_nuget_debug_var(CPACK_TEMPORARY_DIRECTORY) +_cpack_nuget_debug_var(CPACK_NUGET_GROUPS) +if(CPACK_NUGET_GROUPS) + foreach(_group IN LISTS CPACK_NUGET_GROUPS) + string(MAKE_C_IDENTIFIER "${_group}" _group_up) + string(TOUPPER "${_group_up}" _group_up) + _cpack_nuget_debug_var(CPACK_NUGET_${_group_up}_GROUP_COMPONENTS) + endforeach() +endif() +_cpack_nuget_debug_var(CPACK_NUGET_COMPONENTS) +_cpack_nuget_debug_var(CPACK_NUGET_ALL_IN_ONE) +_cpack_nuget_debug_var(CPACK_NUGET_ORDINAL_MONOLITIC) +_cpack_nuget_debug("-----------------------------------") + +function(_cpack_nuget_render_spec) + # Make a variable w/ upper-cased component name + if(CPACK_NUGET_PACKAGE_COMPONENT) + string(TOUPPER "${CPACK_NUGET_PACKAGE_COMPONENT}" CPACK_NUGET_PACKAGE_COMPONENT_UPPER) + endif() + + # Set mandatory variables (not wrapped into XML elements) + # https://docs.microsoft.com/en-us/nuget/reference/nuspec#required-metadata-elements + if(CPACK_NUGET_PACKAGE_COMPONENT) + if(CPACK_NUGET_${CPACK_NUGET_PACKAGE_COMPONENT_UPPER}_PACKAGE_NAME) + set( + CPACK_NUGET_PACKAGE_NAME + "${CPACK_NUGET_${CPACK_NUGET_PACKAGE_COMPONENT_UPPER}_PACKAGE_NAME}" + ) + elseif(NOT CPACK_NUGET_PACKAGE_COMPONENT STREQUAL "Unspecified") + set( + CPACK_NUGET_PACKAGE_NAME + "${CPACK_PACKAGE_NAME}.${CPACK_NUGET_PACKAGE_COMPONENT}" + ) + else() + set(CPACK_NUGET_PACKAGE_NAME "${CPACK_PACKAGE_NAME}") + endif() + elseif(NOT CPACK_NUGET_PACKAGE_NAME) + set(CPACK_NUGET_PACKAGE_NAME "${CPACK_PACKAGE_NAME}") + endif() + + _cpack_nuget_variable_fallback( + CPACK_NUGET_PACKAGE_VERSION VERSION + FALLBACK_VARS + CPACK_PACKAGE_VERSION + ) + _cpack_nuget_variable_fallback( + CPACK_NUGET_PACKAGE_DESCRIPTION DESCRIPTION + FALLBACK_VARS + CPACK_COMPONENT_${CPACK_NUGET_PACKAGE_COMPONENT}_DESCRIPTION + CPACK_COMPONENT_${CPACK_NUGET_PACKAGE_COMPONENT_UPPER}_DESCRIPTION + CPACK_COMPONENT_GROUP_${CPACK_NUGET_PACKAGE_COMPONENT_UPPER}_DESCRIPTION + CPACK_PACKAGE_DESCRIPTION + USE_CDATA + ) + _cpack_nuget_variable_fallback( + CPACK_NUGET_PACKAGE_AUTHORS AUTHORS + FALLBACK_VARS + CPACK_PACKAGE_VENDOR + USE_CDATA + LIST_GLUE "," + ) + + # Set optional variables (wrapped into XML elements) + # https://docs.microsoft.com/en-us/nuget/reference/nuspec#optional-metadata-elements + _cpack_nuget_variable_fallback_and_wrap_into_element( + title + TITLE + FALLBACK_VARS + CPACK_COMPONENT_${CPACK_NUGET_PACKAGE_COMPONENT}_DISPLAY_NAME + CPACK_COMPONENT_${CPACK_NUGET_PACKAGE_COMPONENT_UPPER}_DISPLAY_NAME + CPACK_COMPONENT_GROUP_${CPACK_NUGET_PACKAGE_COMPONENT_UPPER}_DISPLAY_NAME + ) + _cpack_nuget_variable_fallback_and_wrap_into_element(owners OWNERS LIST_GLUE ",") + _cpack_nuget_variable_fallback_and_wrap_into_element( + projectUrl + HOMEPAGE_URL + FALLBACK_VARS + CPACK_PACKAGE_HOMEPAGE_URL + ) + _cpack_nuget_variable_fallback_and_wrap_into_element(licenseUrl LICENSEURL) + _cpack_nuget_variable_fallback_and_wrap_into_element(iconUrl ICONURL) + _cpack_nuget_variable_fallback_and_wrap_into_element( + summary DESCRIPTION_SUMMARY + FALLBACK_VARS + CPACK_PACKAGE_DESCRIPTION_SUMMARY + ) + if(CPACK_NUGET_PACKAGE_REQUIRE_LICENSE_ACCEPTANCE) + set( + _CPACK_NUGET_REQUIRELICENSEACCEPTANCE_TAG + "<requireLicenseAcceptance>true</requireLicenseAcceptance>" + ) + endif() + _cpack_nuget_variable_fallback_and_wrap_into_element(releaseNotes RELEASE_NOTES) + _cpack_nuget_variable_fallback_and_wrap_into_element(copyright COPYRIGHT) + _cpack_nuget_variable_fallback_and_wrap_into_element(tags TAGS LIST_GLUE " ") + + # Handle dependencies + _cpack_nuget_variable_fallback(_deps DEPENDENCIES) + set(_collected_deps) + foreach(_dep IN LISTS _deps) + _cpack_nuget_debug(" checking dependency `${_dep}`") + + string(MAKE_C_IDENTIFIER "${_dep}" _dep_id) + + _cpack_nuget_variable_fallback(_ver DEPENDENCIES_${_dep_id}_VERSION) + + if(NOT _ver) + string(TOUPPER "${_dep_id}" _dep_id) + _cpack_nuget_variable_fallback(_ver DEPENDENCIES_${_dep_id}_VERSION) + endif() + + if(_ver) + _cpack_nuget_debug(" got `${_dep}` dependency version ${_ver}") + list(APPEND _collected_deps "<dependency id=\"${_dep}\" version=\"${_ver}\" />") + endif() + endforeach() + + # Render deps into the variable + if(_collected_deps) + set(_CPACK_NUGET_DEPENDENCIES_TAG "<dependencies>\n") + foreach(_line IN LISTS _collected_deps) + string( + APPEND _CPACK_NUGET_DEPENDENCIES_TAG + " ${_line}\n" + ) + endforeach() + string(APPEND _CPACK_NUGET_DEPENDENCIES_TAG " </dependencies>") + endif() + + # Render the spec file + # NOTE The spec filename doesn't matter. Being included into a package, + # NuGet will name it properly. + _cpack_nuget_debug("Rendering `${CPACK_TEMPORARY_DIRECTORY}/CPack.NuGet.nuspec` file...") + configure_file( + "${CMAKE_CURRENT_LIST_DIR}/CPack.NuGet.nuspec.in" + "${CPACK_TEMPORARY_DIRECTORY}/CPack.NuGet.nuspec" + @ONLY + ) +endfunction() + +function(_cpack_nuget_make_files_tag) + set(_files) + foreach(_comp IN LISTS ARGN) + string(APPEND _files " <file src=\"${_comp}\\**\" target=\".\" />\n") + endforeach() + set(_CPACK_NUGET_FILES_TAG "<files>\n${_files} </files>" PARENT_SCOPE) +endfunction() + +find_program(NUGET_EXECUTABLE NuGet) +_cpack_nuget_debug_var(NUGET_EXECUTABLE) +if(NOT NUGET_EXECUTABLE) + message(FATAL_ERROR "NuGet executable not found") +endif() + +# Add details for debug run +if(CPACK_NUGET_PACKAGE_DEBUG) + list(APPEND CPACK_NUGET_PACK_ADDITIONAL_OPTIONS "-Verbosity" "detailed") +endif() + +# Case one: ordinal all-in-one package +if(CPACK_NUGET_ORDINAL_MONOLITIC) + # This variable `CPACK_NUGET_ALL_IN_ONE` set by C++ code: + # Meaning to pack all installed files into a single package + _cpack_nuget_debug("---[Making an ordinal monolitic package]---") + _cpack_nuget_render_spec() + execute_process( + COMMAND "${NUGET_EXECUTABLE}" pack ${CPACK_NUGET_PACK_ADDITIONAL_OPTIONS} + WORKING_DIRECTORY "${CPACK_TEMPORARY_DIRECTORY}" + ) + +elseif(CPACK_NUGET_ALL_IN_ONE) + # This variable `CPACK_NUGET_ALL_IN_ONE` set by C++ code: + # Meaning to pack all installed components into a single package + _cpack_nuget_debug("---[Making a monolitic package from installed components]---") + + # Prepare the `files` element which include files from several components + _cpack_nuget_make_files_tag(${CPACK_NUGET_COMPONENTS}) + _cpack_nuget_render_spec() + execute_process( + COMMAND "${NUGET_EXECUTABLE}" pack ${CPACK_NUGET_PACK_ADDITIONAL_OPTIONS} + WORKING_DIRECTORY "${CPACK_TEMPORARY_DIRECTORY}" + ) + +else() + # Is there any grouped component? + if(CPACK_NUGET_GROUPS) + _cpack_nuget_debug("---[Making grouped component(s) package(s)]---") + foreach(_group IN LISTS CPACK_NUGET_GROUPS) + _cpack_nuget_debug("Starting to make the pacakge for group `${_group}`") + string(MAKE_C_IDENTIFIER "${_group}" _group_up) + string(TOUPPER "${_group_up}" _group_up) + + # Render a spec file which includes all components in the current group + unset(_CPACK_NUGET_FILES_TAG) + _cpack_nuget_make_files_tag(${CPACK_NUGET_${_group_up}_GROUP_COMPONENTS}) + # Temporary set `CPACK_NUGET_PACKAGE_COMPONENT` to the group name + # to properly collect various per group settings + set(CPACK_NUGET_PACKAGE_COMPONENT ${_group}) + _cpack_nuget_render_spec() + unset(CPACK_NUGET_PACKAGE_COMPONENT) + execute_process( + COMMAND "${NUGET_EXECUTABLE}" pack ${CPACK_NUGET_PACK_ADDITIONAL_OPTIONS} + WORKING_DIRECTORY "${CPACK_TEMPORARY_DIRECTORY}" + ) + endforeach() + endif() + # Is there any single component package needed? + if(CPACK_NUGET_COMPONENTS) + _cpack_nuget_debug("---[Making single-component(s) package(s)]---") + foreach(_comp IN LISTS CPACK_NUGET_COMPONENTS) + _cpack_nuget_debug("Starting to make the pacakge for component `${_comp}`") + # Render a spec file which includes only given component + unset(_CPACK_NUGET_FILES_TAG) + _cpack_nuget_make_files_tag(${_comp}) + # Temporary set `CPACK_NUGET_PACKAGE_COMPONENT` to the the current + # component name to properly collect various per group settings + set(CPACK_NUGET_PACKAGE_COMPONENT ${_comp}) + _cpack_nuget_render_spec() + unset(CPACK_NUGET_PACKAGE_COMPONENT) + execute_process( + COMMAND "${NUGET_EXECUTABLE}" pack ${CPACK_NUGET_PACK_ADDITIONAL_OPTIONS} + WORKING_DIRECTORY "${CPACK_TEMPORARY_DIRECTORY}" + ) + endforeach() + endif() +endif() + +file(GLOB_RECURSE GEN_CPACK_OUTPUT_FILES "${CPACK_TEMPORARY_DIRECTORY}/*.nupkg") +if(NOT GEN_CPACK_OUTPUT_FILES) + message(FATAL_ERROR "NuGet package was not generated at `${CPACK_TEMPORARY_DIRECTORY}`!") +endif() + +_cpack_nuget_debug("Generated files: ${GEN_CPACK_OUTPUT_FILES}") diff --git a/Modules/CPackProductBuild.cmake b/Modules/CPackProductBuild.cmake index 4779b95..ee78d8d 100644 --- a/Modules/CPackProductBuild.cmake +++ b/Modules/CPackProductBuild.cmake @@ -47,6 +47,22 @@ # Specify a specific keychain to search for the signing identity. # # +# .. variable:: CPACK_PREFLIGHT_<COMP>_SCRIPT +# +# Full path to a file that will be used as the ``preinstall`` script for the +# named ``<COMP>`` component's package, where ``<COMP>`` is the uppercased +# component name. No ``preinstall`` script is added if this variable is not +# defined for a given component. +# +# +# .. variable:: CPACK_POSTFLIGHT_<COMP>_SCRIPT +# +# Full path to a file that will be used as the ``postinstall`` script for the +# named ``<COMP>`` component's package, where ``<COMP>`` is the uppercased +# component name. No ``postinstall`` script is added if this variable is not +# defined for a given component. +# +# # .. variable:: CPACK_PRODUCTBUILD_RESOURCES_DIR # # If specified the productbuild generator copies files from this directory diff --git a/Modules/CPackRPM.cmake b/Modules/CPackRPM.cmake index bb5181f..8d8eab3 100644 --- a/Modules/CPackRPM.cmake +++ b/Modules/CPackRPM.cmake @@ -40,8 +40,8 @@ # Here are some CPackRPM wiki resources that are here for historic reasons and # are no longer maintained but may still prove useful: # -# - https://cmake.org/Wiki/CMake:CPackConfiguration -# - https://cmake.org/Wiki/CMake:CPackPackageGenerators#RPM_.28Unix_Only.29 +# - https://gitlab.kitware.com/cmake/community/wikis/doc/cpack/Configuration +# - https://gitlab.kitware.com/cmake/community/wikis/doc/cpack/PackageGenerators#rpm-unix-only # # List of CPackRPM specific variables: # @@ -191,7 +191,7 @@ # The projects URL. # # * Mandatory : NO -# * Default : - +# * Default : :variable:`CMAKE_PROJECT_HOMEPAGE_URL` # # .. variable:: CPACK_RPM_PACKAGE_DESCRIPTION # CPACK_RPM_<component>_PACKAGE_DESCRIPTION @@ -1787,6 +1787,10 @@ function(cpack_rpm_generate_package) endif() endif() + if(NOT CPACK_RPM_PACKAGE_URL AND CMAKE_PROJECT_HOMEPAGE_URL) + set(CPACK_RPM_PACKAGE_URL "${CMAKE_PROJECT_HOMEPAGE_URL}") + endif() + # CPACK_RPM_PACKAGE_NAME (mandatory) if(NOT CPACK_RPM_PACKAGE_NAME) string(TOLOWER "${CPACK_PACKAGE_NAME}" CPACK_RPM_PACKAGE_NAME) @@ -1984,7 +1988,7 @@ function(cpack_rpm_generate_package) endif() if(DEFINED CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER}) - # Prefix can be replaced by Prefixes but the old version stil works so we'll ignore it for now + # Prefix can be replaced by Prefixes but the old version still works so we'll ignore it for now # Requires* is a special case because it gets transformed to Requires(pre/post/preun/postun) # Auto* is a special case because the tags can not be queried by querytags rpmbuild flag set(special_case_tags_ PREFIX REQUIRES_PRE REQUIRES_POST REQUIRES_PREUN REQUIRES_POSTUN AUTOPROV AUTOREQ AUTOREQPROV) diff --git a/Modules/CTest.cmake b/Modules/CTest.cmake index a08282e..2ea931d 100644 --- a/Modules/CTest.cmake +++ b/Modules/CTest.cmake @@ -54,7 +54,7 @@ in the ``CTestConfig.cmake`` file. option(BUILD_TESTING "Build the testing tree." ON) # function to turn generator name into a version string -# like vs8 vs9 +# like vs9 or vs10 function(GET_VS_VERSION_STRING generator var) string(REGEX REPLACE "Visual Studio ([0-9][0-9]?)($|.*)" "\\1" NUMBER "${generator}") diff --git a/Modules/CheckCSourceRuns.cmake b/Modules/CheckCSourceRuns.cmake index fa51346..7eb050c 100644 --- a/Modules/CheckCSourceRuns.cmake +++ b/Modules/CheckCSourceRuns.cmake @@ -92,7 +92,8 @@ macro(CHECK_C_SOURCE_RUNS SOURCE VAR) CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_FUNCTION_DEFINITIONS} -DCMAKE_SKIP_RPATH:BOOL=${CMAKE_SKIP_RPATH} "${CHECK_C_SOURCE_COMPILES_ADD_INCLUDES}" - COMPILE_OUTPUT_VARIABLE OUTPUT) + 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) @@ -104,8 +105,10 @@ macro(CHECK_C_SOURCE_RUNS SOURCE VAR) message(STATUS "Performing Test ${VAR} - Success") endif() file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log - "Performing C SOURCE FILE Test ${VAR} succeeded with the following output:\n" + "Performing C 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() @@ -119,8 +122,10 @@ macro(CHECK_C_SOURCE_RUNS SOURCE VAR) message(STATUS "Performing Test ${VAR} - Failed") endif() file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log - "Performing C SOURCE FILE Test ${VAR} failed with the following output:\n" + "Performing C 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") diff --git a/Modules/CheckIncludeFile.cmake b/Modules/CheckIncludeFile.cmake index e5554c4..24bc349 100644 --- a/Modules/CheckIncludeFile.cmake +++ b/Modules/CheckIncludeFile.cmake @@ -27,6 +27,8 @@ # list of macros to define (-DFOO=bar) # ``CMAKE_REQUIRED_INCLUDES`` # list of include directories +# ``CMAKE_REQUIRED_LIBRARIES`` +# A list of libraries to link. See policy :policy:`CMP0075`. # ``CMAKE_REQUIRED_QUIET`` # execute quietly without messages # @@ -55,14 +57,39 @@ macro(CHECK_INCLUDE_FILE INCLUDE VARIABLE) string(APPEND CMAKE_C_FLAGS " ${ARGV2}") endif() + set(_CIF_LINK_LIBRARIES "") + if(CMAKE_REQUIRED_LIBRARIES) + cmake_policy(GET CMP0075 _CIF_CMP0075 + PARENT_SCOPE # undocumented, do not use outside of CMake + ) + if("x${_CIF_CMP0075}x" STREQUAL "xNEWx") + set(_CIF_LINK_LIBRARIES LINK_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES}) + elseif("x${_CIF_CMP0075}x" STREQUAL "xOLDx") + elseif(NOT _CIF_CMP0075_WARNED) + set(_CIF_CMP0075_WARNED 1) + message(AUTHOR_WARNING + "Policy CMP0075 is not set: Include file check macros honor CMAKE_REQUIRED_LIBRARIES. " + "Run \"cmake --help-policy CMP0075\" for policy details. " + "Use the cmake_policy command to set the policy and suppress this warning." + "\n" + "CMAKE_REQUIRED_LIBRARIES is set to:\n" + " ${CMAKE_REQUIRED_LIBRARIES}\n" + "For compatibility with CMake 3.11 and below this check is ignoring it." + ) + endif() + unset(_CIF_CMP0075) + endif() + try_compile(${VARIABLE} ${CMAKE_BINARY_DIR} ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckIncludeFile.c COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS} + ${_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_LIBRARIES) if(${ARGC} EQUAL 3) set(CMAKE_C_FLAGS ${CMAKE_C_FLAGS_SAVE}) diff --git a/Modules/CheckIncludeFileCXX.cmake b/Modules/CheckIncludeFileCXX.cmake index 7948bab..f13d983 100644 --- a/Modules/CheckIncludeFileCXX.cmake +++ b/Modules/CheckIncludeFileCXX.cmake @@ -27,6 +27,8 @@ # list of macros to define (-DFOO=bar) # ``CMAKE_REQUIRED_INCLUDES`` # list of include directories +# ``CMAKE_REQUIRED_LIBRARIES`` +# A list of libraries to link. See policy :policy:`CMP0075`. # ``CMAKE_REQUIRED_QUIET`` # execute quietly without messages # @@ -54,14 +56,39 @@ macro(CHECK_INCLUDE_FILE_CXX INCLUDE VARIABLE) string(APPEND CMAKE_CXX_FLAGS " ${ARGV2}") endif() + set(_CIF_LINK_LIBRARIES "") + if(CMAKE_REQUIRED_LIBRARIES) + cmake_policy(GET CMP0075 _CIF_CMP0075 + PARENT_SCOPE # undocumented, do not use outside of CMake + ) + if("x${_CIF_CMP0075}x" STREQUAL "xNEWx") + set(_CIF_LINK_LIBRARIES LINK_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES}) + elseif("x${_CIF_CMP0075}x" STREQUAL "xOLDx") + elseif(NOT _CIF_CMP0075_WARNED) + set(_CIF_CMP0075_WARNED 1) + message(AUTHOR_WARNING + "Policy CMP0075 is not set: Include file check macros honor CMAKE_REQUIRED_LIBRARIES. " + "Run \"cmake --help-policy CMP0075\" for policy details. " + "Use the cmake_policy command to set the policy and suppress this warning." + "\n" + "CMAKE_REQUIRED_LIBRARIES is set to:\n" + " ${CMAKE_REQUIRED_LIBRARIES}\n" + "For compatibility with CMake 3.11 and below this check is ignoring it." + ) + endif() + unset(_CIF_CMP0075) + endif() + try_compile(${VARIABLE} ${CMAKE_BINARY_DIR} ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckIncludeFile.cxx COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS} + ${_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_LIBRARIES) if(${ARGC} EQUAL 3) set(CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS_SAVE}) diff --git a/Modules/CheckIncludeFiles.cmake b/Modules/CheckIncludeFiles.cmake index 59afdab..c689f05 100644 --- a/Modules/CheckIncludeFiles.cmake +++ b/Modules/CheckIncludeFiles.cmake @@ -33,6 +33,8 @@ # list of macros to define (-DFOO=bar) # ``CMAKE_REQUIRED_INCLUDES`` # list of include directories +# ``CMAKE_REQUIRED_LIBRARIES`` +# A list of libraries to link. See policy :policy:`CMP0075`. # ``CMAKE_REQUIRED_QUIET`` # execute quietly without messages # @@ -95,6 +97,29 @@ macro(CHECK_INCLUDE_FILES INCLUDE VARIABLE) set(_description "include file ${_INCLUDE}") endif() + set(_CIF_LINK_LIBRARIES "") + if(CMAKE_REQUIRED_LIBRARIES) + cmake_policy(GET CMP0075 _CIF_CMP0075 + PARENT_SCOPE # undocumented, do not use outside of CMake + ) + if("x${_CIF_CMP0075}x" STREQUAL "xNEWx") + set(_CIF_LINK_LIBRARIES LINK_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES}) + elseif("x${_CIF_CMP0075}x" STREQUAL "xOLDx") + elseif(NOT _CIF_CMP0075_WARNED) + set(_CIF_CMP0075_WARNED 1) + message(AUTHOR_WARNING + "Policy CMP0075 is not set: Include file check macros honor CMAKE_REQUIRED_LIBRARIES. " + "Run \"cmake --help-policy CMP0075\" for policy details. " + "Use the cmake_policy command to set the policy and suppress this warning." + "\n" + "CMAKE_REQUIRED_LIBRARIES is set to:\n" + " ${CMAKE_REQUIRED_LIBRARIES}\n" + "For compatibility with CMake 3.11 and below this check is ignoring it." + ) + endif() + unset(_CIF_CMP0075) + endif() + if(NOT CMAKE_REQUIRED_QUIET) message(STATUS "Looking for ${_description}") endif() @@ -102,10 +127,12 @@ macro(CHECK_INCLUDE_FILES INCLUDE VARIABLE) ${CMAKE_BINARY_DIR} ${src} COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS} + ${_CIF_LINK_LIBRARIES} CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_INCLUDE_FILES_FLAGS} "${CHECK_INCLUDE_FILES_INCLUDE_DIRS}" OUTPUT_VARIABLE OUTPUT) + unset(_CIF_LINK_LIBRARIES) if(${VARIABLE}) if(NOT CMAKE_REQUIRED_QUIET) message(STATUS "Looking for ${_description} - found") diff --git a/Modules/CheckSymbolExists.cmake b/Modules/CheckSymbolExists.cmake index d9c9ae4..3483121 100644 --- a/Modules/CheckSymbolExists.cmake +++ b/Modules/CheckSymbolExists.cmake @@ -45,6 +45,9 @@ the way the check is run: include_guard(GLOBAL) +cmake_policy(PUSH) +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_IMPL("${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckSymbolExists.c" "${SYMBOL}" "${FILES}" "${VARIABLE}" ) @@ -116,3 +119,5 @@ macro(__CHECK_SYMBOL_EXISTS_IMPL SOURCEFILE SYMBOL FILES VARIABLE) endif() endif() endmacro() + +cmake_policy(POP) diff --git a/Modules/Compiler/CMakeCommonCompilerMacros.cmake b/Modules/Compiler/CMakeCommonCompilerMacros.cmake index 684fd30..ad464c7 100644 --- a/Modules/Compiler/CMakeCommonCompilerMacros.cmake +++ b/Modules/Compiler/CMakeCommonCompilerMacros.cmake @@ -78,6 +78,9 @@ endmacro() # Define to allow compile features to be automatically determined macro(cmake_record_cxx_compile_features) set(_result 0) + if(_result EQUAL 0 AND DEFINED CMAKE_CXX20_STANDARD_COMPILE_OPTION) + _record_compiler_features_cxx(20) + endif() if(_result EQUAL 0 AND DEFINED CMAKE_CXX17_STANDARD_COMPILE_OPTION) _record_compiler_features_cxx(17) endif() diff --git a/Modules/Compiler/Clang-CXX.cmake b/Modules/Compiler/Clang-CXX.cmake index efc68b3..e99011b 100644 --- a/Modules/Compiler/Clang-CXX.cmake +++ b/Modules/Compiler/Clang-CXX.cmake @@ -32,12 +32,52 @@ if(NOT "x${CMAKE_CXX_SIMULATE_ID}" STREQUAL "xMSVC") set(CMAKE_CXX14_EXTENSION_COMPILE_OPTION "-std=gnu++1y") endif() - if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.5) + set(_clang_version_std17 5.0) + if(CMAKE_SYSTEM_NAME STREQUAL "Android") + set(_clang_version_std17 6.0) + endif() + + if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS "${_clang_version_std17}") + set(CMAKE_CXX17_STANDARD_COMPILE_OPTION "-std=c++17") + set(CMAKE_CXX17_EXTENSION_COMPILE_OPTION "-std=gnu++17") + elseif (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.5) set(CMAKE_CXX17_STANDARD_COMPILE_OPTION "-std=c++1z") set(CMAKE_CXX17_EXTENSION_COMPILE_OPTION "-std=gnu++1z") endif() + + if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS "${_clang_version_std17}") + set(CMAKE_CXX20_STANDARD_COMPILE_OPTION "-std=c++2a") + set(CMAKE_CXX20_EXTENSION_COMPILE_OPTION "-std=gnu++2a") + endif() + + unset(_clang_version_std17) + + __compiler_check_default_language_standard(CXX 2.1 98) +elseif(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 3.9 + AND CMAKE_CXX_SIMULATE_VERSION VERSION_GREATER_EQUAL 19.0) + # This version of clang-cl and the MSVC version it simulates have + # support for -std: flags. + set(CMAKE_CXX98_STANDARD_COMPILE_OPTION "") + set(CMAKE_CXX98_EXTENSION_COMPILE_OPTION "") + set(CMAKE_CXX11_STANDARD_COMPILE_OPTION "") + set(CMAKE_CXX11_EXTENSION_COMPILE_OPTION "") + set(CMAKE_CXX14_STANDARD_COMPILE_OPTION "-std:c++14") + set(CMAKE_CXX14_EXTENSION_COMPILE_OPTION "-std:c++14") + if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 6.0) + set(CMAKE_CXX17_STANDARD_COMPILE_OPTION "-std:c++17") + set(CMAKE_CXX17_EXTENSION_COMPILE_OPTION "-std:c++17") + set(CMAKE_CXX20_STANDARD_COMPILE_OPTION "-std:c++latest") + set(CMAKE_CXX20_EXTENSION_COMPILE_OPTION "-std:c++latest") + else() + set(CMAKE_CXX17_STANDARD_COMPILE_OPTION "-std:c++latest") + set(CMAKE_CXX17_EXTENSION_COMPILE_OPTION "-std:c++latest") + endif() + + __compiler_check_default_language_standard(CXX 3.9 14) else() - # clang-cl does not know these options because it behaves like cl.exe + # This version of clang-cl, or the MSVC version it simulates, does not have + # language standards. Set these options as empty strings so the feature + # test infrastructure can at least check to see if they are defined. set(CMAKE_CXX98_STANDARD_COMPILE_OPTION "") set(CMAKE_CXX98_EXTENSION_COMPILE_OPTION "") set(CMAKE_CXX11_STANDARD_COMPILE_OPTION "") @@ -46,10 +86,24 @@ else() set(CMAKE_CXX14_EXTENSION_COMPILE_OPTION "") set(CMAKE_CXX17_STANDARD_COMPILE_OPTION "") set(CMAKE_CXX17_EXTENSION_COMPILE_OPTION "") -endif() + set(CMAKE_CXX20_STANDARD_COMPILE_OPTION "") + set(CMAKE_CXX20_EXTENSION_COMPILE_OPTION "") -if(NOT "x${CMAKE_CXX_SIMULATE_ID}" STREQUAL "xMSVC") - __compiler_check_default_language_standard(CXX 2.1 98) -else() + # There is no meaningful default for this set(CMAKE_CXX_STANDARD_DEFAULT "") + + # There are no compiler modes so we only need to test features once. + # Override the default macro for this special case. Pretend that + # all language standards are available so that at least compilation + # can be attempted. + macro(cmake_record_cxx_compile_features) + list(APPEND CMAKE_CXX_COMPILE_FEATURES + cxx_std_98 + cxx_std_11 + cxx_std_14 + cxx_std_17 + cxx_std_20 + ) + _record_compiler_features(CXX "" CMAKE_CXX_COMPILE_FEATURES) + endmacro() endif() diff --git a/Modules/Compiler/GNU-CXX.cmake b/Modules/Compiler/GNU-CXX.cmake index 4f1f30e..0058223 100644 --- a/Modules/Compiler/GNU-CXX.cmake +++ b/Modules/Compiler/GNU-CXX.cmake @@ -33,9 +33,17 @@ elseif (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.8) set(CMAKE_CXX14_EXTENSION_COMPILE_OPTION "-std=gnu++1y") endif() -if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.1) +if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 8.0) + set(CMAKE_CXX17_STANDARD_COMPILE_OPTION "-std=c++17") + set(CMAKE_CXX17_EXTENSION_COMPILE_OPTION "-std=gnu++17") +elseif (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.1) set(CMAKE_CXX17_STANDARD_COMPILE_OPTION "-std=c++1z") set(CMAKE_CXX17_EXTENSION_COMPILE_OPTION "-std=gnu++1z") endif() +if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 8.0) + set(CMAKE_CXX20_STANDARD_COMPILE_OPTION "-std=c++2a") + set(CMAKE_CXX20_EXTENSION_COMPILE_OPTION "-std=gnu++2a") +endif() + __compiler_check_default_language_standard(CXX 3.4 98 6.0 14) diff --git a/Modules/Compiler/MSVC-C-FeatureTests.cmake b/Modules/Compiler/MSVC-C-FeatureTests.cmake new file mode 100644 index 0000000..3f09be2 --- /dev/null +++ b/Modules/Compiler/MSVC-C-FeatureTests.cmake @@ -0,0 +1,8 @@ +set(_cmake_oldestSupported "_MSC_VER >= 1600") + +# Not yet supported: +#set(_cmake_feature_test_c_static_assert "") +#set(_cmake_feature_test_c_restrict "") + +set(_cmake_feature_test_c_variadic_macros "${_cmake_oldestSupported}") +set(_cmake_feature_test_c_function_prototypes "${_cmake_oldestSupported}") diff --git a/Modules/Compiler/MSVC-C.cmake b/Modules/Compiler/MSVC-C.cmake new file mode 100644 index 0000000..22c34f8 --- /dev/null +++ b/Modules/Compiler/MSVC-C.cmake @@ -0,0 +1,25 @@ +# MSVC has no specific options to set C language standards, but set them as +# empty strings anyways so the feature test infrastructure can at least check +# to see if they are defined. +set(CMAKE_C90_STANDARD_COMPILE_OPTION "") +set(CMAKE_C90_EXTENSION_COMPILE_OPTION "") +set(CMAKE_C99_STANDARD_COMPILE_OPTION "") +set(CMAKE_C99_EXTENSION_COMPILE_OPTION "") +set(CMAKE_C11_STANDARD_COMPILE_OPTION "") +set(CMAKE_C11_EXTENSION_COMPILE_OPTION "") + +# There is no meaningful default for this +set(CMAKE_C_STANDARD_DEFAULT "") + +# There are no C compiler modes so we only need to test features once. +# Override the default macro for this special case. Pretend that +# all language standards are available so that at least compilation +# can be attempted. +macro(cmake_record_c_compile_features) + list(APPEND CMAKE_C_COMPILE_FEATURES + c_std_90 + c_std_99 + c_std_11 + ) + _record_compiler_features(C "" CMAKE_C_COMPILE_FEATURES) +endmacro() diff --git a/Modules/Compiler/MSVC-CXX.cmake b/Modules/Compiler/MSVC-CXX.cmake index 789fff5..be259ff 100644 --- a/Modules/Compiler/MSVC-CXX.cmake +++ b/Modules/Compiler/MSVC-CXX.cmake @@ -22,6 +22,10 @@ if ((CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 19.0.24215.1 AND set(CMAKE_CXX17_STANDARD_COMPILE_OPTION "-std:c++latest") set(CMAKE_CXX17_EXTENSION_COMPILE_OPTION "-std:c++latest") endif() + if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 19.12.25835) + set(CMAKE_CXX20_STANDARD_COMPILE_OPTION "-std:c++latest") + set(CMAKE_CXX20_EXTENSION_COMPILE_OPTION "-std:c++latest") + endif() __compiler_check_default_language_standard(CXX 19.0 14) @@ -29,6 +33,12 @@ if ((CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 19.0.24215.1 AND # for meta-features for C++14 and above. Override the default macro # to avoid doing unnecessary work. macro(cmake_record_cxx_compile_features) + if (DEFINED CMAKE_CXX20_STANDARD_COMPILE_OPTION) + list(APPEND CMAKE_CXX20_COMPILE_FEATURES cxx_std_20) + endif() + # The main cmake_record_cxx_compile_features macro makes all + # these conditional on CMAKE_CXX##_STANDARD_COMPILE_OPTION, + # but we can skip the conditions because we set them above. list(APPEND CMAKE_CXX17_COMPILE_FEATURES cxx_std_17) list(APPEND CMAKE_CXX14_COMPILE_FEATURES cxx_std_14) list(APPEND CMAKE_CXX98_COMPILE_FEATURES cxx_std_11) # no flag needed for 11 @@ -46,6 +56,8 @@ elseif (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 16.0) set(CMAKE_CXX14_EXTENSION_COMPILE_OPTION "") set(CMAKE_CXX17_STANDARD_COMPILE_OPTION "") set(CMAKE_CXX17_EXTENSION_COMPILE_OPTION "") + set(CMAKE_CXX20_STANDARD_COMPILE_OPTION "") + set(CMAKE_CXX20_EXTENSION_COMPILE_OPTION "") # There is no meaningful default for this set(CMAKE_CXX_STANDARD_DEFAULT "") @@ -60,6 +72,7 @@ elseif (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 16.0) cxx_std_11 cxx_std_14 cxx_std_17 + cxx_std_20 ) _record_compiler_features(CXX "" CMAKE_CXX_COMPILE_FEATURES) endmacro() diff --git a/Modules/Compiler/NVIDIA-DetermineCompiler.cmake b/Modules/Compiler/NVIDIA-DetermineCompiler.cmake index cb0beaf..bf9111a 100644 --- a/Modules/Compiler/NVIDIA-DetermineCompiler.cmake +++ b/Modules/Compiler/NVIDIA-DetermineCompiler.cmake @@ -2,9 +2,11 @@ set(_compiler_id_pp_test "defined(__NVCC__)") set(_compiler_id_version_compute " -# define @PREFIX@COMPILER_VERSION_MAJOR @MACRO_DEC@(__CUDACC_VER_MAJOR__) -# define @PREFIX@COMPILER_VERSION_MINOR @MACRO_DEC@(__CUDACC_VER_MINOR__) -# define @PREFIX@COMPILER_VERSION_PATCH @MACRO_DEC@(__CUDACC_VER_BUILD__) +# if defined(__CUDACC_VER_MAJOR__) +# define @PREFIX@COMPILER_VERSION_MAJOR @MACRO_DEC@(__CUDACC_VER_MAJOR__) +# define @PREFIX@COMPILER_VERSION_MINOR @MACRO_DEC@(__CUDACC_VER_MINOR__) +# define @PREFIX@COMPILER_VERSION_PATCH @MACRO_DEC@(__CUDACC_VER_BUILD__) +# endif # if defined(_MSC_VER) /* _MSC_VER = VVRR */ # define @PREFIX@SIMULATE_VERSION_MAJOR @MACRO_DEC@(_MSC_VER / 100) diff --git a/Modules/Compiler/SunPro-C.cmake b/Modules/Compiler/SunPro-C.cmake index 29c2f22..8d0e6d6 100644 --- a/Modules/Compiler/SunPro-C.cmake +++ b/Modules/Compiler/SunPro-C.cmake @@ -18,6 +18,8 @@ string(APPEND CMAKE_C_FLAGS_MINSIZEREL_INIT " -xO2 -xspace -DNDEBUG") string(APPEND CMAKE_C_FLAGS_RELEASE_INIT " -xO3 -DNDEBUG") string(APPEND CMAKE_C_FLAGS_RELWITHDEBINFO_INIT " -g -xO2 -DNDEBUG") +set(CMAKE_DEPFILE_FLAGS_C "-xMD -xMF <DEPFILE>") + # Initialize C 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 diff --git a/Modules/Compiler/SunPro-CXX.cmake b/Modules/Compiler/SunPro-CXX.cmake index 5cb7edc..14196b7 100644 --- a/Modules/Compiler/SunPro-CXX.cmake +++ b/Modules/Compiler/SunPro-CXX.cmake @@ -18,6 +18,8 @@ string(APPEND CMAKE_CXX_FLAGS_MINSIZEREL_INIT " -xO2 -xspace -DNDEBUG") string(APPEND CMAKE_CXX_FLAGS_RELEASE_INIT " -xO3 -DNDEBUG") string(APPEND CMAKE_CXX_FLAGS_RELWITHDEBINFO_INIT " -g -xO2 -DNDEBUG") +set(CMAKE_DEPFILE_FLAGS_CXX "-xMD -xMF <DEPFILE>") + # Initialize C 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 diff --git a/Modules/Compiler/XL.cmake b/Modules/Compiler/XL.cmake index e527a04..3361f8f 100644 --- a/Modules/Compiler/XL.cmake +++ b/Modules/Compiler/XL.cmake @@ -30,6 +30,8 @@ macro(__compiler_xl lang) 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_DEPFILE_FLAGS_${lang} "-MF <DEPFILE> -qmakedep=gcc") + # CMAKE_XL_CreateExportList is part of the AIX XL compilers but not the linux ones. # If we found the tool, we'll use it to create exports, otherwise stick with the regular # create shared library compile line. diff --git a/Modules/ExternalData.cmake b/Modules/ExternalData.cmake index 7331fb2..e5dbcd9 100644 --- a/Modules/ExternalData.cmake +++ b/Modules/ExternalData.cmake @@ -1133,7 +1133,7 @@ if("${ExternalData_ACTION}" STREQUAL "fetch") if(file_up_to_date) # Touch the file to convince the build system it is up to date. - execute_process(COMMAND "${CMAKE_COMMAND}" -E touch "${file}") + file(TOUCH "${file}") else() _ExternalData_link_or_copy("${obj}" "${file}") endif() diff --git a/Modules/FindBLAS.cmake b/Modules/FindBLAS.cmake index 8e8c6f4..5223b1d 100644 --- a/Modules/FindBLAS.cmake +++ b/Modules/FindBLAS.cmake @@ -90,7 +90,11 @@ if(BLA_PREFER_PKGCONFIG) find_package(PkgConfig) pkg_check_modules(PKGC_BLAS IMPORTED_TARGET blas) if(PKGC_BLAS_FOUND) - set(BLAS_LIBRARIES PkgConfig::PKGC_BLAS) + # FIXME: We should not interpret the INTERFACE_LINK_LIBRARIES property + # because it could have generator expressions and such. This is a + # workaround for pkg_check_modules not providing a first-class way to + # get the list of libraries. + get_property(BLAS_LIBRARIES TARGET PkgConfig::PKGC_BLAS PROPERTY INTERFACE_LINK_LIBRARIES) find_package_handle_standard_args(BLAS REQUIRED_VARS BLAS_LIBRARIES VERSION_VAR PKGC_BLAS_VERSION) diff --git a/Modules/FindBoost.cmake b/Modules/FindBoost.cmake index 8d44aee..08d9762 100644 --- a/Modules/FindBoost.cmake +++ b/Modules/FindBoost.cmake @@ -458,20 +458,10 @@ function(_Boost_GUESS_COMPILER_PREFIX _ret) elseif (GHSMULTI) set(_boost_COMPILER "-ghs") elseif("x${CMAKE_CXX_COMPILER_ID}" STREQUAL "xMSVC") - if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 19.10) + if(MSVC_TOOLSET_VERSION GREATER_EQUAL 141) set(_boost_COMPILER "-vc141;-vc140") - elseif (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 19) - set(_boost_COMPILER "-vc140") - elseif(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 18) - set(_boost_COMPILER "-vc120") - elseif(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 17) - set(_boost_COMPILER "-vc110") - elseif(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 16) - set(_boost_COMPILER "-vc100") - elseif(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 15) - set(_boost_COMPILER "-vc90") - elseif(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 14) - set(_boost_COMPILER "-vc80") + elseif(MSVC_TOOLSET_VERSION GREATER_EQUAL 80) + set(_boost_COMPILER "-vc${MSVC_TOOLSET_VERSION}") elseif(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 13.10) set(_boost_COMPILER "-vc71") elseif(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 13) # Good luck! @@ -595,7 +585,7 @@ function(_Boost_COMPONENT_DEPENDENCIES component _ret) set(_Boost_FILESYSTEM_DEPENDENCIES system) set(_Boost_IOSTREAMS_DEPENDENCIES regex) set(_Boost_MPI_DEPENDENCIES serialization) - set(_Boost_MPI_PYTHON_DEPENDENCIES python mpi serialization) + set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization) set(_Boost_WAVE_DEPENDENCIES filesystem system thread) set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) elseif(NOT Boost_VERSION VERSION_LESS 103600 AND Boost_VERSION VERSION_LESS 103800) @@ -603,7 +593,7 @@ function(_Boost_COMPONENT_DEPENDENCIES component _ret) set(_Boost_IOSTREAMS_DEPENDENCIES regex) set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l) set(_Boost_MPI_DEPENDENCIES serialization) - set(_Boost_MPI_PYTHON_DEPENDENCIES python mpi serialization) + set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization) set(_Boost_WAVE_DEPENDENCIES filesystem system thread) set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) elseif(NOT Boost_VERSION VERSION_LESS 103800 AND Boost_VERSION VERSION_LESS 104300) @@ -611,7 +601,7 @@ function(_Boost_COMPONENT_DEPENDENCIES component _ret) set(_Boost_IOSTREAMS_DEPENDENCIES regex) set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l) set(_Boost_MPI_DEPENDENCIES serialization) - set(_Boost_MPI_PYTHON_DEPENDENCIES python mpi serialization) + set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization) set(_Boost_THREAD_DEPENDENCIES date_time) set(_Boost_WAVE_DEPENDENCIES filesystem system thread date_time) set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) @@ -620,7 +610,7 @@ function(_Boost_COMPONENT_DEPENDENCIES component _ret) set(_Boost_IOSTREAMS_DEPENDENCIES regex) set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l random) set(_Boost_MPI_DEPENDENCIES serialization) - set(_Boost_MPI_PYTHON_DEPENDENCIES python mpi serialization) + set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization) set(_Boost_THREAD_DEPENDENCIES date_time) set(_Boost_WAVE_DEPENDENCIES filesystem system thread date_time) set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) @@ -629,7 +619,7 @@ function(_Boost_COMPONENT_DEPENDENCIES component _ret) set(_Boost_IOSTREAMS_DEPENDENCIES regex) set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l random serialization) set(_Boost_MPI_DEPENDENCIES serialization) - set(_Boost_MPI_PYTHON_DEPENDENCIES python mpi serialization) + set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization) set(_Boost_THREAD_DEPENDENCIES date_time) set(_Boost_WAVE_DEPENDENCIES serialization filesystem system thread date_time) set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) @@ -638,7 +628,7 @@ function(_Boost_COMPONENT_DEPENDENCIES component _ret) set(_Boost_IOSTREAMS_DEPENDENCIES regex) set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l random) set(_Boost_MPI_DEPENDENCIES serialization) - set(_Boost_MPI_PYTHON_DEPENDENCIES python mpi serialization) + set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization) set(_Boost_THREAD_DEPENDENCIES date_time) set(_Boost_WAVE_DEPENDENCIES filesystem system serialization thread date_time) set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) @@ -648,7 +638,7 @@ function(_Boost_COMPONENT_DEPENDENCIES component _ret) set(_Boost_IOSTREAMS_DEPENDENCIES regex) set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l random) set(_Boost_MPI_DEPENDENCIES serialization) - set(_Boost_MPI_PYTHON_DEPENDENCIES python mpi serialization) + set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization) set(_Boost_THREAD_DEPENDENCIES date_time) set(_Boost_WAVE_DEPENDENCIES filesystem system serialization thread date_time) set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) @@ -658,7 +648,7 @@ function(_Boost_COMPONENT_DEPENDENCIES component _ret) set(_Boost_IOSTREAMS_DEPENDENCIES regex) set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l random) set(_Boost_MPI_DEPENDENCIES serialization) - set(_Boost_MPI_PYTHON_DEPENDENCIES python mpi serialization) + set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization) set(_Boost_THREAD_DEPENDENCIES date_time) set(_Boost_TIMER_DEPENDENCIES chrono system) set(_Boost_WAVE_DEPENDENCIES filesystem system serialization thread date_time) @@ -669,7 +659,7 @@ function(_Boost_COMPONENT_DEPENDENCIES component _ret) set(_Boost_IOSTREAMS_DEPENDENCIES regex) set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l regex random) set(_Boost_MPI_DEPENDENCIES serialization) - set(_Boost_MPI_PYTHON_DEPENDENCIES python mpi serialization) + set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization) set(_Boost_THREAD_DEPENDENCIES chrono system date_time) set(_Boost_TIMER_DEPENDENCIES chrono system) set(_Boost_WAVE_DEPENDENCIES filesystem system serialization thread chrono date_time) @@ -681,7 +671,7 @@ function(_Boost_COMPONENT_DEPENDENCIES component _ret) set(_Boost_IOSTREAMS_DEPENDENCIES regex) set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l regex random) set(_Boost_MPI_DEPENDENCIES serialization) - set(_Boost_MPI_PYTHON_DEPENDENCIES python mpi serialization) + set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization) set(_Boost_THREAD_DEPENDENCIES chrono system date_time atomic) set(_Boost_TIMER_DEPENDENCIES chrono system) set(_Boost_WAVE_DEPENDENCIES filesystem system serialization thread chrono date_time) @@ -694,7 +684,7 @@ function(_Boost_COMPONENT_DEPENDENCIES component _ret) set(_Boost_LOG_DEPENDENCIES log_setup date_time system filesystem thread regex chrono) set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l regex random) set(_Boost_MPI_DEPENDENCIES serialization) - set(_Boost_MPI_PYTHON_DEPENDENCIES python mpi serialization) + set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization) set(_Boost_THREAD_DEPENDENCIES chrono system date_time atomic) set(_Boost_TIMER_DEPENDENCIES chrono system) set(_Boost_WAVE_DEPENDENCIES filesystem system serialization thread chrono date_time atomic) @@ -707,7 +697,7 @@ function(_Boost_COMPONENT_DEPENDENCIES component _ret) set(_Boost_LOG_DEPENDENCIES log_setup date_time system filesystem thread regex chrono) set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l regex random) set(_Boost_MPI_DEPENDENCIES serialization) - set(_Boost_MPI_PYTHON_DEPENDENCIES python mpi serialization) + set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization) set(_Boost_THREAD_DEPENDENCIES chrono system date_time atomic) set(_Boost_TIMER_DEPENDENCIES chrono system) set(_Boost_WAVE_DEPENDENCIES filesystem system serialization thread chrono date_time atomic) @@ -720,7 +710,7 @@ function(_Boost_COMPONENT_DEPENDENCIES component _ret) set(_Boost_LOG_DEPENDENCIES log_setup date_time system filesystem thread regex chrono) set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l atomic) set(_Boost_MPI_DEPENDENCIES serialization) - set(_Boost_MPI_PYTHON_DEPENDENCIES python mpi serialization) + set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization) set(_Boost_RANDOM_DEPENDENCIES system) set(_Boost_THREAD_DEPENDENCIES chrono system date_time atomic) set(_Boost_TIMER_DEPENDENCIES chrono system) @@ -734,7 +724,7 @@ function(_Boost_COMPONENT_DEPENDENCIES component _ret) set(_Boost_LOG_DEPENDENCIES log_setup date_time system filesystem thread regex chrono atomic) set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l atomic) set(_Boost_MPI_DEPENDENCIES serialization) - set(_Boost_MPI_PYTHON_DEPENDENCIES python mpi serialization) + set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization) set(_Boost_RANDOM_DEPENDENCIES system) set(_Boost_THREAD_DEPENDENCIES chrono system date_time atomic) set(_Boost_TIMER_DEPENDENCIES chrono system) @@ -748,7 +738,7 @@ function(_Boost_COMPONENT_DEPENDENCIES component _ret) set(_Boost_LOG_DEPENDENCIES date_time log_setup system filesystem thread regex chrono atomic) set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l atomic) set(_Boost_MPI_DEPENDENCIES serialization) - set(_Boost_MPI_PYTHON_DEPENDENCIES python mpi serialization) + set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization) set(_Boost_RANDOM_DEPENDENCIES system) set(_Boost_THREAD_DEPENDENCIES chrono system date_time atomic) set(_Boost_TIMER_DEPENDENCIES chrono system) @@ -763,7 +753,7 @@ function(_Boost_COMPONENT_DEPENDENCIES component _ret) set(_Boost_LOG_DEPENDENCIES date_time log_setup system filesystem thread regex chrono atomic) set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l atomic) set(_Boost_MPI_DEPENDENCIES serialization) - set(_Boost_MPI_PYTHON_DEPENDENCIES python mpi serialization) + set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization) set(_Boost_RANDOM_DEPENDENCIES system) set(_Boost_THREAD_DEPENDENCIES chrono system date_time atomic) set(_Boost_WAVE_DEPENDENCIES filesystem system serialization thread chrono date_time atomic) @@ -778,7 +768,7 @@ function(_Boost_COMPONENT_DEPENDENCIES component _ret) set(_Boost_LOG_DEPENDENCIES date_time log_setup system filesystem thread regex chrono atomic) set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l atomic) set(_Boost_MPI_DEPENDENCIES serialization) - set(_Boost_MPI_PYTHON_DEPENDENCIES python mpi serialization) + set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization) set(_Boost_RANDOM_DEPENDENCIES system) set(_Boost_THREAD_DEPENDENCIES chrono system date_time atomic) set(_Boost_WAVE_DEPENDENCIES filesystem system serialization thread chrono date_time atomic) @@ -794,28 +784,28 @@ function(_Boost_COMPONENT_DEPENDENCIES component _ret) set(_Boost_LOG_DEPENDENCIES date_time log_setup system filesystem thread regex chrono atomic) set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l atomic) set(_Boost_MPI_DEPENDENCIES serialization) - set(_Boost_MPI_PYTHON_DEPENDENCIES python mpi serialization) + set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization) set(_Boost_RANDOM_DEPENDENCIES system) set(_Boost_THREAD_DEPENDENCIES chrono system date_time atomic) set(_Boost_WAVE_DEPENDENCIES filesystem system serialization thread chrono date_time atomic) set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) elseif(NOT Boost_VERSION VERSION_LESS 106500 AND Boost_VERSION VERSION_LESS 106700) - set(_Boost_CHRONO_DEPENDENCIES system) - set(_Boost_CONTEXT_DEPENDENCIES thread chrono system date_time) - set(_Boost_COROUTINE_DEPENDENCIES context system) - set(_Boost_FIBER_DEPENDENCIES context thread chrono system date_time) - set(_Boost_FILESYSTEM_DEPENDENCIES system) - set(_Boost_IOSTREAMS_DEPENDENCIES regex) - set(_Boost_LOG_DEPENDENCIES date_time log_setup system filesystem thread regex chrono atomic) - set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l atomic) - set(_Boost_MPI_DEPENDENCIES serialization) - set(_Boost_MPI_PYTHON_DEPENDENCIES python mpi serialization) - set(_Boost_NUMPY_DEPENDENCIES python) - set(_Boost_RANDOM_DEPENDENCIES system) - set(_Boost_THREAD_DEPENDENCIES chrono system date_time atomic) - set(_Boost_TIMER_DEPENDENCIES chrono system) - set(_Boost_WAVE_DEPENDENCIES filesystem system serialization thread chrono date_time atomic) - set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) + set(_Boost_CHRONO_DEPENDENCIES system) + set(_Boost_CONTEXT_DEPENDENCIES thread chrono system date_time) + set(_Boost_COROUTINE_DEPENDENCIES context system) + set(_Boost_FIBER_DEPENDENCIES context thread chrono system date_time) + set(_Boost_FILESYSTEM_DEPENDENCIES system) + set(_Boost_IOSTREAMS_DEPENDENCIES regex) + set(_Boost_LOG_DEPENDENCIES date_time log_setup system filesystem thread regex chrono atomic) + set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l atomic) + set(_Boost_MPI_DEPENDENCIES serialization) + set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization) + set(_Boost_NUMPY_DEPENDENCIES python${component_python_version}) + set(_Boost_RANDOM_DEPENDENCIES system) + set(_Boost_THREAD_DEPENDENCIES chrono system date_time atomic) + set(_Boost_TIMER_DEPENDENCIES chrono system) + set(_Boost_WAVE_DEPENDENCIES filesystem system serialization thread chrono date_time atomic) + set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) else() if(NOT Boost_VERSION VERSION_LESS 106700) set(_Boost_CHRONO_DEPENDENCIES system) @@ -1009,21 +999,12 @@ function(_Boost_UPDATE_WINDOWS_LIBRARY_SEARCH_DIRS_WITH_PREBUILT_PATHS component else() set(_arch_suffix 32) endif() - if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 19.10) + if(MSVC_TOOLSET_VERSION GREATER_EQUAL 141) list(APPEND ${componentlibvar} ${basedir}/lib${_arch_suffix}-msvc-14.1) list(APPEND ${componentlibvar} ${basedir}/lib${_arch_suffix}-msvc-14.0) - elseif(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 19) - list(APPEND ${componentlibvar} ${basedir}/lib${_arch_suffix}-msvc-14.0) - elseif(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 18) - list(APPEND ${componentlibvar} ${basedir}/lib${_arch_suffix}-msvc-12.0) - elseif(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 17) - list(APPEND ${componentlibvar} ${basedir}/lib${_arch_suffix}-msvc-11.0) - elseif(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 16) - list(APPEND ${componentlibvar} ${basedir}/lib${_arch_suffix}-msvc-10.0) - elseif(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 15) - list(APPEND ${componentlibvar} ${basedir}/lib${_arch_suffix}-msvc-9.0) - elseif(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 14) - list(APPEND ${componentlibvar} ${basedir}/lib${_arch_suffix}-msvc-8.0) + elseif(MSVC_TOOLSET_VERSION GREATER_EQUAL 80) + math(EXPR _toolset_major_version "${MSVC_TOOLSET_VERSION} / 10") + list(APPEND ${componentlibvar} ${basedir}/lib${_arch_suffix}-msvc-${_toolset_major_version}.0) endif() set(${componentlibvar} ${${componentlibvar}} PARENT_SCOPE) endif() diff --git a/Modules/FindCUDA.cmake b/Modules/FindCUDA.cmake index 0a31ac2..874fb89 100644 --- a/Modules/FindCUDA.cmake +++ b/Modules/FindCUDA.cmake @@ -175,7 +175,7 @@ # -- Same as CUDA_ADD_EXECUTABLE except that a library is created. # # CUDA_BUILD_CLEAN_TARGET() -# -- Creates a convience target that deletes all the dependency files +# -- Creates a convenience target that deletes all the dependency files # generated. You should make clean after running this target to ensure the # dependency files get regenerated. # @@ -557,6 +557,11 @@ else() set(c_compiler_realpath "") endif() set(CUDA_HOST_COMPILER "${c_compiler_realpath}" CACHE FILEPATH "Host side compiler used by NVCC") + elseif(MSVC AND "${CMAKE_C_COMPILER}" MATCHES "clcache|sccache") + # NVCC does not think it will work if it is passed clcache.exe or sccache.exe + # as the host compiler, which means that builds with CC=cl.exe won't work. + # Best to just feed it whatever the actual cl.exe is as the host compiler. + set(CUDA_HOST_COMPILER "cl.exe" CACHE FILEPATH "Host side compiler used by NVCC") else() set(CUDA_HOST_COMPILER "${CMAKE_C_COMPILER}" CACHE FILEPATH "Host side compiler used by NVCC") @@ -733,16 +738,20 @@ endif() # CUDA_NVCC_EXECUTABLE -cuda_find_host_program(CUDA_NVCC_EXECUTABLE - NAMES nvcc - PATHS "${CUDA_TOOLKIT_ROOT_DIR}" - ENV CUDA_PATH - ENV CUDA_BIN_PATH - PATH_SUFFIXES bin bin64 - NO_DEFAULT_PATH - ) -# Search default search paths, after we search our own set of paths. -cuda_find_host_program(CUDA_NVCC_EXECUTABLE nvcc) +if(DEFINED ENV{CUDA_NVCC_EXECUTABLE}) + set(CUDA_NVCC_EXECUTABLE "$ENV{CUDA_NVCC_EXECUTABLE}" CACHE FILEPATH "The CUDA compiler") +else() + cuda_find_host_program(CUDA_NVCC_EXECUTABLE + NAMES nvcc + PATHS "${CUDA_TOOLKIT_ROOT_DIR}" + ENV CUDA_PATH + ENV CUDA_BIN_PATH + PATH_SUFFIXES bin bin64 + NO_DEFAULT_PATH + ) + # Search default search paths, after we search our own set of paths. + cuda_find_host_program(CUDA_NVCC_EXECUTABLE nvcc) +endif() mark_as_advanced(CUDA_NVCC_EXECUTABLE) if(CUDA_NVCC_EXECUTABLE AND NOT CUDA_VERSION) @@ -1564,7 +1573,7 @@ macro(CUDA_WRAP_SRCS cuda_target format generated_files) # Bring in the dependencies. Creates a variable CUDA_NVCC_DEPEND ####### cuda_include_nvcc_dependencies(${cmake_dependency_file}) - # Convience string for output ########################################### + # Convenience string for output ######################################### if(CUDA_BUILD_EMULATION) set(cuda_build_type "Emulation") else() @@ -1760,7 +1769,7 @@ function(CUDA_LINK_SEPARABLE_COMPILATION_OBJECTS output_file cuda_target options add_custom_command( OUTPUT ${output_file} DEPENDS ${object_files} - COMMAND ${CUDA_NVCC_EXECUTABLE} ${nvcc_flags} -dlink ${object_files} ${CUDA_cublas_device_LIBRARY} -o ${output_file} + COMMAND ${CUDA_NVCC_EXECUTABLE} ${nvcc_flags} -dlink ${object_files} -o ${output_file} ${flags} COMMENT "Building NVCC intermediate link file ${output_file_relative_path}" COMMAND_EXPAND_LISTS @@ -1773,7 +1782,7 @@ function(CUDA_LINK_SEPARABLE_COMPILATION_OBJECTS output_file cuda_target options PRE_LINK COMMAND ${CMAKE_COMMAND} -E echo "Building NVCC intermediate link file ${output_file_relative_path}" COMMAND ${CMAKE_COMMAND} -E make_directory "${output_file_dir}" - COMMAND ${CUDA_NVCC_EXECUTABLE} ${nvcc_flags} ${flags} -dlink ${object_files} ${CUDA_cublas_device_LIBRARY} -o "${output_file}" + COMMAND ${CUDA_NVCC_EXECUTABLE} ${nvcc_flags} ${flags} -dlink ${object_files} -o "${output_file}" COMMAND_EXPAND_LISTS ${_verbatim} ) @@ -1975,9 +1984,9 @@ endmacro() ############################################################################### ############################################################################### macro(CUDA_BUILD_CLEAN_TARGET) - # Call this after you add all your CUDA targets, and you will get a convience - # target. You should also make clean after running this target to get the - # build system to generate all the code again. + # Call this after you add all your CUDA targets, and you will get a + # convenience target. You should also make clean after running this target + # to get the build system to generate all the code again. set(cuda_clean_target_name clean_cuda_depends) if (CMAKE_GENERATOR MATCHES "Visual Studio") diff --git a/Modules/FindCUDA/select_compute_arch.cmake b/Modules/FindCUDA/select_compute_arch.cmake index b604a17..22c04df 100644 --- a/Modules/FindCUDA/select_compute_arch.cmake +++ b/Modules/FindCUDA/select_compute_arch.cmake @@ -17,29 +17,55 @@ # More info on CUDA architectures: https://en.wikipedia.org/wiki/CUDA # +if(CMAKE_CUDA_COMPILER_LOADED) # CUDA as a language + if(CMAKE_CUDA_COMPILER_ID STREQUAL "NVIDIA") + set(CUDA_VERSION "${CMAKE_CUDA_COMPILER_VERSION}") + endif() +endif() + +# See: https://docs.nvidia.com/cuda/cuda-compiler-driver-nvcc/index.html#gpu-feature-list + # This list will be used for CUDA_ARCH_NAME = All option set(CUDA_KNOWN_GPU_ARCHITECTURES "Fermi" "Kepler" "Maxwell") # This list will be used for CUDA_ARCH_NAME = Common option (enabled by default) set(CUDA_COMMON_GPU_ARCHITECTURES "3.0" "3.5" "5.0") -if (CUDA_VERSION VERSION_GREATER "6.5") +if(CUDA_VERSION VERSION_LESS "7.0") + set(CUDA_LIMIT_GPU_ARCHITECTURE "5.2") +endif() + +# This list is used to filter CUDA archs when autodetecting +set(CUDA_ALL_GPU_ARCHITECTURES "3.0" "3.2" "3.5" "5.0") + +if(CUDA_VERSION VERSION_GREATER_EQUAL "7.0") list(APPEND CUDA_KNOWN_GPU_ARCHITECTURES "Kepler+Tegra" "Kepler+Tesla" "Maxwell+Tegra") list(APPEND CUDA_COMMON_GPU_ARCHITECTURES "5.2") -endif () -if (CUDA_VERSION VERSION_GREATER "7.5") + if(CUDA_VERSION VERSION_LESS "8.0") + list(APPEND CUDA_COMMON_GPU_ARCHITECTURES "5.2+PTX") + set(CUDA_LIMIT_GPU_ARCHITECTURE "6.0") + endif() +endif() + +if(CUDA_VERSION VERSION_GREATER_EQUAL "8.0") list(APPEND CUDA_KNOWN_GPU_ARCHITECTURES "Pascal") list(APPEND CUDA_COMMON_GPU_ARCHITECTURES "6.0" "6.1") -else() - list(APPEND CUDA_COMMON_GPU_ARCHITECTURES "5.2+PTX") + list(APPEND CUDA_ALL_GPU_ARCHITECTURES "6.0" "6.1" "6.2") + + if(CUDA_VERSION VERSION_LESS "9.0") + list(APPEND CUDA_COMMON_GPU_ARCHITECTURES "6.1+PTX") + set(CUDA_LIMIT_GPU_ARCHITECTURE "7.0") + endif() endif () -if (CUDA_VERSION VERSION_GREATER "8.5") +if(CUDA_VERSION VERSION_GREATER_EQUAL "9.0") list(APPEND CUDA_KNOWN_GPU_ARCHITECTURES "Volta") list(APPEND CUDA_COMMON_GPU_ARCHITECTURES "7.0" "7.0+PTX") -else() - list(APPEND CUDA_COMMON_GPU_ARCHITECTURES "6.1+PTX") + + if(CUDA_VERSION VERSION_LESS "10.0") + set(CUDA_LIMIT_GPU_ARCHITECTURE "8.0") + endif() endif() ################################################################################################ @@ -49,7 +75,11 @@ endif() # function(CUDA_DETECT_INSTALLED_GPUS OUT_VARIABLE) if(NOT CUDA_GPU_DETECT_OUTPUT) - set(file ${PROJECT_BINARY_DIR}/detect_cuda_compute_capabilities.cpp) + if(CMAKE_CUDA_COMPILER_LOADED) # CUDA as a language + set(file "${PROJECT_BINARY_DIR}/detect_cuda_compute_capabilities.cu") + else() + set(file "${PROJECT_BINARY_DIR}/detect_cuda_compute_capabilities.cpp") + endif() file(WRITE ${file} "" "#include <cuda_runtime.h>\n" @@ -68,10 +98,15 @@ function(CUDA_DETECT_INSTALLED_GPUS OUT_VARIABLE) " return 0;\n" "}\n") - try_run(run_result compile_result ${PROJECT_BINARY_DIR} ${file} - CMAKE_FLAGS "-DINCLUDE_DIRECTORIES=${CUDA_INCLUDE_DIRS}" - LINK_LIBRARIES ${CUDA_LIBRARIES} - RUN_OUTPUT_VARIABLE compute_capabilities) + if(CMAKE_CUDA_COMPILER_LOADED) # CUDA as a language + try_run(run_result compile_result ${PROJECT_BINARY_DIR} ${file} + RUN_OUTPUT_VARIABLE compute_capabilities) + else() + try_run(run_result compile_result ${PROJECT_BINARY_DIR} ${file} + CMAKE_FLAGS "-DINCLUDE_DIRECTORIES=${CUDA_INCLUDE_DIRS}" + LINK_LIBRARIES ${CUDA_LIBRARIES} + RUN_OUTPUT_VARIABLE compute_capabilities) + endif() if(run_result EQUAL 0) string(REPLACE "2.1" "2.1(2.0)" compute_capabilities "${compute_capabilities}") @@ -84,7 +119,19 @@ function(CUDA_DETECT_INSTALLED_GPUS OUT_VARIABLE) message(STATUS "Automatic GPU detection failed. Building for common architectures.") set(${OUT_VARIABLE} ${CUDA_COMMON_GPU_ARCHITECTURES} PARENT_SCOPE) else() - set(${OUT_VARIABLE} ${CUDA_GPU_DETECT_OUTPUT} PARENT_SCOPE) + # Filter based on CUDA version supported archs + set(CUDA_GPU_DETECT_OUTPUT_FILTERED "") + separate_arguments(CUDA_GPU_DETECT_OUTPUT) + foreach(ITEM IN ITEMS ${CUDA_GPU_DETECT_OUTPUT}) + if(CUDA_LIMIT_GPU_ARCHITECTURE AND ITEM VERSION_GREATER_EQUAL CUDA_LIMIT_GPU_ARCHITECTURE) + list(GET CUDA_COMMON_GPU_ARCHITECTURES -1 NEWITEM) + string(APPEND CUDA_GPU_DETECT_OUTPUT_FILTERED " ${NEWITEM}") + else() + string(APPEND CUDA_GPU_DETECT_OUTPUT_FILTERED " ${ITEM}") + endif() + endforeach() + + set(${OUT_VARIABLE} ${CUDA_GPU_DETECT_OUTPUT_FILTERED} PARENT_SCOPE) endif() endfunction() diff --git a/Modules/FindCURL.cmake b/Modules/FindCURL.cmake index f4bcc36..e66ae92 100644 --- a/Modules/FindCURL.cmake +++ b/Modules/FindCURL.cmake @@ -5,16 +5,30 @@ # FindCURL # -------- # -# Find curl -# # Find the native CURL headers and libraries. # -# :: +# IMPORTED Targets +# ^^^^^^^^^^^^^^^^ +# +# This module defines :prop_tgt:`IMPORTED` target ``CURL::CURL``, if +# curl has been found. +# +# Result Variables +# ^^^^^^^^^^^^^^^^ +# +# This module defines the following variables: # -# CURL_INCLUDE_DIRS - where to find curl/curl.h, etc. -# CURL_LIBRARIES - List of libraries when using curl. -# CURL_FOUND - True if curl found. -# CURL_VERSION_STRING - the version of curl found (since CMake 2.8.8) +# ``CURL_FOUND`` +# True if curl found. +# +# ``CURL_INCLUDE_DIRS`` +# where to find curl/curl.h, etc. +# +# ``CURL_LIBRARIES`` +# List of libraries when using curl. +# +# ``CURL_VERSION_STRING`` +# The version of curl found. # Look for the header file. find_path(CURL_INCLUDE_DIR NAMES curl/curl.h) @@ -52,4 +66,10 @@ FIND_PACKAGE_HANDLE_STANDARD_ARGS(CURL if(CURL_FOUND) set(CURL_LIBRARIES ${CURL_LIBRARY}) set(CURL_INCLUDE_DIRS ${CURL_INCLUDE_DIR}) + + if(NOT TARGET CURL::CURL) + add_library(CURL::CURL UNKNOWN IMPORTED) + set_target_properties(CURL::CURL PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${CURL_INCLUDE_DIRS}") + set_property(TARGET CURL::CURL APPEND PROPERTY IMPORTED_LOCATION "${CURL_LIBRARY}") + endif() endif() diff --git a/Modules/FindCxxTest.cmake b/Modules/FindCxxTest.cmake index 2aa5f6f..25454fd 100644 --- a/Modules/FindCxxTest.cmake +++ b/Modules/FindCxxTest.cmake @@ -196,7 +196,7 @@ if(NOT DEFINED CXXTEST_TESTGEN_ARGS) set(CXXTEST_TESTGEN_ARGS --error-printer) endif() -find_package(PythonInterp QUIET) +find_package(Python QUIET) find_package(Perl QUIET) find_path(CXXTEST_INCLUDE_DIR cxxtest/TestSuite.h) @@ -206,17 +206,17 @@ find_program(CXXTEST_PYTHON_TESTGEN_EXECUTABLE find_program(CXXTEST_PERL_TESTGEN_EXECUTABLE cxxtestgen.pl PATHS ${CXXTEST_INCLUDE_DIR}) -if(PYTHONINTERP_FOUND OR PERL_FOUND) +if(PYTHON_FOUND OR PERL_FOUND) include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) - if(PYTHONINTERP_FOUND AND (CXXTEST_USE_PYTHON OR NOT PERL_FOUND OR NOT DEFINED CXXTEST_USE_PYTHON)) + if(PYTHON_FOUND AND (CXXTEST_USE_PYTHON OR NOT PERL_FOUND OR NOT DEFINED CXXTEST_USE_PYTHON)) set(CXXTEST_TESTGEN_EXECUTABLE ${CXXTEST_PYTHON_TESTGEN_EXECUTABLE}) execute_process(COMMAND ${CXXTEST_PYTHON_TESTGEN_EXECUTABLE} --version OUTPUT_VARIABLE _CXXTEST_OUT ERROR_VARIABLE _CXXTEST_OUT RESULT_VARIABLE _CXXTEST_RESULT) if(_CXXTEST_RESULT EQUAL 0) set(CXXTEST_TESTGEN_INTERPRETER "") else() - set(CXXTEST_TESTGEN_INTERPRETER ${PYTHON_EXECUTABLE}) + set(CXXTEST_TESTGEN_INTERPRETER ${Python_EXECUTABLE}) endif() FIND_PACKAGE_HANDLE_STANDARD_ARGS(CxxTest DEFAULT_MSG CXXTEST_INCLUDE_DIR CXXTEST_PYTHON_TESTGEN_EXECUTABLE) diff --git a/Modules/FindDCMTK.cmake b/Modules/FindDCMTK.cmake index f348d3a..39c1a5b 100644 --- a/Modules/FindDCMTK.cmake +++ b/Modules/FindDCMTK.cmake @@ -301,7 +301,7 @@ endif() # Compatibility: This variable is deprecated set(DCMTK_INCLUDE_DIR ${DCMTK_INCLUDE_DIRS}) -include(FindPackageHandleStandardArgs) +include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) find_package_handle_standard_args(DCMTK REQUIRED_VARS ${DCMTK_INCLUDE_DIR_NAMES} DCMTK_LIBRARIES FAIL_MESSAGE "Please set DCMTK_DIR and re-run configure") @@ -309,20 +309,14 @@ find_package_handle_standard_args(DCMTK # Workaround bug in packaging of DCMTK 3.6.0 on Debian. # See http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=637687 if(DCMTK_FOUND AND UNIX AND NOT APPLE) - include(CheckCXXSourceCompiles) + include(${CMAKE_CURRENT_LIST_DIR}/CheckIncludeFiles.cmake) set(CMAKE_REQUIRED_FLAGS ) set(CMAKE_REQUIRED_DEFINITIONS ) set(CMAKE_REQUIRED_INCLUDES ${DCMTK_INCLUDE_DIRS}) set(CMAKE_REQUIRED_LIBRARIES ${DCMTK_LIBRARIES}) set(CMAKE_REQUIRED_QUIET ${DCMTK_FIND_QUIETLY}) - check_cxx_source_compiles("#include <dcmtk/config/osconfig.h>\n#include <dcmtk/ofstd/ofstream.h>\nint main(int,char*[]){return 0;}" - DCMTK_HAVE_CONFIG_H_OPTIONAL - ) + check_include_files("dcmtk/config/osconfig.h;dcmtk/ofstd/ofstream.h" DCMTK_HAVE_CONFIG_H_OPTIONAL LANGUAGE CXX) if(NOT DCMTK_HAVE_CONFIG_H_OPTIONAL) set(DCMTK_DEFINITIONS "HAVE_CONFIG_H") endif() endif() - -if(NOT DCMTK_FIND_QUIETLY) - message(STATUS "Trying to find DCMTK relying on FindDCMTK.cmake - ok") -endif() diff --git a/Modules/FindGDAL.cmake b/Modules/FindGDAL.cmake index 2b940b0..ff2976e 100644 --- a/Modules/FindGDAL.cmake +++ b/Modules/FindGDAL.cmake @@ -66,11 +66,49 @@ if(UNIX) if(GDAL_CONFIG) exec_program(${GDAL_CONFIG} ARGS --libs OUTPUT_VARIABLE GDAL_CONFIG_LIBS) + if(GDAL_CONFIG_LIBS) - string(REGEX MATCHALL "-l[^ ]+" _gdal_dashl ${GDAL_CONFIG_LIBS}) - string(REPLACE "-l" "" _gdal_lib "${_gdal_dashl}") - string(REGEX MATCHALL "-L[^ ]+" _gdal_dashL ${GDAL_CONFIG_LIBS}) - string(REPLACE "-L" "" _gdal_libpath "${_gdal_dashL}") + # treat the output as a command line and split it up + separate_arguments(args NATIVE_COMMAND "${GDAL_CONFIG_LIBS}") + + # only consider libraries whose name matches this pattern + set(name_pattern "[gG][dD][aA][lL]") + + # consider each entry as a possible library path, name, or parent directory + foreach(arg IN LISTS args) + # library name + if("${arg}" MATCHES "^-l(.*)$") + set(lib "${CMAKE_MATCH_1}") + + # only consider libraries whose name matches the expected pattern + if("${lib}" MATCHES "${name_pattern}") + list(APPEND _gdal_lib "${lib}") + endif() + # library search path + elseif("${arg}" MATCHES "^-L(.*)$") + list(APPEND _gdal_libpath "${CMAKE_MATCH_1}") + # assume this is a full path to a library + elseif(IS_ABSOLUTE "${arg}" AND EXISTS "${arg}") + # extract the file name + get_filename_component(lib "${arg}" NAME) + + # only consider libraries whose name matches the expected pattern + if(NOT "${lib}" MATCHES "${name_pattern}") + continue() + endif() + + # extract the file directory + get_filename_component(dir "${arg}" DIRECTORY) + + # remove library prefixes/suffixes + string(REGEX REPLACE "^(${CMAKE_SHARED_LIBRARY_PREFIX}|${CMAKE_STATIC_LIBRARY_PREFIX})" "" lib "${lib}") + string(REGEX REPLACE "(${CMAKE_SHARED_LIBRARY_SUFFIX}|${CMAKE_STATIC_LIBRARY_SUFFIX})$" "" lib "${lib}") + + # use the file name and directory as hints + list(APPEND _gdal_libpath "${dir}") + list(APPEND _gdal_lib "${lib}") + endif() + endforeach() endif() endif() endif() diff --git a/Modules/FindGTK2.cmake b/Modules/FindGTK2.cmake index 8d0da51..15d1230 100644 --- a/Modules/FindGTK2.cmake +++ b/Modules/FindGTK2.cmake @@ -352,13 +352,9 @@ function(_GTK2_FIND_LIBRARY _var _lib _expand_vc _append_version) if(_expand_vc AND MSVC) # Add vc80/vc90/vc100 midfixes - if(MSVC_VERSION EQUAL 1400) - set(_library ${_library}-vc80) - elseif(MSVC_VERSION EQUAL 1500) - set(_library ${_library}-vc90) - elseif(MSVC_VERSION EQUAL 1600) - set(_library ${_library}-vc100) - elseif(MSVC_VERSION EQUAL 1700) + if(MSVC_TOOLSET_VERSION LESS 110) + set(_library ${_library}-vc${MSVC_TOOLSET_VERSION}) + else() # Up to gtkmm-win 2.22.0-2 there are no vc110 libraries but vc100 can be used set(_library ${_library}-vc100) endif() diff --git a/Modules/FindIce.cmake b/Modules/FindIce.cmake index b37f796..df76e5a 100644 --- a/Modules/FindIce.cmake +++ b/Modules/FindIce.cmake @@ -255,21 +255,15 @@ function(_Ice_FIND) unset(vcvers) if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") - if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 19.10) + if(MSVC_TOOLSET_VERSION GREATER_EQUAL 141) set(vcvers "141;140") - elseif (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 19) - set(vcvers "140") - elseif(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 18) - set(vcvers "120") - elseif(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 17) - set(vcvers "110") - elseif(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 16) - set(vcvers "100") - elseif(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 15) - set(vcvers "90") + elseif(MSVC_TOOLSET_VERSION GREATER_EQUAL 100) + set(vcvers "${MSVC_TOOLSET_VERSION}") + elseif(MSVC_TOOLSET_VERSION GREATER_EQUAL 90) + set(vcvers "${MSVC_TOOLSET_VERSION}") set(vcyear "2008") - elseif(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 14) - set(vcvers "80") + elseif(MSVC_TOOLSET_VERSION GREATER_EQUAL 80) + set(vcvers "${MSVC_TOOLSET_VERSION}") set(vcyear "2005") else() # Unknown version set(vcvers Unknown) diff --git a/Modules/FindImageMagick.cmake b/Modules/FindImageMagick.cmake index 881bff1..6d94d3b 100644 --- a/Modules/FindImageMagick.cmake +++ b/Modules/FindImageMagick.cmake @@ -104,6 +104,7 @@ function(FIND_IMAGEMAGICK_API component header) PATH_SUFFIXES ImageMagick ImageMagick-6 ImageMagick-7 DOC "Path to the ImageMagick arch-independent include dir." + NO_DEFAULT_PATH ) find_path(ImageMagick_${component}_ARCH_INCLUDE_DIR NAMES magick/magick-baseconfig.h @@ -116,6 +117,7 @@ function(FIND_IMAGEMAGICK_API component header) PATH_SUFFIXES ImageMagick ImageMagick-6 ImageMagick-7 DOC "Path to the ImageMagick arch-specific include dir." + NO_DEFAULT_PATH ) find_library(ImageMagick_${component}_LIBRARY NAMES ${ARGN} @@ -125,6 +127,7 @@ function(FIND_IMAGEMAGICK_API component header) PATHS "[HKEY_LOCAL_MACHINE\\SOFTWARE\\ImageMagick\\Current;BinPath]/lib" DOC "Path to the ImageMagick Magick++ library." + NO_DEFAULT_PATH ) # old version have only indep dir diff --git a/Modules/FindJNI.cmake b/Modules/FindJNI.cmake index e31c19e..4913e05 100644 --- a/Modules/FindJNI.cmake +++ b/Modules/FindJNI.cmake @@ -120,14 +120,51 @@ if(_JAVA_HOME) ${_JAVA_HOME} ) endif() -get_filename_component(java_install_version - "[HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Development Kit;CurrentVersion]" NAME) -list(APPEND JAVA_AWT_LIBRARY_DIRECTORIES - "[HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Development Kit\\1.4;JavaHome]/lib" - "[HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Development Kit\\1.3;JavaHome]/lib" - "[HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Development Kit\\${java_install_version};JavaHome]/lib" - ) +if (WIN32) + set (_JNI_HINTS) + execute_process(COMMAND REG QUERY HKLM\\SOFTWARE\\JavaSoft\\JDK /f "." /k + RESULT_VARIABLE _JNI_RESULT + OUTPUT_VARIABLE _JNI_VERSIONS + ERROR_QUIET) + if (NOT _JNI_RESULT) + string (REGEX MATCHALL "HKEY_LOCAL_MACHINE\\\\SOFTWARE\\\\JavaSoft\\\\JDK\\\\[0-9.]+" _JNI_VERSIONS "${_JNI_VERSIONS}") + if (_JNI_VERSIONS) + # sort versions. Most recent first + ## handle version 9 apart from other versions to get correct ordering + set (_JNI_V9 ${_JNI_VERSIONS}) + list (FILTER _JNI_VERSIONS EXCLUDE REGEX "JDK\\\\9") + list (SORT _JNI_VERSIONS) + list (REVERSE _JNI_VERSIONS) + list (FILTER _JNI_V9 INCLUDE REGEX "JDK\\\\9") + list (SORT _JNI_V9) + list (REVERSE _JNI_V9) + list (APPEND _JNI_VERSIONS ${_JNI_V9}) + foreach (_JNI_HINT IN LISTS _JNI_VERSIONS) + list(APPEND _JNI_HINTS "[${_JNI_HINT};JavaHome]") + endforeach() + endif() + endif() + + foreach (_JNI_HINT IN LISTS _JNI_HINTS) + list(APPEND JAVA_AWT_LIBRARY_DIRECTORIES "${_JNI_HINT}/lib") + endforeach() + + get_filename_component(java_install_version + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Development Kit;CurrentVersion]" NAME) + + list(APPEND JAVA_AWT_LIBRARY_DIRECTORIES + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Development Kit\\1.9;JavaHome]/lib" + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Development Kit\\1.8;JavaHome]/lib" + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Development Kit\\1.7;JavaHome]/lib" + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Development Kit\\1.6;JavaHome]/lib" + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Development Kit\\1.5;JavaHome]/lib" + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Development Kit\\1.4;JavaHome]/lib" + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Development Kit\\1.3;JavaHome]/lib" + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Development Kit\\${java_install_version};JavaHome]/lib" + ) +endif() + JAVA_APPEND_LIBRARY_DIRECTORIES(JAVA_AWT_LIBRARY_DIRECTORIES /usr/lib/jvm/java/lib /usr/lib/java/jre/lib/{libarch} @@ -179,11 +216,21 @@ set(JAVA_AWT_INCLUDE_DIRECTORIES) if(_JAVA_HOME) list(APPEND JAVA_AWT_INCLUDE_DIRECTORIES ${_JAVA_HOME}/include) endif() -list(APPEND JAVA_AWT_INCLUDE_DIRECTORIES - "[HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Development Kit\\1.4;JavaHome]/include" - "[HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Development Kit\\1.3;JavaHome]/include" - "[HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Development Kit\\${java_install_version};JavaHome]/include" -) +if (WIN32) + foreach (_JNI_HINT IN LISTS _JNI_HINTS) + list(APPEND JAVA_AWT_INCLUDE_DIRECTORIES "${_JNI_HINT}/include") + endforeach() + list(APPEND JAVA_AWT_INCLUDE_DIRECTORIES + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Development Kit\\1.9;JavaHome]/include" + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Development Kit\\1.8;JavaHome]/include" + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Development Kit\\1.7;JavaHome]/include" + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Development Kit\\1.6;JavaHome]/include" + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Development Kit\\1.5;JavaHome]/include" + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Development Kit\\1.4;JavaHome]/include" + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Development Kit\\1.3;JavaHome]/include" + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Development Kit\\${java_install_version};JavaHome]/include" + ) +endif() JAVA_APPEND_LIBRARY_DIRECTORIES(JAVA_AWT_INCLUDE_DIRECTORIES /usr/lib/java/include @@ -330,4 +377,3 @@ set(JNI_INCLUDE_DIRS ${JAVA_INCLUDE_PATH2} ${JAVA_AWT_INCLUDE_PATH} ) - diff --git a/Modules/FindJPEG.cmake b/Modules/FindJPEG.cmake index e233714..61a2213 100644 --- a/Modules/FindJPEG.cmake +++ b/Modules/FindJPEG.cmake @@ -5,38 +5,127 @@ # FindJPEG # -------- # -# Find JPEG +# Find the JPEG library (libjpeg) # -# Find the native JPEG includes and library This module defines +# Imported targets +# ^^^^^^^^^^^^^^^^ # -# :: +# This module defines the following :prop_tgt:`IMPORTED` targets: # -# JPEG_INCLUDE_DIR, where to find jpeglib.h, etc. -# JPEG_LIBRARIES, the libraries needed to use JPEG. -# JPEG_FOUND, If false, do not try to use JPEG. +# ``JPEG::JPEG`` +# The JPEG library, if found. # -# also defined, but not for general use are +# Result variables +# ^^^^^^^^^^^^^^^^ # -# :: +# This module will set the following variables in your project: # -# JPEG_LIBRARY, where to find the JPEG library. +# ``JPEG_FOUND`` +# If false, do not try to use JPEG. +# ``JPEG_INCLUDE_DIRS`` +# where to find jpeglib.h, etc. +# ``JPEG_LIBRARIES`` +# the libraries needed to use JPEG. +# ``JPEG_VERSION`` +# the version of the JPEG library found +# +# Cache variables +# ^^^^^^^^^^^^^^^ +# +# The following cache variables may also be set: +# +# ``JPEG_INCLUDE_DIRS`` +# where to find jpeglib.h, etc. +# ``JPEG_LIBRARY_RELEASE`` +# where to find the JPEG library (optimized). +# ``JPEG_LIBRARY_DEBUG`` +# where to find the JPEG library (debug). +# +# Obsolete variables +# ^^^^^^^^^^^^^^^^^^ +# +# ``JPEG_INCLUDE_DIR`` +# where to find jpeglib.h, etc. (same as JPEG_INCLUDE_DIRS) +# ``JPEG_LIBRARY`` +# where to find the JPEG library. find_path(JPEG_INCLUDE_DIR jpeglib.h) -set(JPEG_NAMES ${JPEG_NAMES} jpeg libjpeg) -find_library(JPEG_LIBRARY NAMES ${JPEG_NAMES} ) +set(jpeg_names ${JPEG_NAMES} jpeg jpeg-static libjpeg libjpeg-static) +foreach(name ${JPEG_NAMES}) + list(APPEND jpeg_names_debug "${name}d") +endforeach() + +if(NOT JPEG_LIBRARY) + find_library(JPEG_LIBRARY_RELEASE NAMES ${jpeg_names}) + find_library(JPEG_LIBRARY_DEBUG NAMES ${jpeg_names_debug}) + include(${CMAKE_CURRENT_LIST_DIR}/SelectLibraryConfigurations.cmake) + select_library_configurations(JPEG) + mark_as_advanced(JPEG_LIBRARY_RELEASE JPEG_LIBRARY_DEBUG) +endif() +unset(jpeg_names) +unset(jpeg_names_debug) + +if(JPEG_INCLUDE_DIR AND EXISTS "${JPEG_INCLUDE_DIR}/jpeglib.h") + file(STRINGS "${JPEG_INCLUDE_DIR}/jpeglib.h" + jpeg_lib_version REGEX "^#define[\t ]+JPEG_LIB_VERSION[\t ]+.*") + + if (NOT jpeg_lib_version) + # libjpeg-turbo sticks JPEG_LIB_VERSION in jconfig.h + find_path(jconfig_dir jconfig.h) + if (jconfig_dir) + file(STRINGS "${jconfig_dir}/jconfig.h" + jpeg_lib_version REGEX "^#define[\t ]+JPEG_LIB_VERSION[\t ]+.*") + endif() + unset(jconfig_dir) + endif() + + string(REGEX REPLACE "^#define[\t ]+JPEG_LIB_VERSION[\t ]+([0-9]+).*" + "\\1" JPEG_VERSION "${jpeg_lib_version}") + unset(jpeg_lib_version) +endif() include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) -FIND_PACKAGE_HANDLE_STANDARD_ARGS(JPEG DEFAULT_MSG JPEG_LIBRARY JPEG_INCLUDE_DIR) +find_package_handle_standard_args(JPEG + REQUIRED_VARS JPEG_LIBRARY JPEG_INCLUDE_DIR + VERSION_VAR JPEG_VERSION) if(JPEG_FOUND) set(JPEG_LIBRARIES ${JPEG_LIBRARY}) + set(JPEG_INCLUDE_DIRS "${JPEG_INCLUDE_DIR}") + + if(NOT TARGET JPEG::JPEG) + add_library(JPEG::JPEG UNKNOWN IMPORTED) + if(JPEG_INCLUDE_DIRS) + set_target_properties(JPEG::JPEG PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES "${JPEG_INCLUDE_DIRS}") + endif() + if(EXISTS "${JPEG_LIBRARY}") + set_target_properties(JPEG::JPEG PROPERTIES + IMPORTED_LINK_INTERFACE_LANGUAGES "C" + IMPORTED_LOCATION "${JPEG_LIBRARY}") + endif() + if(EXISTS "${JPEG_LIBRARY_RELEASE}") + set_property(TARGET JPEG::JPEG APPEND PROPERTY + IMPORTED_CONFIGURATIONS RELEASE) + set_target_properties(JPEG::JPEG PROPERTIES + IMPORTED_LINK_INTERFACE_LANGUAGES_RELEASE "C" + IMPORTED_LOCATION_RELEASE "${JPEG_LIBRARY_RELEASE}") + endif() + if(EXISTS "${JPEG_LIBRARY_DEBUG}") + set_property(TARGET JPEG::JPEG APPEND PROPERTY + IMPORTED_CONFIGURATIONS DEBUG) + set_target_properties(JPEG::JPEG PROPERTIES + IMPORTED_LINK_INTERFACE_LANGUAGES_DEBUG "C" + IMPORTED_LOCATION_DEBUG "${JPEG_LIBRARY_DEBUG}") + endif() + endif() endif() # Deprecated declarations. -set (NATIVE_JPEG_INCLUDE_PATH ${JPEG_INCLUDE_DIR} ) +set(NATIVE_JPEG_INCLUDE_PATH ${JPEG_INCLUDE_DIR}) if(JPEG_LIBRARY) - get_filename_component (NATIVE_JPEG_LIB_PATH ${JPEG_LIBRARY} PATH) + get_filename_component(NATIVE_JPEG_LIB_PATH ${JPEG_LIBRARY} PATH) endif() -mark_as_advanced(JPEG_LIBRARY JPEG_INCLUDE_DIR ) +mark_as_advanced(JPEG_LIBRARY JPEG_INCLUDE_DIR) diff --git a/Modules/FindJava.cmake b/Modules/FindJava.cmake index e3f5af6..cddc5d2 100644 --- a/Modules/FindJava.cmake +++ b/Modules/FindJava.cmake @@ -18,7 +18,7 @@ # :: # # Runtime = User just want to execute some Java byte-compiled -# Development = Development tools (java, javac, javah and javadoc), includes Runtime component +# Development = Development tools (java, javac, javah, jar and javadoc), includes Runtime component # IdlJ = idl compiler for Java # JarSigner = signer tool for jar # @@ -77,8 +77,37 @@ set(_JAVA_HINTS) if(_JAVA_HOME) list(APPEND _JAVA_HINTS ${_JAVA_HOME}/bin) endif() -list(APPEND _JAVA_HINTS - "[HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Development Kit\\2.0;JavaHome]/bin" +if (WIN32) + macro (_JAVA_GET_INSTALLED_VERSIONS _KIND) + execute_process(COMMAND REG QUERY HKLM\\SOFTWARE\\JavaSoft\\${_KIND} /f "." /k + RESULT_VARIABLE _JAVA_RESULT + OUTPUT_VARIABLE _JAVA_VERSIONS + ERROR_QUIET) + if (NOT _JAVA_RESULT) + string (REGEX MATCHALL "HKEY_LOCAL_MACHINE\\\\SOFTWARE\\\\JavaSoft\\\\${_KIND}\\\\[0-9.]+" _JAVA_VERSIONS "${_JAVA_VERSIONS}") + if (_JAVA_VERSIONS) + # sort versions. Most recent first + ## handle version 9 apart from other versions to get correct ordering + set (_JAVA_V9 ${_JAVA_VERSIONS}) + list (FILTER _JAVA_VERSIONS EXCLUDE REGEX "${_KIND}\\\\9") + list (SORT _JAVA_VERSIONS) + list (REVERSE _JAVA_VERSIONS) + list (FILTER _JAVA_V9 INCLUDE REGEX "${_KIND}\\\\9") + list (SORT _JAVA_V9) + list (REVERSE _JAVA_V9) + list (APPEND _JAVA_VERSIONS ${_JAVA_V9}) + foreach (_JAVA_HINT IN LISTS _JAVA_VERSIONS) + list(APPEND _JAVA_HINTS "[${_JAVA_HINT};JavaHome]/bin") + endforeach() + endif() + endif() + endmacro() + + # search for installed versions for version 9 and upper + _JAVA_GET_INSTALLED_VERSIONS("JDK") + _JAVA_GET_INSTALLED_VERSIONS("JRE") + + list(APPEND _JAVA_HINTS "[HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Development Kit\\1.9;JavaHome]/bin" "[HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Development Kit\\1.8;JavaHome]/bin" "[HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Development Kit\\1.7;JavaHome]/bin" @@ -86,7 +115,6 @@ list(APPEND _JAVA_HINTS "[HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Development Kit\\1.5;JavaHome]/bin" "[HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Development Kit\\1.4;JavaHome]/bin" "[HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Development Kit\\1.3;JavaHome]/bin" - "[HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Runtime Environment\\2.0;JavaHome]/bin" "[HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Runtime Environment\\1.9;JavaHome]/bin" "[HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Runtime Environment\\1.8;JavaHome]/bin" "[HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Runtime Environment\\1.7;JavaHome]/bin" @@ -95,6 +123,8 @@ list(APPEND _JAVA_HINTS "[HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Runtime Environment\\1.4;JavaHome]/bin" "[HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Runtime Environment\\1.3;JavaHome]/bin" ) +endif() + # Hard-coded guesses should still go in PATHS. This ensures that the user # environment can always override hard guesses. set(_JAVA_PATHS @@ -139,15 +169,31 @@ if(Java_JAVA_EXECUTABLE) # Sun, GCJ, older OpenJDK set(Java_VERSION_STRING "${CMAKE_MATCH_1}") set(Java_VERSION_MAJOR "${CMAKE_MATCH_2}") + if (CMAKE_MATCH_4) set(Java_VERSION_MINOR "${CMAKE_MATCH_4}") + else() + set(Java_VERSION_MINOR 0) + endif() + if (CMAKE_MATCH_6) set(Java_VERSION_PATCH "${CMAKE_MATCH_6}") + else() + set(Java_VERSION_PATCH 0) + endif() set(Java_VERSION_TWEAK "${CMAKE_MATCH_8}") elseif(var MATCHES "openjdk version \"${_java_version_regex}\"") # OpenJDK set(Java_VERSION_STRING "${CMAKE_MATCH_1}") set(Java_VERSION_MAJOR "${CMAKE_MATCH_2}") + if (CMAKE_MATCH_4) set(Java_VERSION_MINOR "${CMAKE_MATCH_4}") + else() + set(Java_VERSION_MINOR 0) + endif() + if (CMAKE_MATCH_6) set(Java_VERSION_PATCH "${CMAKE_MATCH_6}") + else() + set(Java_VERSION_PATCH 0) + endif() set(Java_VERSION_TWEAK "${CMAKE_MATCH_8}") elseif(var MATCHES "openjdk version \"([0-9]+)-[A-Za-z]+\"") # OpenJDK 9 early access builds or locally built @@ -237,16 +283,16 @@ if(Java_FIND_COMPONENTS) endif() elseif(component STREQUAL "Development") list(APPEND _JAVA_REQUIRED_VARS Java_JAVA_EXECUTABLE Java_JAVAC_EXECUTABLE - Java_JAVADOC_EXECUTABLE) - if(Java_VERSION VERSION_LESS "1.10") + Java_JAR_EXECUTABLE Java_JAVADOC_EXECUTABLE) + if(Java_VERSION VERSION_LESS "10") list(APPEND _JAVA_REQUIRED_VARS Java_JAVAH_EXECUTABLE) if(Java_JAVA_EXECUTABLE AND Java_JAVAC_EXECUTABLE - AND Java_JAVAH_EXECUTABLE AND Java_JAVADOC_EXECUTABLE) + AND Java_JAVAH_EXECUTABLE AND Java_JAR_EXECUTABLE AND Java_JAVADOC_EXECUTABLE) set(Java_Development_FOUND TRUE) endif() else() if(Java_JAVA_EXECUTABLE AND Java_JAVAC_EXECUTABLE - AND Java_JAVADOC_EXECUTABLE) + AND Java_JAR_EXECUTABLE AND Java_JAVADOC_EXECUTABLE) set(Java_Development_FOUND TRUE) endif() endif() @@ -276,7 +322,7 @@ if(Java_FIND_COMPONENTS) endif() else() # Check for Development - if(Java_VERSION VERSION_LESS "1.10") + if(Java_VERSION VERSION_LESS "10") find_package_handle_standard_args(Java REQUIRED_VARS Java_JAVA_EXECUTABLE Java_JAR_EXECUTABLE Java_JAVAC_EXECUTABLE Java_JAVAH_EXECUTABLE Java_JAVADOC_EXECUTABLE diff --git a/Modules/FindLibXml2.cmake b/Modules/FindLibXml2.cmake index 8ac2980..615de49 100644 --- a/Modules/FindLibXml2.cmake +++ b/Modules/FindLibXml2.cmake @@ -7,6 +7,12 @@ # # Find the XML processing library (libxml2). # +# IMPORTED Targets +# ^^^^^^^^^^^^^^^^ +# +# This module defines :prop_tgt:`IMPORTED` target ``LibXml2::LibXml2``, if +# libxml2 has been found. +# # Result variables # ^^^^^^^^^^^^^^^^ # @@ -87,3 +93,9 @@ FIND_PACKAGE_HANDLE_STANDARD_ARGS(LibXml2 VERSION_VAR LIBXML2_VERSION_STRING) mark_as_advanced(LIBXML2_INCLUDE_DIR LIBXML2_LIBRARY LIBXML2_XMLLINT_EXECUTABLE) + +if(LibXml2_FOUND AND NOT TARGET LibXml2::LibXml2) + add_library(LibXml2::LibXml2 UNKNOWN IMPORTED) + set_target_properties(LibXml2::LibXml2 PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${LIBXML2_INCLUDE_DIRS}") + set_property(TARGET LibXml2::LibXml2 APPEND PROPERTY IMPORTED_LOCATION "${LIBXML2_LIBRARY}") +endif() diff --git a/Modules/FindLua.cmake b/Modules/FindLua.cmake index b59b9b3..7eba206 100644 --- a/Modules/FindLua.cmake +++ b/Modules/FindLua.cmake @@ -122,6 +122,7 @@ endif () if (NOT LUA_VERSION_STRING) foreach (subdir IN LISTS _lua_include_subdirs) unset(LUA_INCLUDE_PREFIX CACHE) + unset(LUA_INCLUDE_PREFIX) find_path(LUA_INCLUDE_PREFIX ${subdir}/lua.h HINTS ENV LUA_DIR diff --git a/Modules/FindMPI.cmake b/Modules/FindMPI.cmake index 4bfbf03..75c4441 100644 --- a/Modules/FindMPI.cmake +++ b/Modules/FindMPI.cmake @@ -352,6 +352,9 @@ function (_MPI_check_compiler LANG QUERY_FLAG OUTPUT_VARIABLE RESULT_VARIABLE) # Ensure that no error output might be passed upwards. if(NOT WRAPPER_RETURN EQUAL 0) unset(WRAPPER_OUTPUT) + else() + # Strip leading whitespace + string(REGEX REPLACE "^ +" "" WRAPPER_OUTPUT "${WRAPPER_OUTPUT}") endif() set(${OUTPUT_VARIABLE} "${WRAPPER_OUTPUT}" PARENT_SCOPE) set(${RESULT_VARIABLE} "${WRAPPER_RETURN}" PARENT_SCOPE) @@ -715,20 +718,20 @@ function (_MPI_interrogate_compiler LANG) # or shared libraries if there aren't any import libraries in use on the system. # Note that we do not consider CMAKE_<TYPE>_LIBRARY_PREFIX intentionally here: The linker will for a given file # decide how to link it based on file type, not based on a prefix like 'lib'. - set(_MPI_LIB_NAME_REGEX "[^\" ]+${CMAKE_STATIC_LIBRARY_SUFFIX}|\"[^\"]+${CMAKE_STATIC_LIBRARY_SUFFIX}\"") + 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_LIB_NAME_REGEX "[^\" ]+${CMAKE_IMPORT_LIBRARY_SUFFIX}|\"[^\"]+${CMAKE_IMPORT_LIBRARY_SUFFIX}\"") + string(APPEND _MPI_SUFFIX_REGEX "|${CMAKE_IMPORT_LIBRARY_SUFFIX}") endif() else() - string(APPEND _MPI_LIB_NAME_REGEX "[^\" ]+${CMAKE_SHARED_LIBRARY_SUFFIX}|\"[^\"]+${CMAKE_SHARED_LIBRARY_SUFFIX}\"") + string(APPEND _MPI_LIB_SUFFIX_REGEX "|${CMAKE_SHARED_LIBRARY_SUFFIX}") endif() + set(_MPI_LIB_NAME_REGEX "(([^\" ]+(${_MPI_LIB_SUFFIX_REGEX}))|(\"[^\"]+(${_MPI_LIB_SUFFIX_REGEX})\"))( +|$)") string(REPLACE "." "\\." _MPI_LIB_NAME_REGEX "${_MPI_LIB_NAME_REGEX}") - string(REGEX MATCHALL "(^| )(${_MPI_LIB_NAME_REGEX})" MPI_LIBNAMES "${MPI_LINK_CMDLINE}") + 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}") - string(REPLACE "\"" "" _MPI_LIB_NAME "${_MPI_LIB_NAME}") + 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}") diff --git a/Modules/FindMatlab.cmake b/Modules/FindMatlab.cmake index 8402b23..b03f793 100644 --- a/Modules/FindMatlab.cmake +++ b/Modules/FindMatlab.cmake @@ -5,22 +5,25 @@ # FindMatlab # ---------- # -# Finds Matlab installations and provides Matlab tools and libraries to cmake. +# Finds Matlab or Matlab Compiler Runtime (MCR) and provides Matlab tools, +# libraries and compilers to CMake. # -# This package first intention is to find the libraries associated with Matlab -# in order to be able to build Matlab extensions (mex files). It can also be -# used: +# This package primary purpose is to find the libraries associated with Matlab +# or the MCR in order to be able to build Matlab extensions (mex files). It +# can also be used: # -# * run specific commands in Matlab -# * declare Matlab unit test -# * retrieve various information from Matlab (mex extensions, versions and +# * to run specific commands in Matlab in case Matlab is available +# * for declaring Matlab unit test +# * to retrieve various information from Matlab (mex extensions, versions and # release queries, ...) # # The module supports the following components: # -# * ``MX_LIBRARY``, ``ENG_LIBRARY`` and ``MAT_LIBRARY``: respectively the MX, -# ENG and MAT libraries of Matlab -# * ``MAIN_PROGRAM`` the Matlab binary program. +# * ``MX_LIBRARY``, ``ENG_LIBRARY`` and ``MAT_LIBRARY``: respectively the ``MX``, +# ``ENG`` and ``MAT`` libraries of Matlab +# * ``MAIN_PROGRAM`` the Matlab binary program. Note that this component is not +# available on the MCR version, and will yield an error if the MCR is found +# instead of the regular Matlab installation. # * ``MEX_COMPILER`` the MEX compiler. # * ``SIMULINK`` the Simulink environment. # @@ -30,24 +33,26 @@ # **version**, which should not be confused with the Matlab *release* name # (eg. `R2014`). # The :command:`matlab_get_version_from_release_name` and -# :command:`matlab_get_release_name_from_version` allow a mapping -# from the release name to the version. +# :command:`matlab_get_release_name_from_version` provide a mapping +# between the release name and the version. # # The variable :variable:`Matlab_ROOT_DIR` may be specified in order to give # the path of the desired Matlab version. Otherwise, the behaviour is platform # specific: # -# * Windows: The installed versions of Matlab are retrieved from the +# * Windows: The installed versions of Matlab/MCR are retrieved from the # Windows registry -# * OS X: The installed versions of Matlab are given by the MATLAB -# paths in ``/Application``. If no such application is found, it falls back -# to the one that might be accessible from the PATH. -# * Unix: The desired Matlab should be accessible from the PATH. +# * OS X: The installed versions of Matlab/MCR are given by the MATLAB +# default installation paths in ``/Application``. If no such application is +# found, it falls back to the one that might be accessible from the ``PATH``. +# * Unix: The desired Matlab should be accessible from the ``PATH``. This does +# not work for MCR installation and :variable:`Matlab_ROOT_DIR` should be +# specified on this platform. # # Additional information is provided when :variable:`MATLAB_FIND_DEBUG` is set. -# When a Matlab binary is found automatically and the ``MATLAB_VERSION`` -# is not given, the version is queried from Matlab directly. -# On Windows, it can make a window running Matlab appear. +# When a Matlab/MCR installation is found automatically and the ``MATLAB_VERSION`` +# is not given, the version is queried from Matlab directly (on Windows this +# may pop up a Matlab window) or from the MCR installation. # # The mapping of the release names and the version of Matlab is performed by # defining pairs (name, version). The variable @@ -135,15 +140,15 @@ # parses the registry for all Matlab versions. Available on Windows only. # The part of the registry parsed is dependent on the host processor # :command:`matlab_get_all_valid_matlab_roots_from_registry` -# returns all the possible Matlab paths, according to a previously +# returns all the possible Matlab or MCR paths, according to a previously # given list. Only the existing/accessible paths are kept. This is mainly # useful for the searching all possible Matlab installation. # :command:`matlab_get_mex_suffix` # returns the suffix to be used for the mex files # (platform/architecture dependent) # :command:`matlab_get_version_from_matlab_run` -# returns the version of Matlab, given the full directory of the Matlab -# program. +# returns the version of Matlab/MCR, given the full directory of the Matlab/MCR +# installation path. # # # Known issues @@ -213,7 +218,7 @@ set(_FindMatlab_SELF_DIR "${CMAKE_CURRENT_LIST_DIR}") -include(FindPackageHandleStandardArgs) +include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) include(CheckCXXCompilerFlag) include(CheckCCompilerFlag) @@ -256,7 +261,7 @@ endif() # .. command:: matlab_get_version_from_release_name # # Returns the version of Matlab (17.58) from a release name (R2017k) -macro (matlab_get_version_from_release_name release_name version_name) +macro(matlab_get_version_from_release_name release_name version_name) string(REGEX MATCHALL "${release_name}=([0-9]+\\.?[0-9]*)" _matched ${MATLAB_VERSIONS_MAPPING}) @@ -264,7 +269,7 @@ macro (matlab_get_version_from_release_name release_name version_name) if(NOT _matched STREQUAL "") set(${version_name} ${CMAKE_MATCH_1}) else() - message(WARNING "The release name ${release_name} is not registered") + message(WARNING "[MATLAB] The release name ${release_name} is not registered") endif() unset(_matched) @@ -278,7 +283,7 @@ endmacro() # .. command:: matlab_get_release_name_from_version # # Returns the release name (R2017k) from the version of Matlab (17.58) -macro (matlab_get_release_name_from_version version release_name) +macro(matlab_get_release_name_from_version version release_name) set(${release_name} "") foreach(_var IN LISTS MATLAB_VERSIONS_MAPPING) @@ -292,7 +297,7 @@ macro (matlab_get_release_name_from_version version release_name) unset(_var) unset(_matched) if(${release_name} STREQUAL "") - message(WARNING "The version ${version} is not registered") + message(WARNING "[MATLAB] The version ${version} is not registered") endif() endmacro() @@ -341,8 +346,9 @@ endmacro() # installed. The found versions are returned in `matlab_versions`. # Set `win64` to `TRUE` if the 64 bit version of Matlab should be looked for # The returned list contains all versions under -# ``HKLM\\SOFTWARE\\Mathworks\\MATLAB`` or an empty list in case an error -# occurred (or nothing found). +# ``HKLM\\SOFTWARE\\Mathworks\\MATLAB`` and +# ``HKLM\\SOFTWARE\\Mathworks\\MATLAB Runtime`` or an empty list in case an +# error occurred (or nothing found). # # .. note:: # @@ -352,51 +358,54 @@ endmacro() function(matlab_extract_all_installed_versions_from_registry win64 matlab_versions) if(NOT CMAKE_HOST_WIN32) - message(FATAL_ERROR "This macro can only be called by a windows host (call to reg.exe") + message(FATAL_ERROR "[MATLAB] This macro can only be called by a windows host (call to reg.exe)") endif() - if(${win64} AND CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "64") set(APPEND_REG "/reg:64") else() set(APPEND_REG "/reg:32") endif() - # /reg:64 should be added on 64 bits capable OSs in order to enable the - # redirection of 64 bits applications - execute_process( - COMMAND reg query HKEY_LOCAL_MACHINE\\SOFTWARE\\Mathworks\\MATLAB /f * /k ${APPEND_REG} - RESULT_VARIABLE resultMatlab - OUTPUT_VARIABLE varMatlab - ERROR_VARIABLE errMatlab - INPUT_FILE NUL - ) + set(matlabs_from_registry) + foreach(_installation_type IN ITEMS "MATLAB" "MATLAB Runtime") - set(matlabs_from_registry) - if(${resultMatlab} EQUAL 0) + # /reg:64 should be added on 64 bits capable OSs in order to enable the + # redirection of 64 bits applications + execute_process( + COMMAND reg query HKEY_LOCAL_MACHINE\\SOFTWARE\\Mathworks\\${_installation_type} /f * /k ${APPEND_REG} + RESULT_VARIABLE resultMatlab + OUTPUT_VARIABLE varMatlab + ERROR_VARIABLE errMatlab + INPUT_FILE NUL + ) - string( - REGEX MATCHALL "MATLAB\\\\([0-9]+(\\.[0-9]+)?)" - matlab_versions_regex ${varMatlab}) - foreach(match IN LISTS matlab_versions_regex) - string( - REGEX MATCH "MATLAB\\\\(([0-9]+)(\\.([0-9]+))?)" - current_match ${match}) + if(${resultMatlab} EQUAL 0) - set(_matlab_current_version ${CMAKE_MATCH_1}) - set(current_matlab_version_major ${CMAKE_MATCH_2}) - set(current_matlab_version_minor ${CMAKE_MATCH_4}) - if(NOT current_matlab_version_minor) - set(current_matlab_version_minor "0") - endif() + string( + REGEX MATCHALL "MATLAB\\\\([0-9]+(\\.[0-9]+)?)" + matlab_versions_regex ${varMatlab}) + + foreach(match IN LISTS matlab_versions_regex) + string( + REGEX MATCH "MATLAB\\\\(([0-9]+)(\\.([0-9]+))?)" + current_match ${match}) + + set(_matlab_current_version ${CMAKE_MATCH_1}) + set(current_matlab_version_major ${CMAKE_MATCH_2}) + set(current_matlab_version_minor ${CMAKE_MATCH_4}) + if(NOT current_matlab_version_minor) + set(current_matlab_version_minor "0") + endif() - list(APPEND matlabs_from_registry ${_matlab_current_version}) - unset(_matlab_current_version) - endforeach(match) + list(APPEND matlabs_from_registry ${_matlab_current_version}) + unset(_matlab_current_version) + endforeach() - endif() + endif() + endforeach() if(matlabs_from_registry) list(REMOVE_DUPLICATES matlabs_from_registry) @@ -441,7 +450,6 @@ macro(extract_matlab_versions_from_registry_brute_force matlab_versions) # list(APPEND matlab_supported_versions MATLAB_ADDITIONAL_VERSIONS) # endif() - # we order from more recent to older if(matlab_supported_versions) list(REMOVE_DUPLICATES matlab_supported_versions) @@ -449,10 +457,7 @@ macro(extract_matlab_versions_from_registry_brute_force matlab_versions) list(REVERSE matlab_supported_versions) endif() - set(${matlab_versions} ${matlab_supported_versions}) - - endmacro() @@ -461,9 +466,11 @@ endmacro() #.rst: # .. command:: matlab_get_all_valid_matlab_roots_from_registry # -# Populates the Matlab root with valid versions of Matlab. -# The returned matlab_roots is organized in pairs -# ``(version_number,matlab_root_path)``. +# Populates the Matlab root with valid versions of Matlab or +# Matlab Runtime (MCR). +# The returned matlab_roots is organized in triplets +# ``(type,version_number,matlab_root_path)``, where ``type`` +# indicates either ``MATLAB`` or ``MCR``. # # :: # @@ -472,17 +479,17 @@ endmacro() # matlab_roots) # # ``matlab_versions`` -# the versions of each of the Matlab installations +# the versions of each of the Matlab or MCR installations # ``matlab_roots`` -# the location of each of the Matlab installations +# the location of each of the Matlab or MCR installations function(matlab_get_all_valid_matlab_roots_from_registry matlab_versions matlab_roots) # The matlab_versions comes either from # extract_matlab_versions_from_registry_brute_force or # matlab_extract_all_installed_versions_from_registry. - set(_matlab_roots_list ) + # check for Matlab installations foreach(_matlab_current_version ${matlab_versions}) get_filename_component( current_MATLAB_ROOT @@ -490,13 +497,27 @@ function(matlab_get_all_valid_matlab_roots_from_registry matlab_versions matlab_ ABSOLUTE) if(EXISTS ${current_MATLAB_ROOT}) - list(APPEND _matlab_roots_list ${_matlab_current_version} ${current_MATLAB_ROOT}) + list(APPEND _matlab_roots_list "MATLAB" ${_matlab_current_version} ${current_MATLAB_ROOT}) + endif() + + endforeach() + + # Check for MCR installations + foreach(_matlab_current_version ${matlab_versions}) + get_filename_component( + current_MATLAB_ROOT + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MathWorks\\MATLAB Runtime\\${_matlab_current_version};MATLABROOT]" + ABSOLUTE) + + # remove the dot + string(REPLACE "." "" _matlab_current_version_without_dot "${_matlab_current_version}") + + if(EXISTS ${current_MATLAB_ROOT}) + list(APPEND _matlab_roots_list "MCR" ${_matlab_current_version} "${current_MATLAB_ROOT}/v${_matlab_current_version_without_dot}") endif() - endforeach(_matlab_current_version) - unset(_matlab_current_version) + endforeach() set(${matlab_roots} ${_matlab_roots_list} PARENT_SCOPE) - unset(_matlab_roots_list) endfunction() #.rst: @@ -513,7 +534,7 @@ endfunction() # mex_suffix) # # ``matlab_root`` -# the root of the Matlab installation +# the root of the Matlab/MCR installation # ``mex_suffix`` # the variable name in which the suffix will be returned. function(matlab_get_mex_suffix matlab_root mex_suffix) @@ -548,7 +569,9 @@ function(matlab_get_mex_suffix matlab_root mex_suffix) ) 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})) @@ -568,12 +591,29 @@ function(matlab_get_mex_suffix matlab_root mex_suffix) set(devnull INPUT_FILE NUL) endif() + # this is the prefered way. If this does not work properly (eg. MCR on Windows), then we use our own knowledge execute_process( COMMAND ${Matlab_MEXEXTENSIONS_PROG} OUTPUT_VARIABLE _matlab_mex_extension + #RESULT_VARIABLE _matlab_mex_extension_call ERROR_VARIABLE _matlab_mex_extension_error ${devnull}) - string(STRIP ${_matlab_mex_extension} _matlab_mex_extension) + + if(NOT "${_matlab_mex_extension_error}" STREQUAL "") + if(WIN32) + # this is only for intel architecture + if(CMAKE_SIZEOF_VOID_P EQUAL 8) + set(_matlab_mex_extension "mexw64") + else() + set(_matlab_mex_extension "mexw32") + endif() + endif() + endif() + + string(STRIP "${_matlab_mex_extension}" _matlab_mex_extension) + if(MATLAB_FIND_DEBUG) + message(STATUS "[MATLAB] '${Matlab_MEXEXTENSIONS_PROG}' : returned '${_matlab_mex_extension_call}', 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) @@ -586,7 +626,8 @@ endfunction() # .. command:: matlab_get_version_from_matlab_run # # This function runs Matlab program specified on arguments and extracts its -# version. +# version. If the path provided for the Matlab installation points to an MCR +# installation, the version is extracted from the installed files. # # :: # @@ -602,7 +643,6 @@ function(matlab_get_version_from_matlab_run matlab_binary_program matlab_list_ve set(${matlab_list_versions} "" PARENT_SCOPE) - if(MATLAB_FIND_DEBUG) message(STATUS "[MATLAB] Determining the version of Matlab from ${matlab_binary_program}") endif() @@ -704,7 +744,9 @@ endfunction() # .. command:: matlab_add_unit_test # # Adds a Matlab unit test to the test set of cmake/ctest. -# This command requires the component ``MAIN_PROGRAM``. +# This command requires the component ``MAIN_PROGRAM`` and hence is not +# available for an MCR installation. +# # The unit test uses the Matlab unittest framework (default, available # starting Matlab 2013b+) except if the option ``NO_UNITTEST_FRAMEWORK`` # is given. @@ -929,7 +971,7 @@ function(matlab_add_mex) TARGET ${${prefix}_NAME} PRE_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different ${${prefix}_DOCUMENTATION} $<TARGET_FILE_DIR:${${prefix}_NAME}>/${output_name}.m - COMMENT "Copy ${${prefix}_NAME} documentation file into the output folder" + COMMENT "[MATLAB] Copy ${${prefix}_NAME} documentation file into the output folder" ) endif() # documentation @@ -1005,10 +1047,10 @@ endfunction() # (internal) # Used to get the version of matlab, using caching. This basically transforms the # output of the root list, with possible unknown version, to a version -# -function(_Matlab_get_version_from_root matlab_root matlab_known_version matlab_final_version) +# This can possibly run Matlab for extracting the version. +function(_Matlab_get_version_from_root matlab_root matlab_or_mcr matlab_known_version matlab_final_version) - # if the version is not trivial, we query matlab for that + # if the version is not trivial, we query matlab (if not MCR) for that # we keep track of the location of matlab that induced this version #if(NOT DEFINED Matlab_PROG_VERSION_STRING_AUTO_DETECT) # set(Matlab_PROG_VERSION_STRING_AUTO_DETECT "" CACHE INTERNAL "internal matlab location for the discovered version") @@ -1021,189 +1063,231 @@ function(_Matlab_get_version_from_root matlab_root matlab_known_version matlab_f return() endif() - # - set(_matlab_current_program ${Matlab_MAIN_PROGRAM}) - - # do we already have a matlab program? - if(NOT _matlab_current_program) - - set(_find_matlab_options) - if(matlab_root AND EXISTS ${matlab_root}) - set(_find_matlab_options PATHS ${matlab_root} ${matlab_root}/bin NO_DEFAULT_PATH) + if("${matlab_or_mcr}" STREQUAL "UNKNOWN") + if(MATLAB_FIND_DEBUG) + message(WARNING "[MATLAB] Determining Matlab or MCR") endif() - find_program( - _matlab_current_program - matlab - ${_find_matlab_options} - DOC "Matlab main program" - ) - endif() + if(EXISTS "${matlab_root}/appdata/version.xml") + # we inspect the application version.xml file that contains the product information + file(STRINGS "${matlab_root}/appdata/version.xml" productinfo_string NEWLINE_CONSUME) + string(REGEX MATCH "<installedProductData.*displayedString=\"([a-zA-Z ]+)\".*/>" + product_reg_match + ${productinfo_string} + ) + + # default fallback to Matlab + set(matlab_or_mcr "MATLAB") + if(NOT "${CMAKE_MATCH_1}" STREQUAL "") + string(TOLOWER "${CMAKE_MATCH_1}" product_reg_match) + + if("${product_reg_match}" STREQUAL "matlab runtime") + set(matlab_or_mcr "MCR") + endif() + endif() + endif() - if(NOT _matlab_current_program OR NOT EXISTS ${_matlab_current_program}) - # if not found, clear the dependent variables if(MATLAB_FIND_DEBUG) - message(WARNING "[MATLAB] Cannot find the main matlab program under ${matlab_root}") + message(WARNING "[MATLAB] '${matlab_root}' contains the '${matlab_or_mcr}'") endif() - set(Matlab_PROG_VERSION_STRING_AUTO_DETECT "" CACHE INTERNAL "internal matlab location for the discovered version" FORCE) - set(Matlab_VERSION_STRING_INTERNAL "" CACHE INTERNAL "internal matlab location for the discovered version" FORCE) - unset(_matlab_current_program) - unset(_matlab_current_program CACHE) - return() endif() - # full real path for path comparison - get_filename_component(_matlab_main_real_path_tmp "${_matlab_current_program}" REALPATH) - unset(_matlab_current_program) - unset(_matlab_current_program CACHE) + # UNKNOWN is the default behaviour in case we + # - have an erroneous matlab_root + # - have an initial 'UNKNOWN' + if("${matlab_or_mcr}" STREQUAL "MATLAB" OR "${matlab_or_mcr}" STREQUAL "UNKNOWN") + # MATLAB versions + set(_matlab_current_program ${Matlab_MAIN_PROGRAM}) - # is it the same as the previous one? - if(_matlab_main_real_path_tmp STREQUAL Matlab_PROG_VERSION_STRING_AUTO_DETECT) - set(${matlab_final_version} ${Matlab_VERSION_STRING_INTERNAL} PARENT_SCOPE) - return() - endif() + # do we already have a matlab program? + if(NOT _matlab_current_program) - # update the location of the program - set(Matlab_PROG_VERSION_STRING_AUTO_DETECT ${_matlab_main_real_path_tmp} CACHE INTERNAL "internal matlab location for the discovered version" FORCE) + set(_find_matlab_options) + if(matlab_root AND EXISTS ${matlab_root}) + set(_find_matlab_options PATHS ${matlab_root} ${matlab_root}/bin NO_DEFAULT_PATH) + endif() - set(matlab_list_of_all_versions) - matlab_get_version_from_matlab_run("${Matlab_PROG_VERSION_STRING_AUTO_DETECT}" matlab_list_of_all_versions) + find_program( + _matlab_current_program + matlab + ${_find_matlab_options} + DOC "Matlab main program" + ) + endif() - list(LENGTH matlab_list_of_all_versions list_of_all_versions_length) - if(${list_of_all_versions_length} GREATER 0) - list(GET matlab_list_of_all_versions 0 _matlab_version_tmp) - else() - set(_matlab_version_tmp "unknown") - endif() + if(NOT _matlab_current_program OR NOT EXISTS ${_matlab_current_program}) + # if not found, clear the dependent variables + if(MATLAB_FIND_DEBUG) + message(WARNING "[MATLAB] Cannot find the main matlab program under ${matlab_root}") + endif() + set(Matlab_PROG_VERSION_STRING_AUTO_DETECT "" CACHE INTERNAL "internal matlab location for the discovered version" FORCE) + set(Matlab_VERSION_STRING_INTERNAL "" CACHE INTERNAL "internal matlab location for the discovered version" FORCE) + unset(_matlab_current_program) + unset(_matlab_current_program CACHE) + return() + endif() - # set the version into the cache - set(Matlab_VERSION_STRING_INTERNAL ${_matlab_version_tmp} CACHE INTERNAL "Matlab version (automatically determined)" FORCE) + # full real path for path comparison + get_filename_component(_matlab_main_real_path_tmp "${_matlab_current_program}" REALPATH) + unset(_matlab_current_program) + unset(_matlab_current_program CACHE) - # warning, just in case several versions found (should not happen) - if((${list_of_all_versions_length} GREATER 1) AND MATLAB_FIND_DEBUG) - message(WARNING "[MATLAB] Found several versions, taking the first one (versions found ${matlab_list_of_all_versions})") - endif() + # is it the same as the previous one? + if(_matlab_main_real_path_tmp STREQUAL Matlab_PROG_VERSION_STRING_AUTO_DETECT) + set(${matlab_final_version} ${Matlab_VERSION_STRING_INTERNAL} PARENT_SCOPE) + return() + endif() - # return the updated value - set(${matlab_final_version} ${Matlab_VERSION_STRING_INTERNAL} PARENT_SCOPE) + # update the location of the program + set(Matlab_PROG_VERSION_STRING_AUTO_DETECT + ${_matlab_main_real_path_tmp} + CACHE INTERNAL "internal matlab location for the discovered version" FORCE) -endfunction() + set(matlab_list_of_all_versions) + matlab_get_version_from_matlab_run("${Matlab_PROG_VERSION_STRING_AUTO_DETECT}" matlab_list_of_all_versions) + list(LENGTH matlab_list_of_all_versions list_of_all_versions_length) + if(${list_of_all_versions_length} GREATER 0) + list(GET matlab_list_of_all_versions 0 _matlab_version_tmp) + else() + set(_matlab_version_tmp "unknown") + endif() + # set the version into the cache + set(Matlab_VERSION_STRING_INTERNAL ${_matlab_version_tmp} CACHE INTERNAL "Matlab version (automatically determined)" FORCE) + # warning, just in case several versions found (should not happen) + if((${list_of_all_versions_length} GREATER 1) AND MATLAB_FIND_DEBUG) + message(WARNING "[MATLAB] Found several versions, taking the first one (versions found ${matlab_list_of_all_versions})") + endif() + # return the updated value + set(${matlab_final_version} ${Matlab_VERSION_STRING_INTERNAL} PARENT_SCOPE) + else() + # MCR + # we cannot run anything in order to extract the version. We assume that the file + # VersionInfo.xml exists under the MatlabRoot, we look for it and extract the version from there + set(_matlab_version_tmp "unknown") + file(STRINGS "${matlab_root}/VersionInfo.xml" versioninfo_string NEWLINE_CONSUME) + # parses "<version>9.2.0.538062</version>" + string(REGEX MATCH "<version>(.*)</version>" + version_reg_match + ${versioninfo_string} + ) + + if(NOT "${version_reg_match}" STREQUAL "") + if("${CMAKE_MATCH_1}" MATCHES "(([0-9])\\.([0-9]))[\\.0-9]*") + set(_matlab_version_tmp "${CMAKE_MATCH_1}") + endif() + endif() + set(${matlab_final_version} "${_matlab_version_tmp}" PARENT_SCOPE) + set(Matlab_VERSION_STRING_INTERNAL + "${_matlab_version_tmp}" + CACHE INTERNAL "Matlab (MCR) version (automatically determined)" + FORCE) + endif() # Matlab or MCR +endfunction() -# ################################### -# Exploring the possible Matlab_ROOTS -# this variable will get all Matlab installations found in the current system. -set(_matlab_possible_roots) +# Utility function for finding Matlab or MCR on Win32 +function(_Matlab_find_instances_win32 matlab_roots) + # On WIN32, we look for Matlab installation in the registry + # if unsuccessful, we look for all known revision and filter the existing + # ones. + # testing if we are able to extract the needed information from the registry + set(_matlab_versions_from_registry) + if(CMAKE_SIZEOF_VOID_P EQUAL 8) + set(_matlab_win64 ON) + else() + set(_matlab_win64 OFF) + endif() -if(Matlab_ROOT_DIR) - # if the user specifies a possible root, we keep this one + matlab_extract_all_installed_versions_from_registry(_matlab_win64 _matlab_versions_from_registry) - if(NOT EXISTS ${Matlab_ROOT_DIR}) - # if Matlab_ROOT_DIR specified but erroneous + # the returned list is empty, doing the search on all known versions + if(NOT _matlab_versions_from_registry) if(MATLAB_FIND_DEBUG) - message(WARNING "[MATLAB] the specified path for Matlab_ROOT_DIR does not exist (${Matlab_ROOT_DIR})") - endif() - else() - # NOTFOUND indicates the code below to search for the version automatically - if("${Matlab_VERSION_STRING_INTERNAL}" STREQUAL "") - list(APPEND _matlab_possible_roots "NOTFOUND" ${Matlab_ROOT_DIR}) # empty version - else() - list(APPEND _matlab_possible_roots ${Matlab_VERSION_STRING_INTERNAL} ${Matlab_ROOT_DIR}) # cached version + message(STATUS "[MATLAB] Search for Matlab from the registry unsuccessful, testing all supported versions") endif() + extract_matlab_versions_from_registry_brute_force(_matlab_versions_from_registry) endif() + # filtering the results with the registry keys + matlab_get_all_valid_matlab_roots_from_registry("${_matlab_versions_from_registry}" _matlab_possible_roots) + unset(_matlab_versions_from_registry) -else() - - # if the user does not specify the possible installation root, we look for - # one installation using the appropriate heuristics + set(_matlab_versions_from_registry) + matlab_extract_all_installed_versions_from_registry(CMAKE_CL_64 _matlab_versions_from_registry) - if(WIN32) + # the returned list is empty, doing the search on all known versions + if(NOT _matlab_versions_from_registry) + if(MATLAB_FIND_DEBUG) + message(STATUS "[MATLAB] Search for Matlab from the registry unsuccessful, testing all supported versions") + endif() + extract_matlab_versions_from_registry_brute_force(_matlab_versions_from_registry) + endif() - # On WIN32, we look for Matlab installation in the registry - # if unsuccessful, we look for all known revision and filter the existing - # ones. + # filtering the results with the registry keys + matlab_get_all_valid_matlab_roots_from_registry("${_matlab_versions_from_registry}" _matlab_possible_roots) + set(${matlab_roots} ${_matlab_possible_roots} PARENT_SCOPE) - # testing if we are able to extract the needed information from the registry - set(_matlab_versions_from_registry) +endfunction() - if(CMAKE_SIZEOF_VOID_P EQUAL 8) - set(_matlab_win64 ON) - else() - set(_matlab_win64 OFF) - endif() +# Utility function for finding Matlab or MCR on OSX +function(_Matlab_find_instances_osx matlab_roots) - matlab_extract_all_installed_versions_from_registry(_matlab_win64 _matlab_versions_from_registry) + set(_matlab_possible_roots) + # on mac, we look for the /Application paths + # this corresponds to the behaviour on Windows. On Linux, we do not have + # any other guess. + matlab_get_supported_releases(_matlab_releases) + if(MATLAB_FIND_DEBUG) + message(STATUS "[MATLAB] Matlab supported versions ${_matlab_releases}. If more version should be supported " + "the variable MATLAB_ADDITIONAL_VERSIONS can be set according to the documentation") + endif() - # the returned list is empty, doing the search on all known versions - if(NOT _matlab_versions_from_registry) + foreach(_matlab_current_release IN LISTS _matlab_releases) + matlab_get_version_from_release_name("${_matlab_current_release}" _matlab_current_version) + string(REPLACE "." "" _matlab_current_version_without_dot "${_matlab_current_version}") + set(_matlab_base_path "/Applications/MATLAB_${_matlab_current_release}.app") + # Check Matlab, has precedence over MCR + if(EXISTS ${_matlab_base_path}) if(MATLAB_FIND_DEBUG) - message(STATUS "[MATLAB] Search for Matlab from the registry unsuccessful, testing all supported versions") + message(STATUS "[MATLAB] Found version ${_matlab_current_release} (${_matlab_current_version}) in ${_matlab_base_path}") endif() - - extract_matlab_versions_from_registry_brute_force(_matlab_versions_from_registry) + list(APPEND _matlab_possible_roots "MATLAB" ${_matlab_current_version} ${_matlab_base_path}) endif() - # filtering the results with the registry keys - matlab_get_all_valid_matlab_roots_from_registry("${_matlab_versions_from_registry}" _matlab_possible_roots) - unset(_matlab_versions_from_registry) - - elseif(APPLE) - - # on mac, we look for the /Application paths - # this corresponds to the behaviour on Windows. On Linux, we do not have - # any other guess. - matlab_get_supported_releases(_matlab_releases) - if(MATLAB_FIND_DEBUG) - message(STATUS "[MATLAB] Matlab supported versions ${_matlab_releases}. If more version should be supported " - "the variable MATLAB_ADDITIONAL_VERSIONS can be set according to the documentation") - endif() - - foreach(_matlab_current_release IN LISTS _matlab_releases) - set(_matlab_full_string "/Applications/MATLAB_${_matlab_current_release}.app") - if(EXISTS ${_matlab_full_string}) - set(_matlab_current_version) - matlab_get_version_from_release_name("${_matlab_current_release}" _matlab_current_version) - if(MATLAB_FIND_DEBUG) - message(STATUS "[MATLAB] Found version ${_matlab_current_release} (${_matlab_current_version}) in ${_matlab_full_string}") - endif() - list(APPEND _matlab_possible_roots ${_matlab_current_version} ${_matlab_full_string}) - unset(_matlab_current_version) + # Checks MCR + set(_mcr_path "/Applications/MATLAB/MATLAB_Runtime/v${_matlab_current_version_without_dot}") + if(EXISTS "${_mcr_path}") + if(MATLAB_FIND_DEBUG) + message(STATUS "[MATLAB] Found MCR version ${_matlab_current_release} (${_matlab_current_version}) in ${_mcr_path}") endif() + list(APPEND _matlab_possible_roots "MCR" ${_matlab_current_version} ${_mcr_path}) + endif() - unset(_matlab_full_string) - endforeach(_matlab_current_release) - - unset(_matlab_current_release) - unset(_matlab_releases) - - endif() - -endif() - + endforeach() + set(${matlab_roots} ${_matlab_possible_roots} PARENT_SCOPE) +endfunction() -list(LENGTH _matlab_possible_roots _numbers_of_matlab_roots) -if(_numbers_of_matlab_roots EQUAL 0) - # if we have not found anything, we fall back on the PATH +# Utility function for finding Matlab or MCR from the PATH +function(_Matlab_find_instances_from_path matlab_roots) + set(_matlab_possible_roots) # At this point, we have no other choice than trying to find it from PATH. - # If set by the user, this won't change + # If set by the user, this wont change find_program( _matlab_main_tmp NAMES matlab) - if(_matlab_main_tmp) # we then populate the list of roots, with empty version if(MATLAB_FIND_DEBUG) @@ -1218,17 +1302,88 @@ if(_numbers_of_matlab_roots EQUAL 0) get_filename_component(_matlab_current_location "${_matlab_current_location}" DIRECTORY) get_filename_component(_matlab_current_location "${_matlab_current_location}" DIRECTORY) # Matlab should be in bin - list(APPEND _matlab_possible_roots "NOTFOUND" ${_matlab_current_location}) + # We found the Matlab program + list(APPEND _matlab_possible_roots "MATLAB" "NOTFOUND" ${_matlab_current_location}) + + # we remove this from the CACHE + unset(_matlab_main_tmp CACHE) + else() + find_program( + _matlab_mex_tmp + NAMES mex) + if(_matlab_mex_tmp) + # we then populate the list of roots, with empty version + if(MATLAB_FIND_DEBUG) + message(STATUS "[MATLAB] mex compiler found from PATH: ${_matlab_mex_tmp}") + endif() + + # resolve symlinks + get_filename_component(_mex_current_location "${_matlab_mex_tmp}" REALPATH) + + # get the directory (the command below has to be run twice) + # this will be the matlab root + get_filename_component(_mex_current_location "${_mex_current_location}" DIRECTORY) + get_filename_component(_mex_current_location "${_mex_current_location}" DIRECTORY) # Matlab Runtime mex compiler should be in bin + + # We found the Matlab program + list(APPEND _matlab_possible_roots "MCR" "NOTFOUND" ${_mex_current_location}) + + unset(_matlab_mex_tmp CACHE) + else() + if(MATLAB_FIND_DEBUG) + message(STATUS "[MATLAB] mex compiler not found") + endif() + endif() - unset(_matlab_current_location) endif() - unset(_matlab_main_tmp CACHE) -endif() + set(${matlab_roots} ${_matlab_possible_roots} PARENT_SCOPE) +endfunction() +# ################################### +# Exploring the possible Matlab_ROOTS +# this variable will get all Matlab installations found in the current system. +set(_matlab_possible_roots) + +if(Matlab_ROOT_DIR) + # if the user specifies a possible root, we keep this one + + if(NOT EXISTS "${Matlab_ROOT_DIR}") + # if Matlab_ROOT_DIR specified but erroneous + if(MATLAB_FIND_DEBUG) + message(WARNING "[MATLAB] the specified path for Matlab_ROOT_DIR does not exist (${Matlab_ROOT_DIR})") + endif() + else() + # NOTFOUND indicates the code below to search for the version automatically + if("${Matlab_VERSION_STRING_INTERNAL}" STREQUAL "") + list(APPEND _matlab_possible_roots "UNKNOWN" "NOTFOUND" ${Matlab_ROOT_DIR}) # empty version, empty MCR/Matlab indication + else() + list(APPEND _matlab_possible_roots "UNKNOWN" ${Matlab_VERSION_STRING_INTERNAL} ${Matlab_ROOT_DIR}) # cached version + endif() + endif() +else() + + # if the user does not specify the possible installation root, we look for + # one installation using the appropriate heuristics. + # There is apparently no standard way on Linux. + if(WIN32) + _Matlab_find_instances_win32(_matlab_possible_roots_win32) + list(APPEND _matlab_possible_roots ${_matlab_possible_roots_win32}) + elseif(APPLE) + _Matlab_find_instances_osx(_matlab_possible_roots_osx) + list(APPEND _matlab_possible_roots ${_matlab_possible_roots_osx}) + endif() +endif() + + +list(LENGTH _matlab_possible_roots _numbers_of_matlab_roots) +if(_numbers_of_matlab_roots EQUAL 0) + # if we have not found anything, we fall back on the PATH + _Matlab_find_instances_from_path(_matlab_possible_roots) +endif() if(MATLAB_FIND_DEBUG) @@ -1242,12 +1397,14 @@ endif() # take the first possible Matlab root list(LENGTH _matlab_possible_roots _numbers_of_matlab_roots) set(Matlab_VERSION_STRING "NOTFOUND") +set(Matlab_Or_MCR "UNKNOWN") if(_numbers_of_matlab_roots GREATER 0) - list(GET _matlab_possible_roots 0 Matlab_VERSION_STRING) - list(GET _matlab_possible_roots 1 Matlab_ROOT_DIR) + list(GET _matlab_possible_roots 0 Matlab_Or_MCR) + list(GET _matlab_possible_roots 1 Matlab_VERSION_STRING) + list(GET _matlab_possible_roots 2 Matlab_ROOT_DIR) # adding a warning in case of ambiguity - if(_numbers_of_matlab_roots GREATER 2 AND MATLAB_FIND_DEBUG) + if(_numbers_of_matlab_roots GREATER 3 AND MATLAB_FIND_DEBUG) message(WARNING "[MATLAB] Found several distributions of Matlab. Setting the current version to ${Matlab_VERSION_STRING} (located ${Matlab_ROOT_DIR})." " If this is not the desired behaviour, provide the -DMatlab_ROOT_DIR=... on the command line") endif() @@ -1290,13 +1447,11 @@ set(Matlab_ROOT_DIR ${Matlab_ROOT_DIR} CACHE PATH "Matlab installation root path # Fix the version, in case this one is NOTFOUND _Matlab_get_version_from_root( "${Matlab_ROOT_DIR}" + "${Matlab_Or_MCR}" ${Matlab_VERSION_STRING} Matlab_VERSION_STRING ) - - - if(MATLAB_FIND_DEBUG) message(STATUS "[MATLAB] Current version is ${Matlab_VERSION_STRING} located ${Matlab_ROOT_DIR}") endif() diff --git a/Modules/FindOpenAL.cmake b/Modules/FindOpenAL.cmake index c3d202e..7521d51 100644 --- a/Modules/FindOpenAL.cmake +++ b/Modules/FindOpenAL.cmake @@ -58,7 +58,7 @@ find_path(OPENAL_INCLUDE_DIR al.h HINTS ENV OPENALDIR - PATH_SUFFIXES include/AL include/OpenAL include + PATH_SUFFIXES include/AL include/OpenAL include AL OpenAL PATHS ~/Library/Frameworks /Library/Frameworks diff --git a/Modules/FindOpenMP.cmake b/Modules/FindOpenMP.cmake index 1bf589d..329ace1 100644 --- a/Modules/FindOpenMP.cmake +++ b/Modules/FindOpenMP.cmake @@ -85,6 +85,7 @@ function(_OPENMP_FLAG_CANDIDATES LANG) set(OMP_FLAG_GNU "-fopenmp") set(OMP_FLAG_Clang "-fopenmp=libomp" "-fopenmp=libiomp5" "-fopenmp") + set(OMP_FLAG_AppleClang "-Xclang -fopenmp") set(OMP_FLAG_HP "+Oopenmp") if(WIN32) set(OMP_FLAG_Intel "-Qopenmp") @@ -125,6 +126,7 @@ set(OpenMP_C_CXX_TEST_SOURCE #include <omp.h> int main() { #ifdef _OPENMP + int n = omp_get_max_threads(); return 0; #else breaks_on_purpose @@ -163,7 +165,7 @@ function(_OPENMP_WRITE_SOURCE_FILE LANG SRC_FILE_CONTENT_VAR SRC_FILE_NAME SRC_F set(${SRC_FILE_FULLPATH} "${SRC_FILE}" PARENT_SCOPE) endfunction() -include(${CMAKE_ROOT}/Modules/CMakeParseImplicitLinkInfo.cmake) +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}") @@ -246,6 +248,28 @@ function(_OPENMP_GET_FLAGS LANG FLAG_MODE OPENMP_FLAG_VAR OPENMP_LIB_NAMES_VAR) set("${OPENMP_LIB_NAMES_VAR}" "" PARENT_SCOPE) endif() break() + elseif(CMAKE_${LANG}_COMPILER_ID STREQUAL "AppleClang" + AND CMAKE_${LANG}_COMPILER_VERSION VERSION_GREATER_EQUAL "7.0") + + # Check for separate OpenMP library on AppleClang 7+ + find_library(OpenMP_libomp_LIBRARY + NAMES omp gomp iomp5 + HINTS ${CMAKE_${LANG}_IMPLICIT_LINK_DIRECTORIES} + ) + 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} + 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) + set("${OPENMP_LIB_NAMES_VAR}" "libomp" PARENT_SCOPE) + break() + endif() + endif() endif() set("${OPENMP_LIB_NAMES_VAR}" "NOTFOUND" PARENT_SCOPE) set("${OPENMP_FLAG_VAR}" "NOTFOUND" PARENT_SCOPE) @@ -414,6 +438,8 @@ endif() unset(_OpenMP_MIN_VERSION) +include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) + foreach(LANG IN LISTS OpenMP_FINDLIST) if(CMAKE_${LANG}_COMPILER_LOADED) if (NOT OpenMP_${LANG}_SPEC_DATE AND OpenMP_${LANG}_FLAGS) @@ -423,8 +449,6 @@ foreach(LANG IN LISTS OpenMP_FINDLIST) _OPENMP_SET_VERSION_BY_SPEC_DATE("${LANG}") endif() - include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) - set(OpenMP_${LANG}_FIND_QUIETLY ${OpenMP_FIND_QUIETLY}) set(OpenMP_${LANG}_FIND_REQUIRED ${OpenMP_FIND_REQUIRED}) set(OpenMP_${LANG}_FIND_VERSION ${OpenMP_FIND_VERSION}) diff --git a/Modules/FindOpenSSL.cmake b/Modules/FindOpenSSL.cmake index c358ff1..d5cd8bc 100644 --- a/Modules/FindOpenSSL.cmake +++ b/Modules/FindOpenSSL.cmake @@ -7,6 +7,12 @@ # # Find the OpenSSL encryption library. # +# Optional COMPONENTS +# ^^^^^^^^^^^^^^^^^^^ +# +# This module supports two optional COMPONENTS: ``Crypto`` and ``SSL``. Both +# components have associated imported targets, as described below. +# # Imported Targets # ^^^^^^^^^^^^^^^^ # @@ -23,7 +29,8 @@ # This module will set the following variables in your project: # # ``OPENSSL_FOUND`` -# System has the OpenSSL library. +# System has the OpenSSL library. If no components are requested it only +# requires the crypto library. # ``OPENSSL_INCLUDE_DIR`` # The OpenSSL include directory. # ``OPENSSL_CRYPTO_LIBRARY`` @@ -371,28 +378,47 @@ if(OPENSSL_INCLUDE_DIR AND EXISTS "${OPENSSL_INCLUDE_DIR}/openssl/opensslv.h") endif () endif () -include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) - set(OPENSSL_LIBRARIES ${OPENSSL_SSL_LIBRARY} ${OPENSSL_CRYPTO_LIBRARY} ) -if (OPENSSL_VERSION) - find_package_handle_standard_args(OpenSSL - REQUIRED_VARS - #OPENSSL_SSL_LIBRARY # FIXME: require based on a component request? - OPENSSL_CRYPTO_LIBRARY - OPENSSL_INCLUDE_DIR - VERSION_VAR - OPENSSL_VERSION - FAIL_MESSAGE - "Could NOT find OpenSSL, try to set the path to OpenSSL root folder in the system variable OPENSSL_ROOT_DIR" - ) -else () - find_package_handle_standard_args(OpenSSL "Could NOT find OpenSSL, try to set the path to OpenSSL root folder in the system variable OPENSSL_ROOT_DIR" - #OPENSSL_SSL_LIBRARY # FIXME: require based on a component request? +foreach(_comp IN LISTS OpenSSL_FIND_COMPONENTS) + if(_comp STREQUAL "Crypto") + if(EXISTS "${OPENSSL_INCLUDE_DIR}" AND + (EXISTS "${OPENSSL_CRYPTO_LIBRARY}" OR + EXISTS "${LIB_EAY_LIBRARY_DEBUG}" OR + EXISTS "${LIB_EAY_LIBRARY_RELEASE}") + ) + set(OpenSSL_${_comp}_FOUND TRUE) + else() + set(OpenSSL_${_comp}_FOUND FALSE) + endif() + elseif(_comp STREQUAL "SSL") + if(EXISTS "${OPENSSL_INCLUDE_DIR}" AND + (EXISTS "${OPENSSL_SSL_LIBRARY}" OR + EXISTS "${SSL_EAY_LIBRARY_DEBUG}" OR + EXISTS "${SSL_EAY_LIBRARY_RELEASE}") + ) + set(OpenSSL_${_comp}_FOUND TRUE) + else() + set(OpenSSL_${_comp}_FOUND FALSE) + endif() + else() + message(WARNING "${_comp} is not a valid OpenSSL component") + set(OpenSSL_${_comp}_FOUND FALSE) + endif() +endforeach() +unset(_comp) + +include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) +find_package_handle_standard_args(OpenSSL + REQUIRED_VARS OPENSSL_CRYPTO_LIBRARY OPENSSL_INCLUDE_DIR - ) -endif () + VERSION_VAR + OPENSSL_VERSION + HANDLE_COMPONENTS + FAIL_MESSAGE + "Could NOT find OpenSSL, try to set the path to OpenSSL root folder in the system variable OPENSSL_ROOT_DIR" +) mark_as_advanced(OPENSSL_INCLUDE_DIR OPENSSL_LIBRARIES) @@ -425,6 +451,7 @@ if(OPENSSL_FOUND) IMPORTED_LOCATION_DEBUG "${LIB_EAY_LIBRARY_DEBUG}") endif() endif() + if(NOT TARGET OpenSSL::SSL AND (EXISTS "${OPENSSL_SSL_LIBRARY}" OR EXISTS "${SSL_EAY_LIBRARY_DEBUG}" OR diff --git a/Modules/FindPkgConfig.cmake b/Modules/FindPkgConfig.cmake index 952ca92..95af0bf 100644 --- a/Modules/FindPkgConfig.cmake +++ b/Modules/FindPkgConfig.cmake @@ -200,9 +200,7 @@ function(_pkg_create_imp_target _prefix _no_cmake_path _no_cmake_environment_pat unset(_search_paths) foreach (flag IN LISTS ${_prefix}_LDFLAGS) if (flag MATCHES "^-L(.*)") - # only look into the given paths from now on list(APPEND _search_paths ${CMAKE_MATCH_1}) - set(_find_opts HINTS ${_search_paths} NO_DEFAULT_PATH) continue() endif() if (flag MATCHES "^-l(.*)") @@ -211,6 +209,12 @@ function(_pkg_create_imp_target _prefix _no_cmake_path _no_cmake_environment_pat continue() endif() + if(_search_paths) + # Firstly search in -L paths + find_library(pkgcfg_lib_${_prefix}_${_pkg_search} + NAMES ${_pkg_search} + HINTS ${_search_paths} NO_DEFAULT_PATH) + endif() find_library(pkgcfg_lib_${_prefix}_${_pkg_search} NAMES ${_pkg_search} ${_find_opts}) @@ -222,7 +226,6 @@ function(_pkg_create_imp_target _prefix _no_cmake_path _no_cmake_environment_pat AND ( ${_prefix}_INCLUDE_DIRS OR _libs OR ${_prefix}_CFLAGS_OTHER )) add_library(PkgConfig::${_prefix} INTERFACE IMPORTED) - unset(_props) if(${_prefix}_INCLUDE_DIRS) set_property(TARGET PkgConfig::${_prefix} PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${${_prefix}_INCLUDE_DIRS}") diff --git a/Modules/FindPython.cmake b/Modules/FindPython.cmake new file mode 100644 index 0000000..8139e53 --- /dev/null +++ b/Modules/FindPython.cmake @@ -0,0 +1,181 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + +#[=======================================================================[.rst: +FindPython +---------- + +Find Python interpreter, compiler and development environment (include +directories and libraries). + +Three components are supported: + +* ``Interpreter``: search for Python interpreter. +* ``Compiler``: search for Python compiler. Only offered by IronPython. +* ``Development``: search for development artifacts (include directories and + libraries). + +If no ``COMPONENTS`` is specified, ``Interpreter`` is assumed. + +To ensure consistent versions between components ``Interpreter``, ``Compiler`` +and ``Development``, specify all components at the same time:: + + find_package (Python COMPONENTS Interpreter Development) + +This module looks preferably for version 3 of Python. If not found, version 2 +is searched. +To manage concurrent versions 3 and 2 of Python, use :module:`FindPython3` and +:module:`FindPython2` modules rather than this one. + +Imported Targets +^^^^^^^^^^^^^^^^ + +This module defines the following :ref:`Imported Targets <Imported Targets>`: + +``Python::Interpreter`` + Python interpreter. Target defined if component ``Interpreter`` is found. +``Python::Compiler`` + Python compiler. Target defined if component ``Compiler`` is found. +``Python::Python`` + Python library. Target defined if component ``Development`` is found. + +Result Variables +^^^^^^^^^^^^^^^^ + +This module will set the following variables in your project +(see :ref:`Standard Variable Names <CMake Developer Standard Variable Names>`): + +``Python_FOUND`` + System has the Python requested components. +``Python_Interpreter_FOUND`` + System has the Python interpreter. +``Python_EXECUTABLE`` + Path to the Python interpreter. +``Python_INTERPRETER_ID`` + A short string unique to the interpreter. Possible values include: + * Python + * ActivePython + * Anaconda + * Canopy + * IronPython +``Python_STDLIB`` + Standard platform independent installation directory. + + Information returned by + ``distutils.sysconfig.get_python_lib(plat_specific=False,standard_lib=True)``. +``Python_STDARCH`` + Standard platform dependent installation directory. + + Information returned by + ``distutils.sysconfig.get_python_lib(plat_specific=True,standard_lib=True)``. +``Python_SITELIB`` + Third-party platform independent installation directory. + + Information returned by + ``distutils.sysconfig.get_python_lib(plat_specific=False,standard_lib=False)``. +``Python_SITEARCH`` + Third-party platform dependent installation directory. + + Information returned by + ``distutils.sysconfig.get_python_lib(plat_specific=True,standard_lib=False)``. +``Python_Compiler_FOUND`` + System has the Python compiler. +``Python_COMPILER`` + Path to the Python compiler. Only offered by IronPython. +``Python_COMPILER_ID`` + A short string unique to the compiler. Possible values include: + * IronPython +``Python_Development_FOUND`` + System has the Python development artifacts. +``Python_INCLUDE_DIRS`` + The Python include directories. +``Python_LIBRARIES`` + The Python libraries. +``Python_LIBRARY_DIRS`` + The Python library directories. +``Python_RUNTIME_LIBRARY_DIRS`` + The Python runtime library directories. +``Python_VERSION`` + Python version. +``Python_VERSION_MAJOR`` + Python major version. +``Python_VERSION_MINOR`` + Python minor version. +``Python_VERSION_PATCH`` + Python patch version. + +Hints +^^^^^ + +``Python_ROOT_DIR`` + Define the root directory of a Python installation. + +``Python_USE_STATIC_LIBS`` + * If not defined, search for shared libraries and static libraries in that + order. + * If set to TRUE, search **only** for static libraries. + * If set to FALSE, search **only** for shared libraries. + +Commands +^^^^^^^^ + +This module defines the command ``Python_add_library`` which have the same +semantic as :command:`add_library` but take care of Python module naming rules +(only applied if library is of type ``MODULE``) and add dependency to target +``Python::Python``:: + + Python_add_library (my_module MODULE src1.cpp) + +If library type is not specified, ``MODULE`` is assumed. +#]=======================================================================] + + +set (_PYTHON_PREFIX Python) + +if (DEFINED Python_FIND_VERSION) + set (_Python_REQUIRED_VERSION_MAJOR ${Python_FIND_VERSION_MAJOR}) + + include (${CMAKE_CURRENT_LIST_DIR}/FindPython/Support.cmake) +else() + # iterate over versions in quiet and NOT required modes to avoid multiple + # "Found" messages and prematurally failure. + set (_Python_QUIETLY ${Python_FIND_QUIETLY}) + set (_Python_REQUIRED ${Python_FIND_REQUIRED}) + set (Python_FIND_QUIETLY TRUE) + set (Python_FIND_REQUIRED FALSE) + + set (_Python_REQUIRED_VERSIONS 3 2) + set (_Python_REQUIRED_VERSION_LAST 2) + + foreach (_Python_REQUIRED_VERSION_MAJOR IN LISTS _Python_REQUIRED_VERSIONS) + set (Python_FIND_VERSION ${_Python_REQUIRED_VERSION_MAJOR}) + include (${CMAKE_CURRENT_LIST_DIR}/FindPython/Support.cmake) + if (Python_FOUND OR + _Python_REQUIRED_VERSION_MAJOR EQUAL _Python_REQUIRED_VERSION_LAST) + break() + endif() + # clean-up some CACHE variables to ensure look-up restart from scratch + foreach (_Python_ITEM IN LISTS _Python_CACHED_VARS) + unset (${_Python_ITEM} CACHE) + endforeach() + endforeach() + + unset (Python_FIND_VERSION) + + set (Python_FIND_QUIETLY ${_Python_QUIETLY}) + set (Python_FIND_REQUIRED ${_Python_REQUIRED}) + if (Python_FIND_REQUIRED OR NOT Python_FIND_QUIETLY) + # call again validation command to get "Found" or error message + find_package_handle_standard_args (Python HANDLE_COMPONENTS + REQUIRED_VARS ${_Python_REQUIRED_VARS} + VERSION_VAR Python_VERSION) + endif() +endif() + +if (COMMAND __Python_add_library) + macro (Python_add_library) + __Python_add_library (Python ${ARGV}) + endmacro() +endif() + +unset (_PYTHON_PREFIX) diff --git a/Modules/FindPython/Support.cmake b/Modules/FindPython/Support.cmake new file mode 100644 index 0000000..9903a6d --- /dev/null +++ b/Modules/FindPython/Support.cmake @@ -0,0 +1,929 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + +# +# This file is a "template" file used by various FindPython modules. +# + +cmake_policy (VERSION 3.7) + +# +# Initial configuration +# +if (NOT DEFINED _PYTHON_PREFIX) + message (FATAL_ERROR "FindPython: INTERNAL ERROR") +endif() +if (NOT DEFINED _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR) + message (FATAL_ERROR "FindPython: INTERNAL ERROR") +endif() +if (_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR EQUAL 3) + set(_${_PYTHON_PREFIX}_VERSIONS 3.7 3.6 3.5 3.4 3.3 3.2 3.1 3.0) +elseif (_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR EQUAL 2) + set(_${_PYTHON_PREFIX}_VERSIONS 2.7 2.6 2.5 2.4 2.3 2.2 2.1 2.0) +else() + message (FATAL_ERROR "FindPython: INTERNAL ERROR") +endif() + + +# +# helper commands +# +macro (_PYTHON_DISPLAY_FAILURE _PYTHON_MSG) + if (${_PYTHON_PREFIX}_FIND_REQUIRED) + message (FATAL_ERROR "${_PYTHON_MSG}") + else() + if (NOT ${_PYTHON_PREFIX}_FIND_QUIETLY) + message(STATUS "${_PYTHON_MSG}") + endif () + endif() + + set (${_PYTHON_PREFIX}_FOUND FALSE) + string (TOUPPER "${_PYTHON_PREFIX}" _${_PYTHON_PREFIX}_UPPER_PREFIX) + set (${_PYTHON_UPPER_PREFIX}_FOUND FALSE) + return() +endmacro() + + +function (_PYTHON_GET_FRAMEWORKS _PYTHON_PGF_FRAMEWORK_PATHS _PYTHON_VERSION) + set (_PYTHON_FRAMEWORK_PATHS) + foreach (_PYTHON_FRAMEWORK IN LISTS Python_FRAMEWORKS) + list (APPEND _PYTHON_FRAMEWORK_PATHS + "${_PYTHON_FRAMEWORK}/Versions/${_PYTHON_VERSION}") + endforeach() + set (${_PYTHON_PGF_FRAMEWORK_PATHS} ${_PYTHON_FRAMEWORK_PATHS} PARENT_SCOPE) +endfunction() + + +function (_PYTHON_VALIDATE_INTERPRETER) + if (NOT ${_PYTHON_PREFIX}_EXECUTABLE) + return() + endif() + + if (${_PYTHON_PREFIX}_EXECUTABLE MATCHES "python${CMAKE_EXECUTABLE_SUFFIX}$") + # executable found do not have version in name + # ensure major version is OK + execute_process (COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -c + "import sys; sys.stdout.write(str(sys.version_info[0]))" + RESULT_VARIABLE result + OUTPUT_VARIABLE version + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE) + if (result OR NOT version EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR) + # interpreter not usable or has wrong major version + set (${_PYTHON_PREFIX}_EXECUTABLE ${_PYTHON_PREFIX}_EXECUTABLE-NOTFOUND CACHE INTERNAL "" FORCE) + return() + endif() + endif() + + if (CMAKE_SIZEOF_VOID_P AND "Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS + AND NOT CMAKE_CROSSCOMPILING) + # In this case, interpreter must have same architecture as environment + execute_process (COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -c + "import sys, struct; sys.stdout.write(str(struct.calcsize(\"P\")))" + RESULT_VARIABLE result + OUTPUT_VARIABLE size + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE) + if (result OR NOT size EQUAL CMAKE_SIZEOF_VOID_P) + # interpreter not usable or has wrong architecture + set (${_PYTHON_PREFIX}_EXECUTABLE ${_PYTHON_PREFIX}_EXECUTABLE-NOTFOUND CACHE INTERNAL "" FORCE) + return() + endif() + endif() +endfunction() + + +function (_PYTHON_FIND_RUNTIME_LIBRARY _PYTHON_LIB) + string (REPLACE "_RUNTIME" "" _PYTHON_LIB "${_PYTHON_LIB}") + # look at runtime part on systems supporting it + if (CMAKE_SYSTEM_NAME STREQUAL "Windows" OR + (CMAKE_SYSTEM_NAME MATCHES "MSYS|CYGWIN" + AND ${_PYTHON_LIB} MATCHES "${CMAKE_IMPORT_LIBRARY_SUFFIX}$")) + set (CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_SHARED_LIBRARY_SUFFIX}) + # MSYS has a special syntax for runtime libraries + if (CMAKE_SYSTEM_NAME MATCHES "MSYS") + list (APPEND CMAKE_FIND_LIBRARY_PREFIXES "msys-") + endif() + find_library (${ARGV}) + endif() +endfunction() + + +function (_PYTHON_SET_LIBRARY_DIRS _PYTHON_SLD_RESULT) + unset (_PYTHON_DIRS) + set (_PYTHON_LIBS ${ARGV}) + list (REMOVE_AT _PYTHON_LIBS 0) + foreach (_PYTHON_LIB IN LISTS _PYTHON_LIBS) + if (${_PYTHON_LIB}) + get_filename_component (_PYTHON_DIR "${${_PYTHON_LIB}}" DIRECTORY) + list (APPEND _PYTHON_DIRS "${_PYTHON_DIR}") + endif() + endforeach() + if (_PYTHON_DIRS) + list (REMOVE_DUPLICATES _PYTHON_DIRS) + endif() + set (${_PYTHON_SLD_RESULT} ${_PYTHON_DIRS} PARENT_SCOPE) +endfunction() + + +# If major version is specified, it must be the same as internal major version +if (DEFINED ${_PYTHON_PREFIX}_FIND_VERSION_MAJOR + AND NOT ${_PYTHON_PREFIX}_FIND_VERSION_MAJOR VERSION_EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR) + _python_display_failure ("Could NOT find ${_PYTHON_PREFIX}: Wrong major version specified is \"${${_PYTHON_PREFIX}_FIND_VERSION_MAJOR}\", but expected major version is \"${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR}\"") +endif() + + +# handle components +if (NOT ${_PYTHON_PREFIX}_FIND_COMPONENTS) + set (${_PYTHON_PREFIX}_FIND_COMPONENTS Interpreter) + set (${_PYTHON_PREFIX}_FIND_REQUIRED_Interpreter TRUE) +endif() +foreach (_${_PYTHON_PREFIX}_COMPONENT IN LISTS ${_PYTHON_PREFIX}_FIND_COMPONENTS) + set (${_PYTHON_PREFIX}_${_${_PYTHON_PREFIX}_COMPONENT}_FOUND FALSE) +endforeach() +unset (_${_PYTHON_PREFIX}_FIND_VERSIONS) + +# Set versions to search +## default: search any version +set (_${_PYTHON_PREFIX}_FIND_VERSIONS ${_${_PYTHON_PREFIX}_VERSIONS}) + +if (${_PYTHON_PREFIX}_FIND_VERSION_COUNT GREATER 1) + if (${_PYTHON_PREFIX}_FIND_VERSION_EXACT) + set (_${_PYTHON_PREFIX}_FIND_VERSIONS ${${_PYTHON_PREFIX}_FIND_VERSION_MAJOR}.${${_PYTHON_PREFIX}_FIND_VERSION_MINOR}) + else() + unset (_${_PYTHON_PREFIX}_FIND_VERSIONS) + # add all compatible versions + foreach (_${_PYTHON_PREFIX}_VERSION IN LISTS _${_PYTHON_PREFIX}_VERSIONS) + if (_${_PYTHON_PREFIX}_VERSION VERSION_GREATER_EQUAL ${_PYTHON_PREFIX}_FIND_VERSION) + list (APPEND _${_PYTHON_PREFIX}_FIND_VERSIONS ${_${_PYTHON_PREFIX}_VERSION}) + endif() + endforeach() + endif() +endif() + +# Anaconda distribution: define which architectures can be used +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}) +else() + # architecture unknown, search for both 64bit and 32bit + set (_${_PYTHON_PREFIX}_ARCH 64) + set (_${_PYTHON_PREFIX}_ARCH2 32) +endif() + +# IronPython support +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}_IRON_PYTHON_NAMES ipy${_${_PYTHON_PREFIX}_ARCH} ipy) +else() + # architecture unknown, search for natural interpreter + set (_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES ipy) +endif() + +# Apple frameworks handling +include (${CMAKE_CURRENT_LIST_DIR}/../CMakeFindFrameworks.cmake) +cmake_find_frameworks (Python) + +# Save CMAKE_FIND_FRAMEWORK +if (DEFINED CMAKE_FIND_FRAMEWORK) + set (_${_PYTHON_PREFIX}_CMAKE_FIND_FRAMEWORK ${CMAKE_FIND_FRAMEWORK}) +else() + unset (_${_PYTHON_PREFIX}_CMAKE_FIND_FRAMEWORK) +endif() +# To avoid picking up the system elements pre-maturely. +set (CMAKE_FIND_FRAMEWORK LAST) + + +unset (${_PYTHON_PREFIX}_VERSION_MAJOR) +unset (${_PYTHON_PREFIX}_VERSION_MINOR) +unset (${_PYTHON_PREFIX}_VERSION_PATCH) + +unset (_${_PYTHON_PREFIX}_REQUIRED_VARS) +unset (_${_PYTHON_PREFIX}_CACHED_VARS) + + +# first step, search for the interpreter +if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) + if (${_PYTHON_PREFIX}_FIND_REQUIRED_Interpreter) + list (APPEND _${_PYTHON_PREFIX}_REQUIRED_VARS ${_PYTHON_PREFIX}_EXECUTABLE) + list (APPEND _${_PYTHON_PREFIX}_CACHED_VARS ${_PYTHON_PREFIX}_EXECUTABLE) + endif() + + set (_${_PYTHON_PREFIX}_HINTS "${${_PYTHON_PREFIX}_ROOT_DIR}" ENV ${_PYTHON_PREFIX}_ROOT_DIR) + + # look-up for various versions and locations + foreach (_${_PYTHON_PREFIX}_VERSION IN LISTS _${_PYTHON_PREFIX}_FIND_VERSIONS) + string (REPLACE "." "" _${_PYTHON_PREFIX}_VERSION_NO_DOTS ${_${_PYTHON_PREFIX}_VERSION}) + + _python_get_frameworks (_${_PYTHON_PREFIX}_FRAMEWORK_PATHS ${_${_PYTHON_PREFIX}_VERSION}) + + # try using HINTS + find_program (${_PYTHON_PREFIX}_EXECUTABLE + NAMES python${_${_PYTHON_PREFIX}_VERSION} + NAMES_PER_DIR + HINTS ${_${_PYTHON_PREFIX}_HINTS} + PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS} + PATH_SUFFIXES bin + NO_SYSTEM_ENVIRONMENT_PATH + NO_CMAKE_SYSTEM_PATH) + # try using registry + if (WIN32) + find_program (${_PYTHON_PREFIX}_EXECUTABLE + NAMES python${_${_PYTHON_PREFIX}_VERSION} python + ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES} + NAMES_PER_DIR + HINTS ${_${_PYTHON_PREFIX}_HINTS} + PATHS [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] + [HKEY_CURRENT_USER\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath] + [HKEY_CURRENT_USER\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH2}\\InstallPath] + [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] + [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath] + [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH2}\\InstallPath] + [HKEY_LOCAL_MACHINE\\SOFTWARE\\IronPython\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] + PATH_SUFFIXES bin + NO_SYSTEM_ENVIRONMENT_PATH + NO_CMAKE_SYSTEM_PATH) + endif() + # try in standard paths + find_program (${_PYTHON_PREFIX}_EXECUTABLE + NAMES python${_${_PYTHON_PREFIX}_VERSION}) + + _python_validate_interpreter () + if (${_PYTHON_PREFIX}_EXECUTABLE) + break() + endif() + endforeach() + + # try more generic names + if (NOT ${_PYTHON_PREFIX}_EXECUTABLE) + find_program (${_PYTHON_PREFIX}_EXECUTABLE + NAMES python${${_PYTHON_PREFIX}_VERSION_MAJOR} python + ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES} + HINTS ${_${_PYTHON_PREFIX}_HINTS} + PATH_SUFFIXES bin) + + _python_validate_interpreter () + endif() + + # retrieve exact version of executable found + if (${_PYTHON_PREFIX}_EXECUTABLE) + execute_process (COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -c + "import sys; sys.stdout.write('.'.join([str(x) for x in sys.version_info[:3]]))" + RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT + OUTPUT_VARIABLE ${_PYTHON_PREFIX}_VERSION + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE) + if (NOT _${_PYTHON_PREFIX}_RESULT) + string (REGEX MATCHALL "[0-9]+" _${_PYTHON_PREFIX}_VERSIONS "${${_PYTHON_PREFIX}_VERSION}") + list (GET _${_PYTHON_PREFIX}_VERSIONS 0 ${_PYTHON_PREFIX}_VERSION_MAJOR) + list (GET _${_PYTHON_PREFIX}_VERSIONS 1 ${_PYTHON_PREFIX}_VERSION_MINOR) + list (GET _${_PYTHON_PREFIX}_VERSIONS 2 ${_PYTHON_PREFIX}_VERSION_PATCH) + else() + # Interpreter is not usable + set (${_PYTHON_PREFIX}_EXECUTABLE ${_PYTHON_PREFIX}_EXECUTABLE-NOTFOUND CACHE INTERNAL "" FORCE) + unset (${_PYTHON_PREFIX}_VERSION) + endif() + endif() + + if (${_PYTHON_PREFIX}_EXECUTABLE + AND ${_PYTHON_PREFIX}_VERSION_MAJOR VERSION_EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR) + set (${_PYTHON_PREFIX}_Interpreter_FOUND TRUE) + # Use interpreter version for future searchs to ensure consistency + set (_${_PYTHON_PREFIX}_FIND_VERSIONS ${${_PYTHON_PREFIX}_VERSION_MAJOR}.${${_PYTHON_PREFIX}_VERSION_MINOR}) + endif() + + if (${_PYTHON_PREFIX}_Interpreter_FOUND) + # retrieve interpreter identity + execute_process (COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -V + RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT + OUTPUT_VARIABLE ${_PYTHON_PREFIX}_INTERPRETER_ID + ERROR_VARIABLE ${_PYTHON_PREFIX}_INTERPRETER_ID) + if (NOT _${_PYTHON_PREFIX}_RESULT) + if (${_PYTHON_PREFIX}_INTERPRETER_ID MATCHES "Anaconda") + set (${_PYTHON_PREFIX}_INTERPRETER_ID "Anaconda") + elseif (${_PYTHON_PREFIX}_INTERPRETER_ID MATCHES "Enthought") + set (${_PYTHON_PREFIX}_INTERPRETER_ID "Canopy") + else() + string (REGEX REPLACE "^([^ ]+).*" "\\1" ${_PYTHON_PREFIX}_INTERPRETER_ID "${${_PYTHON_PREFIX}_INTERPRETER_ID}") + if (${_PYTHON_PREFIX}_INTERPRETER_ID STREQUAL "Python") + # try to get a more precise ID + execute_process (COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -c "import sys; print(sys.copyright)" + RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT + OUTPUT_VARIABLE ${_PYTHON_PREFIX}_COPYRIGHT + ERROR_QUIET) + if (${_PYTHON_PREFIX}_COPYRIGHT MATCHES "ActiveState") + set (${_PYTHON_PREFIX}_INTERPRETER_ID "ActivePython") + endif() + endif() + endif() + else() + set (${_PYTHON_PREFIX}_INTERPRETER_ID Python) + endif() + else() + unset (${_PYTHON_PREFIX}_INTERPRETER_ID) + endif() + + # retrieve various package installation directories + execute_process (COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -c "import sys; from distutils import sysconfig;sys.stdout.write(';'.join([sysconfig.get_python_lib(plat_specific=False,standard_lib=True),sysconfig.get_python_lib(plat_specific=True,standard_lib=True),sysconfig.get_python_lib(plat_specific=False,standard_lib=False),sysconfig.get_python_lib(plat_specific=True,standard_lib=False)]))" + + RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT + OUTPUT_VARIABLE _${_PYTHON_PREFIX}_LIBPATHS + ERROR_QUIET) + if (NOT _${_PYTHON_PREFIX}_RESULT) + list (GET _${_PYTHON_PREFIX}_LIBPATHS 0 ${_PYTHON_PREFIX}_STDLIB) + list (GET _${_PYTHON_PREFIX}_LIBPATHS 1 ${_PYTHON_PREFIX}_STDARCH) + list (GET _${_PYTHON_PREFIX}_LIBPATHS 2 ${_PYTHON_PREFIX}_SITELIB) + list (GET _${_PYTHON_PREFIX}_LIBPATHS 3 ${_PYTHON_PREFIX}_SITEARCH) + else() + unset (${_PYTHON_PREFIX}_STDLIB) + unset (${_PYTHON_PREFIX}_STDARCH) + unset (${_PYTHON_PREFIX}_SITELIB) + unset (${_PYTHON_PREFIX}_SITEARCH) + endif() + + mark_as_advanced (${_PYTHON_PREFIX}_EXECUTABLE) +endif() + + +# second step, search for compiler (IronPython) +if ("Compiler" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) + if (${_PYTHON_PREFIX}_FIND_REQUIRED_Compiler) + list (APPEND _${_PYTHON_PREFIX}_REQUIRED_VARS ${_PYTHON_PREFIX}_COMPILER) + list (APPEND _${_PYTHON_PREFIX}_CACHED_VARS ${_PYTHON_PREFIX}_COMPILER) + endif() + + # IronPython specific artifacts + # If IronPython interpreter is found, use its path + unset (_${_PYTHON_PREFIX}_IRON_ROOT) + if (${_PYTHON_PREFIX}_Interpreter_FOUND AND ${_PYTHON_PREFIX}_INTERPRETER_ID STREQUAL "IronPython") + get_filename_component (_${_PYTHON_PREFIX}_IRON_ROOT "${${_PYTHON_PREFIX}_EXECUTABLE}" DIRECTORY) + endif() + + # try using root dir and registry + foreach (_${_PYTHON_PREFIX}_VERSION IN LISTS _${_PYTHON_PREFIX}_FIND_VERSIONS) + find_program (${_PYTHON_PREFIX}_COMPILER + NAMES ipyc + HINTS ${_${_PYTHON_PREFIX}_IRON_ROOT} ${_${_PYTHON_PREFIX}_HINTS} + PATHS [HKEY_LOCAL_MACHINE\\SOFTWARE\\IronPython\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] + NO_SYSTEM_ENVIRONMENT_PATH + NO_CMAKE_SYSTEM_PATH) + if (${_PYTHON_PREFIX}_COMPILER) + break() + endif() + endforeach() + # try in standard paths + find_program (${_PYTHON_PREFIX}_COMPILER + NAMES ipyc) + + if (${_PYTHON_PREFIX}_COMPILER) + # retrieve python environment version from compiler + set (_${_PYTHON_PREFIX}_VERSION_DIR "${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/PythonCompilerVersion.dir") + file (WRITE "${_${_PYTHON_PREFIX}_VERSION_DIR}/version.py" "import sys; sys.stdout.write('.'.join([str(x) for x in sys.version_info[:3]]))\n") + execute_process (COMMAND "${${_PYTHON_PREFIX}_COMPILER}" /target:exe /embed "${_${_PYTHON_PREFIX}_VERSION_DIR}/version.py" + WORKING_DIRECTORY "${_${_PYTHON_PREFIX}_VERSION_DIR}" + OUTPUT_QUIET + ERROR_QUIET) + execute_process (COMMAND "${_${_PYTHON_PREFIX}_VERSION_DIR}/version" + WORKING_DIRECTORY "${_${_PYTHON_PREFIX}_VERSION_DIR}" + RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT + OUTPUT_VARIABLE _${_PYTHON_PREFIX}_VERSION + ERROR_QUIET) + if (NOT _${_PYTHON_PREFIX}_RESULT) + string (REGEX MATCHALL "[0-9]+" _${_PYTHON_PREFIX}_VERSIONS "${_${_PYTHON_PREFIX}_VERSION}") + list (GET _${_PYTHON_PREFIX}_VERSIONS 0 _${_PYTHON_PREFIX}_VERSION_MAJOR) + list (GET _${_PYTHON_PREFIX}_VERSIONS 1 _${_PYTHON_PREFIX}_VERSION_MINOR) + list (GET _${_PYTHON_PREFIX}_VERSIONS 2 _${_PYTHON_PREFIX}_VERSION_PATCH) + + if (NOT ${_PYTHON_PREFIX}_Interpreter_FOUND) + # set public version information + 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() + else() + # compiler not usable + set (${_PYTHON_PREFIX}_COMPILER ${_PYTHON_PREFIX}_COMPILER-NOTFOUND CACHE INTERNAL "" FORCE) + endif() + file (REMOVE_RECURSE "${_${_PYTHON_PREFIX}_VERSION_DIR}") + endif() + + if (${_PYTHON_PREFIX}_COMPILER) + if (${_PYTHON_PREFIX}_Interpreter_FOUND) + # Compiler must be compatible with interpreter + if (${_${_PYTHON_PREFIX}_VERSION_MAJOR}.${_${_PYTHON_PREFIX}_VERSION_MINOR} VERSION_EQUAL ${${_PYTHON_PREFIX}_VERSION_MAJOR}.${${_PYTHON_PREFIX}_VERSION_MINOR}) + set (${_PYTHON_PREFIX}_Compiler_FOUND TRUE) + endif() + elseif (${_PYTHON_PREFIX}_VERSION_MAJOR VERSION_EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR) + set (${_PYTHON_PREFIX}_Compiler_FOUND TRUE) + # Use compiler version for future searchs to ensure consistency + set (_${_PYTHON_PREFIX}_FIND_VERSIONS ${${_PYTHON_PREFIX}_VERSION_MAJOR}.${${_PYTHON_PREFIX}_VERSION_MINOR}) + endif() + endif() + + if (${_PYTHON_PREFIX}_Compiler_FOUND) + set (${_PYTHON_PREFIX}_COMPILER_ID IronPython) + else() + unset (${_PYTHON_PREFIX}_COMPILER_ID) + endif() + + mark_as_advanced (${_PYTHON_PREFIX}_COMPILER) +endif() + + +# third step, search for the development artifacts +## Development environment is not compatible with IronPython interpreter +if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS + AND NOT ${_PYTHON_PREFIX}_INTERPRETER_ID STREQUAL "IronPython") + if (${_PYTHON_PREFIX}_FIND_REQUIRED_Development) + list (APPEND _${_PYTHON_PREFIX}_REQUIRED_VARS ${_PYTHON_PREFIX}_LIBRARY + ${_PYTHON_PREFIX}_INCLUDE_DIR) + list (APPEND _${_PYTHON_PREFIX}_CACHED_VARS ${_PYTHON_PREFIX}_LIBRARY + ${_PYTHON_PREFIX}_LIBRARY_RELEASE + ${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE + ${_PYTHON_PREFIX}_LIBRARY_DEBUG + ${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG + ${_PYTHON_PREFIX}_INCLUDE_DIR) + endif() + + # Support preference of static libs by adjusting CMAKE_FIND_LIBRARY_SUFFIXES + unset (_${_PYTHON_PREFIX}_CMAKE_FIND_LIBRARY_SUFFIXES) + if (DEFINED ${_PYTHON_PREFIX}_USE_STATIC_LIBS AND NOT WIN32) + set(_${_PYTHON_PREFIX}_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES}) + if(${_PYTHON_PREFIX}_USE_STATIC_LIBS) + set (CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_STATIC_LIBRARY_SUFFIX}) + else() + list (REMOVE_ITEM CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_STATIC_LIBRARY_SUFFIX}) + endif() + else() + endif() + + # if python interpreter is found, use its location and version to ensure consistency + # between interpreter and development environment + unset (_${_PYTHON_PREFIX}_PREFIX) + if (${_PYTHON_PREFIX}_Interpreter_FOUND) + execute_process (COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -c + "import sys; from distutils import sysconfig; sys.stdout.write(sysconfig.PREFIX)" + RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT + OUTPUT_VARIABLE _${_PYTHON_PREFIX}_PREFIX + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE) + if (_${_PYTHON_PREFIX}_RESULT) + unset (_${_PYTHON_PREFIX}_PREFIX) + endif() + endif() + set (_${_PYTHON_PREFIX}_HINTS "${_${_PYTHON_PREFIX}_PREFIX}" "${${_PYTHON_PREFIX}_ROOT_DIR}" ENV ${_PYTHON_PREFIX}_ROOT_DIR) + + foreach (_${_PYTHON_PREFIX}_VERSION IN LISTS _${_PYTHON_PREFIX}_FIND_VERSIONS) + string (REPLACE "." "" _${_PYTHON_PREFIX}_VERSION_NO_DOTS ${_${_PYTHON_PREFIX}_VERSION}) + + # try to use pythonX.Y-config tool + set (_${_PYTHON_PREFIX}_CONFIG_NAMES) + if (DEFINED CMAKE_LIBRARY_ARCHITECTURE) + set (_${_PYTHON_PREFIX}_CONFIG_NAMES "${CMAKE_LIBRARY_ARCHITECTURE}-python${_${_PYTHON_PREFIX}_VERSION}-config") + endif() + list (APPEND _${_PYTHON_PREFIX}_CONFIG_NAMES "python${_${_PYTHON_PREFIX}_VERSION}-config") + find_program (_${_PYTHON_PREFIX}_CONFIG + NAMES ${_${_PYTHON_PREFIX}_CONFIG_NAMES} + HINTS ${_${_PYTHON_PREFIX}_HINTS} + PATH_SUFFIXES bin) + unset (_${_PYTHON_PREFIX}_CONFIG_NAMES) + + if (NOT _${_PYTHON_PREFIX}_CONFIG) + continue() + endif() + + # retrieve root install directory + execute_process (COMMAND "${_${_PYTHON_PREFIX}_CONFIG}" --prefix + RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT + OUTPUT_VARIABLE _${_PYTHON_PREFIX}_PREFIX + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE) + if (_${_PYTHON_PREFIX}_RESULT) + # python-config is not usable + unset (_${_PYTHON_PREFIX}_CONFIG CACHE) + continue() + endif() + set (_${_PYTHON_PREFIX}_HINTS "${_${_PYTHON_PREFIX}_PREFIX}" "${${_PYTHON_PREFIX}_ROOT_DIR}" ENV ${_PYTHON_PREFIX}_ROOT_DIR) + + # retrieve library + execute_process (COMMAND "${_${_PYTHON_PREFIX}_CONFIG}" --ldflags + RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT + OUTPUT_VARIABLE _${_PYTHON_PREFIX}_FLAGS + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE) + if (NOT _${_PYTHON_PREFIX}_RESULT) + # retrieve library directory + string (REGEX MATCHALL "-L[^ ]+" _${_PYTHON_PREFIX}_LIB_DIRS "${_${_PYTHON_PREFIX}_FLAGS}") + string (REPLACE "-L" "" _${_PYTHON_PREFIX}_LIB_DIRS "${_${_PYTHON_PREFIX}_LIB_DIRS}") + list (REMOVE_DUPLICATES _${_PYTHON_PREFIX}_LIB_DIRS) + # retrieve library name + string (REGEX MATCHALL "-lpython[^ ]+" _${_PYTHON_PREFIX}_LIB_NAMES "${_${_PYTHON_PREFIX}_FLAGS}") + string (REPLACE "-l" "" _${_PYTHON_PREFIX}_LIB_NAMES "${_${_PYTHON_PREFIX}_LIB_NAMES}") + list (REMOVE_DUPLICATES _${_PYTHON_PREFIX}_LIB_NAMES) + + find_library (${_PYTHON_PREFIX}_LIBRARY_RELEASE + NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES} + NAMES_PER_DIR + HINTS ${_${_PYTHON_PREFIX}_HINTS} ${_${_PYTHON_PREFIX}_LIB_DIRS} + PATH_SUFFIXES lib + NO_SYSTEM_ENVIRONMENT_PATH + NO_CMAKE_SYSTEM_PATH) + # retrieve runtime library + if (${_PYTHON_PREFIX}_LIBRARY_RELEASE) + get_filename_component (_${_PYTHON_PREFIX}_PATH "${${_PYTHON_PREFIX}_LIBRARY_RELEASE}" DIRECTORY) + _python_find_runtime_library (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE + NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES} + NAMES_PER_DIR + HINTS ${_${_PYTHON_PREFIX}_PATH} ${_${_PYTHON_PREFIX}_HINTS} + PATH_SUFFIXES bin + NO_SYSTEM_ENVIRONMENT_PATH + NO_CMAKE_SYSTEM_PATH) + endif() + endif() + + # retrieve include directory + execute_process (COMMAND "${_${_PYTHON_PREFIX}_CONFIG}" --includes + RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT + OUTPUT_VARIABLE _${_PYTHON_PREFIX}_FLAGS + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE) + if (NOT _${_PYTHON_PREFIX}_RESULT) + # retrieve include directory + string (REGEX MATCHALL "-I[^ ]+" _${_PYTHON_PREFIX}_INCLUDE_DIRS "${_${_PYTHON_PREFIX}_FLAGS}") + string (REPLACE "-I" "" _${_PYTHON_PREFIX}_INCLUDE_DIRS "${_${_PYTHON_PREFIX}_INCLUDE_DIRS}") + list (REMOVE_DUPLICATES _${_PYTHON_PREFIX}_INCLUDE_DIRS) + + find_path (${_PYTHON_PREFIX}_INCLUDE_DIR + NAMES Python.h + HINTS ${_${_PYTHON_PREFIX}_INCLUDE_DIRS} + NO_SYSTEM_ENVIRONMENT_PATH + NO_CMAKE_SYSTEM_PATH) + endif() + + if (${_PYTHON_PREFIX}_LIBRARY_RELEASE AND ${_PYTHON_PREFIX}_INCLUDE_DIR) + break() + endif() + endforeach() + + # Rely on HINTS and standard paths if config tool failed to locate artifacts + if (NOT (${_PYTHON_PREFIX}_LIBRARY_RELEASE OR ${_PYTHON_PREFIX}_LIBRARY_DEBUG) OR NOT ${_PYTHON_PREFIX}_INCLUDE_DIR) + foreach (_${_PYTHON_PREFIX}_VERSION IN LISTS _${_PYTHON_PREFIX}_FIND_VERSIONS) + string (REPLACE "." "" _${_PYTHON_PREFIX}_VERSION_NO_DOTS ${_${_PYTHON_PREFIX}_VERSION}) + + _python_get_frameworks (_${_PYTHON_PREFIX}_FRAMEWORK_PATHS ${_${_PYTHON_PREFIX}_VERSION}) + + # search first in known locations + find_library (${_PYTHON_PREFIX}_LIBRARY_RELEASE + NAMES python${_${_PYTHON_PREFIX}_VERSION_NO_DOTS} + python${_${_PYTHON_PREFIX}_VERSION}mu + python${_${_PYTHON_PREFIX}_VERSION}m + python${_${_PYTHON_PREFIX}_VERSION}u + python${_${_PYTHON_PREFIX}_VERSION} + NAMES_PER_DIR + HINTS ${_${_PYTHON_PREFIX}_HINTS} + PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS} + [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] + [HKEY_CURRENT_USER\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath] + [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] + [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath] + PATH_SUFFIXES lib/${CMAKE_LIBRARY_ARCHITECTURE} lib libs + lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}mu + lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}m + lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}u + lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION} + lib/python${_${_PYTHON_PREFIX}_VERSION}/config + NO_SYSTEM_ENVIRONMENT_PATH + NO_CMAKE_SYSTEM_PATH) + # search in all default paths + find_library (${_PYTHON_PREFIX}_LIBRARY_RELEASE + NAMES python${_${_PYTHON_PREFIX}_VERSION_NO_DOTS} + python${_${_PYTHON_PREFIX}_VERSION}mu + python${_${_PYTHON_PREFIX}_VERSION}m + python${_${_PYTHON_PREFIX}_VERSION}u + python${_${_PYTHON_PREFIX}_VERSION} + NAMES_PER_DIR + PATH_SUFFIXES lib/${CMAKE_LIBRARY_ARCHITECTURE} lib libs + lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}mu + lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}m + lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}u + lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION} + lib/python${_${_PYTHON_PREFIX}_VERSION}/config) + # retrieve runtime library + if (${_PYTHON_PREFIX}_LIBRARY_RELEASE) + get_filename_component (_${_PYTHON_PREFIX}_PATH "${${_PYTHON_PREFIX}_LIBRARY_RELEASE}" DIRECTORY) + _python_find_runtime_library (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE + NAMES python${_${_PYTHON_PREFIX}_VERSION_NO_DOTS} + python${_${_PYTHON_PREFIX}_VERSION}mu + python${_${_PYTHON_PREFIX}_VERSION}m + python${_${_PYTHON_PREFIX}_VERSION}u + python${_${_PYTHON_PREFIX}_VERSION} + NAMES_PER_DIR + HINTS "${_${_PYTHON_PREFIX}_PATH}" ${_${_PYTHON_PREFIX}_HINTS} + PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS} + [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] + [HKEY_CURRENT_USER\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath] + [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] + [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath] + PATH_SUFFIXES bin) + endif() + + if (WIN32) + # search for debug library + if (${_PYTHON_PREFIX}_LIBRARY_RELEASE) + # use library location as a hint + get_filename_component (_${_PYTHON_PREFIX}_PATH "${${_PYTHON_PREFIX}_LIBRARY_RELEASE}" DIRECTORY) + find_library (${_PYTHON_PREFIX}_LIBRARY_DEBUG + NAMES python${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}_d + NAMES_PER_DIR + HINTS "${_${_PYTHON_PREFIX}_PATH}" ${_${_PYTHON_PREFIX}_HINTS} + NO_DEFAULT_PATH) + else() + # search first in known locations + find_library (${_PYTHON_PREFIX}_LIBRARY_DEBUG + NAMES python${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}_d + NAMES_PER_DIR + HINTS ${_${_PYTHON_PREFIX}_HINTS} + PATHS [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] + [HKEY_CURRENT_USER\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath] + [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] + [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath] + PATH_SUFFIXES lib libs + NO_SYSTEM_ENVIRONMENT_PATH + NO_CMAKE_SYSTEM_PATH) + # search in all default paths + find_library (${_PYTHON_PREFIX}_LIBRARY_DEBUG + NAMES python${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}_d + NAMES_PER_DIR + PATH_SUFFIXES lib libs) + endif() + if (${_PYTHON_PREFIX}_LIBRARY_DEBUG) + get_filename_component (_${_PYTHON_PREFIX}_PATH "${${_PYTHON_PREFIX}_LIBRARY_DEBUG}" DIRECTORY) + _python_find_runtime_library (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG + NAMES python${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}_d + NAMES_PER_DIR + HINTS "${_${_PYTHON_PREFIX}_PATH}" ${_${_PYTHON_PREFIX}_HINTS} + PATHS [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] + [HKEY_CURRENT_USER\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath] + [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] + [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath] + PATH_SUFFIXES bin) + endif() + endif() + + # Don't search for include dir until library location is known + if (${_PYTHON_PREFIX}_LIBRARY_RELEASE OR ${_PYTHON_PREFIX}_LIBRARY_DEBUG) + unset (_${_PYTHON_PREFIX}_INCLUDE_HINTS) + foreach (_${_PYTHON_PREFIX}_LIB IN ITEMS ${_PYTHON_PREFIX}_LIBRARY_RELEASE ${_PYTHON_PREFIX}_LIBRARY_DEBUG) + if (${_${_PYTHON_PREFIX}_LIB}) + # Use the library's install prefix as a hint + if (${_${_PYTHON_PREFIX}_LIB} MATCHES "^(.+/Frameworks/Python.framework/Versions/[0-9.]+)") + list (APPEND _${_PYTHON_PREFIX}_INCLUDE_HINTS "${CMAKE_MATCH_1}") + elseif (${_${_PYTHON_PREFIX}_LIB} 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}_LIB} 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}_LIB}}" DIRECTORY) + get_filename_component (_${_PYTHON_PREFIX}_PREFIX "${_${_PYTHON_PREFIX}_PREFIX}" DIRECTORY) + list (APPEND _${_PYTHON_PREFIX}_INCLUDE_HINTS "${_${_PYTHON_PREFIX}_PREFIX}") + endif() + endif() + endforeach() + list (REMOVE_DUPLICATES _${_PYTHON_PREFIX}_INCLUDE_HINTS) + + find_path (${_PYTHON_PREFIX}_INCLUDE_DIR + NAMES Python.h + HINTS ${_${_PYTHON_PREFIX}_INCLUDE_HINTS} ${_${_PYTHON_PREFIX}_HINTS} + PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS} + [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] + [HKEY_CURRENT_USER\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath] + [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] + [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath] + PATH_SUFFIXES include/python${_${_PYTHON_PREFIX}_VERSION}mu + include/python${_${_PYTHON_PREFIX}_VERSION}m + include/python${_${_PYTHON_PREFIX}_VERSION}u + include/python${_${_PYTHON_PREFIX}_VERSION} + include + NO_SYSTEM_ENVIRONMENT_PATH + NO_CMAKE_SYSTEM_PATH) + endif() + + if ((${_PYTHON_PREFIX}_LIBRARY_RELEASE OR ${_PYTHON_PREFIX}_LIBRARY_DEBUG) AND ${_PYTHON_PREFIX}_INCLUDE_DIR) + break() + endif() + endforeach() + + # search header file in standard locations + find_path (${_PYTHON_PREFIX}_INCLUDE_DIR + NAMES Python.h) + endif() + + if (${_PYTHON_PREFIX}_INCLUDE_DIR) + # retrieve version from header file + file (STRINGS "${${_PYTHON_PREFIX}_INCLUDE_DIR}/patchlevel.h" _${_PYTHON_PREFIX}_VERSION + REGEX "^#define[ \t]+PY_VERSION[ \t]+\"[^\"]+\"") + string (REGEX REPLACE "^#define[ \t]+PY_VERSION[ \t]+\"([^\"]+)\".*" "\\1" + _${_PYTHON_PREFIX}_VERSION "${_${_PYTHON_PREFIX}_VERSION}") + string (REGEX MATCHALL "[0-9]+" _${_PYTHON_PREFIX}_VERSIONS "${_${_PYTHON_PREFIX}_VERSION}") + list (GET _${_PYTHON_PREFIX}_VERSIONS 0 _${_PYTHON_PREFIX}_VERSION_MAJOR) + list (GET _${_PYTHON_PREFIX}_VERSIONS 1 _${_PYTHON_PREFIX}_VERSION_MINOR) + list (GET _${_PYTHON_PREFIX}_VERSIONS 2 _${_PYTHON_PREFIX}_VERSION_PATCH) + + if (NOT ${_PYTHON_PREFIX}_Interpreter_FOUND AND NOT ${_PYTHON_PREFIX}_Compiler_FOUND) + # set public version information + 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() + endif() + + # define public variables + include (${CMAKE_CURRENT_LIST_DIR}/../SelectLibraryConfigurations.cmake) + select_library_configurations (${_PYTHON_PREFIX}) + if (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE) + set (${_PYTHON_PREFIX}_RUNTIME_LIBRARY "${${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE}") + elseif (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG) + set (${_PYTHON_PREFIX}_RUNTIME_LIBRARY "${${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG}") + else() + set (${_PYTHON_PREFIX}_RUNTIME_LIBRARY "$${_PYTHON_PREFIX}_RUNTIME_LIBRARY-NOTFOUND") + endif() + + _python_set_library_dirs (${_PYTHON_PREFIX}_LIBRARY_DIRS + ${_PYTHON_PREFIX}_LIBRARY_RELEASE ${_PYTHON_PREFIX}_LIBRARY_DEBUG) + if (UNIX) + if (${_PYTHON_PREFIX}_LIBRARY_RELEASE MATCHES "${CMAKE_SHARED_LIBRARY_SUFFIX}$" + OR ${_PYTHON_PREFIX}_LIBRARY_RELEASE MATCHES "${CMAKE_SHARED_LIBRARY_SUFFIX}$") + set (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DIRS ${${_PYTHON_PREFIX}_LIBRARY_DIRS}) + endif() + else() + _python_set_library_dirs (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DIRS + ${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE ${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG) + endif() + + set (${_PYTHON_PREFIX}_INCLUDE_DIRS "${${_PYTHON_PREFIX}_INCLUDE_DIR}") + + mark_as_advanced (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE + ${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG + ${_PYTHON_PREFIX}_INCLUDE_DIR) + + if ((${_PYTHON_PREFIX}_LIBRARY_RELEASE OR ${_PYTHON_PREFIX}_LIBRARY_DEBUG) + AND ${_PYTHON_PREFIX}_INCLUDE_DIR) + if (${_PYTHON_PREFIX}_Interpreter_FOUND OR ${_PYTHON_PREFIX}_Compiler_FOUND) + # devlopment 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}) + set (${_PYTHON_PREFIX}_Development_FOUND TRUE) + endif() + elseif (${_PYTHON_PREFIX}_VERSION_MAJOR VERSION_EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR) + set (${_PYTHON_PREFIX}_Development_FOUND TRUE) + endif() + endif() + + # Restore the original find library ordering + if (DEFINED _${_PYTHON_PREFIX}_CMAKE_FIND_LIBRARY_SUFFIXES) + set (CMAKE_FIND_LIBRARY_SUFFIXES ${_${_PYTHON_PREFIX}_CMAKE_FIND_LIBRARY_SUFFIXES}) + endif() +endif() + +# final validation +if (${_PYTHON_PREFIX}_VERSION_MAJOR AND + NOT ${_PYTHON_PREFIX}_VERSION_MAJOR VERSION_EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR) + _python_display_failure ("Could NOT find ${_PYTHON_PREFIX}: Found unsuitable major version \"${${_PYTHON_PREFIX}_VERSION_MAJOR}\", but required major version is exact version \"${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR}\"") +endif() + +include (${CMAKE_CURRENT_LIST_DIR}/../FindPackageHandleStandardArgs.cmake) +find_package_handle_standard_args (${_PYTHON_PREFIX} + REQUIRED_VARS ${_${_PYTHON_PREFIX}_REQUIRED_VARS} + VERSION_VAR ${_PYTHON_PREFIX}_VERSION + HANDLE_COMPONENTS) + +# Create imported targets and helper functions +if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS + AND ${_PYTHON_PREFIX}_Interpreter_FOUND + AND NOT TARGET ${_PYTHON_PREFIX}::Interpreter) + add_executable (${_PYTHON_PREFIX}::Interpreter IMPORTED) + set_property (TARGET ${_PYTHON_PREFIX}::Interpreter + PROPERTY IMPORTED_LOCATION "${${_PYTHON_PREFIX}_EXECUTABLE}") +endif() + +if ("Compiler" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS + AND ${_PYTHON_PREFIX}_Compiler_FOUND + AND NOT TARGET ${_PYTHON_PREFIX}::Compiler) + add_executable (${_PYTHON_PREFIX}::Compiler IMPORTED) + set_property (TARGET ${_PYTHON_PREFIX}::Compiler + PROPERTY IMPORTED_LOCATION "${${_PYTHON_PREFIX}_COMPILER}") +endif() + +if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS + AND ${_PYTHON_PREFIX}_Development_FOUND AND NOT TARGET ${_PYTHON_PREFIX}::Python) + + if (${_PYTHON_PREFIX}_LIBRARY_RELEASE MATCHES "${CMAKE_SHARED_LIBRARY_SUFFIX}$" + OR ${_PYTHON_PREFIX}_LIBRARY_DEBUG MATCHES "${CMAKE_SHARED_LIBRARY_SUFFIX}$" + OR ${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE OR ${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG) + set (_${_PYTHON_PREFIX}_LIBRARY_TYPE SHARED) + else() + set (_${_PYTHON_PREFIX}_LIBRARY_TYPE STATIC) + endif() + + add_library (${_PYTHON_PREFIX}::Python ${_${_PYTHON_PREFIX}_LIBRARY_TYPE} IMPORTED) + + set_property (TARGET ${_PYTHON_PREFIX}::Python + PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${${_PYTHON_PREFIX}_INCLUDE_DIR}") + + if ((${_PYTHON_PREFIX}_LIBRARY_RELEASE AND ${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE) + OR (${_PYTHON_PREFIX}_LIBRARY_DEBUG AND ${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG)) + # System manage shared libraries in two parts: import and runtime + if (${_PYTHON_PREFIX}_LIBRARY_RELEASE AND ${_PYTHON_PREFIX}_LIBRARY_DEBUG) + set_property (TARGET ${_PYTHON_PREFIX}::Python PROPERTY IMPORTED_CONFIGURATIONS RELEASE DEBUG) + set_target_properties (${_PYTHON_PREFIX}::Python + PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES_RELEASE "C" + IMPORTED_IMPLIB_RELEASE "${${_PYTHON_PREFIX}_LIBRARY_RELEASE}" + IMPORTED_LOCATION_RELEASE "${${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE}") + set_target_properties (${_PYTHON_PREFIX}::Python + PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES_DEBUG "C" + IMPORTED_IMPLIB_DEBUG "${${_PYTHON_PREFIX}_LIBRARY_DEBUG}" + IMPORTED_LOCATION_DEBUG "${${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG}") + else() + set_target_properties (${_PYTHON_PREFIX}::Python + PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES "C" + IMPORTED_IMPLIB "${${_PYTHON_PREFIX}_LIBRARY}" + IMPORTED_LOCATION "${${_PYTHON_PREFIX}_RUNTIME_LIBRARY}") + endif() + else() + if (${_PYTHON_PREFIX}_LIBRARY_RELEASE AND ${_PYTHON_PREFIX}_LIBRARY_DEBUG) + set_property (TARGET ${_PYTHON_PREFIX}::Python PROPERTY IMPORTED_CONFIGURATIONS RELEASE DEBUG) + set_target_properties (${_PYTHON_PREFIX}::Python + PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES_RELEASE "C" + IMPORTED_LOCATION_RELEASE "${${_PYTHON_PREFIX}_LIBRARY_RELEASE}") + set_target_properties (${_PYTHON_PREFIX}::Python + PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES_DEBUG "C" + IMPORTED_LOCATION_DEBUG "${${_PYTHON_PREFIX}_LIBRARY_DEBUG}") + else() + set_target_properties (${_PYTHON_PREFIX}::Python + PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES "C" + IMPORTED_LOCATION "${${_PYTHON_PREFIX}_LIBRARY}") + endif() + endif() + + if (_${_PYTHON_PREFIX}_CONFIG AND _${_PYTHON_PREFIX}_LIBRARY_TYPE STREQUAL "STATIC") + # extend link information with dependent libraries + execute_process (COMMAND "${_${_PYTHON_PREFIX}_CONFIG}" --ldflags + RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT + OUTPUT_VARIABLE _${_PYTHON_PREFIX}_FLAGS + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE) + if (NOT _${_PYTHON_PREFIX}_RESULT) + string (REGEX MATCHALL "-[Ll][^ ]+" _${_PYTHON_PREFIX}_LINK_LIBRARIES "${_${_PYTHON_PREFIX}_FLAGS}") + # remove elements relative to python library itself + list (FILTER _${_PYTHON_PREFIX}_LINK_LIBRARIES EXCLUDE REGEX "-lpython") + foreach (_${_PYTHON_PREFIX}_DIR IN LISTS ${_PYTHON_PREFIX}_LIBRARY_DIRS) + list (FILTER _${_PYTHON_PREFIX}_LINK_LIBRARIES EXCLUDE REGEX "-L${${_PYTHON_PREFIX}_DIR}") + endforeach() + set_property (TARGET ${_PYTHON_PREFIX}::Python + PROPERTY INTERFACE_LINK_LIBRARIES ${_${_PYTHON_PREFIX}_LINK_LIBRARIES}) + endif() + endif() + + # + # PYTHON_ADD_LIBRARY (<name> [STATIC|SHARED|MODULE] src1 src2 ... srcN) + # 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" "" "") + + unset (type) + if (NOT (PYTHON_ADD_LIBRARY_STATIC + OR PYTHON_ADD_LIBRARY_SHARED + OR PYTHON_ADD_LIBRARY_MODULE)) + set (type MODULE) + endif() + add_library (${name} ${type} ${ARGN}) + target_link_libraries (${name} PRIVATE ${prefix}::Python) + + # customize library name to follow module name rules + get_property (type TARGET ${name} PROPERTY TYPE) + if (type STREQUAL "MODULE_LIBRARY") + set_property (TARGET ${name} PROPERTY PREFIX "") + if(CMAKE_SYSTEM_NAME STREQUAL "Windows") + set_property (TARGET ${name} PROPERTY SUFFIX ".pyd") + endif() + endif() + endfunction() +endif() + +# final clean-up + +# Restore CMAKE_FIND_FRAMEWORK +if (DEFINED _${_PYTHON_PREFIX}_CMAKE_FIND_FRAMEWORK) + set (CMAKE_FIND_FRAMEWORK ${_${_PYTHON_PREFIX}_CMAKE_FIND_FRAMEWORK}) + unset (_${_PYTHON_PREFIX}_CMAKE_FIND_FRAMEWORK) +else() + unset (CMAKE_FIND_FRAMEWORK) +endif() + +unset (_${_PYTHON_PREFIX}_CONFIG CACHE) diff --git a/Modules/FindPython2.cmake b/Modules/FindPython2.cmake new file mode 100644 index 0000000..22e9a8f --- /dev/null +++ b/Modules/FindPython2.cmake @@ -0,0 +1,146 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + +#[=======================================================================[.rst: +FindPython2 +----------- + +Find Python 2 interpreter, compiler and development environment (include +directories and libraries). + +Three components are supported: + +* ``Interpreter``: search for Python 2 interpreter +* ``Compiler``: search for Python 2 compiler. Only offered by IronPython. +* ``Development``: search for development artifacts (include directories and + libraries) + +If no ``COMPONENTS`` is specified, ``Interpreter`` is assumed. + +To ensure consistent versions between components ``Interpreter``, ``Compiler`` +and ``Development``, specify all components at the same time:: + + find_package (Python2 COMPONENTS Interpreter Development) + +This module looks only for version 2 of Python. This module can be used +concurrently with :module:`FindPython3` module to use both Python versions. + +The :module:`FindPython` module can be used if Python version does not matter +for you. + +Imported Targets +^^^^^^^^^^^^^^^^ + +This module defines the following :ref:`Imported Targets <Imported Targets>`: + +``Python2::Interpreter`` + Python 2 interpreter. Target defined if component ``Interpreter`` is found. +``Python2::Compiler`` + Python 2 compiler. Target defined if component ``Compiler`` is found. +``Python2::Python`` + Python 2 library. Target defined if component ``Development`` is found. + +Result Variables +^^^^^^^^^^^^^^^^ + +This module will set the following variables in your project +(see :ref:`Standard Variable Names <CMake Developer Standard Variable Names>`): + +``Python2_FOUND`` + System has the Python 2 requested components. +``Python2_Interpreter_FOUND`` + System has the Python 2 interpreter. +``Python2_EXECUTABLE`` + Path to the Python 2 interpreter. +``Python2_INTERPRETER_ID`` + A short string unique to the interpreter. Possible values include: + * Python + * ActivePython + * Anaconda + * Canopy + * IronPython +``Python2_STDLIB`` + Standard platform independent installation directory. + + Information returned by + ``distutils.sysconfig.get_python_lib(plat_specific=False,standard_lib=True)``. +``Python2_STDARCH`` + Standard platform dependent installation directory. + + Information returned by + ``distutils.sysconfig.get_python_lib(plat_specific=True,standard_lib=True)``. +``Python2_SITELIB`` + Third-party platform independent installation directory. + + Information returned by + ``distutils.sysconfig.get_python_lib(plat_specific=False,standard_lib=False)``. +``Python2_SITEARCH`` + Third-party platform dependent installation directory. + + Information returned by + ``distutils.sysconfig.get_python_lib(plat_specific=True,standard_lib=False)``. +``Python2_Compiler_FOUND`` + System has the Python 2 compiler. +``Python2_COMPILER`` + Path to the Python 2 compiler. Only offered by IronPython. +``Python2_COMPILER_ID`` + A short string unique to the compiler. Possible values include: + * IronPython +``Python2_Development_FOUND`` + System has the Python 2 development artifacts. +``Python2_INCLUDE_DIRS`` + The Python 2 include directories. +``Python2_LIBRARIES`` + The Python 2 libraries. +``Python2_LIBRARY_DIRS`` + The Python 2 library directories. +``Python2_RUNTIME_LIBRARY_DIRS`` + The Python 2 runtime library directories. +``Python2_VERSION`` + Python 2 version. +``Python2_VERSION_MAJOR`` + Python 2 major version. +``Python2_VERSION_MINOR`` + Python 2 minor version. +``Python2_VERSION_PATCH`` + Python 2 patch version. + +Hints +^^^^^ + +``Python2_ROOT_DIR`` + Define the root directory of a Python 2 installation. + +``Python2_USE_STATIC_LIBS`` + * If not defined, search for shared libraries and static libraries in that + order. + * If set to TRUE, search **only** for static libraries. + * If set to FALSE, search **only** for shared libraries. + +Commands +^^^^^^^^ + +This module defines the command ``Python2_add_library`` which have the same +semantic as :command:`add_library` but take care of Python module naming rules +(only applied if library is of type ``MODULE``) and add dependency to target +``Python2::Python``:: + + Python2_add_library (my_module MODULE src1.cpp) + +If library type is not specified, ``MODULE`` is assumed. +#]=======================================================================] + + +set (_PYTHON_PREFIX Python2) + +set (_Python2_REQUIRED_VERSION_MAJOR 2) + +include (${CMAKE_CURRENT_LIST_DIR}/FindPython/Support.cmake) + +if (COMMAND __Python2_add_library) + macro (Python2_add_library) + __Python2_add_library (Python2 ${ARGV}) + endmacro() +endif() + +unset (_PYTHON_PREFIX) diff --git a/Modules/FindPython3.cmake b/Modules/FindPython3.cmake new file mode 100644 index 0000000..99c159b --- /dev/null +++ b/Modules/FindPython3.cmake @@ -0,0 +1,146 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + +#[=======================================================================[.rst: +FindPython3 +----------- + +Find Python 3 interpreter, compiler and development environment (include +directories and libraries). + +Three components are supported: + +* ``Interpreter``: search for Python 3 interpreter +* ``Compiler``: search for Python 3 compiler. Only offered by IronPython. +* ``Development``: search for development artifacts (include directories and + libraries) + +If no ``COMPONENTS`` is specified, ``Interpreter`` is assumed. + +To ensure consistent versions between components ``Interpreter``, ``Compiler`` +and ``Development``, specify all components at the same time:: + + find_package (Python3 COMPONENTS Interpreter Development) + +This module looks only for version 3 of Python. This module can be used +concurrently with :module:`FindPython2` module to use both Python versions. + +The :module:`FindPython` module can be used if Python version does not matter +for you. + +Imported Targets +^^^^^^^^^^^^^^^^ + +This module defines the following :ref:`Imported Targets <Imported Targets>`: + +``Python3::Interpreter`` + Python 3 interpreter. Target defined if component ``Interpreter`` is found. +``Python3::Compiler`` + Python 3 compiler. Target defined if component ``Compiler`` is found. +``Python3::Python`` + Python 3 library. Target defined if component ``Development`` is found. + +Result Variables +^^^^^^^^^^^^^^^^ + +This module will set the following variables in your project +(see :ref:`Standard Variable Names <CMake Developer Standard Variable Names>`): + +``Python3_FOUND`` + System has the Python 3 requested components. +``Python3_Interpreter_FOUND`` + System has the Python 3 interpreter. +``Python3_EXECUTABLE`` + Path to the Python 3 interpreter. +``Python3_INTERPRETER_ID`` + A short string unique to the interpreter. Possible values include: + * Python + * ActivePython + * Anaconda + * Canopy + * IronPython +``Python3_STDLIB`` + Standard platform independent installation directory. + + Information returned by + ``distutils.sysconfig.get_python_lib(plat_specific=False,standard_lib=True)``. +``Python3_STDARCH`` + Standard platform dependent installation directory. + + Information returned by + ``distutils.sysconfig.get_python_lib(plat_specific=True,standard_lib=True)``. +``Python3_SITELIB`` + Third-party platform independent installation directory. + + Information returned by + ``distutils.sysconfig.get_python_lib(plat_specific=False,standard_lib=False)``. +``Python3_SITEARCH`` + Third-party platform dependent installation directory. + + Information returned by + ``distutils.sysconfig.get_python_lib(plat_specific=True,standard_lib=False)``. +``Python3_Compiler_FOUND`` + System has the Python 3 compiler. +``Python3_COMPILER`` + Path to the Python 3 compiler. Only offered by IronPython. +``Python3_COMPILER_ID`` + A short string unique to the compiler. Possible values include: + * IronPython +``Python3_Development_FOUND`` + System has the Python 3 development artifacts. +``Python3_INCLUDE_DIRS`` + The Python 3 include directories. +``Python3_LIBRARIES`` + The Python 3 libraries. +``Python3_LIBRARY_DIRS`` + The Python 3 library directories. +``Python3_RUNTIME_LIBRARY_DIRS`` + The Python 3 runtime library directories. +``Python3_VERSION`` + Python 3 version. +``Python3_VERSION_MAJOR`` + Python 3 major version. +``Python3_VERSION_MINOR`` + Python 3 minor version. +``Python3_VERSION_PATCH`` + Python 3 patch version. + +Hints +^^^^^ + +``Python3_ROOT_DIR`` + Define the root directory of a Python 3 installation. + +``Python3_USE_STATIC_LIBS`` + * If not defined, search for shared libraries and static libraries in that + order. + * If set to TRUE, search **only** for static libraries. + * If set to FALSE, search **only** for shared libraries. + +Commands +^^^^^^^^ + +This module defines the command ``Python3_add_library`` which have the same +semantic as :command:`add_library` but take care of Python module naming rules +(only applied if library is of type ``MODULE``) and add dependency to target +``Python3::Python``:: + + Python3_add_library (my_module MODULE src1.cpp) + +If library type is not specified, ``MODULE`` is assumed. +#]=======================================================================] + + +set (_PYTHON_PREFIX Python3) + +set (_Python3_REQUIRED_VERSION_MAJOR 3) + +include (${CMAKE_CURRENT_LIST_DIR}/FindPython/Support.cmake) + +if (COMMAND __Python3_add_library) + macro (Python3_add_library) + __Python3_add_library (Python3 ${ARGV}) + endmacro() +endif() + +unset (_PYTHON_PREFIX) diff --git a/Modules/FindPythonInterp.cmake b/Modules/FindPythonInterp.cmake index 3ef8e9f..bd64762 100644 --- a/Modules/FindPythonInterp.cmake +++ b/Modules/FindPythonInterp.cmake @@ -7,6 +7,10 @@ # # Find python interpreter # +# .. deprecated:: 3.12 +# +# Use :module:`FindPython3`, :module:`FindPython2` or :module:`FindPython` instead. +# # This module finds if Python interpreter is installed and determines # where the executables are. This code sets the following variables: # diff --git a/Modules/FindPythonLibs.cmake b/Modules/FindPythonLibs.cmake index 341d5d9..1a0cc2e 100644 --- a/Modules/FindPythonLibs.cmake +++ b/Modules/FindPythonLibs.cmake @@ -7,6 +7,10 @@ # # Find python libraries # +# .. deprecated:: 3.12 +# +# Use :module:`FindPython3`, :module:`FindPython2` or :module:`FindPython` instead. +# # This module finds if Python is installed and determines where the # include files and libraries are. It also determines what the name of # the library is. This code sets the following variables: diff --git a/Modules/FindVulkan.cmake b/Modules/FindVulkan.cmake index 1f4c8ad..4c60ed7 100644 --- a/Modules/FindVulkan.cmake +++ b/Modules/FindVulkan.cmake @@ -65,7 +65,7 @@ endif() set(Vulkan_LIBRARIES ${Vulkan_LIBRARY}) set(Vulkan_INCLUDE_DIRS ${Vulkan_INCLUDE_DIR}) -include(FindPackageHandleStandardArgs) +include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) find_package_handle_standard_args(Vulkan DEFAULT_MSG Vulkan_LIBRARY Vulkan_INCLUDE_DIR) diff --git a/Modules/FindZLIB.cmake b/Modules/FindZLIB.cmake index 4065999..a5c04ac 100644 --- a/Modules/FindZLIB.cmake +++ b/Modules/FindZLIB.cmake @@ -75,8 +75,8 @@ endforeach() # Allow ZLIB_LIBRARY to be set manually, as the location of the zlib library if(NOT ZLIB_LIBRARY) foreach(search ${_ZLIB_SEARCHES}) - find_library(ZLIB_LIBRARY_RELEASE NAMES ${ZLIB_NAMES} ${${search}} PATH_SUFFIXES lib) - find_library(ZLIB_LIBRARY_DEBUG NAMES ${ZLIB_NAMES_DEBUG} ${${search}} PATH_SUFFIXES lib) + 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() include(${CMAKE_CURRENT_LIST_DIR}/SelectLibraryConfigurations.cmake) diff --git a/Modules/FindwxWidgets.cmake b/Modules/FindwxWidgets.cmake index e21ec38..f2d6285 100644 --- a/Modules/FindwxWidgets.cmake +++ b/Modules/FindwxWidgets.cmake @@ -498,19 +498,7 @@ if(wxWidgets_FIND_STYLE STREQUAL "win32") set(_WX_TOOL gcc) elseif(MSVC) set(_WX_TOOL vc) - if(MSVC_VERSION EQUAL 1910) - set(_WX_TOOLVER 141) - elseif(MSVC_VERSION EQUAL 1900) - set(_WX_TOOLVER 140) - elseif(MSVC_VERSION EQUAL 1800) - set(_WX_TOOLVER 120) - elseif(MSVC_VERSION EQUAL 1700) - set(_WX_TOOLVER 110) - elseif(MSVC_VERSION EQUAL 1600) - set(_WX_TOOLVER 100) - elseif(MSVC_VERSION EQUAL 1500) - set(_WX_TOOLVER 90) - endif() + set(_WX_TOOLVER ${MSVC_TOOLSET_VERSION}) if(CMAKE_SIZEOF_VOID_P EQUAL 8) set(_WX_ARCH _x64) endif() @@ -837,7 +825,7 @@ else() # extract linkdirs (-L) for rpath (i.e., LINK_DIRECTORIES) string(REGEX MATCHALL "-L[^;]+" wxWidgets_LIBRARY_DIRS "${wxWidgets_LIBRARIES}") - string(REPLACE "-L" "" + string(REGEX REPLACE "-L([^;]+)" "\\1" wxWidgets_LIBRARY_DIRS "${wxWidgets_LIBRARY_DIRS}") DBG_MSG_V("wxWidgets_LIBRARIES=${wxWidgets_LIBRARIES}") @@ -875,6 +863,26 @@ else() set(wxWidgets_INCLUDE_DIRS ${_tmp_path}) separate_arguments(wxWidgets_INCLUDE_DIRS) list(REMOVE_ITEM wxWidgets_INCLUDE_DIRS "") + + set(_tmp_path "") + foreach(_path ${wxWidgets_LIBRARY_DIRS}) + execute_process( + COMMAND cygpath -w ${_path} + OUTPUT_VARIABLE _native_path + RESULT_VARIABLE _retv + OUTPUT_STRIP_TRAILING_WHITESPACE + ERROR_QUIET + ) + if(_retv EQUAL 0) + file(TO_CMAKE_PATH ${_native_path} _native_path) + DBG_MSG_V("Path ${_path} converted to ${_native_path}") + string(APPEND _tmp_path " ${_native_path}") + endif() + endforeach() + DBG_MSG("Setting wxWidgets_LIBRARY_DIRS = ${_tmp_path}") + set(wxWidgets_LIBRARY_DIRS ${_tmp_path}) + separate_arguments(wxWidgets_LIBRARY_DIRS) + list(REMOVE_ITEM wxWidgets_LIBRARY_DIRS "") endif() unset(_cygpath_exe CACHE) endif() @@ -917,14 +925,16 @@ unset(_wx_lib_missing) # Check if a specific version was requested by find_package(). if(wxWidgets_FOUND) - find_file(_filename wx/version.h PATHS ${wxWidgets_INCLUDE_DIRS} NO_DEFAULT_PATH) - dbg_msg("_filename: ${_filename}") + 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 _filename) + if(NOT _wx_filename) message(FATAL_ERROR "wxWidgets wx/version.h file not found in ${wxWidgets_INCLUDE_DIRS}.") endif() - file(READ ${_filename} _wx_version_h) + 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}" ) diff --git a/Modules/GenerateExportHeader.cmake b/Modules/GenerateExportHeader.cmake index 17a3357..e6dcd00 100644 --- a/Modules/GenerateExportHeader.cmake +++ b/Modules/GenerateExportHeader.cmake @@ -185,6 +185,7 @@ # :prop_tgt:`CXX_VISIBILITY_PRESET <<LANG>_VISIBILITY_PRESET>` and # :prop_tgt:`VISIBILITY_INLINES_HIDDEN` instead. +include(CheckCCompilerFlag) include(CheckCXXCompilerFlag) # TODO: Install this macro separately? @@ -194,6 +195,13 @@ macro(_check_cxx_compiler_attribute _ATTRIBUTE _RESULT) ) endmacro() +# TODO: Install this macro separately? +macro(_check_c_compiler_attribute _ATTRIBUTE _RESULT) + check_c_source_compiles("${_ATTRIBUTE} int somefunc() { return 0; } + int main() { return somefunc();}" ${_RESULT} + ) +endmacro() + macro(_test_compiler_hidden_visibility) if(CMAKE_COMPILER_IS_GNUCXX AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS "4.2") @@ -213,9 +221,15 @@ macro(_test_compiler_hidden_visibility) AND NOT CMAKE_CXX_COMPILER_ID MATCHES XL AND NOT CMAKE_CXX_COMPILER_ID MATCHES PGI AND NOT CMAKE_CXX_COMPILER_ID MATCHES Watcom) - check_cxx_compiler_flag(-fvisibility=hidden COMPILER_HAS_HIDDEN_VISIBILITY) - check_cxx_compiler_flag(-fvisibility-inlines-hidden - COMPILER_HAS_HIDDEN_INLINE_VISIBILITY) + if (CMAKE_CXX_COMPILER_LOADED) + check_cxx_compiler_flag(-fvisibility=hidden COMPILER_HAS_HIDDEN_VISIBILITY) + check_cxx_compiler_flag(-fvisibility-inlines-hidden + COMPILER_HAS_HIDDEN_INLINE_VISIBILITY) + else() + check_c_compiler_flag(-fvisibility=hidden COMPILER_HAS_HIDDEN_VISIBILITY) + check_c_compiler_flag(-fvisibility-inlines-hidden + COMPILER_HAS_HIDDEN_INLINE_VISIBILITY) + endif() endif() endmacro() @@ -232,14 +246,27 @@ macro(_test_compiler_has_deprecated) set(COMPILER_HAS_DEPRECATED "" CACHE INTERNAL "Compiler support for a deprecated attribute") else() - _check_cxx_compiler_attribute("__attribute__((__deprecated__))" - COMPILER_HAS_DEPRECATED_ATTR) - if(COMPILER_HAS_DEPRECATED_ATTR) - set(COMPILER_HAS_DEPRECATED "${COMPILER_HAS_DEPRECATED_ATTR}" - CACHE INTERNAL "Compiler support for a deprecated attribute") + if (CMAKE_CXX_COMPILER_LOADED) + _check_cxx_compiler_attribute("__attribute__((__deprecated__))" + COMPILER_HAS_DEPRECATED_ATTR) + if(COMPILER_HAS_DEPRECATED_ATTR) + set(COMPILER_HAS_DEPRECATED "${COMPILER_HAS_DEPRECATED_ATTR}" + CACHE INTERNAL "Compiler support for a deprecated attribute") + else() + _check_cxx_compiler_attribute("__declspec(deprecated)" + COMPILER_HAS_DEPRECATED) + endif() else() - _check_cxx_compiler_attribute("__declspec(deprecated)" - COMPILER_HAS_DEPRECATED) + _check_c_compiler_attribute("__attribute__((__deprecated__))" + COMPILER_HAS_DEPRECATED_ATTR) + if(COMPILER_HAS_DEPRECATED_ATTR) + set(COMPILER_HAS_DEPRECATED "${COMPILER_HAS_DEPRECATED_ATTR}" + CACHE INTERNAL "Compiler support for a deprecated attribute") + else() + _check_c_compiler_attribute("__declspec(deprecated)" + COMPILER_HAS_DEPRECATED) + endif() + endif() endif() endmacro() diff --git a/Modules/InstallRequiredSystemLibraries.cmake b/Modules/InstallRequiredSystemLibraries.cmake index 5a1843b..36dd0a0 100644 --- a/Modules/InstallRequiredSystemLibraries.cmake +++ b/Modules/InstallRequiredSystemLibraries.cmake @@ -121,9 +121,7 @@ if(MSVC) ) endif() - if(MSVC_VERSION EQUAL 1400) - set(MSVC_REDIST_NAME VC80) - + if(MSVC_TOOLSET_VERSION EQUAL 80) # Find the runtime library redistribution directory. get_filename_component(msvc_install_dir "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\8.0;InstallDir]" ABSOLUTE) @@ -163,9 +161,7 @@ if(MSVC) endif() endif() - if(MSVC_VERSION EQUAL 1500) - set(MSVC_REDIST_NAME VC90) - + if(MSVC_TOOLSET_VERSION EQUAL 90) # Find the runtime library redistribution directory. get_filename_component(msvc_install_dir "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\9.0;InstallDir]" ABSOLUTE) @@ -209,34 +205,31 @@ if(MSVC) endif() set(MSVC_REDIST_NAME "") - set(_MSVCRT_DLL_VERSION "") - set(_MSVCRT_IDE_VERSION "") + set(_MSVC_DLL_VERSION "") + set(_MSVC_IDE_VERSION "") if(MSVC_VERSION GREATER_EQUAL 2000) message(WARNING "MSVC ${MSVC_VERSION} not yet supported.") - elseif(MSVC_VERSION GREATER_EQUAL 1911) - set(MSVC_REDIST_NAME VC141) - set(_MSVCRT_DLL_VERSION 140) - set(_MSVCRT_IDE_VERSION 15) - elseif(MSVC_VERSION EQUAL 1910) - set(MSVC_REDIST_NAME VC150) - set(_MSVCRT_DLL_VERSION 140) - set(_MSVCRT_IDE_VERSION 15) - elseif(MSVC_VERSION EQUAL 1900) - set(MSVC_REDIST_NAME VC140) - set(_MSVCRT_DLL_VERSION 140) - set(_MSVCRT_IDE_VERSION 14) - elseif(MSVC_VERSION EQUAL 1800) - set(MSVC_REDIST_NAME VC120) - set(_MSVCRT_DLL_VERSION 120) - set(_MSVCRT_IDE_VERSION 12) - elseif(MSVC_VERSION EQUAL 1700) - set(MSVC_REDIST_NAME VC110) - set(_MSVCRT_DLL_VERSION 110) - set(_MSVCRT_IDE_VERSION 11) - elseif(MSVC_VERSION EQUAL 1600) - set(MSVC_REDIST_NAME VC100) - set(_MSVCRT_DLL_VERSION 100) - set(_MSVCRT_IDE_VERSION 10) + elseif(MSVC_TOOLSET_VERSION) + set(MSVC_REDIST_NAME VC${MSVC_TOOLSET_VERSION}) + if(MSVC_VERSION EQUAL 1910) + # VS2017 named this differently prior to update 3. + set(MSVC_REDIST_NAME VC150) + endif() + + math(EXPR _MSVC_DLL_VERSION "${MSVC_TOOLSET_VERSION} / 10 * 10") + + if(MSVC_TOOLSET_VERSION EQUAL 141) + set(_MSVC_IDE_VERSION 15) + else() + math(EXPR _MSVC_IDE_VERSION "${MSVC_TOOLSET_VERSION} / 10") + endif() + endif() + + set(_MSVCRT_DLL_VERSION "") + set(_MSVCRT_IDE_VERSION "") + if(_MSVC_IDE_VERSION GREATER_EQUAL 10) + set(_MSVCRT_DLL_VERSION "${_MSVC_DLL_VERSION}") + set(_MSVCRT_IDE_VERSION "${_MSVC_IDE_VERSION}") endif() if(_MSVCRT_DLL_VERSION) @@ -433,23 +426,9 @@ if(MSVC) set(_MFC_DLL_VERSION "") set(_MFC_IDE_VERSION "") - if(MSVC_VERSION GREATER_EQUAL 2000) - # Version not yet supported. - elseif(MSVC_VERSION GREATER_EQUAL 1910) - set(_MFC_DLL_VERSION 140) - set(_MFC_IDE_VERSION 15) - elseif(MSVC_VERSION EQUAL 1900) - set(_MFC_DLL_VERSION 140) - set(_MFC_IDE_VERSION 14) - elseif(MSVC_VERSION EQUAL 1800) - set(_MFC_DLL_VERSION 120) - set(_MFC_IDE_VERSION 12) - elseif(MSVC_VERSION EQUAL 1700) - set(_MFC_DLL_VERSION 110) - set(_MFC_IDE_VERSION 11) - elseif(MSVC_VERSION EQUAL 1600) - set(_MFC_DLL_VERSION 100) - set(_MFC_IDE_VERSION 10) + if(_MSVC_IDE_VERSION GREATER_EQUAL 10) + set(_MFC_DLL_VERSION ${_MSVC_DLL_VERSION}) + set(_MFC_IDE_VERSION ${_MSVC_IDE_VERSION}) endif() if(_MFC_DLL_VERSION) @@ -481,6 +460,10 @@ if(MSVC) if("${v}" LESS 12 OR EXISTS "${MSVC_MFC_DIR}/mfc${v}d.dll") set(__install__libs ${__install__libs} "${MSVC_MFC_DIR}/mfc${v}d.dll" + ) + endif() + if("${v}" LESS 12 OR EXISTS "${MSVC_MFC_DIR}/mfcm${v}d.dll") + set(__install__libs ${__install__libs} "${MSVC_MFC_DIR}/mfcm${v}d.dll" ) endif() @@ -495,6 +478,10 @@ if(MSVC) if("${v}" LESS 12 OR EXISTS "${MSVC_MFC_DIR}/mfc${v}.dll") set(__install__libs ${__install__libs} "${MSVC_MFC_DIR}/mfc${v}.dll" + ) + endif() + if("${v}" LESS 12 OR EXISTS "${MSVC_MFC_DIR}/mfcm${v}.dll") + set(__install__libs ${__install__libs} "${MSVC_MFC_DIR}/mfcm${v}.dll" ) endif() @@ -520,32 +507,8 @@ if(MSVC) # MSVC 8 was the first version with OpenMP # Furthermore, there is no debug version of this if(CMAKE_INSTALL_OPENMP_LIBRARIES AND _IRSL_HAVE_MSVC) - set(_MSOMP_DLL_VERSION "") - set(_MSOMP_IDE_VERSION "") - if(MSVC_VERSION GREATER_EQUAL 2000) - # Version not yet supported. - elseif(MSVC_VERSION GREATER_EQUAL 1910) - set(_MSOMP_DLL_VERSION 140) - set(_MSOMP_IDE_VERSION 15) - elseif(MSVC_VERSION EQUAL 1900) - set(_MSOMP_DLL_VERSION 140) - set(_MSOMP_IDE_VERSION 14) - elseif(MSVC_VERSION EQUAL 1800) - set(_MSOMP_DLL_VERSION 120) - set(_MSOMP_IDE_VERSION 12) - elseif(MSVC_VERSION EQUAL 1700) - set(_MSOMP_DLL_VERSION 110) - set(_MSOMP_IDE_VERSION 11) - elseif(MSVC_VERSION EQUAL 1600) - set(_MSOMP_DLL_VERSION 100) - set(_MSOMP_IDE_VERSION 10) - elseif(MSVC_VERSION EQUAL 1500) - set(_MSOMP_DLL_VERSION 90) - set(_MSOMP_IDE_VERSION 9) - elseif(MSVC_VERSION EQUAL 1400) - set(_MSOMP_DLL_VERSION 80) - set(_MSOMP_IDE_VERSION 8) - endif() + set(_MSOMP_DLL_VERSION ${_MSVC_DLL_VERSION}) + set(_MSOMP_IDE_VERSION ${_MSVC_IDE_VERSION}) if(_MSOMP_DLL_VERSION) set(v "${_MSOMP_DLL_VERSION}") diff --git a/Modules/MatlabTestsRedirect.cmake b/Modules/MatlabTestsRedirect.cmake index 64d580d..fc36fc3 100644 --- a/Modules/MatlabTestsRedirect.cmake +++ b/Modules/MatlabTestsRedirect.cmake @@ -55,11 +55,12 @@ endif() if(no_unittest_framework) - set(unittest_to_run "try, ${unittest_file_to_run_name}, catch err, disp('An exception has been thrown during the execution'), disp(err), disp(err.stack), exit(1), end, exit(0)") + set(unittest_to_run "${unittest_file_to_run_name}") endif() +set(command_to_run "try, ${unittest_to_run}, catch err, disp('An exception has been thrown during the execution'), disp(err), disp(err.stack), exit(1), end, exit(0)") set(Matlab_SCRIPT_TO_RUN - "addpath(${concat_string}); ${cmd_to_run_before_test}; ${unittest_to_run}" + "addpath(${concat_string}); ${cmd_to_run_before_test}; ${command_to_run}" ) # if the working directory is not specified then default # to the output_directory because the log file will go there diff --git a/Modules/Platform/Android-Clang-CXX.cmake b/Modules/Platform/Android-Clang-CXX.cmake index 7111836..85d5088 100644 --- a/Modules/Platform/Android-Clang-CXX.cmake +++ b/Modules/Platform/Android-Clang-CXX.cmake @@ -1,2 +1,9 @@ include(Platform/Android-Clang) __android_compiler_clang(CXX) +if(_ANDROID_STL_NOSTDLIBXX) + if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 6) + string(APPEND CMAKE_CXX_STANDARD_LIBRARIES " -nostdlib++") + else() + string(APPEND CMAKE_CXX_STANDARD_LIBRARIES " -nodefaultlibs -lgcc -lc -lm -ldl") + endif() +endif() diff --git a/Modules/Platform/Android-Determine.cmake b/Modules/Platform/Android-Determine.cmake index add1dc1..e623902 100644 --- a/Modules/Platform/Android-Determine.cmake +++ b/Modules/Platform/Android-Determine.cmake @@ -261,7 +261,40 @@ if(NOT CMAKE_ANDROID_ARCH_ABI) else() # https://developer.android.com/ndk/guides/application_mk.html # Default is the oldest ARM ABI. - set(CMAKE_ANDROID_ARCH_ABI "armeabi") + + # Lookup the available ABIs among all toolchains. + set(_ANDROID_ABIS "") + file(GLOB _ANDROID_CONFIG_MKS + "${CMAKE_ANDROID_NDK}/build/core/toolchains/*/config.mk" + "${CMAKE_ANDROID_NDK}/toolchains/*/config.mk" + ) + foreach(config_mk IN LISTS _ANDROID_CONFIG_MKS) + file(STRINGS "${config_mk}" _ANDROID_TOOL_ABIS REGEX "^TOOLCHAIN_ABIS :=") + string(REPLACE "TOOLCHAIN_ABIS :=" "" _ANDROID_TOOL_ABIS "${_ANDROID_TOOL_ABIS}") + separate_arguments(_ANDROID_TOOL_ABIS UNIX_COMMAND "${_ANDROID_TOOL_ABIS}") + list(APPEND _ANDROID_ABIS ${_ANDROID_TOOL_ABIS}) + unset(_ANDROID_TOOL_ABIS) + endforeach() + unset(_ANDROID_CONFIG_MKS) + + # Choose the oldest among the available arm ABIs. + if(_ANDROID_ABIS) + list(REMOVE_DUPLICATES _ANDROID_ABIS) + cmake_policy(PUSH) + cmake_policy(SET CMP0057 NEW) + foreach(abi armeabi armeabi-v7a arm64-v8a) + if("${abi}" IN_LIST _ANDROID_ABIS) + set(CMAKE_ANDROID_ARCH_ABI "${abi}") + break() + endif() + endforeach() + cmake_policy(POP) + endif() + unset(_ANDROID_ABIS) + + if(NOT CMAKE_ANDROID_ARCH_ABI) + set(CMAKE_ANDROID_ARCH_ABI "armeabi") + endif() endif() endif() set(CMAKE_ANDROID_ARCH "${_ANDROID_ABI_${CMAKE_ANDROID_ARCH_ABI}_ARCH}") diff --git a/Modules/Platform/Android-GNU-CXX.cmake b/Modules/Platform/Android-GNU-CXX.cmake index 41279d1..d30d0ff 100644 --- a/Modules/Platform/Android-GNU-CXX.cmake +++ b/Modules/Platform/Android-GNU-CXX.cmake @@ -1,2 +1,5 @@ include(Platform/Android-GNU) __android_compiler_gnu(CXX) +if(_ANDROID_STL_NOSTDLIBXX) + string(APPEND CMAKE_CXX_STANDARD_LIBRARIES " -nodefaultlibs -lgcc -lc -lm -ldl") +endif() diff --git a/Modules/Platform/Android/ndk-stl-c++.cmake b/Modules/Platform/Android/ndk-stl-c++.cmake index a12411c..1cafd1f 100644 --- a/Modules/Platform/Android/ndk-stl-c++.cmake +++ b/Modules/Platform/Android/ndk-stl-c++.cmake @@ -1,6 +1,7 @@ # <ndk>/sources/cxx-stl/llvm-libc++/Android.mk set(_ANDROID_STL_RTTI 1) set(_ANDROID_STL_EXCEPTIONS 1) +set(_ANDROID_STL_NOSTDLIBXX 1) macro(__android_stl_cxx lang filename) # Add the include directory. if(EXISTS "${CMAKE_ANDROID_NDK}/sources/cxx-stl/llvm-libc++/libcxx/include/cstddef") diff --git a/Modules/Platform/Android/ndk-stl-gabi++.cmake b/Modules/Platform/Android/ndk-stl-gabi++.cmake index 850a47a..d3b9e45 100644 --- a/Modules/Platform/Android/ndk-stl-gabi++.cmake +++ b/Modules/Platform/Android/ndk-stl-gabi++.cmake @@ -1,6 +1,7 @@ # <ndk>/sources/cxx-stl/gabi++/Android.mk set(_ANDROID_STL_RTTI 1) set(_ANDROID_STL_EXCEPTIONS 1) +set(_ANDROID_STL_NOSTDLIBXX 1) macro(__android_stl_gabixx lang filename) __android_stl_inc(${lang} "${CMAKE_ANDROID_NDK}/sources/cxx-stl/gabi++/include" 1) __android_stl_lib(${lang} "${CMAKE_ANDROID_NDK}/sources/cxx-stl/gabi++/libs/${CMAKE_ANDROID_ARCH_ABI}/${filename}" 1) diff --git a/Modules/Platform/Android/ndk-stl-gnustl.cmake b/Modules/Platform/Android/ndk-stl-gnustl.cmake index b3226ee..46cedc6 100644 --- a/Modules/Platform/Android/ndk-stl-gnustl.cmake +++ b/Modules/Platform/Android/ndk-stl-gnustl.cmake @@ -1,6 +1,7 @@ # <ndk>/sources/cxx-stl/gnu-libstdc++/Android.mk set(_ANDROID_STL_RTTI 1) set(_ANDROID_STL_EXCEPTIONS 1) +set(_ANDROID_STL_NOSTDLIBXX 1) macro(__android_stl_gnustl lang filename) __android_stl_inc(${lang} "${CMAKE_ANDROID_NDK}/sources/cxx-stl/gnu-libstdc++/${CMAKE_${lang}_ANDROID_TOOLCHAIN_VERSION}/include" 1) __android_stl_inc(${lang} "${CMAKE_ANDROID_NDK}/sources/cxx-stl/gnu-libstdc++/${CMAKE_${lang}_ANDROID_TOOLCHAIN_VERSION}/libs/${CMAKE_ANDROID_ARCH_ABI}/include" 1) diff --git a/Modules/Platform/Android/ndk-stl-none.cmake b/Modules/Platform/Android/ndk-stl-none.cmake index 9049c91..45122f7 100644 --- a/Modules/Platform/Android/ndk-stl-none.cmake +++ b/Modules/Platform/Android/ndk-stl-none.cmake @@ -1,2 +1,3 @@ +set(_ANDROID_STL_NOSTDLIBXX 1) macro(__android_stl lang) endmacro() diff --git a/Modules/Platform/Android/ndk-stl-stlport.cmake b/Modules/Platform/Android/ndk-stl-stlport.cmake index eab6b94..efad33b 100644 --- a/Modules/Platform/Android/ndk-stl-stlport.cmake +++ b/Modules/Platform/Android/ndk-stl-stlport.cmake @@ -1,6 +1,7 @@ # <ndk>/sources/cxx-stl/stlport/Android.mk set(_ANDROID_STL_RTTI 1) set(_ANDROID_STL_EXCEPTIONS 1) +set(_ANDROID_STL_NOSTDLIBXX 0) macro(__android_stl_stlport lang filename) __android_stl_inc(${lang} "${CMAKE_ANDROID_NDK}/sources/cxx-stl/stlport/stlport" 1) __android_stl_lib(${lang} "${CMAKE_ANDROID_NDK}/sources/cxx-stl/stlport/libs/${CMAKE_ANDROID_ARCH_ABI}/${filename}" 1) diff --git a/Modules/Platform/Android/ndk-stl-system.cmake b/Modules/Platform/Android/ndk-stl-system.cmake index dd554fe..7d86a40 100644 --- a/Modules/Platform/Android/ndk-stl-system.cmake +++ b/Modules/Platform/Android/ndk-stl-system.cmake @@ -1,6 +1,7 @@ # <ndk>/android-ndk-r11c/sources/cxx-stl/system/Android.mk set(_ANDROID_STL_RTTI 0) set(_ANDROID_STL_EXCEPTIONS 0) +set(_ANDROID_STL_NOSTDLIBXX 0) macro(__android_stl lang) __android_stl_inc(${lang} "${CMAKE_ANDROID_NDK}/sources/cxx-stl/system/include" 1) endmacro() diff --git a/Modules/Platform/Darwin-Absoft-Fortran.cmake b/Modules/Platform/Apple-Absoft-Fortran.cmake index 8caa202..8caa202 100644 --- a/Modules/Platform/Darwin-Absoft-Fortran.cmake +++ b/Modules/Platform/Apple-Absoft-Fortran.cmake diff --git a/Modules/Platform/Darwin-AppleClang-C.cmake b/Modules/Platform/Apple-AppleClang-C.cmake index 3216b29..f45ccf4 100644 --- a/Modules/Platform/Darwin-AppleClang-C.cmake +++ b/Modules/Platform/Apple-AppleClang-C.cmake @@ -1,4 +1,4 @@ -include(Platform/Darwin-Clang-C) +include(Platform/Apple-Clang-C) if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.2) set(CMAKE_C_SYSTEM_FRAMEWORK_SEARCH_FLAG "-iframework ") else() diff --git a/Modules/Platform/Darwin-AppleClang-CXX.cmake b/Modules/Platform/Apple-AppleClang-CXX.cmake index 3fedf8c..1128204 100644 --- a/Modules/Platform/Darwin-AppleClang-CXX.cmake +++ b/Modules/Platform/Apple-AppleClang-CXX.cmake @@ -1,4 +1,4 @@ -include(Platform/Darwin-Clang-CXX) +include(Platform/Apple-Clang-CXX) if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.2) set(CMAKE_CXX_SYSTEM_FRAMEWORK_SEARCH_FLAG "-iframework ") else() diff --git a/Modules/Platform/Apple-Clang-C.cmake b/Modules/Platform/Apple-Clang-C.cmake new file mode 100644 index 0000000..4d0dc82 --- /dev/null +++ b/Modules/Platform/Apple-Clang-C.cmake @@ -0,0 +1,2 @@ +include(Platform/Apple-Clang) +__apple_compiler_clang(C) diff --git a/Modules/Platform/Apple-Clang-CXX.cmake b/Modules/Platform/Apple-Clang-CXX.cmake new file mode 100644 index 0000000..6c1ddc1 --- /dev/null +++ b/Modules/Platform/Apple-Clang-CXX.cmake @@ -0,0 +1,2 @@ +include(Platform/Apple-Clang) +__apple_compiler_clang(CXX) diff --git a/Modules/Platform/Darwin-Clang.cmake b/Modules/Platform/Apple-Clang.cmake index f8a07ec..0681bfb 100644 --- a/Modules/Platform/Darwin-Clang.cmake +++ b/Modules/Platform/Apple-Clang.cmake @@ -3,12 +3,9 @@ # This module is shared by multiple languages; use include blocker. -if(__DARWIN_COMPILER_CLANG) - return() -endif() -set(__DARWIN_COMPILER_CLANG 1) +include_guard() -macro(__darwin_compiler_clang lang) +macro(__apple_compiler_clang lang) set(CMAKE_${lang}_VERBOSE_FLAG "-v -Wl,-v") # also tell linker to print verbose output set(CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS "-dynamiclib -Wl,-headerpad_max_install_names") set(CMAKE_SHARED_MODULE_CREATE_${lang}_FLAGS "-bundle -Wl,-headerpad_max_install_names") diff --git a/Modules/Platform/Darwin-GNU-C.cmake b/Modules/Platform/Apple-GNU-C.cmake index efdfd00..5481c99 100644 --- a/Modules/Platform/Darwin-GNU-C.cmake +++ b/Modules/Platform/Apple-GNU-C.cmake @@ -1,4 +1,4 @@ -include(Platform/Darwin-GNU) -__darwin_compiler_gnu(C) +include(Platform/Apple-GNU) +__apple_compiler_gnu(C) cmake_gnu_set_sysroot_flag(C) cmake_gnu_set_osx_deployment_target_flag(C) diff --git a/Modules/Platform/Darwin-GNU-CXX.cmake b/Modules/Platform/Apple-GNU-CXX.cmake index e3c2ea7..727f726 100644 --- a/Modules/Platform/Darwin-GNU-CXX.cmake +++ b/Modules/Platform/Apple-GNU-CXX.cmake @@ -1,4 +1,4 @@ -include(Platform/Darwin-GNU) -__darwin_compiler_gnu(CXX) +include(Platform/Apple-GNU) +__apple_compiler_gnu(CXX) cmake_gnu_set_sysroot_flag(CXX) cmake_gnu_set_osx_deployment_target_flag(CXX) diff --git a/Modules/Platform/Darwin-GNU-Fortran.cmake b/Modules/Platform/Apple-GNU-Fortran.cmake index 568d79b..2f53603 100644 --- a/Modules/Platform/Darwin-GNU-Fortran.cmake +++ b/Modules/Platform/Apple-GNU-Fortran.cmake @@ -1,8 +1,8 @@ # Distributed under the OSI-approved BSD 3-Clause License. See accompanying # file Copyright.txt or https://cmake.org/licensing for details. -include(Platform/Darwin-GNU) -__darwin_compiler_gnu(Fortran) +include(Platform/Apple-GNU) +__apple_compiler_gnu(Fortran) cmake_gnu_set_sysroot_flag(Fortran) cmake_gnu_set_osx_deployment_target_flag(Fortran) diff --git a/Modules/Platform/Darwin-GNU.cmake b/Modules/Platform/Apple-GNU.cmake index 9f9ef01..0eb8168 100644 --- a/Modules/Platform/Darwin-GNU.cmake +++ b/Modules/Platform/Apple-GNU.cmake @@ -3,12 +3,9 @@ # This module is shared by multiple languages; use include blocker. -if(__DARWIN_COMPILER_GNU) - return() -endif() -set(__DARWIN_COMPILER_GNU 1) +include_guard() -macro(__darwin_compiler_gnu lang) +macro(__apple_compiler_gnu lang) set(CMAKE_${lang}_VERBOSE_FLAG "-v -Wl,-v") # also tell linker to print verbose output # GNU does not have -shared on OS X set(CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS "-dynamiclib -Wl,-headerpad_max_install_names") diff --git a/Modules/Platform/Apple-Intel-C.cmake b/Modules/Platform/Apple-Intel-C.cmake new file mode 100644 index 0000000..95bb270 --- /dev/null +++ b/Modules/Platform/Apple-Intel-C.cmake @@ -0,0 +1,2 @@ +include(Platform/Apple-Intel) +__apple_compiler_intel(C) diff --git a/Modules/Platform/Apple-Intel-CXX.cmake b/Modules/Platform/Apple-Intel-CXX.cmake new file mode 100644 index 0000000..b87e512 --- /dev/null +++ b/Modules/Platform/Apple-Intel-CXX.cmake @@ -0,0 +1,2 @@ +include(Platform/Apple-Intel) +__apple_compiler_intel(CXX) diff --git a/Modules/Platform/Darwin-Intel-Fortran.cmake b/Modules/Platform/Apple-Intel-Fortran.cmake index 2299da9..e54e237 100644 --- a/Modules/Platform/Darwin-Intel-Fortran.cmake +++ b/Modules/Platform/Apple-Intel-Fortran.cmake @@ -1,8 +1,8 @@ # Distributed under the OSI-approved BSD 3-Clause License. See accompanying # file Copyright.txt or https://cmake.org/licensing for details. -include(Platform/Darwin-Intel) -__darwin_compiler_intel(Fortran) +include(Platform/Apple-Intel) +__apple_compiler_intel(Fortran) set(CMAKE_Fortran_OSX_COMPATIBILITY_VERSION_FLAG "-compatibility_version ") set(CMAKE_Fortran_OSX_CURRENT_VERSION_FLAG "-current_version ") diff --git a/Modules/Platform/Darwin-Intel.cmake b/Modules/Platform/Apple-Intel.cmake index dd33cec..2d4f7e5 100644 --- a/Modules/Platform/Darwin-Intel.cmake +++ b/Modules/Platform/Apple-Intel.cmake @@ -3,12 +3,9 @@ # This module is shared by multiple languages; use include blocker. -if(__DARWIN_COMPILER_INTEL) - return() -endif() -set(__DARWIN_COMPILER_INTEL 1) +include_guard() -macro(__darwin_compiler_intel lang) +macro(__apple_compiler_intel lang) set(CMAKE_${lang}_VERBOSE_FLAG "-v -Wl,-v") # also tell linker to print verbose output set(CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS "-dynamiclib -Wl,-headerpad_max_install_names") set(CMAKE_SHARED_MODULE_CREATE_${lang}_FLAGS "-bundle -Wl,-headerpad_max_install_names") diff --git a/Modules/Platform/Darwin-NAG-Fortran.cmake b/Modules/Platform/Apple-NAG-Fortran.cmake index 8d3e741..8d3e741 100644 --- a/Modules/Platform/Darwin-NAG-Fortran.cmake +++ b/Modules/Platform/Apple-NAG-Fortran.cmake diff --git a/Modules/Platform/Darwin-NVIDIA-CUDA.cmake b/Modules/Platform/Apple-NVIDIA-CUDA.cmake index bec3948..bec3948 100644 --- a/Modules/Platform/Darwin-NVIDIA-CUDA.cmake +++ b/Modules/Platform/Apple-NVIDIA-CUDA.cmake diff --git a/Modules/Platform/Apple-PGI-C.cmake b/Modules/Platform/Apple-PGI-C.cmake new file mode 100644 index 0000000..1e11724 --- /dev/null +++ b/Modules/Platform/Apple-PGI-C.cmake @@ -0,0 +1,2 @@ +include(Platform/Apple-PGI) +__apple_compiler_pgi(C) diff --git a/Modules/Platform/Apple-PGI-CXX.cmake b/Modules/Platform/Apple-PGI-CXX.cmake new file mode 100644 index 0000000..aa5daf7 --- /dev/null +++ b/Modules/Platform/Apple-PGI-CXX.cmake @@ -0,0 +1,2 @@ +include(Platform/Apple-PGI) +__apple_compiler_pgi(CXX) diff --git a/Modules/Platform/Apple-PGI-Fortran.cmake b/Modules/Platform/Apple-PGI-Fortran.cmake new file mode 100644 index 0000000..1e3e4b1 --- /dev/null +++ b/Modules/Platform/Apple-PGI-Fortran.cmake @@ -0,0 +1,2 @@ +include(Platform/Apple-PGI) +__apple_compiler_pgi(Fortran) diff --git a/Modules/Platform/Darwin-PGI.cmake b/Modules/Platform/Apple-PGI.cmake index 04479a8..8d343b7 100644 --- a/Modules/Platform/Darwin-PGI.cmake +++ b/Modules/Platform/Apple-PGI.cmake @@ -2,12 +2,9 @@ # file Copyright.txt or https://cmake.org/licensing for details. # This module is shared by multiple languages; use include blocker. -if(__DARWIN_COMPILER_PGI) - return() -endif() -set(__DARWIN_COMPILER_PGI 1) +include_guard() -macro(__darwin_compiler_pgi lang) +macro(__apple_compiler_pgi lang) set(CMAKE_${lang}_OSX_COMPATIBILITY_VERSION_FLAG "-Wl,-compatibility_version,") set(CMAKE_${lang}_OSX_CURRENT_VERSION_FLAG "-Wl,-current_version,") set(CMAKE_SHARED_LIBRARY_SONAME_${lang}_FLAG "-Wl,-install_name") diff --git a/Modules/Platform/Apple-VisualAge-C.cmake b/Modules/Platform/Apple-VisualAge-C.cmake new file mode 100644 index 0000000..7fa6032 --- /dev/null +++ b/Modules/Platform/Apple-VisualAge-C.cmake @@ -0,0 +1 @@ +include(Platform/Apple-XL-C) diff --git a/Modules/Platform/Apple-VisualAge-CXX.cmake b/Modules/Platform/Apple-VisualAge-CXX.cmake new file mode 100644 index 0000000..12dd347 --- /dev/null +++ b/Modules/Platform/Apple-VisualAge-CXX.cmake @@ -0,0 +1 @@ +include(Platform/Apple-XL-CXX) diff --git a/Modules/Platform/Darwin-XL-C.cmake b/Modules/Platform/Apple-XL-C.cmake index 2aeb132..2aeb132 100644 --- a/Modules/Platform/Darwin-XL-C.cmake +++ b/Modules/Platform/Apple-XL-C.cmake diff --git a/Modules/Platform/Darwin-XL-CXX.cmake b/Modules/Platform/Apple-XL-CXX.cmake index f8e1906..f8e1906 100644 --- a/Modules/Platform/Darwin-XL-CXX.cmake +++ b/Modules/Platform/Apple-XL-CXX.cmake diff --git a/Modules/Platform/Darwin-Clang-C.cmake b/Modules/Platform/Darwin-Clang-C.cmake deleted file mode 100644 index 0a1502e..0000000 --- a/Modules/Platform/Darwin-Clang-C.cmake +++ /dev/null @@ -1,2 +0,0 @@ -include(Platform/Darwin-Clang) -__darwin_compiler_clang(C) diff --git a/Modules/Platform/Darwin-Clang-CXX.cmake b/Modules/Platform/Darwin-Clang-CXX.cmake deleted file mode 100644 index f8e8d88..0000000 --- a/Modules/Platform/Darwin-Clang-CXX.cmake +++ /dev/null @@ -1,2 +0,0 @@ -include(Platform/Darwin-Clang) -__darwin_compiler_clang(CXX) diff --git a/Modules/Platform/Darwin-Initialize.cmake b/Modules/Platform/Darwin-Initialize.cmake index b539e45..3db77aa 100644 --- a/Modules/Platform/Darwin-Initialize.cmake +++ b/Modules/Platform/Darwin-Initialize.cmake @@ -20,6 +20,10 @@ execute_process(COMMAND sw_vers -productVersion set(CMAKE_OSX_ARCHITECTURES "$ENV{CMAKE_OSX_ARCHITECTURES}" CACHE STRING "Build architectures for OSX") +# macOS, iOS, tvOS, and watchOS should lookup compilers from +# Platform/Apple-${CMAKE_CXX_COMPILER_ID}-<LANG> +set(CMAKE_EFFECTIVE_SYSTEM_NAME "Apple") + #---------------------------------------------------------------------------- # _CURRENT_OSX_VERSION - as a two-component string: 10.5, 10.6, ... # diff --git a/Modules/Platform/Darwin-Intel-C.cmake b/Modules/Platform/Darwin-Intel-C.cmake deleted file mode 100644 index 81c630f..0000000 --- a/Modules/Platform/Darwin-Intel-C.cmake +++ /dev/null @@ -1,2 +0,0 @@ -include(Platform/Darwin-Intel) -__darwin_compiler_intel(C) diff --git a/Modules/Platform/Darwin-Intel-CXX.cmake b/Modules/Platform/Darwin-Intel-CXX.cmake deleted file mode 100644 index 90ae53b..0000000 --- a/Modules/Platform/Darwin-Intel-CXX.cmake +++ /dev/null @@ -1,2 +0,0 @@ -include(Platform/Darwin-Intel) -__darwin_compiler_intel(CXX) diff --git a/Modules/Platform/Darwin-PGI-C.cmake b/Modules/Platform/Darwin-PGI-C.cmake deleted file mode 100644 index 790919b..0000000 --- a/Modules/Platform/Darwin-PGI-C.cmake +++ /dev/null @@ -1,2 +0,0 @@ -include(Platform/Darwin-PGI) -__darwin_compiler_pgi(C) diff --git a/Modules/Platform/Darwin-PGI-CXX.cmake b/Modules/Platform/Darwin-PGI-CXX.cmake deleted file mode 100644 index ceaed71..0000000 --- a/Modules/Platform/Darwin-PGI-CXX.cmake +++ /dev/null @@ -1,2 +0,0 @@ -include(Platform/Darwin-PGI) -__darwin_compiler_pgi(CXX) diff --git a/Modules/Platform/Darwin-PGI-Fortran.cmake b/Modules/Platform/Darwin-PGI-Fortran.cmake deleted file mode 100644 index 146807b..0000000 --- a/Modules/Platform/Darwin-PGI-Fortran.cmake +++ /dev/null @@ -1,2 +0,0 @@ -include(Platform/Darwin-PGI) -__darwin_compiler_pgi(Fortran) diff --git a/Modules/Platform/Darwin-VisualAge-C.cmake b/Modules/Platform/Darwin-VisualAge-C.cmake deleted file mode 100644 index 859914f..0000000 --- a/Modules/Platform/Darwin-VisualAge-C.cmake +++ /dev/null @@ -1 +0,0 @@ -include(Platform/Darwin-XL-C) diff --git a/Modules/Platform/Darwin-VisualAge-CXX.cmake b/Modules/Platform/Darwin-VisualAge-CXX.cmake deleted file mode 100644 index 46c1005..0000000 --- a/Modules/Platform/Darwin-VisualAge-CXX.cmake +++ /dev/null @@ -1 +0,0 @@ -include(Platform/Darwin-XL-CXX) diff --git a/Modules/Platform/Windows-MSVC.cmake b/Modules/Platform/Windows-MSVC.cmake index 0737c12..ae180ed 100644 --- a/Modules/Platform/Windows-MSVC.cmake +++ b/Modules/Platform/Windows-MSVC.cmake @@ -71,6 +71,31 @@ if(NOT MSVC_VERSION) message(FATAL_ERROR "MSVC compiler version not detected properly: ${_compiler_version}") endif() + if(MSVC_VERSION GREATER_EQUAL 1910) + # VS 2017 or greater + set(MSVC_TOOLSET_VERSION 141) + elseif(MSVC_VERSION EQUAL 1900) + # VS 2015 + set(MSVC_TOOLSET_VERSION 140) + elseif(MSVC_VERSION EQUAL 1800) + # VS 2013 + set(MSVC_TOOLSET_VERSION 120) + elseif(MSVC_VERSION EQUAL 1700) + # VS 2012 + set(MSVC_TOOLSET_VERSION 110) + elseif(MSVC_VERSION EQUAL 1600) + # VS 2010 + set(MSVC_TOOLSET_VERSION 100) + elseif(MSVC_VERSION EQUAL 1500) + # VS 2008 + set(MSVC_TOOLSET_VERSION 90) + elseif(MSVC_VERSION EQUAL 1400) + # VS 2005 + set(MSVC_TOOLSET_VERSION 80) + else() + # We don't support MSVC_TOOLSET_VERSION for earlier compiler. + endif() + set(MSVC10) set(MSVC11) set(MSVC12) @@ -293,6 +318,34 @@ macro(__windows_compiler_msvc lang) set(CMAKE_${lang}_LINK_EXECUTABLE "${_CMAKE_VS_LINK_EXE}<CMAKE_LINKER> ${CMAKE_CL_NOLOGO} <OBJECTS> ${CMAKE_START_TEMP_FILE} /out:<TARGET> /implib:<TARGET_IMPLIB> /pdb:<TARGET_PDB> /version:<TARGET_VERSION_MAJOR>.<TARGET_VERSION_MINOR>${_PLATFORM_LINK_FLAGS} <CMAKE_${lang}_LINK_FLAGS> <LINK_FLAGS> <LINK_LIBRARIES>${CMAKE_END_TEMP_FILE}") + if("x${CMAKE_${lang}_COMPILER_ID}" STREQUAL "xMSVC") + set(_CMAKE_${lang}_IPO_SUPPORTED_BY_CMAKE YES) + set(_CMAKE_${lang}_IPO_MAY_BE_SUPPORTED_BY_COMPILER YES) + + set(CMAKE_${lang}_COMPILE_OPTIONS_IPO "/GL") + set(CMAKE_${lang}_LINK_OPTIONS_IPO "/INCREMENTAL:NO" "/LTCG") + string(REPLACE "<LINK_FLAGS> " "/LTCG <LINK_FLAGS> " + CMAKE_${lang}_CREATE_STATIC_LIBRARY_IPO "${CMAKE_${lang}_CREATE_STATIC_LIBRARY}") + elseif("x${CMAKE_${lang}_COMPILER_ID}" STREQUAL "xClang" OR + "x${CMAKE_${lang}_COMPILER_ID}" STREQUAL "xFlang") + set(_CMAKE_${lang}_IPO_SUPPORTED_BY_CMAKE YES) + set(_CMAKE_${lang}_IPO_MAY_BE_SUPPORTED_BY_COMPILER YES) + + # '-flto=thin' available since Clang 3.9 and Xcode 8 + # * http://clang.llvm.org/docs/ThinLTO.html#clang-llvm + # * https://trac.macports.org/wiki/XcodeVersionInfo + set(_CMAKE_LTO_THIN TRUE) + if(CMAKE_${lang}_COMPILER_VERSION VERSION_LESS 3.9) + set(_CMAKE_LTO_THIN FALSE) + endif() + + if(_CMAKE_LTO_THIN) + set(CMAKE_${lang}_COMPILE_OPTIONS_IPO "-flto=thin") + else() + set(CMAKE_${lang}_COMPILE_OPTIONS_IPO "-flto") + endif() + endif() + if("x${lang}" STREQUAL "xC" OR "x${lang}" STREQUAL "xCXX") if(CMAKE_VS_PLATFORM_TOOLSET MATCHES "v[0-9]+_clang_.*") diff --git a/Modules/Platform/Windows-NVIDIA-CUDA.cmake b/Modules/Platform/Windows-NVIDIA-CUDA.cmake index 970c2c6..0c11e55 100644 --- a/Modules/Platform/Windows-NVIDIA-CUDA.cmake +++ b/Modules/Platform/Windows-NVIDIA-CUDA.cmake @@ -36,12 +36,27 @@ else() set(_CMAKE_CUDA_EXTRA_DEVICE_LINK_FLAGS "") endif() +# Add implicit host link directories that contain device libraries +# to the device link line. +set(__IMPLICT_DLINK_DIRS ${CMAKE_CUDA_IMPLICIT_LINK_DIRECTORIES}) +if(__IMPLICT_DLINK_DIRS) + list(REMOVE_ITEM __IMPLICT_DLINK_DIRS ${CMAKE_CUDA_HOST_IMPLICIT_LINK_DIRECTORIES}) +endif() +set(__IMPLICT_DLINK_FLAGS ) +foreach(dir ${__IMPLICT_DLINK_DIRS}) + if(EXISTS "${dir}/cublas_device.lib") + string(APPEND __IMPLICT_DLINK_FLAGS " -L\"${dir}\"") + endif() +endforeach() +unset(__IMPLICT_DLINK_DIRS) + set(CMAKE_CUDA_DEVICE_LINK_LIBRARY - "<CMAKE_CUDA_COMPILER> <CMAKE_CUDA_LINK_FLAGS> <LANGUAGE_COMPILE_FLAGS> ${_CMAKE_CUDA_EXTRA_DEVICE_LINK_FLAGS} -shared -dlink <OBJECTS> -o <TARGET> <LINK_LIBRARIES> -Xcompiler=-Fd<TARGET_COMPILE_PDB>,-FS") + "<CMAKE_CUDA_COMPILER> <CMAKE_CUDA_LINK_FLAGS> <LANGUAGE_COMPILE_FLAGS> ${_CMAKE_CUDA_EXTRA_DEVICE_LINK_FLAGS} -shared -dlink <OBJECTS> -o <TARGET> <LINK_LIBRARIES> -Xcompiler=-Fd<TARGET_COMPILE_PDB>,-FS${__IMPLICT_DLINK_FLAGS}") set(CMAKE_CUDA_DEVICE_LINK_EXECUTABLE - "<CMAKE_CUDA_COMPILER> <FLAGS> <CMAKE_CUDA_LINK_FLAGS> ${_CMAKE_CUDA_EXTRA_DEVICE_LINK_FLAGS} -shared -dlink <OBJECTS> -o <TARGET> <LINK_LIBRARIES> -Xcompiler=-Fd<TARGET_COMPILE_PDB>,-FS") + "<CMAKE_CUDA_COMPILER> <FLAGS> <CMAKE_CUDA_LINK_FLAGS> ${_CMAKE_CUDA_EXTRA_DEVICE_LINK_FLAGS} -shared -dlink <OBJECTS> -o <TARGET> <LINK_LIBRARIES> -Xcompiler=-Fd<TARGET_COMPILE_PDB>,-FS${__IMPLICT_DLINK_FLAGS}") unset(_CMAKE_CUDA_EXTRA_DEVICE_LINK_FLAGS) +unset(__IMPLICT_DLINK_FLAGS) string(REPLACE "/D" "-D" _PLATFORM_DEFINES_CUDA "${_PLATFORM_DEFINES}${_PLATFORM_DEFINES_CXX}") diff --git a/Modules/Platform/Windows-df.cmake b/Modules/Platform/Windows-df.cmake index c59be45..f948914 100644 --- a/Modules/Platform/Windows-df.cmake +++ b/Modules/Platform/Windows-df.cmake @@ -30,9 +30,6 @@ set(CMAKE_Fortran_LINK_EXECUTABLE set(CMAKE_CREATE_WIN32_EXE /winapp) set(CMAKE_CREATE_CONSOLE_EXE ) -if(CMAKE_GENERATOR MATCHES "Visual Studio 8") - set (CMAKE_NO_BUILD_TYPE 1) -endif() # does the compiler support pdbtype and is it the newer compiler set(CMAKE_BUILD_TYPE_INIT Debug) diff --git a/Modules/TestBigEndian.cmake b/Modules/TestBigEndian.cmake index cc627d0..9a4bce5 100644 --- a/Modules/TestBigEndian.cmake +++ b/Modules/TestBigEndian.cmake @@ -14,6 +14,8 @@ # TEST_BIG_ENDIAN(VARIABLE) # VARIABLE - variable to store the result to +include(CheckTypeSize) + macro(TEST_BIG_ENDIAN VARIABLE) if(NOT DEFINED HAVE_${VARIABLE}) message(STATUS "Check if the system is big endian") @@ -27,8 +29,6 @@ macro(TEST_BIG_ENDIAN VARIABLE) message(FATAL_ERROR "TEST_BIG_ENDIAN needs either C or CXX language enabled") endif() - include(CheckTypeSize) - CHECK_TYPE_SIZE("unsigned short" CMAKE_SIZEOF_UNSIGNED_SHORT LANGUAGE ${_test_language}) if(CMAKE_SIZEOF_UNSIGNED_SHORT EQUAL 2) message(STATUS "Using unsigned short") diff --git a/Modules/UseJava.cmake b/Modules/UseJava.cmake index 939bd7b..6e2c511 100644 --- a/Modules/UseJava.cmake +++ b/Modules/UseJava.cmake @@ -36,7 +36,7 @@ # The default OUTPUT_DIR can also be changed by setting the variable # CMAKE_JAVA_TARGET_OUTPUT_DIR. # -# Optionaly, using option GENERATE_NATIVE_HEADERS, native header files can be generated +# Optionally, using option GENERATE_NATIVE_HEADERS, native header files can be generated # for methods declared as native. These files provide the connective glue that allow your # Java and C code to interact. An INTERFACE target will be created for an easy usage # of generated files. Sub-option DESTINATION can be used to specify output directory for @@ -384,7 +384,7 @@ # Create C header files from java classes. These files provide the connective glue # that allow your Java and C code to interact. # -# This command will no longer be supported starting with version 1.10 of the JDK due +# 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>`_. # Command ``add_jar(GENERATE_NATIVE_HEADERS)`` must be used instead. # @@ -527,7 +527,7 @@ function(add_jar _TARGET_NAME) if (_add_jar_GENERATE_NATIVE_HEADERS) # Raise an error if JDK version is less than 1.8 because javac -h is not supported # by earlier versions. - if ("${Java_VERSION}" VERSION_LESS 1.8) + if (Java_VERSION VERSION_LESS 1.8) message (FATAL_ERROR "ADD_JAR: GENERATE_NATIVE_HEADERS is not supported with this version of Java.") endif() cmake_parse_arguments (_add_jar_GENERATE_NATIVE_HEADERS "" "DESTINATION" "" ${_add_jar_GENERATE_NATIVE_HEADERS}) @@ -1312,10 +1312,10 @@ function(create_javadoc _target) endfunction() function (create_javah) - if ("${Java_VERSION}" VERSION_GREATER_EQUAL 1.10) + if (Java_VERSION VERSION_GREATER_EQUAL 10) message (FATAL_ERROR "create_javah: not supported with this Java version. Use add_jar(GENERATE_NATIVE_HEADERS) instead.") - elseif ("${Java_VERSION}" VERSION_GREATER_EQUAL 1.8) - message (DEPRECATION "create_javah: this command will no longer be supported starting with version 1.10 of JDK. Update your project by using command add_jar(GENERATE_NATIVE_HEADERS) instead.") + elseif (Java_VERSION VERSION_GREATER_EQUAL 1.8) + message (DEPRECATION "create_javah: this command will no longer be supported starting with version 10 of JDK. Update your project by using command add_jar(GENERATE_NATIVE_HEADERS) instead.") endif() cmake_parse_arguments(_create_javah diff --git a/Modules/UseSWIG.cmake b/Modules/UseSWIG.cmake index 959893f..8713cd8 100644 --- a/Modules/UseSWIG.cmake +++ b/Modules/UseSWIG.cmake @@ -5,7 +5,10 @@ UseSWIG ------- -Defines the following macros for use with SWIG: +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``: .. command:: swig_add_library @@ -14,20 +17,71 @@ Defines the following macros for use with SWIG: swig_add_library(<name> [TYPE <SHARED|MODULE|STATIC|USE_BUILD_SHARED_LIBS>] LANGUAGE <language> + [NO_PROXY] + [OUTPUT_DIR <directory>] + [OUTFILE_DIR <directory>] SOURCES <file>... - ) - - The variable ``SWIG_MODULE_<name>_REAL_NAME`` will be set to the name - of the swig module target library. - -.. command:: swig_link_libraries - - Link libraries to swig module:: - - swig_link_libraries(<name> [ libraries ]) - -Source file properties on module files can be set before the invocation -of the ``swig_add_library`` macro to specify special behavior of SWIG: + ) + + Targets created with the ``swig_add_library`` command have the same + capabilities as targets created with the :command:`add_library` command, so + those targets can be used with any command expecting a target (e.g. + :command:`target_link_libraries`). + + .. note:: + + For multi-config generators, this module does not support + configuration-specific files generated by ``SWIG``. All build + configurations must result in the same generated source file. + + ``TYPE`` + ``SHARED``, ``MODULE`` and ``STATIC`` have the same semantic as for the + :command:`add_library` command. If ``USE_BUILD_SHARED_LIBS`` is specified, + the library type will be ``STATIC`` or ``SHARED`` based on whether the + current value of the :variable:`BUILD_SHARED_LIBS` variable is ``ON``. If + no type is specified, ``MODULE`` will be used. + + ``LANGUAGE`` + Specify the target language. + + ``NO_PROXY`` + Prevent the generation of the wrapper layer (swig ``-noproxy`` option). + + ``OUTPUT_DIR`` + Specify where to write the language specific files (swig ``-outdir`` + option). If not given, the ``CMAKE_SWIG_OUTDIR`` variable will be used. + If neither is specified, the default depends on the value of the + ``UseSWIG_MODULE_VERSION`` variable as follows: + + * If ``UseSWIG_MODULE_VERSION`` is 1 or is undefined, output is written to + the :variable:`CMAKE_CURRENT_BINARY_DIR` directory. + * If ``UseSWIG_MODULE_VERSION`` is 2, a dedicated directory will be used. + The path of this directory can be retrieved from the + ``SWIG_SUPPORT_FILES_DIRECTORY`` target property. + + ``OUTFILE_DIR`` + Specify an output directory name where the generated source file will be + placed (swig -o option). If not specified, the ``SWIG_OUTFILE_DIR`` variable + will be used. If neither is specified, ``OUTPUT_DIR`` or + ``CMAKE_SWIG_OUTDIR`` is used instead. + + ``SOURCES`` + List of sources for the library. Files with extension ``.i`` will be + identified as sources for the ``SWIG`` tool. Other files will be handled in + the standard way. + +.. note:: + + If ``UseSWIG_MODULE_VERSION`` is set to 2, it is **strongly** recommended + to use a dedicated directory unique to the target when either the + ``OUTPUT_DIR`` option or the ``CMAKE_SWIG_OUTDIR`` variable are specified. + The output directory contents are erased as part of the target build, so + to prevent interference between targets or losing other important files, each + target should have its own dedicated output directory. + +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 +ensure generated files will receive the required settings. ``CPLUSPLUS`` Call SWIG in c++ mode. For example: @@ -37,9 +91,18 @@ of the ``swig_add_library`` macro to specify special behavior of SWIG: set_property(SOURCE mymod.i PROPERTY CPLUSPLUS ON) swig_add_library(mymod LANGUAGE python SOURCES mymod.i) -``SWIG_FLAGS`` - Add custom flags to the SWIG executable. +``INCLUDE_DIRECTORIES``, ``COMPILE_DEFINITIONS`` and ``COMPILE_OPTIONS`` + Add custom flags to SWIG compiler and have same semantic as properties + :prop_sf:`INCLUDE_DIRECTORIES`, :prop_sf:`COMPILE_DEFINITIONS` and + :prop_sf:`COMPILE_OPTIONS`. + +``GENERATED_INCLUDE_DIRECTORIES``, ``GENERATED_COMPILE_DEFINITIONS`` and ``GENERATED_COMPILE_OPTIONS`` + Add custom flags to the C/C++ generated source. They will fill, respectively, + properties :prop_sf:`INCLUDE_DIRECTORIES`, :prop_sf:`COMPILE_DEFINITIONS` and + :prop_sf:`COMPILE_OPTIONS` of generated C/C++ file. +``DEPENDS`` + Specify additional dependencies to the source file. ``SWIG_MODULE_NAME`` Specify the actual import name of the module in the target language. @@ -50,7 +113,59 @@ of the ``swig_add_library`` macro to specify special behavior of SWIG: set_property(SOURCE mymod.i PROPERTY SWIG_MODULE_NAME mymod_realname) -Some variables can be set to specify special behavior of SWIG: +Target library properties can be set to apply same configuration to all SWIG +input files. + +``SWIG_INCLUDE_DIRECTORIES``, ``SWIG_COMPILE_DEFINITIONS`` and ``SWIG_COMPILE_OPTIONS`` + These properties will be applied to all SWIG input files and have same + semantic as target properties :prop_tgt:`INCLUDE_DIRECTORIES`, + :prop_tgt:`COMPILE_DEFINITIONS` and :prop_tgt:`COMPILE_OPTIONS`. + + .. code-block:: cmake + + swig_add_library(mymod LANGUAGE python SOURCES mymod.i) + set_property(TARGET mymod PROPERTY SWIG_COMPILE_DEFINITIONS MY_DEF1 MY_DEF2) + set_property(TARGET mymod PROPERTY SWIG_COMPILE_OPTIONS -bla -blb) + +``SWIG_GENERATED_INCLUDE_DIRECTORIES``, ``SWIG_GENERATED_COMPILE_DEFINITIONS`` and ``SWIG_GENERATED_COMPILE_OPTIONS`` + These properties will populate, respectively, properties + :prop_sf:`INCLUDE_DIRECTORIES`, :prop_sf:`COMPILE_DEFINITIONS` and + :prop_sf:`COMPILE_FLAGS` of all generated C/C++ files. + +``SWIG_DEPENDS`` + Add dependencies to all SWIG input files. + +The following target properties are output properties and can be used to get +information about support files generated by ``SWIG`` interface compilation. + +``SWIG_SUPPORT_FILES`` + This output property list of wrapper files generated during SWIG compilation. + + .. code-block:: cmake + + swig_add_library(mymod LANGUAGE python SOURCES mymod.i) + get_property(support_files TARGET mymod PROPERTY SWIG_SUPPORT_FILES) + + .. note:: + + Only most principal support files are listed. In case some advanced + features of ``SWIG`` are used (for example ``%template``), associated + support files may not be listed. Prefer to use the + ``SWIG_SUPPORT_FILES_DIRECTORY`` property to handle support files. + +``SWIG_SUPPORT_FILES_DIRECTORY`` + This output property specifies the directory where support files will be + generated. + +Some variables can be set to customize the behavior of ``swig_add_library`` +as well as ``SWIG``: + +``UseSWIG_MODULE_VERSION`` + Specify different behaviors for ``UseSWIG`` module. + + * Set to 1 or undefined: Legacy behavior is applied. + * Set to 2: A new strategy is applied regarding support files: the output + directory of support files is erased before ``SWIG`` interface compilation. ``CMAKE_SWIG_FLAGS`` Add flags to all swig calls. @@ -66,34 +181,50 @@ Some variables can be set to specify special behavior of SWIG: Specify extra dependencies for the generated module for ``<name>``. #]=======================================================================] + +cmake_policy (VERSION 3.11) + set(SWIG_CXX_EXTENSION "cxx") set(SWIG_EXTRA_LIBRARIES "") set(SWIG_PYTHON_EXTRA_FILE_EXTENSIONS ".py") set(SWIG_JAVA_EXTRA_FILE_EXTENSIONS ".java" "JNI.java") +## +## PRIVATE functions +## +function (__SWIG_COMPUTE_TIMESTAMP name language infile workingdir __timestamp) + get_filename_component(filename "${infile}" NAME_WE) + set(${__timestamp} + "${workingdir}/${filename}${language}.stamp" PARENT_SCOPE) + # get_filename_component(filename "${infile}" ABSOLUTE) + # string(UUID uuid NAMESPACE 9735D882-D2F8-4E1D-88C9-A0A4F1F6ECA4 + # NAME ${name}-${language}-${filename} TYPE SHA1) + # set(${__timestamp} "${workingdir}/${uuid}.stamp" PARENT_SCOPE) +endfunction() + # # For given swig module initialize variables associated with it # macro(SWIG_MODULE_INITIALIZE name language) - string(TOUPPER "${language}" swig_uppercase_language) - string(TOLOWER "${language}" swig_lowercase_language) - set(SWIG_MODULE_${name}_LANGUAGE "${swig_uppercase_language}") - set(SWIG_MODULE_${name}_SWIG_LANGUAGE_FLAG "${swig_lowercase_language}") + string(TOUPPER "${language}" SWIG_MODULE_${name}_LANGUAGE) + string(TOLOWER "${language}" SWIG_MODULE_${name}_SWIG_LANGUAGE_FLAG) - set(SWIG_MODULE_${name}_REAL_NAME "${name}") - if (";${CMAKE_SWIG_FLAGS};" MATCHES ";-noproxy;") + set(SWIG_MODULE_${name}_EXTRA_FLAGS) + if (NOT DEFINED SWIG_MODULE_${name}_NOPROXY) + set (SWIG_MODULE_${name}_NOPROXY FALSE) + endif() + if ("-noproxy" IN_LIST CMAKE_SWIG_FLAGS) set (SWIG_MODULE_${name}_NOPROXY TRUE) endif () - if("x${SWIG_MODULE_${name}_LANGUAGE}" STREQUAL "xUNKNOWN") + + if (SWIG_MODULE_${name}_NOPROXY AND NOT "-noproxy" IN_LIST CMAKE_SWIG_FLAGS) + list (APPEND SWIG_MODULE_${name}_EXTRA_FLAGS "-noproxy") + endif() + if(SWIG_MODULE_${name}_LANGUAGE STREQUAL "UNKNOWN") message(FATAL_ERROR "SWIG Error: Language \"${language}\" not found") - elseif("x${SWIG_MODULE_${name}_LANGUAGE}" STREQUAL "xPYTHON" AND NOT SWIG_MODULE_${name}_NOPROXY) - # swig will produce a module.py containing an 'import _modulename' statement, - # which implies having a corresponding _modulename.so (*NIX), _modulename.pyd (Win32), - # unless the -noproxy flag is used - set(SWIG_MODULE_${name}_REAL_NAME "_${name}") - elseif("x${SWIG_MODULE_${name}_LANGUAGE}" STREQUAL "xPERL") - set(SWIG_MODULE_${name}_EXTRA_FLAGS "-shadow") + elseif(SWIG_MODULE_${name}_LANGUAGE STREQUAL "PERL") + list(APPEND SWIG_MODULE_${name}_EXTRA_FLAGS "-shadow") endif() endmacro() @@ -102,79 +233,108 @@ endmacro() # will be generated. This is internal swig macro. # -macro(SWIG_GET_EXTRA_OUTPUT_FILES language outfiles generatedpath infile) - set(${outfiles} "") - get_source_file_property(SWIG_GET_EXTRA_OUTPUT_FILES_module_basename - ${infile} SWIG_MODULE_NAME) - if(SWIG_GET_EXTRA_OUTPUT_FILES_module_basename STREQUAL "NOTFOUND") +function(SWIG_GET_EXTRA_OUTPUT_FILES language outfiles generatedpath infile) + set(files) + get_source_file_property(module_basename + "${infile}" SWIG_MODULE_NAME) + if(NOT swig_module_basename) # try to get module name from "%module foo" syntax - if ( EXISTS ${infile} ) - file ( STRINGS ${infile} _MODULE_NAME REGEX "[ ]*%module[ ]*[a-zA-Z0-9_]+.*" ) + if ( EXISTS "${infile}" ) + file ( STRINGS "${infile}" module_basename REGEX "[ ]*%module[ ]*[a-zA-Z0-9_]+.*" ) endif () - if ( _MODULE_NAME ) - string ( REGEX REPLACE "[ ]*%module[ ]*([a-zA-Z0-9_]+).*" "\\1" _MODULE_NAME "${_MODULE_NAME}" ) - set(SWIG_GET_EXTRA_OUTPUT_FILES_module_basename "${_MODULE_NAME}") + if ( module_basename ) + string ( REGEX REPLACE "[ ]*%module[ ]*([a-zA-Z0-9_]+).*" "\\1" module_basename "${module_basename}" ) else () # try to get module name from "%module (options=...) foo" syntax - if ( EXISTS ${infile} ) - file ( STRINGS ${infile} _MODULE_NAME REGEX "[ ]*%module[ ]*\\(.*\\)[ ]*[a-zA-Z0-9_]+.*" ) + if ( EXISTS "${infile}" ) + file ( STRINGS "${infile}" module_basename REGEX "[ ]*%module[ ]*\\(.*\\)[ ]*[a-zA-Z0-9_]+.*" ) endif () - if ( _MODULE_NAME ) - string ( REGEX REPLACE "[ ]*%module[ ]*\\(.*\\)[ ]*([a-zA-Z0-9_]+).*" "\\1" _MODULE_NAME "${_MODULE_NAME}" ) - set(SWIG_GET_EXTRA_OUTPUT_FILES_module_basename "${_MODULE_NAME}") + if ( module_basename ) + string ( REGEX REPLACE "[ ]*%module[ ]*\\(.*\\)[ ]*([a-zA-Z0-9_]+).*" "\\1" module_basename "${module_basename}" ) else () # fallback to file basename - get_filename_component(SWIG_GET_EXTRA_OUTPUT_FILES_module_basename ${infile} NAME_WE) + get_filename_component(module_basename "${infile}" NAME_WE) endif () endif () endif() foreach(it ${SWIG_${language}_EXTRA_FILE_EXTENSIONS}) - set(extra_file "${generatedpath}/${SWIG_GET_EXTRA_OUTPUT_FILES_module_basename}${it}") - list(APPEND ${outfiles} ${extra_file}) - # Treat extra outputs as plain files regardless of language. - set_property(SOURCE "${extra_file}" PROPERTY LANGUAGE "") + set(extra_file "${generatedpath}/${module_basename}${it}") + list(APPEND files "${extra_file}") endforeach() -endmacro() + # Treat extra outputs as plain files regardless of language. + set_source_files_properties(${files} PROPERTIES LANGUAGE "") + + set (${outfiles} ${files} PARENT_SCOPE) +endfunction() # # Take swig (*.i) file and add proper custom commands for it # -macro(SWIG_ADD_SOURCE_TO_MODULE name outfiles infile) - set(swig_full_infile ${infile}) +function(SWIG_ADD_SOURCE_TO_MODULE name outfiles infile) get_filename_component(swig_source_file_name_we "${infile}" NAME_WE) - get_source_file_property(swig_source_file_generated ${infile} GENERATED) - get_source_file_property(swig_source_file_cplusplus ${infile} CPLUSPLUS) - get_source_file_property(swig_source_file_flags ${infile} SWIG_FLAGS) - if("${swig_source_file_flags}" STREQUAL "NOTFOUND") - set(swig_source_file_flags "") - endif() - get_filename_component(swig_source_file_fullname "${infile}" ABSOLUTE) + get_source_file_property(swig_source_file_cplusplus "${infile}" CPLUSPLUS) # If CMAKE_SWIG_OUTDIR was specified then pass it to -outdir if(CMAKE_SWIG_OUTDIR) - set(swig_outdir ${CMAKE_SWIG_OUTDIR}) + set(outdir ${CMAKE_SWIG_OUTDIR}) else() - set(swig_outdir ${CMAKE_CURRENT_BINARY_DIR}) + set(outdir ${CMAKE_CURRENT_BINARY_DIR}) endif() if(SWIG_OUTFILE_DIR) - set(swig_outfile_dir ${SWIG_OUTFILE_DIR}) + set(outfiledir ${SWIG_OUTFILE_DIR}) + else() + set(outfiledir ${outdir}) + endif() + + if(SWIG_WORKING_DIR) + set (workingdir "${SWIG_WORKING_DIR}") else() - set(swig_outfile_dir ${swig_outdir}) + set(workingdir "${outdir}") + endif() + + set (swig_source_file_flags ${CMAKE_SWIG_FLAGS}) + # handle various swig compile flags properties + get_source_file_property (include_directories "${infile}" INCLUDE_DIRECTORIES) + if (include_directories) + list (APPEND swig_source_file_flags "$<$<BOOL:${include_directories}>:-I$<JOIN:${include_directories},$<SEMICOLON>-I>>") + endif() + set (property "$<TARGET_PROPERTY:${name},SWIG_INCLUDE_DIRECTORIES>") + list (APPEND swig_source_file_flags "$<$<BOOL:${property}>:-I$<JOIN:${property},$<SEMICOLON>-I>>") + + set (property "$<TARGET_PROPERTY:${name},SWIG_COMPILE_DEFINITIONS>") + list (APPEND swig_source_file_flags "$<$<BOOL:${property}>:-D$<JOIN:${property},$<SEMICOLON>-D>>") + get_source_file_property (compile_definitions "${infile}" COMPILE_DEFINITIONS) + if (compile_definitions) + list (APPEND swig_source_file_flags "$<$<BOOL:${compile_definitions}>:-D$<JOIN:${compile_definitions},$<SEMICOLON>-D>>") + endif() + + list (APPEND swig_source_file_flags "$<TARGET_PROPERTY:${name},SWIG_COMPILE_OPTIONS>") + get_source_file_property (compile_options "${infile}" COMPILE_OPTIONS) + if (compile_options) + list (APPEND swig_source_file_flags ${compile_options}) endif() + # legacy support + get_source_file_property (swig_flags "${infile}" SWIG_FLAGS) + if (swig_flags) + list (APPEND swig_source_file_flags ${swig_flags}) + endif() + + get_filename_component(swig_source_file_fullname "${infile}" ABSOLUTE) + if (NOT SWIG_MODULE_${name}_NOPROXY) SWIG_GET_EXTRA_OUTPUT_FILES(${SWIG_MODULE_${name}_LANGUAGE} swig_extra_generated_files - "${swig_outdir}" + "${outdir}" "${swig_source_file_fullname}") endif() set(swig_generated_file_fullname - "${swig_outfile_dir}/${swig_source_file_name_we}") + "${outfiledir}/${swig_source_file_name_we}") # add the language into the name of the file (i.e. TCL_wrap) # this allows for the same .i file to be wrapped into different languages string(APPEND swig_generated_file_fullname @@ -188,45 +348,55 @@ macro(SWIG_ADD_SOURCE_TO_MODULE name outfiles infile) ".c") endif() - #message("Full path to source file: ${swig_source_file_fullname}") - #message("Full path to the output file: ${swig_generated_file_fullname}") - get_directory_property(cmake_include_directories INCLUDE_DIRECTORIES) - list(REMOVE_DUPLICATES cmake_include_directories) - set(swig_include_dirs) - foreach(it ${cmake_include_directories}) - set(swig_include_dirs ${swig_include_dirs} "-I${it}") - endforeach() + get_directory_property (cmake_include_directories INCLUDE_DIRECTORIES) + list (REMOVE_DUPLICATES cmake_include_directories) + set (swig_include_dirs) + if (cmake_include_directories) + set (swig_include_dirs "$<$<BOOL:${cmake_include_directories}>:-I$<JOIN:${cmake_include_directories},$<SEMICOLON>-I>>") + endif() set(swig_special_flags) # default is c, so add c++ flag if it is c++ if(swig_source_file_cplusplus) - set(swig_special_flags ${swig_special_flags} "-c++") + list (APPEND swig_special_flags "-c++") endif() - if("x${SWIG_MODULE_${name}_LANGUAGE}" STREQUAL "xCSHARP") - if(NOT ";${swig_source_file_flags};${CMAKE_SWIG_FLAGS};" MATCHES ";-dllimport;") + + set (swig_extra_flags) + if(SWIG_MODULE_${name}_LANGUAGE STREQUAL "CSHARP") + if(NOT ("-dllimport" IN_LIST swig_source_file_flags OR "-dllimport" IN_LIST SWIG_MODULE_${name}_EXTRA_FLAGS)) # This makes sure that the name used in the generated DllImport # matches the library name created by CMake - set(SWIG_MODULE_${name}_EXTRA_FLAGS "-dllimport;${name}") + list (APPEND SWIG_MODULE_${name}_EXTRA_FLAGS "-dllimport" "${name}") endif() endif() - set(swig_extra_flags) - if(SWIG_MODULE_${name}_EXTRA_FLAGS) - set(swig_extra_flags ${swig_extra_flags} ${SWIG_MODULE_${name}_EXTRA_FLAGS}) + list (APPEND swig_extra_flags ${SWIG_MODULE_${name}_EXTRA_FLAGS}) + + # dependencies + set (swig_dependencies ${SWIG_MODULE_${name}_EXTRA_DEPS} $<TARGET_PROPERTY:${name},SWIG_DEPENDS>) + get_source_file_property(file_depends "${infile}" DEPENDS) + if (file_depends) + list (APPEND swig_dependencies ${file_depends}) endif() + + if (UseSWIG_MODULE_VERSION VERSION_GREATER 1) + # as part of custom command, start by removing old generated files + # to ensure obsolete files do not stay + set (swig_cleanup_command COMMAND "${CMAKE_COMMAND}" -E remove_directory "${outdir}") + else() + unset (swig_cleanup_command) + endif() + # IMPLICIT_DEPENDS below can not handle situations where a dependent file is # removed. We need an extra step with timestamp and custom target, see #16830 # As this is needed only for Makefile generator do it conditionally if(CMAKE_GENERATOR MATCHES "Make") - get_filename_component(swig_generated_timestamp - "${swig_generated_file_fullname}" NAME_WE) - set(swig_gen_target gen_${name}_${swig_generated_timestamp}) - set(swig_generated_timestamp - "${swig_outdir}/${swig_generated_timestamp}.stamp") - set(swig_custom_output ${swig_generated_timestamp}) + __swig_compute_timestamp(${name} ${SWIG_MODULE_${name}_LANGUAGE} + "${infile}" "${workingdir}" swig_generated_timestamp) + set(swig_custom_output "${swig_generated_timestamp}") set(swig_custom_products BYPRODUCTS "${swig_generated_file_fullname}" ${swig_extra_generated_files}) set(swig_timestamp_command - COMMAND ${CMAKE_COMMAND} -E touch ${swig_generated_timestamp}) + COMMAND ${CMAKE_COMMAND} -E touch "${swig_generated_timestamp}") else() set(swig_custom_output "${swig_generated_file_fullname}" ${swig_extra_generated_files}) @@ -236,34 +406,42 @@ macro(SWIG_ADD_SOURCE_TO_MODULE name outfiles infile) add_custom_command( OUTPUT ${swig_custom_output} ${swig_custom_products} - # Let's create the ${swig_outdir} at execution time, in case dir contains $(OutDir) - COMMAND ${CMAKE_COMMAND} -E make_directory ${swig_outdir} + ${swig_cleanup_command} + # Let's create the ${outdir} at execution time, in case dir contains $(OutDir) + COMMAND "${CMAKE_COMMAND}" -E make_directory ${outdir} ${outfiledir} ${swig_timestamp_command} - COMMAND "${SWIG_EXECUTABLE}" - ARGS "-${SWIG_MODULE_${name}_SWIG_LANGUAGE_FLAG}" - ${swig_source_file_flags} - ${CMAKE_SWIG_FLAGS} - -outdir ${swig_outdir} + COMMAND "${CMAKE_COMMAND}" -E env "SWIG_LIB=${SWIG_DIR}" "${SWIG_EXECUTABLE}" + "-${SWIG_MODULE_${name}_SWIG_LANGUAGE_FLAG}" + "${swig_source_file_flags}" + -outdir "${outdir}" ${swig_special_flags} ${swig_extra_flags} - ${swig_include_dirs} + "${swig_include_dirs}" -o "${swig_generated_file_fullname}" "${swig_source_file_fullname}" MAIN_DEPENDENCY "${swig_source_file_fullname}" - DEPENDS ${SWIG_MODULE_${name}_EXTRA_DEPS} + DEPENDS ${swig_dependencies} IMPLICIT_DEPENDS CXX "${swig_source_file_fullname}" - COMMENT "Swig source") - if(CMAKE_GENERATOR MATCHES "Make") - add_custom_target(${swig_gen_target} DEPENDS ${swig_generated_timestamp}) - endif() - unset(swig_generated_timestamp) - unset(swig_custom_output) - unset(swig_custom_products) - unset(swig_timestamp_command) + COMMENT "Swig source" + COMMAND_EXPAND_LISTS) set_source_files_properties("${swig_generated_file_fullname}" ${swig_extra_generated_files} PROPERTIES GENERATED 1) - set(${outfiles} "${swig_generated_file_fullname}" ${swig_extra_generated_files}) -endmacro() + + ## add all properties for generated file to various properties + get_property (include_directories SOURCE "${infile}" PROPERTY GENERATED_INCLUDE_DIRECTORIES) + set_property (SOURCE "${swig_generated_file_fullname}" PROPERTY INCLUDE_DIRECTORIES ${include_directories} $<TARGET_PROPERTY:${name},SWIG_GENERATED_INCLUDE_DIRECTORIES>) + + get_property (compile_definitions SOURCE "${infile}" PROPERTY GENERATED_COMPILE_DEFINITIONS) + set_property (SOURCE "${swig_generated_file_fullname}" PROPERTY COMPILE_DEFINITIONS $<TARGET_PROPERTY:${name},SWIG_GENERATED_COMPILE_DEFINITIONS> ${compile_definitions}) + + get_property (compile_options SOURCE "${infile}" PROPERTY GENERATED_COMPILE_OPTIONS) + set_property (SOURCE "${swig_generated_file_fullname}" PROPERTY COMPILE_OPTIONS $<TARGET_PROPERTY:${name},SWIG_GENERATED_COMPILE_OPTIONS> ${compile_options}) + + set(${outfiles} "${swig_generated_file_fullname}" ${swig_extra_generated_files} PARENT_SCOPE) + + # legacy support + set (swig_generated_file_fullname "${swig_generated_file_fullname}" PARENT_SCOPE) +endfunction() # # Create Swig module @@ -277,13 +455,26 @@ macro(SWIG_ADD_MODULE name language) endmacro() -macro(SWIG_ADD_LIBRARY name) - set(options "") +function(SWIG_ADD_LIBRARY name) + set(options NO_PROXY) set(oneValueArgs LANGUAGE - TYPE) + TYPE + OUTPUT_DIR + OUTFILE_DIR) set(multiValueArgs SOURCES) cmake_parse_arguments(_SAM "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + if (TARGET ${name}) + # a target with same name is already defined. + # call NOW add_library command to raise the most useful error message + add_library(${name}) + return() + endif() + + if (_SAM_UNPARSED_ARGUMENTS) + message(FATAL_ERROR "SWIG_ADD_LIBRARY: ${_SAM_UNPARSED_ARGUMENTS}: unexpected arguments") + endif() + if(NOT DEFINED _SAM_LANGUAGE) message(FATAL_ERROR "SWIG_ADD_LIBRARY: Missing LANGUAGE argument") endif() @@ -294,66 +485,123 @@ macro(SWIG_ADD_LIBRARY name) if(NOT DEFINED _SAM_TYPE) set(_SAM_TYPE MODULE) - elseif("${_SAM_TYPE}" STREQUAL "USE_BUILD_SHARED_LIBS") + elseif(_SAM_TYPE STREQUAL "USE_BUILD_SHARED_LIBS") unset(_SAM_TYPE) endif() - swig_module_initialize(${name} ${_SAM_LANGUAGE}) + if (NOT DEFINED UseSWIG_MODULE_VERSION) + set (UseSWIG_MODULE_VERSION 1) + elseif (NOT UseSWIG_MODULE_VERSION MATCHES "^(1|2)$") + message (FATAL_ERROR "UseSWIG_MODULE_VERSION: ${UseSWIG_MODULE_VERSION}: invalid value. 1 or 2 is expected.") + endif() - set(swig_dot_i_sources) - set(swig_other_sources) - foreach(it ${_SAM_SOURCES}) - if(${it} MATCHES "\\.i$") - set(swig_dot_i_sources ${swig_dot_i_sources} "${it}") + set (workingdir "${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/${name}.dir") + # set special variable to pass extra information to command SWIG_ADD_SOURCE_TO_MODULE + # which cannot be changed due to legacy compatibility + set (SWIG_WORKING_DIR "${workingdir}") + + set (outputdir "${_SAM_OUTPUT_DIR}") + if (NOT _SAM_OUTPUT_DIR) + if (CMAKE_SWIG_OUTDIR) + set (outputdir "${CMAKE_SWIG_OUTDIR}") else() - set(swig_other_sources ${swig_other_sources} "${it}") + if (UseSWIG_MODULE_VERSION VERSION_GREATER 1) + set (outputdir "${workingdir}/${_SAM_LANGUAGE}.files") + else() + set (outputdir "${CMAKE_CURRENT_BINARY_DIR}") + endif() endif() - endforeach() + endif() + + set (outfiledir "${_SAM_OUTFILE_DIR}") + if(NOT _SAM_OUTFILE_DIR) + if (SWIG_OUTFILE_DIR) + set (outfiledir "${SWIG_OUTFILE_DIR}") + else() + if (_SAM_OUTPUT_DIR OR CMAKE_SWIG_OUTDIR) + set (outfiledir "${outputdir}") + else() + set (outfiledir "${workingdir}") + endif() + endif() + endif() + # set again, locally, predefined variables to ensure compatibility + # with command SWIG_ADD_SOURCE_TO_MODULE + set(CMAKE_SWIG_OUTDIR "${outputdir}") + set(SWIG_OUTFILE_DIR "${outfiledir}") + + set (SWIG_MODULE_${name}_NOPROXY ${_SAM_NO_PROXY}) + swig_module_initialize(${name} ${_SAM_LANGUAGE}) + + set(swig_dot_i_sources ${_SAM_SOURCES}) + list(FILTER swig_dot_i_sources INCLUDE REGEX "\\.i$") + if (NOT swig_dot_i_sources) + message(FATAL_ERROR "SWIG_ADD_LIBRARY: no SWIG interface files specified") + endif() + set(swig_other_sources ${_SAM_SOURCES}) + list(REMOVE_ITEM swig_other_sources ${swig_dot_i_sources}) set(swig_generated_sources) - set(swig_generated_targets) - foreach(it ${swig_dot_i_sources}) - SWIG_ADD_SOURCE_TO_MODULE(${name} swig_generated_source ${it}) - set(swig_generated_sources ${swig_generated_sources} "${swig_generated_source}") - list(APPEND swig_generated_targets "${swig_gen_target}") + set(swig_generated_timestamps) + foreach(swig_it IN LISTS swig_dot_i_sources) + SWIG_ADD_SOURCE_TO_MODULE(${name} swig_generated_source "${swig_it}") + list (APPEND swig_generated_sources "${swig_generated_source}") + if(CMAKE_GENERATOR MATCHES "Make") + __swig_compute_timestamp(${name} ${SWIG_MODULE_${name}_LANGUAGE} "${swig_it}" + "${workingdir}" swig_timestamp) + list (APPEND swig_generated_timestamps "${swig_timestamp}") + endif() endforeach() - get_directory_property(swig_extra_clean_files ADDITIONAL_MAKE_CLEAN_FILES) - set_directory_properties(PROPERTIES - ADDITIONAL_MAKE_CLEAN_FILES "${swig_extra_clean_files};${swig_generated_sources}") - add_library(${SWIG_MODULE_${name}_REAL_NAME} + set_property (DIRECTORY APPEND PROPERTY + ADDITIONAL_MAKE_CLEAN_FILES ${swig_generated_sources} ${swig_generated_timestamps}) + if (UseSWIG_MODULE_VERSION VERSION_GREATER 1) + set_property (DIRECTORY APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES "${outputdir}") + endif() + + add_library(${name} ${_SAM_TYPE} ${swig_generated_sources} ${swig_other_sources}) if(CMAKE_GENERATOR MATCHES "Make") # see IMPLICIT_DEPENDS above - add_dependencies(${SWIG_MODULE_${name}_REAL_NAME} ${swig_generated_targets}) + add_custom_target(${name}_swig_compilation DEPENDS ${swig_generated_timestamps}) + add_dependencies(${name} ${name}_swig_compilation) endif() - if("${_SAM_TYPE}" STREQUAL "MODULE") - set_target_properties(${SWIG_MODULE_${name}_REAL_NAME} PROPERTIES NO_SONAME ON) + if(_SAM_TYPE STREQUAL "MODULE") + set_target_properties(${name} PROPERTIES NO_SONAME ON) endif() string(TOLOWER "${_SAM_LANGUAGE}" swig_lowercase_language) - if ("${swig_lowercase_language}" STREQUAL "octave") - set_target_properties(${SWIG_MODULE_${name}_REAL_NAME} PROPERTIES PREFIX "") - set_target_properties(${SWIG_MODULE_${name}_REAL_NAME} PROPERTIES SUFFIX ".oct") - elseif ("${swig_lowercase_language}" STREQUAL "go") - set_target_properties(${SWIG_MODULE_${name}_REAL_NAME} PROPERTIES PREFIX "") - elseif ("${swig_lowercase_language}" STREQUAL "java") + if (swig_lowercase_language STREQUAL "octave") + set_target_properties(${name} PROPERTIES PREFIX "") + set_target_properties(${name} PROPERTIES SUFFIX ".oct") + elseif (swig_lowercase_language STREQUAL "go") + set_target_properties(${name} PROPERTIES PREFIX "") + elseif (swig_lowercase_language STREQUAL "java") + # In java you want: + # System.loadLibrary("LIBRARY"); + # then JNI will look for a library whose name is platform dependent, namely + # MacOS : libLIBRARY.jnilib + # Windows: LIBRARY.dll + # Linux : libLIBRARY.so if (APPLE) - # In java you want: - # System.loadLibrary("LIBRARY"); - # then JNI will look for a library whose name is platform dependent, namely - # MacOS : libLIBRARY.jnilib - # Windows: LIBRARY.dll - # Linux : libLIBRARY.so - set_target_properties (${SWIG_MODULE_${name}_REAL_NAME} PROPERTIES SUFFIX ".jnilib") - endif () - elseif ("${swig_lowercase_language}" STREQUAL "lua") - if("${_SAM_TYPE}" STREQUAL "MODULE") - set_target_properties(${SWIG_MODULE_${name}_REAL_NAME} PROPERTIES PREFIX "") + set_target_properties (${name} PROPERTIES SUFFIX ".jnilib") + endif() + if ((WIN32 AND MINGW) OR CYGWIN OR CMAKE_SYSTEM_NAME STREQUAL MSYS) + set_target_properties(${name} PROPERTIES PREFIX "") + endif() + elseif (swig_lowercase_language STREQUAL "lua") + if(_SAM_TYPE STREQUAL "MODULE") + set_target_properties(${name} PROPERTIES PREFIX "") + endif() + elseif (swig_lowercase_language STREQUAL "python") + if (SWIG_MODULE_${name}_NOPROXY) + set_target_properties(${name} PROPERTIES PREFIX "") + else() + # swig will produce a module.py containing an 'import _modulename' statement, + # which implies having a corresponding _modulename.so (*NIX), _modulename.pyd (Win32), + # unless the -noproxy flag is used + set_target_properties(${name} PROPERTIES PREFIX "_") endif() - elseif ("${swig_lowercase_language}" STREQUAL "python") - # this is only needed for the python case where a _modulename.so is generated - set_target_properties(${SWIG_MODULE_${name}_REAL_NAME} PROPERTIES PREFIX "") # Python extension modules on Windows must have the extension ".pyd" # instead of ".dll" as of Python 2.5. Older python versions do support # this suffix. @@ -363,34 +611,68 @@ macro(SWIG_ADD_LIBRARY name) # .pyd is now the only filename extension that will be searched for. # </quote> if(WIN32 AND NOT CYGWIN) - set_target_properties(${SWIG_MODULE_${name}_REAL_NAME} PROPERTIES SUFFIX ".pyd") + set_target_properties(${name} PROPERTIES SUFFIX ".pyd") endif() - elseif ("${swig_lowercase_language}" STREQUAL "r") - set_target_properties(${SWIG_MODULE_${name}_REAL_NAME} PROPERTIES PREFIX "") - elseif ("${swig_lowercase_language}" STREQUAL "ruby") + elseif (swig_lowercase_language STREQUAL "r") + set_target_properties(${name} PROPERTIES PREFIX "") + elseif (swig_lowercase_language STREQUAL "ruby") # In ruby you want: # require 'LIBRARY' # then ruby will look for a library whose name is platform dependent, namely # MacOS : LIBRARY.bundle # Windows: LIBRARY.dll # Linux : LIBRARY.so - set_target_properties (${SWIG_MODULE_${name}_REAL_NAME} PROPERTIES PREFIX "") + set_target_properties (${name} PROPERTIES PREFIX "") + if (APPLE) + set_target_properties (${name} PROPERTIES SUFFIX ".bundle") + endif () + elseif (swig_lowercase_language STREQUAL "perl") + # assume empty prefix because we expect the module to be dynamically loaded + set_target_properties (${name} PROPERTIES PREFIX "") if (APPLE) - set_target_properties (${SWIG_MODULE_${name}_REAL_NAME} PROPERTIES SUFFIX ".bundle") + set_target_properties (${name} PROPERTIES SUFFIX ".dylib") endif () else() # assume empty prefix because we expect the module to be dynamically loaded - set_target_properties (${SWIG_MODULE_${name}_REAL_NAME} PROPERTIES PREFIX "") + set_target_properties (${name} PROPERTIES PREFIX "") endif () -endmacro() + + # target property SWIG_SUPPORT_FILES_DIRECTORY specify output directory of support files + set_property (TARGET ${name} PROPERTY SWIG_SUPPORT_FILES_DIRECTORY "${outputdir}") + # target property SWIG_SUPPORT_FILES lists principal proxy support files + if (NOT SWIG_MODULE_${name}_NOPROXY) + string(TOUPPER "${_SAM_LANGUAGE}" swig_uppercase_language) + set(swig_all_support_files) + foreach (swig_it IN LISTS SWIG_${swig_uppercase_language}_EXTRA_FILE_EXTENSIONS) + set (swig_support_files ${swig_generated_sources}) + list (FILTER swig_support_files INCLUDE REGEX ".*${swig_it}$") + list(APPEND swig_all_support_files ${swig_support_files}) + endforeach() + if (swig_all_support_files) + list(REMOVE_DUPLICATES swig_all_support_files) + endif() + set_property (TARGET ${name} PROPERTY SWIG_SUPPORT_FILES ${swig_all_support_files}) + endif() + + # to ensure legacy behavior, export some variables + set (SWIG_MODULE_${name}_LANGUAGE "${SWIG_MODULE_${name}_LANGUAGE}" PARENT_SCOPE) + set (SWIG_MODULE_${name}_SWIG_LANGUAGE_FLAG "${SWIG_MODULE_${name}_SWIG_LANGUAGE_FLAG}" PARENT_SCOPE) + set (SWIG_MODULE_${name}_REAL_NAME "${name}" PARENT_SCOPE) + set (SWIG_MODULE_${name}_NOPROXY "${SWIG_MODULE_${name}_NOPROXY}" PARENT_SCOPE) + set (SWIG_MODULE_${name}_EXTRA_FLAGS "${SWIG_MODULE_${name}_EXTRA_FLAGS}" PARENT_SCOPE) + # the last one is a bit crazy but it is documented, so... + # NOTA: works as expected if only ONE input file is specified + set (swig_generated_file_fullname "${swig_generated_file_fullname}" PARENT_SCOPE) +endfunction() # # Like TARGET_LINK_LIBRARIES but for swig modules # -macro(SWIG_LINK_LIBRARIES name) +function(SWIG_LINK_LIBRARIES name) + message(DEPRECATION "SWIG_LINK_LIBRARIES is deprecated. Use TARGET_LINK_LIBRARIES instead.") if(SWIG_MODULE_${name}_REAL_NAME) - target_link_libraries(${SWIG_MODULE_${name}_REAL_NAME} ${ARGN}) + target_link_libraries(${name} ${ARGN}) else() message(SEND_ERROR "Cannot find Swig library \"${name}\".") endif() -endmacro() +endfunction() diff --git a/Modules/WriteCompilerDetectionHeader.cmake b/Modules/WriteCompilerDetectionHeader.cmake index e7f9912..3718e9d 100644 --- a/Modules/WriteCompilerDetectionHeader.cmake +++ b/Modules/WriteCompilerDetectionHeader.cmake @@ -17,6 +17,7 @@ # [OUTPUT_FILES_VAR <output_files_var> OUTPUT_DIR <output_dir>] # COMPILERS <compiler> [...] # FEATURES <feature> [...] +# [BARE_FEATURES <feature> [...]] # [VERSION <version>] # [PROLOG <prolog>] # [EPILOG <epilog>] @@ -83,10 +84,14 @@ # See the :manual:`cmake-compile-features(7)` manual for information on # compile features. # +# ``BARE_FEATURES`` will define the compatibility macros with the name used in +# newer versions of the language standard, so the code can use the new feature +# name unconditionally. +# # ``ALLOW_UNKNOWN_COMPILERS`` and ``ALLOW_UNKNOWN_COMPILER_VERSIONS`` cause # the module to generate conditions that treat unknown compilers as simply # lacking all features. Without these options the default behavior is to -# generate a ``#error`` for unknown compilers. +# generate a ``#error`` for unknown compilers and versions. # # Feature Test Macros # =================== @@ -148,20 +153,24 @@ # ``ClimbingStats_CONSTEXPR`` macro will expand to ``constexpr`` # if ``cxx_constexpr`` is supported. # -# The following features generate corresponding symbol defines: +# If ``BARE_FEATURES cxx_final`` was given as argument the ``final`` keyword +# will be defined for old compilers, too. +# +# The following features generate corresponding symbol defines and if they +# are available as ``BARE_FEATURES``: # -# ========================== =================================== ================= -# Feature Define Symbol -# ========================== =================================== ================= -# ``c_restrict`` ``<PREFIX>_RESTRICT`` ``restrict`` -# ``cxx_constexpr`` ``<PREFIX>_CONSTEXPR`` ``constexpr`` +# ========================== =================================== ================= ====== +# Feature Define Symbol bare +# ========================== =================================== ================= ====== +# ``c_restrict`` ``<PREFIX>_RESTRICT`` ``restrict`` yes +# ``cxx_constexpr`` ``<PREFIX>_CONSTEXPR`` ``constexpr`` yes # ``cxx_deleted_functions`` ``<PREFIX>_DELETED_FUNCTION`` ``= delete`` # ``cxx_extern_templates`` ``<PREFIX>_EXTERN_TEMPLATE`` ``extern`` -# ``cxx_final`` ``<PREFIX>_FINAL`` ``final`` -# ``cxx_noexcept`` ``<PREFIX>_NOEXCEPT`` ``noexcept`` +# ``cxx_final`` ``<PREFIX>_FINAL`` ``final`` yes +# ``cxx_noexcept`` ``<PREFIX>_NOEXCEPT`` ``noexcept`` yes # ``cxx_noexcept`` ``<PREFIX>_NOEXCEPT_EXPR(X)`` ``noexcept(X)`` -# ``cxx_override`` ``<PREFIX>_OVERRIDE`` ``override`` -# ========================== =================================== ================= +# ``cxx_override`` ``<PREFIX>_OVERRIDE`` ``override`` yes +# ========================== =================================== ================= ====== # # Compatibility Implementation Macros # =================================== @@ -195,18 +204,18 @@ # decorator or a compiler-specific decorator such as ``__alignof__`` # used by GNU compilers. # -# ============================= ================================ ===================== -# Feature Define Symbol -# ============================= ================================ ===================== +# ============================= ================================ ===================== ====== +# Feature Define Symbol bare +# ============================= ================================ ===================== ====== # ``cxx_alignas`` ``<PREFIX>_ALIGNAS`` ``alignas`` # ``cxx_alignof`` ``<PREFIX>_ALIGNOF`` ``alignof`` -# ``cxx_nullptr`` ``<PREFIX>_NULLPTR`` ``nullptr`` +# ``cxx_nullptr`` ``<PREFIX>_NULLPTR`` ``nullptr`` yes # ``cxx_static_assert`` ``<PREFIX>_STATIC_ASSERT`` ``static_assert`` # ``cxx_static_assert`` ``<PREFIX>_STATIC_ASSERT_MSG`` ``static_assert`` # ``cxx_attribute_deprecated`` ``<PREFIX>_DEPRECATED`` ``[[deprecated]]`` # ``cxx_attribute_deprecated`` ``<PREFIX>_DEPRECATED_MSG`` ``[[deprecated]]`` # ``cxx_thread_local`` ``<PREFIX>_THREAD_LOCAL`` ``thread_local`` -# ============================= ================================ ===================== +# ============================= ================================ ===================== ====== # # A use-case which arises with such deprecation macros is the deprecation # of an entire library. In that case, all public API in the library may @@ -252,6 +261,37 @@ macro(_simpledefine FEATURE_NAME FEATURE_TESTNAME FEATURE_STRING FEATURE_DEFAULT endif() endmacro() +macro(_simplebaredefine FEATURE_NAME FEATURE_STRING FEATURE_DEFAULT_STRING) + if (feature STREQUAL "${FEATURE_NAME}") + string(APPEND file_content " +# if !(defined(${def_name}) && ${def_name}) +# define ${FEATURE_STRING} ${FEATURE_DEFAULT_STRING} +# endif +\n") + endif() +endmacro() + +function(_check_feature_lists C_FEATURE_VAR CXX_FEATURE_VAR) + foreach(feature ${ARGN}) + if (feature MATCHES "^c_std_") + # ignored + elseif (feature MATCHES "^cxx_std_") + # ignored + elseif (feature MATCHES "^cxx_") + list(APPEND _langs CXX) + list(APPEND ${CXX_FEATURE_VAR} ${feature}) + elseif (feature MATCHES "^c_") + list(APPEND _langs C) + list(APPEND ${C_FEATURE_VAR} ${feature}) + else() + message(FATAL_ERROR "Unsupported feature ${feature}.") + endif() + endforeach() + set(${C_FEATURE_VAR} ${${C_FEATURE_VAR}} PARENT_SCOPE) + set(${CXX_FEATURE_VAR} ${${CXX_FEATURE_VAR}} PARENT_SCOPE) + set(_langs ${_langs} PARENT_SCOPE) +endfunction() + function(write_compiler_detection_header file_keyword file_arg prefix_keyword prefix_arg @@ -264,13 +304,13 @@ function(write_compiler_detection_header endif() set(options ALLOW_UNKNOWN_COMPILERS ALLOW_UNKNOWN_COMPILER_VERSIONS) set(oneValueArgs VERSION EPILOG PROLOG OUTPUT_FILES_VAR OUTPUT_DIR) - set(multiValueArgs COMPILERS FEATURES) + set(multiValueArgs COMPILERS FEATURES BARE_FEATURES) cmake_parse_arguments(_WCD "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) if (NOT _WCD_COMPILERS) message(FATAL_ERROR "Invalid arguments. write_compiler_detection_header requires at least one compiler.") endif() - if (NOT _WCD_FEATURES) + if (NOT _WCD_FEATURES AND NOT _WCD_BARE_FEATURES) message(FATAL_ERROR "Invalid arguments. write_compiler_detection_header requires at least one feature.") endif() @@ -377,21 +417,8 @@ function(write_compiler_detection_header )\n") endif() - foreach(feature ${_WCD_FEATURES}) - if (feature MATCHES "^c_std_") - # ignored - elseif (feature MATCHES "^cxx_std_") - # ignored - elseif (feature MATCHES "^cxx_") - list(APPEND _langs CXX) - list(APPEND CXX_features ${feature}) - elseif (feature MATCHES "^c_") - list(APPEND _langs C) - list(APPEND C_features ${feature}) - else() - message(FATAL_ERROR "Unsupported feature ${feature}.") - endif() - endforeach() + _check_feature_lists(C_features CXX_features ${_WCD_FEATURES}) + _check_feature_lists(C_bare_features CXX_bare_features ${_WCD_BARE_FEATURES}) list(REMOVE_DUPLICATES _langs) if(_WCD_OUTPUT_FILES_VAR) @@ -557,7 +584,18 @@ template<> struct ${prefix_arg}StaticAssert<true>{}; # endif \n") endif() - _simpledefine(cxx_nullptr NULLPTR nullptr 0) + if (feature STREQUAL cxx_nullptr) + set(def_value "${prefix_arg}_NULLPTR") + string(APPEND file_content " +# if defined(${def_name}) && ${def_name} +# define ${def_value} nullptr +# elif ${prefix_arg}_COMPILER_IS_GNU +# define ${def_value} __null +# else +# define ${def_value} 0 +# endif +\n") + endif() if (feature STREQUAL cxx_thread_local) set(def_value "${prefix_arg}_THREAD_LOCAL") string(APPEND file_content " @@ -595,6 +633,29 @@ template<> struct ${prefix_arg}StaticAssert<true>{}; endif() endforeach() + foreach(feature ${${_lang}_bare_features}) + string(TOUPPER ${feature} feature_upper) + set(feature_PP "COMPILER_${feature_upper}") + set(def_name ${prefix_arg}_${feature_PP}) + _simplebaredefine(c_restrict restrict "") + _simplebaredefine(cxx_constexpr constexpr "") + _simplebaredefine(cxx_final final "") + _simplebaredefine(cxx_override override "") + if (feature STREQUAL cxx_nullptr) + set(def_value "nullptr") + string(APPEND file_content " +# if !(defined(${def_name}) && ${def_name}) +# if ${prefix_arg}_COMPILER_IS_GNU +# define ${def_value} __null +# else +# define ${def_value} 0 +# endif +# endif +\n") + endif() + _simplebaredefine(cxx_noexcept noexcept "") + endforeach() + string(APPEND file_content "#endif\n") endforeach() diff --git a/Modules/readme.txt b/Modules/readme.txt index 1e0c13b..a629478 100644 --- a/Modules/readme.txt +++ b/Modules/readme.txt @@ -1,4 +1,4 @@ See the "Find Modules" section of the cmake-developer(7) manual page. For more information about how to contribute modules to CMake, see this page: -https://cmake.org/Wiki/CMake:Module_Maintainers +https://gitlab.kitware.com/cmake/community/wikis/doc/cmake/dev/Module-Maintainers |