diff options
204 files changed, 2491 insertions, 1697 deletions
diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index 7e71111..7983be1 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -27,14 +27,15 @@ To contribute patches: #. Run `Utilities/SetupForDevelopment.sh`_ for local git configuration. #. See `Building CMake`_ for building CMake locally. #. See the `CMake Source Code Guide`_ for coding guidelines. -#. Base all new work on the upstream ``master`` branch. +#. Create a topic branch named suitably for your work. + Base all new work on the upstream ``master`` branch. Base work on the upstream ``release`` branch only if it fixes a regression or bug in a feature new to that release. If in doubt, prefer ``master``. Reviewers may simply ask for a rebase if deemed appropriate in particular cases. #. Create commits making incremental, distinct, logically complete changes with appropriate `commit messages`_. -#. Push a topic branch to a personal repository fork on GitLab. +#. Push the topic branch to a personal repository fork on GitLab. #. Create a GitLab Merge Request targeting the upstream ``master`` branch (even if the change is intended for merge to the ``release`` branch). Check the box labelled "Allow commits from members who can merge to the diff --git a/Help/cpack_gen/archive.rst b/Help/cpack_gen/archive.rst index b288aad..d455f4b 100644 --- a/Help/cpack_gen/archive.rst +++ b/Help/cpack_gen/archive.rst @@ -9,6 +9,7 @@ different formats: - TGZ (.tar.gz) - TXZ (.tar.xz) - TZ (.tar.Z) + - TZST (.tar.zst) - ZIP (.zip) Variables specific to CPack Archive generator diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst index 739e4b5..2d473d8 100644 --- a/Help/manual/cmake-variables.7.rst +++ b/Help/manual/cmake-variables.7.rst @@ -112,6 +112,7 @@ Variables that Provide Information /variable/CMAKE_VS_PLATFORM_NAME_DEFAULT /variable/CMAKE_VS_PLATFORM_TOOLSET /variable/CMAKE_VS_PLATFORM_TOOLSET_CUDA + /variable/CMAKE_VS_PLATFORM_TOOLSET_CUDA_CUSTOM_DIR /variable/CMAKE_VS_PLATFORM_TOOLSET_HOST_ARCHITECTURE /variable/CMAKE_VS_PLATFORM_TOOLSET_VERSION /variable/CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION diff --git a/Help/manual/cmake.1.rst b/Help/manual/cmake.1.rst index 26ef904..0645e41 100644 --- a/Help/manual/cmake.1.rst +++ b/Help/manual/cmake.1.rst @@ -462,7 +462,7 @@ Available commands are: but the files or directories it point to. ``copy_directory <dir>... <destination>`` - Copy directories to ``<destination>`` directory. + Copy content of ``<dir>...`` directories to ``<destination>`` directory. If ``<destination>`` directory does not exist it will be created. ``copy_directory`` does follow symlinks. diff --git a/Help/manual/cpack.1.rst b/Help/manual/cpack.1.rst index 10f617e..f82c466 100644 --- a/Help/manual/cpack.1.rst +++ b/Help/manual/cpack.1.rst @@ -48,9 +48,11 @@ Options the :variable:`CPACK_GENERATOR` variable determines the default set of generators that will be used. -``-C <Configuration>`` - Specify the project configuration to be packaged (e.g. ``Debug``, - ``Release``, etc.). When the CMake project uses a multi-configuration +``-C <configs>`` + Specify the project configuration(s) to be packaged (e.g. ``Debug``, + ``Release``, etc.), where ``<configs>`` is a + :ref:`semicolon-separated list <CMake Language Lists>`. + When the CMake project uses a multi-configuration generator such as Xcode or Visual Studio, this option is needed to tell ``cpack`` which built executables to include in the package. diff --git a/Help/release/dev/FindPkgConfig-module-name.rst b/Help/release/dev/FindPkgConfig-module-name.rst new file mode 100644 index 0000000..9f1cd36 --- /dev/null +++ b/Help/release/dev/FindPkgConfig-module-name.rst @@ -0,0 +1,6 @@ +FindPkgConfig-module-name +------------------------- + +* The :module:`FindPkgConfig` module :command:`pkg_search_module` macro + now defines a ``<prefix>_MODULE_NAME`` result variable containing the + first matching module name. diff --git a/Help/release/dev/FindPython-specify_artifacts.rst b/Help/release/dev/FindPython-specify_artifacts.rst new file mode 100644 index 0000000..7032f8b --- /dev/null +++ b/Help/release/dev/FindPython-specify_artifacts.rst @@ -0,0 +1,5 @@ +FindPython-specify_artifacts +---------------------------- + +* Modules :module:`FindPython3`, :module:`FindPython2` and :module:`FindPython` + gain the capability to specify directly artifacts. diff --git a/Help/release/dev/cpack-install-multiple-configurations.rst b/Help/release/dev/cpack-install-multiple-configurations.rst new file mode 100644 index 0000000..d1692dc --- /dev/null +++ b/Help/release/dev/cpack-install-multiple-configurations.rst @@ -0,0 +1,5 @@ +cpack-install-multiple-configurations +------------------------------------- + +* CPack learned :variable:`CPACK_INSTALL_CMAKE_CONFIGURATIONS` to control + what configurations going to be packaged for multi-configuration generators. diff --git a/Help/release/dev/cpack-zstd.rst b/Help/release/dev/cpack-zstd.rst new file mode 100644 index 0000000..e1e64a2 --- /dev/null +++ b/Help/release/dev/cpack-zstd.rst @@ -0,0 +1,5 @@ +cpack-zstd +---------- + +* The :cpack_gen:`CPack Archive Generator` learned to generate `.tar.zst` + packages with Zstandard compression. diff --git a/Help/release/dev/gtest-1.8.1.rst b/Help/release/dev/gtest-1.8.1.rst new file mode 100644 index 0000000..2e48da4 --- /dev/null +++ b/Help/release/dev/gtest-1.8.1.rst @@ -0,0 +1,5 @@ +gtest-1.8.1 +----------- + +* The :module:`FindGTest` module has been updated to recognize + MSVC build trees generated by GTest 1.8.1. diff --git a/Help/variable/CMAKE_GENERATOR_TOOLSET.rst b/Help/variable/CMAKE_GENERATOR_TOOLSET.rst index a01a8b7..222824f 100644 --- a/Help/variable/CMAKE_GENERATOR_TOOLSET.rst +++ b/Help/variable/CMAKE_GENERATOR_TOOLSET.rst @@ -40,10 +40,13 @@ The ``key=value`` pairs form a comma-separated list of options to specify generator-specific details of the toolset selection. Supported pairs are: -``cuda=<version>`` - Specify the CUDA toolkit version to use. Supported by VS 2010 - and above with the CUDA toolkit VS integration installed. - See the :variable:`CMAKE_VS_PLATFORM_TOOLSET_CUDA` variable. +``cuda=<version>|<path>`` + Specify the CUDA toolkit version to use or the path to a + standalone CUDA toolkit directory. Supported by VS 2010 + and above. The version can only be used with the CUDA + toolkit VS integration globally installed. + See the :variable:`CMAKE_VS_PLATFORM_TOOLSET_CUDA` and + :variable:`CMAKE_VS_PLATFORM_TOOLSET_CUDA_CUSTOM_DIR` variables. ``host=<arch>`` Specify the host tools architecture as ``x64`` or ``x86``. diff --git a/Help/variable/CMAKE_VS_PLATFORM_TOOLSET_CUDA.rst b/Help/variable/CMAKE_VS_PLATFORM_TOOLSET_CUDA.rst index 1604a76..67b7f74 100644 --- a/Help/variable/CMAKE_VS_PLATFORM_TOOLSET_CUDA.rst +++ b/Help/variable/CMAKE_VS_PLATFORM_TOOLSET_CUDA.rst @@ -6,7 +6,9 @@ NVIDIA CUDA Toolkit version whose Visual Studio toolset to use. The :ref:`Visual Studio Generators` for VS 2010 and above support using a CUDA toolset provided by a CUDA Toolkit. The toolset version number may be specified by a field in :variable:`CMAKE_GENERATOR_TOOLSET` of -the form ``cuda=8.0``. If none is specified CMake will choose a default -version. CMake provides the selected CUDA toolset version in this variable. +the form ``cuda=8.0``. Or it is automatically detected if a path to +a standalone CUDA directory is specified in the form ``cuda=C:\path\to\cuda``. +If none is specified CMake will choose a default version. +CMake provides the selected CUDA toolset version in this variable. The value may be empty if no CUDA Toolkit with Visual Studio integration is installed. diff --git a/Help/variable/CMAKE_VS_PLATFORM_TOOLSET_CUDA_CUSTOM_DIR.rst b/Help/variable/CMAKE_VS_PLATFORM_TOOLSET_CUDA_CUSTOM_DIR.rst new file mode 100644 index 0000000..060648a --- /dev/null +++ b/Help/variable/CMAKE_VS_PLATFORM_TOOLSET_CUDA_CUSTOM_DIR.rst @@ -0,0 +1,16 @@ +CMAKE_VS_PLATFORM_TOOLSET_CUDA_CUSTOM_DIR +----------------------------------------- + +Path to standalone NVIDIA CUDA Toolkit (eg. extracted from installer). + +The :ref:`Visual Studio Generators` for VS 2010 and above support using +a standalone (non-installed) NVIDIA CUDA toolkit. The path +may be specified by a field in :variable:`CMAKE_GENERATOR_TOOLSET` of +the form ``cuda=C:\path\to\cuda``. The given directory must at least +contain a folder ``.\nvcc`` and must provide Visual Studio integration +files in path ``.\CUDAVisualStudioIntegration\extras\ +visual_studio_integration\MSBuildExtensions\``. One can create a standalone +CUDA toolkit directory by either opening a installer with 7zip or +copying the files that are extracted by the running installer. +The value may be empty if no path to a standalone CUDA Toolkit was +specified. diff --git a/Modules/CMakeDetermineCompilerId.cmake b/Modules/CMakeDetermineCompilerId.cmake index 0fcbbb7..40658ea 100644 --- a/Modules/CMakeDetermineCompilerId.cmake +++ b/Modules/CMakeDetermineCompilerId.cmake @@ -347,8 +347,14 @@ Id flags: ${testflags} ${CMAKE_${lang}_COMPILER_ID_FLAGS_ALWAYS} set(cuda_tools "CUDA ${CMAKE_VS_PLATFORM_TOOLSET_CUDA}") set(id_compile "CudaCompile") set(id_PostBuildEvent_Command [[echo CMAKE_CUDA_COMPILER=$(CudaToolkitBinDir)\nvcc.exe]]) - string(CONCAT id_Import_props [[<Import Project="$(VCTargetsPath)\BuildCustomizations\]] "${cuda_tools}" [[.props" />]]) - string(CONCAT id_Import_targets [[<Import Project="$(VCTargetsPath)\BuildCustomizations\]] "${cuda_tools}" [[.targets" />]]) + if(CMAKE_VS_PLATFORM_TOOLSET_CUDA_CUSTOM_DIR) + set(id_CudaToolkitCustomDir "<CudaToolkitCustomDir>${CMAKE_VS_PLATFORM_TOOLSET_CUDA_CUSTOM_DIR}nvcc</CudaToolkitCustomDir>") + string(CONCAT id_Import_props "<Import Project=\"${CMAKE_VS_PLATFORM_TOOLSET_CUDA_CUSTOM_DIR}\\CUDAVisualStudioIntegration\\extras\\visual_studio_integration\\MSBuildExtensions\\${cuda_tools}.props\" />") + string(CONCAT id_Import_targets "<Import Project=\"${CMAKE_VS_PLATFORM_TOOLSET_CUDA_CUSTOM_DIR}\\CUDAVisualStudioIntegration\\extras\\visual_studio_integration\\MSBuildExtensions\\${cuda_tools}.targets\" />") + else() + string(CONCAT id_Import_props [[<Import Project="$(VCTargetsPath)\BuildCustomizations\]] "${cuda_tools}" [[.props" />]]) + string(CONCAT id_Import_targets [[<Import Project="$(VCTargetsPath)\BuildCustomizations\]] "${cuda_tools}" [[.targets" />]]) + endif() if(CMAKE_VS_PLATFORM_NAME STREQUAL x64) set(id_ItemDefinitionGroup_entry "<CudaCompile><TargetMachinePlatform>64</TargetMachinePlatform></CudaCompile>") endif() diff --git a/Modules/CMakeDetermineSwiftCompiler.cmake b/Modules/CMakeDetermineSwiftCompiler.cmake index 2fcf7b0..9aafe48 100644 --- a/Modules/CMakeDetermineSwiftCompiler.cmake +++ b/Modules/CMakeDetermineSwiftCompiler.cmake @@ -53,7 +53,7 @@ if(NOT CMAKE_Swift_COMPILER_ID_RUN) list(APPEND CMAKE_Swift_COMPILER_ID_MATCH_VENDORS Apple) set(CMAKE_Swift_COMPILER_ID_MATCH_VENDOR_REGEX_Apple "com.apple.xcode.tools.swift.compiler") - set(CMAKE_Swift_COMPILER_ID_TOOL_MATCH_REGEX "\nCompileSwiftSources[^\n]*(\n[ \t]+[^\n]*)*\n[ \t]+([^ \t\r\n]+)[^\r\n]* -c[^\r\n]*CompilerIdSwift/CompilerId/main.swift") + set(CMAKE_Swift_COMPILER_ID_TOOL_MATCH_REGEX "\nCompileSwift[^\n]*(\n[ \t]+[^\n]*)*\n[ \t]+([^ \t\r\n]+)[^\r\n]* -c[^\r\n]*CompilerIdSwift/CompilerId/main.swift") set(CMAKE_Swift_COMPILER_ID_TOOL_MATCH_INDEX 2) endif() diff --git a/Modules/CMakeFindBinUtils.cmake b/Modules/CMakeFindBinUtils.cmake index 773ee53..01f9dae 100644 --- a/Modules/CMakeFindBinUtils.cmake +++ b/Modules/CMakeFindBinUtils.cmake @@ -69,7 +69,12 @@ if(("x${CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_SIMULATE_ID}" STREQUAL "xMSVC" AND OR (CMAKE_GENERATOR MATCHES "Visual Studio" AND NOT CMAKE_VS_PLATFORM_NAME STREQUAL "Tegra-Android")) - find_program(CMAKE_LINKER NAMES link HINTS ${_CMAKE_TOOLCHAIN_LOCATION}) + if("x${CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_ID}" STREQUAL "xClang") + find_program(CMAKE_NM NAMES ${_CMAKE_TOOLCHAIN_PREFIX}nm llvm-nm HINTS ${_CMAKE_TOOLCHAIN_LOCATION}) + set(_CMAKE_ADDITIONAL_LINKER_NAMES "lld-link") + endif() + + find_program(CMAKE_LINKER NAMES ${_CMAKE_ADDITIONAL_LINKER_NAMES} link HINTS ${_CMAKE_TOOLCHAIN_LOCATION}) find_program(CMAKE_MT NAMES mt HINTS ${_CMAKE_TOOLCHAIN_LOCATION}) list(APPEND _CMAKE_TOOL_VARS LINKER MT) @@ -115,6 +120,17 @@ else() list(APPEND _CMAKE_TOOL_VARS AR RANLIB STRIP LINKER NM OBJDUMP OBJCOPY READELF DLLTOOL ADDR2LINE) + + unset(_CMAKE_ADDITIONAL_AR_NAMES) + unset(_CMAKE_ADDITIONAL_RANLIB_NAMES) + unset(_CMAKE_ADDITIONAL_STRIP_NAMES) + unset(_CMAKE_ADDITIONAL_LINKER_NAMES) + unset(_CMAKE_ADDITIONAL_NM_NAMES) + unset(_CMAKE_ADDITIONAL_OBJDUMP_NAMES) + unset(_CMAKE_ADDITIONAL_OBJCOPY_NAMES) + unset(_CMAKE_ADDITIONAL_READELF_NAMES) + unset(_CMAKE_ADDITIONAL_DLLTOOL_NAMES) + unset(_CMAKE_ADDITIONAL_ADDR2LINE_NAMES) endif() if(CMAKE_PLATFORM_HAS_INSTALLNAME) diff --git a/Modules/CPack.cmake b/Modules/CPack.cmake index 8a6a712..1809846 100644 --- a/Modules/CPack.cmake +++ b/Modules/CPack.cmake @@ -301,6 +301,13 @@ The following variables are for advanced uses of CPack: project. Defaults to the value of :variable:`CMAKE_GENERATOR`. Few users will want to change this setting. +.. variable:: CPACK_INSTALL_CMAKE_CONFIGURATIONS + + Specify the project configurations to be packaged (e.g. ``Debug``, ``Release``, + etc.). When the CMake project uses a multi-configuration generator such as Xcode + or Visual Studio, this option can be used to specify what configurations + to include in the package. + .. variable:: CPACK_INSTALL_CMAKE_PROJECTS List of four values that specify what project to install. The four values diff --git a/Modules/Compiler/Intel-Fortran.cmake b/Modules/Compiler/Intel-Fortran.cmake index 5275ddf..156b533 100644 --- a/Modules/Compiler/Intel-Fortran.cmake +++ b/Modules/Compiler/Intel-Fortran.cmake @@ -8,6 +8,8 @@ set(CMAKE_Fortran_MODDIR_FLAG "-module ") set(CMAKE_Fortran_FORMAT_FIXED_FLAG "-fixed") set(CMAKE_Fortran_FORMAT_FREE_FLAG "-free") +set(CMAKE_Fortran_COMPILE_WITH_DEFINES 1) + set(CMAKE_Fortran_CREATE_PREPROCESSED_SOURCE "<CMAKE_Fortran_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>") set(CMAKE_Fortran_CREATE_ASSEMBLY_SOURCE "<CMAKE_Fortran_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -S <SOURCE> -o <ASSEMBLY_SOURCE>") diff --git a/Modules/CompilerId/VS-10.vcxproj.in b/Modules/CompilerId/VS-10.vcxproj.in index 32c4ffc..d742274 100644 --- a/Modules/CompilerId/VS-10.vcxproj.in +++ b/Modules/CompilerId/VS-10.vcxproj.in @@ -14,6 +14,7 @@ @id_system_version@ @id_WindowsTargetPlatformVersion@ @id_WindowsSDKDesktopARMSupport@ + @id_CudaToolkitCustomDir@ </PropertyGroup> @id_toolset_version_props@ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> diff --git a/Modules/FindBoost.cmake b/Modules/FindBoost.cmake index 1f9477b..744d2c7 100644 --- a/Modules/FindBoost.cmake +++ b/Modules/FindBoost.cmake @@ -266,6 +266,21 @@ function(_boost_get_existing_target component target_var) foreach(prefix Boost boost) foreach(name IN LISTS names) if(TARGET "${prefix}::${name}") + # The target may be an INTERFACE library that wraps around a single other + # target for compatibility. Unwrap this layer so we can extract real info. + if("${name}" MATCHES "^(python|numpy|mpi_python)([1-9])([0-9])$") + set(name_nv "${CMAKE_MATCH_1}") + if(TARGET "${prefix}::${name_nv}") + get_property(type TARGET "${prefix}::${name}" PROPERTY TYPE) + if(type STREQUAL "INTERFACE_LIBRARY") + get_property(lib TARGET "${prefix}::${name}" PROPERTY INTERFACE_LINK_LIBRARIES) + if("${lib}" STREQUAL "${prefix}::${name_nv}") + set(${target_var} "${prefix}::${name_nv}" PARENT_SCOPE) + return() + endif() + endif() + endif() + endif() set(${target_var} "${prefix}::${name}" PARENT_SCOPE) return() endif() @@ -330,7 +345,7 @@ function(_boost_set_legacy_variables_from_config) _boost_get_existing_target(${comp} target) if(NOT target) if(Boost_DEBUG OR Boost_VERBOSE) - message(WARNING "Could not find imported target for required component '${comp}'. Standard variables for this component might be missing. Refer to the documentation of your Boost installation for help on variables to use.") + message(WARNING "Could not find imported target for required component '${comp}'. Legacy variables for this component might be missing. Refer to the documentation of your Boost installation for help on variables to use.") endif() continue() endif() @@ -338,14 +353,20 @@ function(_boost_set_legacy_variables_from_config) _boost_set_if_unset(Boost_${uppercomp}_LIBRARY "${target}") _boost_set_if_unset(Boost_${uppercomp}_LIBRARIES "${target}") # Very old legacy variable list(APPEND libraries "${target}") - foreach(cfg RELEASE DEBUG) - get_target_property(lib ${target} IMPORTED_LOCATION_${cfg}) - if(lib) - get_filename_component(lib_dir "${lib}" DIRECTORY) - list(APPEND library_dirs ${lib_dir}) - _boost_set_cache_if_unset(Boost_${uppercomp}_LIBRARY_${cfg} "${lib}") - endif() - endforeach() + get_property(type TARGET "${target}" PROPERTY TYPE) + if(NOT type STREQUAL "INTERFACE_LIBRARY") + foreach(cfg RELEASE DEBUG) + get_target_property(lib ${target} IMPORTED_LOCATION_${cfg}) + if(lib) + get_filename_component(lib_dir "${lib}" DIRECTORY) + list(APPEND library_dirs ${lib_dir}) + _boost_set_cache_if_unset(Boost_${uppercomp}_LIBRARY_${cfg} "${lib}") + endif() + endforeach() + elseif(Boost_DEBUG OR Boost_VERBOSE) + # For projects using only the Boost::* targets this warning can be safely ignored. + message(WARNING "Imported target '${target}' for required component '${comp}' has no artifact. Legacy variables for this component might be missing. Refer to the documentation of your Boost installation for help on variables to use.") + endif() _boost_get_canonical_target_name("${comp}" canonical_target) if(NOT TARGET "${canonical_target}") add_library("${canonical_target}" INTERFACE IMPORTED) @@ -1105,23 +1126,21 @@ function(_Boost_COMPONENT_DEPENDENCIES component _ret) set(_Boost_TIMER_DEPENDENCIES chrono system) set(_Boost_WAVE_DEPENDENCIES filesystem serialization thread chrono date_time atomic) set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) - else() - if(NOT Boost_VERSION_STRING VERSION_LESS 1.70.0) - set(_Boost_CONTRACT_DEPENDENCIES thread chrono date_time) - set(_Boost_COROUTINE_DEPENDENCIES context) - set(_Boost_FIBER_DEPENDENCIES context) - set(_Boost_IOSTREAMS_DEPENDENCIES regex) - set(_Boost_LOG_DEPENDENCIES date_time log_setup 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_THREAD_DEPENDENCIES chrono date_time atomic) - set(_Boost_TIMER_DEPENDENCIES chrono system) - set(_Boost_WAVE_DEPENDENCIES filesystem serialization thread chrono date_time atomic) - set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) - endif() - if(NOT Boost_VERSION_STRING VERSION_LESS 1.71.0) + elseif(NOT Boost_VERSION_STRING VERSION_LESS 1.70.0) + set(_Boost_CONTRACT_DEPENDENCIES thread chrono date_time) + set(_Boost_COROUTINE_DEPENDENCIES context) + set(_Boost_FIBER_DEPENDENCIES context) + set(_Boost_IOSTREAMS_DEPENDENCIES regex) + set(_Boost_LOG_DEPENDENCIES date_time log_setup 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_THREAD_DEPENDENCIES chrono date_time atomic) + set(_Boost_TIMER_DEPENDENCIES chrono) + set(_Boost_WAVE_DEPENDENCIES filesystem serialization thread chrono date_time atomic) + set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) + if(NOT Boost_VERSION_STRING VERSION_LESS 1.72.0) message(WARNING "New Boost version may have incorrect or missing dependencies and imported targets") endif() endif() @@ -1393,7 +1412,7 @@ else() # _Boost_COMPONENT_HEADERS. See the instructions at the top of # _Boost_COMPONENT_DEPENDENCIES. set(_Boost_KNOWN_VERSIONS ${Boost_ADDITIONAL_VERSIONS} - "1.70.0" "1.70" "1.69.0" "1.69" + "1.71.0" "1.71" "1.70.0" "1.70" "1.69.0" "1.69" "1.68.0" "1.68" "1.67.0" "1.67" "1.66.0" "1.66" "1.65.1" "1.65.0" "1.65" "1.64.0" "1.64" "1.63.0" "1.63" "1.62.0" "1.62" "1.61.0" "1.61" "1.60.0" "1.60" "1.59.0" "1.59" "1.58.0" "1.58" "1.57.0" "1.57" "1.56.0" "1.56" "1.55.0" "1.55" diff --git a/Modules/FindGTest.cmake b/Modules/FindGTest.cmake index b0175fe..e015a98 100644 --- a/Modules/FindGTest.cmake +++ b/Modules/FindGTest.cmake @@ -160,6 +160,10 @@ if(MSVC) msvc/gtest-md/Release msvc/x64/Debug msvc/x64/Release + msvc/2010/gtest-md/Win32-Debug + msvc/2010/gtest-md/Win32-Release + msvc/2010/gtest-md/x64-Debug + msvc/2010/gtest-md/x64-Release ) elseif(GTEST_MSVC_SEARCH STREQUAL "MT") list(APPEND _gtest_libpath_suffixes @@ -167,6 +171,10 @@ if(MSVC) msvc/gtest/Release msvc/x64/Debug msvc/x64/Release + msvc/2010/gtest/Win32-Debug + msvc/2010/gtest/Win32-Release + msvc/2010/gtest/x64-Debug + msvc/2010/gtest/x64-Release ) endif() endif() diff --git a/Modules/FindPkgConfig.cmake b/Modules/FindPkgConfig.cmake index e05d5c8..4c9af91 100644 --- a/Modules/FindPkgConfig.cmake +++ b/Modules/FindPkgConfig.cmake @@ -363,6 +363,7 @@ macro(_pkg_check_modules_internal _is_required _is_silent _no_cmake_path _no_cma _pkgconfig_unset(${_prefix}_PREFIX) _pkgconfig_unset(${_prefix}_INCLUDEDIR) _pkgconfig_unset(${_prefix}_LIBDIR) + _pkgconfig_unset(${_prefix}_MODULE_NAME) _pkgconfig_unset(${_prefix}_LIBS) _pkgconfig_unset(${_prefix}_LIBS_L) _pkgconfig_unset(${_prefix}_LIBS_PATHS) @@ -480,6 +481,7 @@ macro(_pkg_check_modules_internal _is_required _is_silent _no_cmake_path _no_cma foreach (variable IN ITEMS PREFIX INCLUDEDIR LIBDIR) _pkgconfig_set("${_pkg_check_prefix}_${variable}" "${${_pkg_check_prefix}_${variable}}") endforeach () + _pkgconfig_set("${_pkg_check_prefix}_MODULE_NAME" "${_pkg_check_modules_pkg}") if (NOT ${_is_silent}) message(STATUS " Found ${_pkg_check_modules_pkg}, version ${_pkgconfig_VERSION}") @@ -664,6 +666,10 @@ endmacro() [IMPORTED_TARGET [GLOBAL]] <moduleSpec> [<moduleSpec>...]) + If a module is found, the ``<prefix>_MODULE_NAME`` variable will contain the + name of the matching module. This variable can be used if you need to run + :command:`pkg_get_variable`. + Example: .. code-block:: cmake @@ -688,6 +694,7 @@ macro(pkg_search_module _prefix _module0) if (${_prefix}_FOUND) set(_pkg_modules_found 1) + break() endif() endforeach() diff --git a/Modules/FindPython.cmake b/Modules/FindPython.cmake index 2056e93..3cc08a1 100644 --- a/Modules/FindPython.cmake +++ b/Modules/FindPython.cmake @@ -243,6 +243,44 @@ Hints recommended to also include the component ``Interpreter`` to get expected result. +Artifacts Specification +^^^^^^^^^^^^^^^^^^^^^^^ + +To solve special cases, it is possible to specify directly the artifacts by +setting the following variables: + +``Python_EXECUTABLE`` + The path to the interpreter. + +``Python_COMPILER`` + The path to the compiler. + +``Python_LIBRARY`` + The path to the library. It will be used to compute the + variables ``Python_LIBRARIES``, ``Python_LIBRAY_DIRS`` and + ``Python_RUNTIME_LIBRARY_DIRS``. + +``Python_INCLUDE_DIR`` + The path to the directory of the ``Python`` headers. It will be used to + compute the variable ``Python_INCLUDE_DIRS``. + +``Python_NumPy_INCLUDE_DIR`` + The path to the directory of the ``NumPy`` headers. It will be used to + compute the variable ``Python_NumPy_INCLUDE_DIRS``. + +.. note:: + + All paths must be absolute. Any artifact specified with a relative path + will be ignored. + +.. note:: + + When an artifact is specified, all ``HINTS`` will be ignored and no search + will be performed for this artifact. + + If more than one artifact is specified, it is the user's responsability to + ensure the consistency of the various artifacts. + Commands ^^^^^^^^ @@ -275,6 +313,14 @@ else() set (_Python_REQUIRED_VERSIONS 3 2) set (_Python_REQUIRED_VERSION_LAST 2) + unset (_Python_INPUT_VARS) + foreach (_Python_ITEM IN ITEMS Python_EXECUTABLE Python_COMPILER Python_LIBRARY + Python_INCLUDE_DIR Python_NumPy_INCLUDE_DIR) + if (NOT DEFINED ${_Python_ITEM}) + list (APPEND _Python_INPUT_VARS ${_Python_ITEM}) + endif() + endforeach() + 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) @@ -282,6 +328,10 @@ else() _Python_REQUIRED_VERSION_MAJOR EQUAL _Python_REQUIRED_VERSION_LAST) break() endif() + # clean-up INPUT variables not set by the user + foreach (_Python_ITEM IN LISTS _Python_INPUT_VARS) + unset (${_Python_ITEM}) + endforeach() # clean-up some CACHE variables to ensure look-up restart from scratch foreach (_Python_ITEM IN LISTS _Python_CACHED_VARS) unset (${_Python_ITEM} CACHE) diff --git a/Modules/FindPython/Support.cmake b/Modules/FindPython/Support.cmake index 90a8264..b67d563 100644 --- a/Modules/FindPython/Support.cmake +++ b/Modules/FindPython/Support.cmake @@ -261,16 +261,16 @@ function (_PYTHON_GET_CONFIG_VAR _PYTHON_PGCV_VALUE NAME) else() if (NAME STREQUAL "INCLUDES") # do some clean-up - string (REGEX MATCHALL "-I[^ ]+" _values "${_values}") - string (REPLACE "-I" "" _values "${_values}") + string (REGEX MATCHALL "(-I|-iwithsysroot)[ ]*[^ ]+" _values "${_values}") + string (REGEX REPLACE "(-I|-iwithsysroot)[ ]*" "" _values "${_values}") list (REMOVE_DUPLICATES _values) endif() endif() endif() - if (${_PYTHON_PREFIX}_EXECUTABLE AND NOT CMAKE_CROSSCOMPILING) + if (_${_PYTHON_PREFIX}_EXECUTABLE AND NOT CMAKE_CROSSCOMPILING) if (NAME STREQUAL "PREFIX") - execute_process (COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -c "import sys; from distutils import sysconfig; sys.stdout.write(';'.join([sysconfig.PREFIX,sysconfig.EXEC_PREFIX,sysconfig.BASE_EXEC_PREFIX]))" + execute_process (COMMAND "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c "import sys; from distutils import sysconfig; sys.stdout.write(';'.join([sysconfig.PREFIX,sysconfig.EXEC_PREFIX,sysconfig.BASE_EXEC_PREFIX]))" RESULT_VARIABLE _result OUTPUT_VARIABLE _values ERROR_QUIET @@ -281,7 +281,7 @@ function (_PYTHON_GET_CONFIG_VAR _PYTHON_PGCV_VALUE NAME) list (REMOVE_DUPLICATES _values) endif() elseif (NAME STREQUAL "INCLUDES") - execute_process (COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -c "import sys; from distutils import sysconfig; sys.stdout.write(';'.join([sysconfig.get_python_inc(plat_specific=True),sysconfig.get_python_inc(plat_specific=False)]))" + execute_process (COMMAND "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c "import sys; from distutils import sysconfig; sys.stdout.write(';'.join([sysconfig.get_python_inc(plat_specific=True),sysconfig.get_python_inc(plat_specific=False)]))" RESULT_VARIABLE _result OUTPUT_VARIABLE _values ERROR_QUIET @@ -294,7 +294,7 @@ function (_PYTHON_GET_CONFIG_VAR _PYTHON_PGCV_VALUE NAME) if (NAME STREQUAL "CONFIGDIR") set (config_flag "LIBPL") endif() - execute_process (COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -c "import sys; from distutils import sysconfig; sys.stdout.write(sysconfig.get_config_var('${config_flag}'))" + execute_process (COMMAND "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c "import sys; from distutils import sysconfig; sys.stdout.write(sysconfig.get_config_var('${config_flag}'))" RESULT_VARIABLE _result OUTPUT_VARIABLE _values ERROR_QUIET @@ -305,13 +305,18 @@ function (_PYTHON_GET_CONFIG_VAR _PYTHON_PGCV_VALUE NAME) endif() endif() + if (config_flag STREQUAL "ABIFLAGS") + set (${_PYTHON_PGCV_VALUE} "${_values}" PARENT_SCOPE) + return() + endif() + if (NOT _values OR _values STREQUAL "None") return() endif() if (NAME STREQUAL "LIBS") # do some clean-up - string (REGEX MATCHALL "-[l][^ ]+" _values "${_values}") + string (REGEX MATCHALL "-(l|framework)[ ]*[^ ]+" _values "${_values}") # remove elements relative to python library itself list (FILTER _values EXCLUDE REGEX "-lpython") list (REMOVE_DUPLICATES _values) @@ -320,22 +325,97 @@ function (_PYTHON_GET_CONFIG_VAR _PYTHON_PGCV_VALUE NAME) set (${_PYTHON_PGCV_VALUE} "${_values}" PARENT_SCOPE) endfunction() +function (_PYTHON_GET_VERSION) + cmake_parse_arguments (PARSE_ARGV 0 _PGV "LIBRARY;INCLUDE" "PREFIX" "") + + unset (${_PGV_PREFIX}VERSION PARENT_SCOPE) + unset (${_PGV_PREFIX}VERSION_MAJOR PARENT_SCOPE) + unset (${_PGV_PREFIX}VERSION_MINOR PARENT_SCOPE) + unset (${_PGV_PREFIX}VERSION_PATCH PARENT_SCOPE) + unset (${_PGV_PREFIX}ABI PARENT_SCOPE) + + if (_PGV_LIBRARY) + # retrieve version and abi from library name + if (_${_PYTHON_PREFIX}_LIBRARY_RELEASE) + # extract version from library name + if (_${_PYTHON_PREFIX}_LIBRARY_RELEASE MATCHES "python([23])([0-9]+)") + set (${_PGV_PREFIX}VERSION_MAJOR "${CMAKE_MATCH_1}" PARENT_SCOPE) + set (${_PGV_PREFIX}VERSION_MINOR "${CMAKE_MATCH_2}" PARENT_SCOPE) + set (${_PGV_PREFIX}VERSION "${CMAKE_MATCH_1}.${CMAKE_MATCH_2}" PARENT_SCOPE) + set (${_PGV_PREFIX}ABI "" PARENT_SCOPE) + elseif (_${_PYTHON_PREFIX}_LIBRARY_RELEASE MATCHES "python([23])\\.([0-9]+)([dmu]*)") + set (${_PGV_PREFIX}VERSION_MAJOR "${CMAKE_MATCH_1}" PARENT_SCOPE) + set (${_PGV_PREFIX}VERSION_MINOR "${CMAKE_MATCH_2}" PARENT_SCOPE) + set (${_PGV_PREFIX}VERSION "${CMAKE_MATCH_1}.${CMAKE_MATCH_2}" PARENT_SCOPE) + set (${_PGV_PREFIX}ABI "${CMAKE_MATCH_3}" PARENT_SCOPE) + endif() + endif() + else() + if (_${_PYTHON_PREFIX}_INCLUDE_DIR) + # retrieve version from header file + file (STRINGS "${_${_PYTHON_PREFIX}_INCLUDE_DIR}/patchlevel.h" version + REGEX "^#define[ \t]+PY_VERSION[ \t]+\"[^\"]+\"") + string (REGEX REPLACE "^#define[ \t]+PY_VERSION[ \t]+\"([^\"]+)\".*" "\\1" + version "${version}") + string (REGEX MATCHALL "[0-9]+" versions "${version}") + list (GET versions 0 version_major) + list (GET versions 1 version_minor) + list (GET versions 2 version_patch) + + set (${_PGV_PREFIX}VERSION "${version_major}.${version_minor}" PARENT_SCOPE) + set (${_PGV_PREFIX}VERSION_MAJOR ${version_major} PARENT_SCOPE) + set (${_PGV_PREFIX}VERSION_MINOR ${version_minor} PARENT_SCOPE) + set (${_PGV_PREFIX}VERSION_PATCH ${version_patch} PARENT_SCOPE) + + # compute ABI flags + if (version_major VERSION_GREATER 2) + file (STRINGS "${_${_PYTHON_PREFIX}_INCLUDE_DIR}/pyconfig.h" config REGEX "(Py_DEBUG|WITH_PYMALLOC|Py_UNICODE_SIZE|MS_WIN32)") + set (abi) + if (config MATCHES "#[ ]*define[ ]+MS_WIN32") + # ABI not used on Windows + set (abi "") + else() + if (config MATCHES "#[ ]*define[ ]+Py_DEBUG[ ]+1") + string (APPEND abi "d") + endif() + if (config MATCHES "#[ ]*define[ ]+WITH_PYMALLOC[ ]+1") + string (APPEND abi "m") + endif() + if (config MATCHES "#[ ]*define[ ]+Py_UNICODE_SIZE[ ]+4") + string (APPEND abi "u") + endif() + set (${_PGV_PREFIX}ABI "${abi}" PARENT_SCOPE) + endif() + else() + # ABI not supported + set (${_PGV_PREFIX}ABI "" PARENT_SCOPE) + endif() + endif() + endif() +endfunction() + function (_PYTHON_VALIDATE_INTERPRETER) - if (NOT ${_PYTHON_PREFIX}_EXECUTABLE) + if (NOT _${_PYTHON_PREFIX}_EXECUTABLE) return() endif() - cmake_parse_arguments (PARSE_ARGV 0 _PVI "EXACT" "" "") + cmake_parse_arguments (PARSE_ARGV 0 _PVI "EXACT;CHECK_EXISTS" "" "") if (_PVI_UNPARSED_ARGUMENTS) set (expected_version ${_PVI_UNPARSED_ARGUMENTS}) else() unset (expected_version) endif() + if (_PVI_CHECK_EXISTS AND NOT EXISTS "${_${_PYTHON_PREFIX}_EXECUTABLE}") + # interpreter does not exist anymore + set_property (CACHE _${_PYTHON_PREFIX}_EXECUTABLE PROPERTY VALUE "_${_PYTHON_PREFIX}_EXECUTABLE-NOTFOUND") + return() + endif() + # validate ABI compatibility if (DEFINED _${_PYTHON_PREFIX}_FIND_ABI) - execute_process (COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -c + execute_process (COMMAND "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c "import sys; sys.stdout.write(sys.abiflags)" RESULT_VARIABLE result OUTPUT_VARIABLE abi @@ -347,16 +427,16 @@ function (_PYTHON_VALIDATE_INTERPRETER) endif() if (NOT abi IN_LIST _${_PYTHON_PREFIX}_ABIFLAGS) # incompatible ABI - set_property (CACHE ${_PYTHON_PREFIX}_EXECUTABLE PROPERTY VALUE "${_PYTHON_PREFIX}_EXECUTABLE-NOTFOUND") + set_property (CACHE _${_PYTHON_PREFIX}_EXECUTABLE PROPERTY VALUE "_${_PYTHON_PREFIX}_EXECUTABLE-NOTFOUND") return() endif() endif() - get_filename_component (python_name "${${_PYTHON_PREFIX}_EXECUTABLE}" NAME) + get_filename_component (python_name "${_${_PYTHON_PREFIX}_EXECUTABLE}" NAME) if (expected_version AND NOT python_name STREQUAL "python${expected_version}${abi}${CMAKE_EXECUTABLE_SUFFIX}") # executable found must have a specific version - execute_process (COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -c + execute_process (COMMAND "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c "import sys; sys.stdout.write('.'.join([str(x) for x in sys.version_info[:2]]))" RESULT_VARIABLE result OUTPUT_VARIABLE version @@ -364,14 +444,14 @@ function (_PYTHON_VALIDATE_INTERPRETER) OUTPUT_STRIP_TRAILING_WHITESPACE) if (result OR (_PVI_EXACT AND NOT version VERSION_EQUAL expected_version) OR (version VERSION_LESS expected_version)) # interpreter not usable or has wrong major version - set_property (CACHE ${_PYTHON_PREFIX}_EXECUTABLE PROPERTY VALUE "${_PYTHON_PREFIX}_EXECUTABLE-NOTFOUND") + set_property (CACHE _${_PYTHON_PREFIX}_EXECUTABLE PROPERTY VALUE "_${_PYTHON_PREFIX}_EXECUTABLE-NOTFOUND") return() endif() else() if (NOT python_name STREQUAL "python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR}${CMAKE_EXECUTABLE_SUFFIX}") # executable found do not have version in name # ensure major version is OK - execute_process (COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -c + execute_process (COMMAND "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c "import sys; sys.stdout.write(str(sys.version_info[0]))" RESULT_VARIABLE result OUTPUT_VARIABLE version @@ -379,7 +459,7 @@ function (_PYTHON_VALIDATE_INTERPRETER) OUTPUT_STRIP_TRAILING_WHITESPACE) if (result OR NOT version EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR) # interpreter not usable or has wrong major version - set_property (CACHE ${_PYTHON_PREFIX}_EXECUTABLE PROPERTY VALUE "${_PYTHON_PREFIX}_EXECUTABLE-NOTFOUND") + set_property (CACHE _${_PYTHON_PREFIX}_EXECUTABLE PROPERTY VALUE "_${_PYTHON_PREFIX}_EXECUTABLE-NOTFOUND") return() endif() endif() @@ -388,7 +468,7 @@ function (_PYTHON_VALIDATE_INTERPRETER) 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 + execute_process (COMMAND "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c "import sys, struct; sys.stdout.write(str(struct.calcsize(\"P\")))" RESULT_VARIABLE result OUTPUT_VARIABLE size @@ -396,7 +476,7 @@ function (_PYTHON_VALIDATE_INTERPRETER) OUTPUT_STRIP_TRAILING_WHITESPACE) if (result OR NOT size EQUAL CMAKE_SIZEOF_VOID_P) # interpreter not usable or has wrong architecture - set_property (CACHE ${_PYTHON_PREFIX}_EXECUTABLE PROPERTY VALUE "${_PYTHON_PREFIX}_EXECUTABLE-NOTFOUND") + set_property (CACHE _${_PYTHON_PREFIX}_EXECUTABLE PROPERTY VALUE "_${_PYTHON_PREFIX}_EXECUTABLE-NOTFOUND") return() endif() endif() @@ -404,11 +484,11 @@ endfunction() function (_PYTHON_VALIDATE_COMPILER expected_version) - if (NOT ${_PYTHON_PREFIX}_COMPILER) + if (NOT _${_PYTHON_PREFIX}_COMPILER) return() endif() - cmake_parse_arguments (_PVC "EXACT" "" "" ${ARGN}) + cmake_parse_arguments (_PVC "EXACT;CHECK_EXISTS" "" "" ${ARGN}) if (_PVC_UNPARSED_ARGUMENTS) set (major_version FALSE) set (expected_version ${_PVC_UNPARSED_ARGUMENTS}) @@ -418,6 +498,12 @@ function (_PYTHON_VALIDATE_COMPILER expected_version) set (_PVC_EXACT TRUE) endif() + if (_PVC_CHECK_EXISTS AND NOT EXISTS "${_${_PYTHON_PREFIX}_COMPILER}") + # Compiler does not exist anymore + set_property (CACHE _${_PYTHON_PREFIX}_COMPILER PROPERTY VALUE "_${_PYTHON_PREFIX}_COMPILER-NOTFOUND") + return() + endif() + # retrieve python environment version from compiler set (working_dir "${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/PythonCompilerVersion.dir") if (major_version) @@ -426,7 +512,7 @@ function (_PYTHON_VALIDATE_COMPILER expected_version) else() file (WRITE "${working_dir}/version.py" "import sys; sys.stdout.write('.'.join([str(x) for x in sys.version_info[:2]]))\n") endif() - execute_process (COMMAND "${${_PYTHON_PREFIX}_COMPILER}" /target:exe /embed "${working_dir}/version.py" + execute_process (COMMAND "${_${_PYTHON_PREFIX}_COMPILER}" /target:exe /embed "${working_dir}/version.py" WORKING_DIRECTORY "${working_dir}" OUTPUT_QUIET ERROR_QUIET @@ -440,7 +526,98 @@ function (_PYTHON_VALIDATE_COMPILER expected_version) if (result OR (_PVC_EXACT AND NOT version VERSION_EQUAL expected_version) OR (version VERSION_LESS expected_version)) # Compiler not usable or has wrong version - set_property (CACHE ${_PYTHON_PREFIX}_COMPILER PROPERTY VALUE "${_PYTHON_PREFIX}_COMPILER-NOTFOUND") + set_property (CACHE _${_PYTHON_PREFIX}_COMPILER PROPERTY VALUE "_${_PYTHON_PREFIX}_COMPILER-NOTFOUND") + endif() +endfunction() + + +function (_PYTHON_VALIDATE_LIBRARY) + if (NOT _${_PYTHON_PREFIX}_LIBRARY_RELEASE) + return() + endif() + + cmake_parse_arguments (PARSE_ARGV 0 _PVL "EXACT;CHECK_EXISTS" "" "") + if (_PVL_UNPARSED_ARGUMENTS) + set (expected_version ${_PVL_UNPARSED_ARGUMENTS}) + else() + unset (expected_version) + endif() + + if (_PVL_CHECK_EXISTS AND NOT EXISTS "${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}") + # library does not exist anymore + set_property (CACHE _${_PYTHON_PREFIX}_LIBRARY_RELEASE PROPERTY VALUE "_${_PYTHON_PREFIX}_LIBRARY_RELEASE-NOTFOUND") + if (WIN32) + set_property (CACHE _${_PYTHON_PREFIX}_LIBRARY_DEBUG PROPERTY VALUE "_${_PYTHON_PREFIX}_LIBRARY_DEBUG-NOTFOUND") + endif() + set_property (CACHE _${_PYTHON_PREFIX}_INCLUDE_DIR PROPERTY VALUE "_${_PYTHON_PREFIX}_INCLUDE_DIR-NOTFOUND") + return() + endif() + + # retrieve version and abi from library name + _python_get_version (LIBRARY PREFIX lib_) + + if (DEFINED _${_PYTHON_PREFIX}_FIND_ABI AND NOT lib_ABI IN_LIST _${_PYTHON_PREFIX}_ABIFLAGS) + # incompatible ABI + set_property (CACHE _${_PYTHON_PREFIX}_LIBRARY_RELEASE PROPERTY VALUE "_${_PYTHON_PREFIX}_LIBRARY_RELEASE-NOTFOUND") + else() + if (expected_version) + if ((_PVL_EXACT AND NOT lib_VERSION VERSION_EQUAL expected_version) OR (lib_VERSION VERSION_LESS expected_version)) + # library has wrong version + set_property (CACHE _${_PYTHON_PREFIX}_LIBRARY_RELEASE PROPERTY VALUE "_${_PYTHON_PREFIX}_LIBRARY_RELEASE-NOTFOUND") + endif() + else() + if (NOT lib_VERSION_MAJOR VERSION_EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR) + # library has wrong major version + set_property (CACHE _${_PYTHON_PREFIX}_LIBRARY_RELEASE PROPERTY VALUE "_${_PYTHON_PREFIX}_LIBRARY_RELEASE-NOTFOUND") + endif() + endif() + endif() + + if (NOT _${_PYTHON_PREFIX}_LIBRARY_RELEASE) + if (WIN32) + set_property (CACHE _${_PYTHON_PREFIX}_LIBRARY_DEBUG PROPERTY VALUE "_${_PYTHON_PREFIX}_LIBRARY_DEBUG-NOTFOUND") + endif() + set_property (CACHE _${_PYTHON_PREFIX}_INCLUDE_DIR PROPERTY VALUE "_${_PYTHON_PREFIX}_INCLUDE_DIR-NOTFOUND") + endif() +endfunction() + + +function (_PYTHON_VALIDATE_INCLUDE_DIR) + if (NOT _${_PYTHON_PREFIX}_INCLUDE_DIR) + return() + endif() + + cmake_parse_arguments (PARSE_ARGV 0 _PVID "EXACT;CHECK_EXISTS" "" "") + if (_PVID_UNPARSED_ARGUMENTS) + set (expected_version ${_PVID_UNPARSED_ARGUMENTS}) + else() + unset (expected_version) + endif() + + if (_PVID_CHECK_EXISTS AND NOT EXISTS "${_${_PYTHON_PREFIX}_INCLUDE_DIR}") + # include file does not exist anymore + set_property (CACHE _${_PYTHON_PREFIX}_INCLUDE_DIR PROPERTY VALUE "_${_PYTHON_PREFIX}_INCLUDE_DIR-NOTFOUND") + return() + endif() + + # retrieve version from header file + _python_get_version (INCLUDE PREFIX inc_) + + if (DEFINED _${_PYTHON_PREFIX}_FIND_ABI AND NOT inc_ABI IN_LIST _${_PYTHON_PREFIX}_ABIFLAGS) + # incompatible ABI + set_property (CACHE _${_PYTHON_PREFIX}_INCLUDE_DIR PROPERTY VALUE "_${_PYTHON_PREFIX}_INCLUDE_DIR-NOTFOUND") + else() + if (expected_version) + if ((_PVID_EXACT AND NOT inc_VERSION VERSION_EQUAL expected_version) OR (inc_VERSION VERSION_LESS expected_version)) + # include dir has wrong version + set_property (CACHE _${_PYTHON_PREFIX}_INCLUDE_DIR PROPERTY VALUE "_${_PYTHON_PREFIX}_INCLUDE_DIR-NOTFOUND") + endif() + else() + if (NOT inc_VERSION_MAJOR VERSION_EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR) + # include dir has wrong major version + set_property (CACHE _${_PYTHON_PREFIX}_INCLUDE_DIR PROPERTY VALUE "_${_PYTHON_PREFIX}_INCLUDE_DIR-NOTFOUND") + endif() + endif() endif() endfunction() @@ -463,8 +640,7 @@ endfunction() function (_PYTHON_SET_LIBRARY_DIRS _PYTHON_SLD_RESULT) unset (_PYTHON_DIRS) - set (_PYTHON_LIBS ${ARGV}) - list (REMOVE_AT _PYTHON_LIBS 0) + set (_PYTHON_LIBS ${ARGN}) foreach (_PYTHON_LIB IN LISTS _PYTHON_LIBS) if (${_PYTHON_LIB}) get_filename_component (_PYTHON_DIR "${${_PYTHON_LIB}}" DIRECTORY) @@ -494,7 +670,7 @@ if ("NumPy" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) list (APPEND ${_PYTHON_PREFIX}_FIND_COMPONENTS "Interpreter" "Development") list (REMOVE_DUPLICATES ${_PYTHON_PREFIX}_FIND_COMPONENTS) endif() -foreach (_${_PYTHON_PREFIX}_COMPONENT IN LISTS ${_PYTHON_PREFIX}_FIND_COMPONENTS) +foreach (_${_PYTHON_PREFIX}_COMPONENT IN ITEMS Interpreter Compiler Development NumPy) set (${_PYTHON_PREFIX}_${_${_PYTHON_PREFIX}_COMPONENT}_FOUND FALSE) endforeach() unset (_${_PYTHON_PREFIX}_FIND_VERSIONS) @@ -644,319 +820,356 @@ else() endif() +# Compute search signature +# This signature will be used to check validity of cached variables on new search +set (_${_PYTHON_PREFIX}_SIGNATURE "${${_PYTHON_PREFIX}_ROOT_DIR}:${${_PYTHON_PREFIX}_FIND_STRATEGY}:${${_PYTHON_PREFIX}_FIND_VIRTUALENV}") +if (NOT WIN32) + string (APPEND _${_PYTHON_PREFIX}_SIGNATURE ":${${_PYTHON_PREFIX}_USE_STATIC_LIBS}:") +endif() +if (CMAKE_HOST_APPLE) + string (APPEND _${_PYTHON_PREFIX}_SIGNATURE ":${${_PYTHON_PREFIX}_FIND_FRAMEWORK}") +endif() +if (CMAKE_HOST_WIN32) + string (APPEND _${_PYTHON_PREFIX}_SIGNATURE ":${${_PYTHON_PREFIX}_FIND_REGISTRY}") +endif() + + unset (_${_PYTHON_PREFIX}_REQUIRED_VARS) unset (_${_PYTHON_PREFIX}_CACHED_VARS) # first step, search for the interpreter if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) - list (APPEND _${_PYTHON_PREFIX}_CACHED_VARS ${_PYTHON_PREFIX}_EXECUTABLE) + list (APPEND _${_PYTHON_PREFIX}_CACHED_VARS _${_PYTHON_PREFIX}_EXECUTABLE) if (${_PYTHON_PREFIX}_FIND_REQUIRED_Interpreter) list (APPEND _${_PYTHON_PREFIX}_REQUIRED_VARS ${_PYTHON_PREFIX}_EXECUTABLE) endif() - set (_${_PYTHON_PREFIX}_HINTS "${${_PYTHON_PREFIX}_ROOT_DIR}" ENV ${_PYTHON_PREFIX}_ROOT_DIR) + if (DEFINED ${_PYTHON_PREFIX}_EXECUTABLE + AND IS_ABSOLUTE "${${_PYTHON_PREFIX}_EXECUTABLE}") + set (_${_PYTHON_PREFIX}_EXECUTABLE "${${_PYTHON_PREFIX}_EXECUTABLE}" CACHE INTERNAL "") + elseif (DEFINED _${_PYTHON_PREFIX}_EXECUTABLE) + # compute interpreter signature and check validity of definition + string (MD5 __${_PYTHON_PREFIX}_INTERPRETER_SIGNATURE "${_${_PYTHON_PREFIX}_SIGNATURE}:${_${_PYTHON_PREFIX}_EXECUTABLE}") + if (__${_PYTHON_PREFIX}_INTERPRETER_SIGNATURE STREQUAL _${_PYTHON_PREFIX}_INTERPRETER_SIGNATURE) + # check version validity + if (${_PYTHON_PREFIX}_FIND_VERSION_EXACT) + _python_validate_interpreter (${${_PYTHON_PREFIX}_FIND_VERSION} EXACT CHECK_EXISTS) + else() + _python_validate_interpreter (${${_PYTHON_PREFIX}_FIND_VERSION} CHECK_EXISTS) + endif() + else() + unset (_${_PYTHON_PREFIX}_EXECUTABLE CACHE) + unset (_${_PYTHON_PREFIX}_INTERPRETER_SIGNATURE CACHE) + endif() + endif() - if (_${_PYTHON_PREFIX}_FIND_STRATEGY STREQUAL "LOCATION") - unset (_${_PYTHON_PREFIX}_NAMES) - unset (_${_PYTHON_PREFIX}_FRAMEWORK_PATHS) - unset (_${_PYTHON_PREFIX}_REGISTRY_PATHS) + if (NOT _${_PYTHON_PREFIX}_EXECUTABLE) + set (_${_PYTHON_PREFIX}_HINTS "${${_PYTHON_PREFIX}_ROOT_DIR}" ENV ${_PYTHON_PREFIX}_ROOT_DIR) - foreach (_${_PYTHON_PREFIX}_VERSION IN LISTS _${_PYTHON_PREFIX}_FIND_VERSIONS) - # build all executable names - _python_get_names (_${_PYTHON_PREFIX}_VERSION_NAMES VERSION ${_${_PYTHON_PREFIX}_VERSION} POSIX EXECUTABLE) - list (APPEND _${_PYTHON_PREFIX}_NAMES ${_${_PYTHON_PREFIX}_VERSION_NAMES}) + if (_${_PYTHON_PREFIX}_FIND_STRATEGY STREQUAL "LOCATION") + unset (_${_PYTHON_PREFIX}_NAMES) + unset (_${_PYTHON_PREFIX}_FRAMEWORK_PATHS) + unset (_${_PYTHON_PREFIX}_REGISTRY_PATHS) - # Framework Paths - _python_get_frameworks (_${_PYTHON_PREFIX}_VERSION_PATHS ${_${_PYTHON_PREFIX}_VERSION}) - list (APPEND _${_PYTHON_PREFIX}_FRAMEWORK_PATHS ${_${_PYTHON_PREFIX}_VERSION_PATHS}) + foreach (_${_PYTHON_PREFIX}_VERSION IN LISTS _${_PYTHON_PREFIX}_FIND_VERSIONS) + # build all executable names + _python_get_names (_${_PYTHON_PREFIX}_VERSION_NAMES VERSION ${_${_PYTHON_PREFIX}_VERSION} POSIX EXECUTABLE) + list (APPEND _${_PYTHON_PREFIX}_NAMES ${_${_PYTHON_PREFIX}_VERSION_NAMES}) - # Registry Paths - _python_get_registries (_${_PYTHON_PREFIX}_VERSION_PATHS ${_${_PYTHON_PREFIX}_VERSION}) - list (APPEND _${_PYTHON_PREFIX}_REGISTRY_PATHS ${_${_PYTHON_PREFIX}_VERSION_PATHS} - [HKEY_LOCAL_MACHINE\\SOFTWARE\\IronPython\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath]) - endforeach() - list (APPEND _${_PYTHON_PREFIX}_NAMES python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR} python) + # Framework Paths + _python_get_frameworks (_${_PYTHON_PREFIX}_VERSION_PATHS ${_${_PYTHON_PREFIX}_VERSION}) + list (APPEND _${_PYTHON_PREFIX}_FRAMEWORK_PATHS ${_${_PYTHON_PREFIX}_VERSION_PATHS}) - while (TRUE) - # Virtual environments handling - if (_${_PYTHON_PREFIX}_FIND_VIRTUALENV MATCHES "^(FIRST|ONLY)$") - find_program (${_PYTHON_PREFIX}_EXECUTABLE - NAMES ${_${_PYTHON_PREFIX}_NAMES} - NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATHS ENV VIRTUAL_ENV - PATH_SUFFIXES bin Scripts - NO_CMAKE_PATH - NO_CMAKE_ENVIRONMENT_PATH - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) + # Registry Paths + _python_get_registries (_${_PYTHON_PREFIX}_VERSION_PATHS ${_${_PYTHON_PREFIX}_VERSION}) + list (APPEND _${_PYTHON_PREFIX}_REGISTRY_PATHS ${_${_PYTHON_PREFIX}_VERSION_PATHS} + [HKEY_LOCAL_MACHINE\\SOFTWARE\\IronPython\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath]) + endforeach() + list (APPEND _${_PYTHON_PREFIX}_NAMES python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR} python) - _python_validate_interpreter (${${_PYTHON_PREFIX}_FIND_VERSION}) - if (${_PYTHON_PREFIX}_EXECUTABLE) - break() + while (TRUE) + # Virtual environments handling + if (_${_PYTHON_PREFIX}_FIND_VIRTUALENV MATCHES "^(FIRST|ONLY)$") + find_program (_${_PYTHON_PREFIX}_EXECUTABLE + NAMES ${_${_PYTHON_PREFIX}_NAMES} + NAMES_PER_DIR + HINTS ${_${_PYTHON_PREFIX}_HINTS} + PATHS ENV VIRTUAL_ENV + PATH_SUFFIXES bin Scripts + NO_CMAKE_PATH + NO_CMAKE_ENVIRONMENT_PATH + NO_SYSTEM_ENVIRONMENT_PATH + NO_CMAKE_SYSTEM_PATH) + + _python_validate_interpreter (${${_PYTHON_PREFIX}_FIND_VERSION}) + if (_${_PYTHON_PREFIX}_EXECUTABLE) + break() + endif() + if (NOT _${_PYTHON_PREFIX}_FIND_VIRTUALENV STREQUAL "ONLY") + break() + endif() endif() - if (NOT _${_PYTHON_PREFIX}_FIND_VIRTUALENV STREQUAL "ONLY") - break() + + # Apple frameworks handling + if (CMAKE_HOST_APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "FIRST") + find_program (_${_PYTHON_PREFIX}_EXECUTABLE + NAMES ${_${_PYTHON_PREFIX}_NAMES} + NAMES_PER_DIR + HINTS ${_${_PYTHON_PREFIX}_HINTS} + PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS} + PATH_SUFFIXES bin + NO_CMAKE_PATH + NO_CMAKE_ENVIRONMENT_PATH + NO_SYSTEM_ENVIRONMENT_PATH + NO_CMAKE_SYSTEM_PATH) + _python_validate_interpreter (${${_PYTHON_PREFIX}_FIND_VERSION}) + if (_${_PYTHON_PREFIX}_EXECUTABLE) + break() + endif() + endif() + # Windows registry + if (CMAKE_HOST_WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "FIRST") + find_program (_${_PYTHON_PREFIX}_EXECUTABLE + NAMES ${_${_PYTHON_PREFIX}_NAMES} + ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES} + NAMES_PER_DIR + HINTS ${_${_PYTHON_PREFIX}_HINTS} + PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS} + PATH_SUFFIXES bin ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES} + NO_SYSTEM_ENVIRONMENT_PATH + NO_CMAKE_SYSTEM_PATH) + _python_validate_interpreter (${${_PYTHON_PREFIX}_FIND_VERSION}) + if (_${_PYTHON_PREFIX}_EXECUTABLE) + break() + endif() endif() - endif() - # Apple frameworks handling - if (CMAKE_HOST_APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "FIRST") - find_program (${_PYTHON_PREFIX}_EXECUTABLE + # try using HINTS + find_program (_${_PYTHON_PREFIX}_EXECUTABLE NAMES ${_${_PYTHON_PREFIX}_NAMES} + ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES} NAMES_PER_DIR HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS} - PATH_SUFFIXES bin - NO_CMAKE_PATH - NO_CMAKE_ENVIRONMENT_PATH + PATH_SUFFIXES bin ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES} NO_SYSTEM_ENVIRONMENT_PATH NO_CMAKE_SYSTEM_PATH) _python_validate_interpreter (${${_PYTHON_PREFIX}_FIND_VERSION}) - if (${_PYTHON_PREFIX}_EXECUTABLE) + if (_${_PYTHON_PREFIX}_EXECUTABLE) break() endif() - endif() - # Windows registry - if (CMAKE_HOST_WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "FIRST") - find_program (${_PYTHON_PREFIX}_EXECUTABLE + # try using standard paths + find_program (_${_PYTHON_PREFIX}_EXECUTABLE NAMES ${_${_PYTHON_PREFIX}_NAMES} ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES} NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS} - PATH_SUFFIXES bin ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES} - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) + PATH_SUFFIXES bin ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES}) _python_validate_interpreter (${${_PYTHON_PREFIX}_FIND_VERSION}) - if (${_PYTHON_PREFIX}_EXECUTABLE) + if (_${_PYTHON_PREFIX}_EXECUTABLE) break() endif() - endif() - - # try using HINTS - find_program (${_PYTHON_PREFIX}_EXECUTABLE - NAMES ${_${_PYTHON_PREFIX}_NAMES} - ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES} - NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATH_SUFFIXES bin ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES} - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - _python_validate_interpreter (${${_PYTHON_PREFIX}_FIND_VERSION}) - if (${_PYTHON_PREFIX}_EXECUTABLE) - break() - endif() - # try using standard paths - find_program (${_PYTHON_PREFIX}_EXECUTABLE - NAMES ${_${_PYTHON_PREFIX}_NAMES} - ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES} - NAMES_PER_DIR - PATH_SUFFIXES bin ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES}) - _python_validate_interpreter (${${_PYTHON_PREFIX}_FIND_VERSION}) - if (${_PYTHON_PREFIX}_EXECUTABLE) - break() - endif() - # Apple frameworks handling - if (CMAKE_HOST_APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "LAST") - find_program (${_PYTHON_PREFIX}_EXECUTABLE - NAMES ${_${_PYTHON_PREFIX}_NAMES} - NAMES_PER_DIR - PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS} - PATH_SUFFIXES bin - NO_DEFAULT_PATH) - _python_validate_interpreter (${${_PYTHON_PREFIX}_FIND_VERSION}) - if (${_PYTHON_PREFIX}_EXECUTABLE) - break() + # Apple frameworks handling + if (CMAKE_HOST_APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "LAST") + find_program (_${_PYTHON_PREFIX}_EXECUTABLE + NAMES ${_${_PYTHON_PREFIX}_NAMES} + NAMES_PER_DIR + PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS} + PATH_SUFFIXES bin + NO_DEFAULT_PATH) + _python_validate_interpreter (${${_PYTHON_PREFIX}_FIND_VERSION}) + if (_${_PYTHON_PREFIX}_EXECUTABLE) + break() + endif() endif() - endif() - # Windows registry - if (CMAKE_HOST_WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "LAST") - find_program (${_PYTHON_PREFIX}_EXECUTABLE - NAMES ${_${_PYTHON_PREFIX}_NAMES} - ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES} - NAMES_PER_DIR - PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS} - PATH_SUFFIXES bin ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES} - NO_DEFAULT_PATH) - _python_validate_interpreter (${${_PYTHON_PREFIX}_FIND_VERSION}) - if (${_PYTHON_PREFIX}_EXECUTABLE) - break() + # Windows registry + if (CMAKE_HOST_WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "LAST") + find_program (_${_PYTHON_PREFIX}_EXECUTABLE + NAMES ${_${_PYTHON_PREFIX}_NAMES} + ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES} + NAMES_PER_DIR + PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS} + PATH_SUFFIXES bin ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES} + NO_DEFAULT_PATH) + _python_validate_interpreter (${${_PYTHON_PREFIX}_FIND_VERSION}) + if (_${_PYTHON_PREFIX}_EXECUTABLE) + break() + endif() endif() - endif() - break() - endwhile() - else() - # look-up for various versions and locations - foreach (_${_PYTHON_PREFIX}_VERSION IN LISTS _${_PYTHON_PREFIX}_FIND_VERSIONS) - _python_get_names (_${_PYTHON_PREFIX}_NAMES VERSION ${_${_PYTHON_PREFIX}_VERSION} POSIX EXECUTABLE) - list (APPEND _${_PYTHON_PREFIX}_NAMES python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR} - python) + break() + endwhile() + else() + # look-up for various versions and locations + foreach (_${_PYTHON_PREFIX}_VERSION IN LISTS _${_PYTHON_PREFIX}_FIND_VERSIONS) + _python_get_names (_${_PYTHON_PREFIX}_NAMES VERSION ${_${_PYTHON_PREFIX}_VERSION} POSIX EXECUTABLE) + list (APPEND _${_PYTHON_PREFIX}_NAMES python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR} + python) - _python_get_frameworks (_${_PYTHON_PREFIX}_FRAMEWORK_PATHS ${_${_PYTHON_PREFIX}_VERSION}) - _python_get_registries (_${_PYTHON_PREFIX}_REGISTRY_PATHS ${_${_PYTHON_PREFIX}_VERSION}) + _python_get_frameworks (_${_PYTHON_PREFIX}_FRAMEWORK_PATHS ${_${_PYTHON_PREFIX}_VERSION}) + _python_get_registries (_${_PYTHON_PREFIX}_REGISTRY_PATHS ${_${_PYTHON_PREFIX}_VERSION}) - # Virtual environments handling - if (_${_PYTHON_PREFIX}_FIND_VIRTUALENV MATCHES "^(FIRST|ONLY)$") - find_program (${_PYTHON_PREFIX}_EXECUTABLE - NAMES ${_${_PYTHON_PREFIX}_NAMES} - NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATHS ENV VIRTUAL_ENV - PATH_SUFFIXES bin Scripts - NO_CMAKE_PATH - NO_CMAKE_ENVIRONMENT_PATH - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) + # Virtual environments handling + if (_${_PYTHON_PREFIX}_FIND_VIRTUALENV MATCHES "^(FIRST|ONLY)$") + find_program (_${_PYTHON_PREFIX}_EXECUTABLE + NAMES ${_${_PYTHON_PREFIX}_NAMES} + NAMES_PER_DIR + HINTS ${_${_PYTHON_PREFIX}_HINTS} + PATHS ENV VIRTUAL_ENV + PATH_SUFFIXES bin Scripts + NO_CMAKE_PATH + NO_CMAKE_ENVIRONMENT_PATH + NO_SYSTEM_ENVIRONMENT_PATH + NO_CMAKE_SYSTEM_PATH) + _python_validate_interpreter (${_${_PYTHON_PREFIX}_VERSION} EXACT) + if (_${_PYTHON_PREFIX}_EXECUTABLE) + break() + endif() + if (_${_PYTHON_PREFIX}_FIND_VIRTUALENV STREQUAL "ONLY") + continue() + endif() + endif() - _python_validate_interpreter (${_${_PYTHON_PREFIX}_VERSION} EXACT) - if (${_PYTHON_PREFIX}_EXECUTABLE) - break() + # Apple frameworks handling + if (CMAKE_HOST_APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "FIRST") + find_program (_${_PYTHON_PREFIX}_EXECUTABLE + NAMES ${_${_PYTHON_PREFIX}_NAMES} + NAMES_PER_DIR + HINTS ${_${_PYTHON_PREFIX}_HINTS} + PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS} + PATH_SUFFIXES bin + NO_CMAKE_PATH + NO_CMAKE_ENVIRONMENT_PATH + NO_SYSTEM_ENVIRONMENT_PATH + NO_CMAKE_SYSTEM_PATH) endif() - if (_${_PYTHON_PREFIX}_FIND_VIRTUALENV STREQUAL "ONLY") - continue() + + # Windows registry + if (CMAKE_HOST_WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "FIRST") + find_program (_${_PYTHON_PREFIX}_EXECUTABLE + NAMES ${_${_PYTHON_PREFIX}_NAMES} + ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES} + NAMES_PER_DIR + HINTS ${_${_PYTHON_PREFIX}_HINTS} + PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS} + [HKEY_LOCAL_MACHINE\\SOFTWARE\\IronPython\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] + PATH_SUFFIXES bin ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES} + NO_SYSTEM_ENVIRONMENT_PATH + NO_CMAKE_SYSTEM_PATH) endif() - endif() - # Apple frameworks handling - if (CMAKE_HOST_APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "FIRST") - find_program (${_PYTHON_PREFIX}_EXECUTABLE - NAMES ${_${_PYTHON_PREFIX}_NAMES} - NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS} - PATH_SUFFIXES bin - NO_CMAKE_PATH - NO_CMAKE_ENVIRONMENT_PATH - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - endif() + _python_validate_interpreter (${_${_PYTHON_PREFIX}_VERSION} EXACT) + if (_${_PYTHON_PREFIX}_EXECUTABLE) + break() + endif() - # Windows registry - if (CMAKE_HOST_WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "FIRST") - find_program (${_PYTHON_PREFIX}_EXECUTABLE + # try using HINTS + find_program (_${_PYTHON_PREFIX}_EXECUTABLE NAMES ${_${_PYTHON_PREFIX}_NAMES} ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES} NAMES_PER_DIR HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS} - [HKEY_LOCAL_MACHINE\\SOFTWARE\\IronPython\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] PATH_SUFFIXES bin ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES} NO_SYSTEM_ENVIRONMENT_PATH NO_CMAKE_SYSTEM_PATH) - endif() - _python_validate_interpreter (${_${_PYTHON_PREFIX}_VERSION} EXACT) - if (${_PYTHON_PREFIX}_EXECUTABLE) - break() - endif() + _python_validate_interpreter (${_${_PYTHON_PREFIX}_VERSION} EXACT) + if (_${_PYTHON_PREFIX}_EXECUTABLE) + break() + endif() + # try using standard paths. + # NAMES_PER_DIR is not defined on purpose to have a chance to find + # expected version. + # For example, typical systems have 'python' for version 2.* and 'python3' + # for version 3.*. So looking for names per dir will find, potentially, + # systematically 'python' (i.e. version 2) even if version 3 is searched. + if (CMAKE_HOST_WIN32) + find_program (_${_PYTHON_PREFIX}_EXECUTABLE + NAMES ${_${_PYTHON_PREFIX}_NAMES} + python + ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES}) + else() + find_program (_${_PYTHON_PREFIX}_EXECUTABLE + NAMES ${_${_PYTHON_PREFIX}_NAMES}) + endif() + _python_validate_interpreter (${_${_PYTHON_PREFIX}_VERSION} EXACT) + if (_${_PYTHON_PREFIX}_EXECUTABLE) + break() + endif() - # try using HINTS - find_program (${_PYTHON_PREFIX}_EXECUTABLE - NAMES ${_${_PYTHON_PREFIX}_NAMES} - ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES} - NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATH_SUFFIXES bin ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES} - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - _python_validate_interpreter (${_${_PYTHON_PREFIX}_VERSION} EXACT) - if (${_PYTHON_PREFIX}_EXECUTABLE) - break() - endif() - # try using standard paths. - # NAMES_PER_DIR is not defined on purpose to have a chance to find - # expected version. - # For example, typical systems have 'python' for version 2.* and 'python3' - # for version 3.*. So looking for names per dir will find, potentially, - # systematically 'python' (i.e. version 2) even if version 3 is searched. - if (CMAKE_HOST_WIN32) - find_program (${_PYTHON_PREFIX}_EXECUTABLE - NAMES ${_${_PYTHON_PREFIX}_NAMES} - python - ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES}) - else() - find_program (${_PYTHON_PREFIX}_EXECUTABLE - NAMES ${_${_PYTHON_PREFIX}_NAMES}) - endif() - _python_validate_interpreter (${_${_PYTHON_PREFIX}_VERSION} EXACT) - if (${_PYTHON_PREFIX}_EXECUTABLE) - break() - endif() + # Apple frameworks handling + if (CMAKE_HOST_APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "LAST") + find_program (_${_PYTHON_PREFIX}_EXECUTABLE + NAMES ${_${_PYTHON_PREFIX}_NAMES} + NAMES_PER_DIR + PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS} + PATH_SUFFIXES bin + NO_DEFAULT_PATH) + endif() - # Apple frameworks handling - if (CMAKE_HOST_APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "LAST") - find_program (${_PYTHON_PREFIX}_EXECUTABLE - NAMES ${_${_PYTHON_PREFIX}_NAMES} - NAMES_PER_DIR - PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS} - PATH_SUFFIXES bin - NO_DEFAULT_PATH) - endif() + # Windows registry + if (CMAKE_HOST_WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "LAST") + find_program (_${_PYTHON_PREFIX}_EXECUTABLE + NAMES ${_${_PYTHON_PREFIX}_NAMES} + ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES} + NAMES_PER_DIR + PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS} + [HKEY_LOCAL_MACHINE\\SOFTWARE\\IronPython\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] + PATH_SUFFIXES bin ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES} + NO_DEFAULT_PATH) + endif() - # Windows registry - if (CMAKE_HOST_WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "LAST") - find_program (${_PYTHON_PREFIX}_EXECUTABLE - NAMES ${_${_PYTHON_PREFIX}_NAMES} - ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES} - NAMES_PER_DIR - PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS} - [HKEY_LOCAL_MACHINE\\SOFTWARE\\IronPython\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] - PATH_SUFFIXES bin ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES} - NO_DEFAULT_PATH) - endif() + _python_validate_interpreter (${_${_PYTHON_PREFIX}_VERSION} EXACT) + if (_${_PYTHON_PREFIX}_EXECUTABLE) + break() + endif() + endforeach() - _python_validate_interpreter (${_${_PYTHON_PREFIX}_VERSION} EXACT) - if (${_PYTHON_PREFIX}_EXECUTABLE) - break() + if (NOT _${_PYTHON_PREFIX}_EXECUTABLE AND + NOT _${_PYTHON_PREFIX}_FIND_VIRTUALENV STREQUAL "ONLY") + # No specific version found. Retry with generic names and standard paths. + # NAMES_PER_DIR is not defined on purpose to have a chance to find + # expected version. + # For example, typical systems have 'python' for version 2.* and 'python3' + # for version 3.*. So looking for names per dir will find, potentially, + # systematically 'python' (i.e. version 2) even if version 3 is searched. + find_program (_${_PYTHON_PREFIX}_EXECUTABLE + NAMES python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR} + python + ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES}) + _python_validate_interpreter () endif() - endforeach() - - if (NOT ${_PYTHON_PREFIX}_EXECUTABLE AND - NOT _${_PYTHON_PREFIX}_FIND_VIRTUALENV STREQUAL "ONLY") - # No specific version found. Retry with generic names and standard paths. - # NAMES_PER_DIR is not defined on purpose to have a chance to find - # expected version. - # For example, typical systems have 'python' for version 2.* and 'python3' - # for version 3.*. So looking for names per dir will find, potentially, - # systematically 'python' (i.e. version 2) even if version 3 is searched. - find_program (${_PYTHON_PREFIX}_EXECUTABLE - NAMES python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR} - python - ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES}) - - _python_validate_interpreter () endif() endif() + set (${_PYTHON_PREFIX}_EXECUTABLE "${_${_PYTHON_PREFIX}_EXECUTABLE}") + # retrieve exact version of executable found - if (${_PYTHON_PREFIX}_EXECUTABLE) - execute_process (COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -c + 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) + set (_${_PYTHON_PREFIX}_EXECUTABLE_USABLE TRUE) 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_property (CACHE ${_PYTHON_PREFIX}_EXECUTABLE PROPERTY VALUE "${_PYTHON_PREFIX}_EXECUTABLE-NOTFOUND") + set (_${_PYTHON_PREFIX}_EXECUTABLE_USABLE FALSE) unset (${_PYTHON_PREFIX}_VERSION) endif() endif() - if (${_PYTHON_PREFIX}_EXECUTABLE + if (_${_PYTHON_PREFIX}_EXECUTABLE AND _${_PYTHON_PREFIX}_EXECUTABLE_USABLE AND ${_PYTHON_PREFIX}_VERSION_MAJOR VERSION_EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR) set (${_PYTHON_PREFIX}_Interpreter_FOUND TRUE) # Use interpreter version and ABI for future searches to ensure consistency set (_${_PYTHON_PREFIX}_FIND_VERSIONS ${${_PYTHON_PREFIX}_VERSION_MAJOR}.${${_PYTHON_PREFIX}_VERSION_MINOR}) - execute_process (COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -c "import sys; sys.stdout.write(sys.abiflags)" + execute_process (COMMAND "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c "import sys; sys.stdout.write(sys.abiflags)" RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT OUTPUT_VARIABLE _${_PYTHON_PREFIX}_ABIFLAGS ERROR_QUIET @@ -968,9 +1181,13 @@ if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) endif() if (${_PYTHON_PREFIX}_Interpreter_FOUND) + # compute and save interpreter signature + string (MD5 __${_PYTHON_PREFIX}_INTERPRETER_SIGNATURE "${_${_PYTHON_PREFIX}_SIGNATURE}:${_${_PYTHON_PREFIX}_EXECUTABLE}") + set (_${_PYTHON_PREFIX}_INTERPRETER_SIGNATURE "${__${_PYTHON_PREFIX}_INTERPRETER_SIGNATURE}" CACHE INTERNAL "") + if (NOT CMAKE_SIZEOF_VOID_P) # determine interpreter architecture - execute_process (COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -c "import sys; print(sys.maxsize > 2**32)" + execute_process (COMMAND "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c "import sys; print(sys.maxsize > 2**32)" RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT OUTPUT_VARIABLE ${_PYTHON_PREFIX}_IS64BIT ERROR_VARIABLE ${_PYTHON_PREFIX}_IS64BIT) @@ -986,7 +1203,7 @@ if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) endif() # retrieve interpreter identity - execute_process (COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -V + execute_process (COMMAND "${_${_PYTHON_PREFIX}_EXECUTABLE}" -V RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT OUTPUT_VARIABLE ${_PYTHON_PREFIX}_INTERPRETER_ID ERROR_VARIABLE ${_PYTHON_PREFIX}_INTERPRETER_ID) @@ -999,7 +1216,7 @@ if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) 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)" + execute_process (COMMAND "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c "import sys; print(sys.copyright)" RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT OUTPUT_VARIABLE ${_PYTHON_PREFIX}_COPYRIGHT ERROR_QUIET) @@ -1011,144 +1228,169 @@ if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) 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)]))" + # 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) + 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() else() - unset (${_PYTHON_PREFIX}_STDLIB) - unset (${_PYTHON_PREFIX}_STDARCH) - unset (${_PYTHON_PREFIX}_SITELIB) - unset (${_PYTHON_PREFIX}_SITEARCH) + unset (_${_PYTHON_PREFIX}_INTERPRETER_SIGNATURE CACHE) + unset (${_PYTHON_PREFIX}_INTERPRETER_ID) endif() - mark_as_advanced (${_PYTHON_PREFIX}_EXECUTABLE) + mark_as_advanced (_${_PYTHON_PREFIX}_EXECUTABLE + _${_PYTHON_PREFIX}_INTERPRETER_SIGNATURE) endif() # second step, search for compiler (IronPython) if ("Compiler" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) - list (APPEND _${_PYTHON_PREFIX}_CACHED_VARS ${_PYTHON_PREFIX}_COMPILER) + list (APPEND _${_PYTHON_PREFIX}_CACHED_VARS _${_PYTHON_PREFIX}_COMPILER) if (${_PYTHON_PREFIX}_FIND_REQUIRED_Compiler) list (APPEND _${_PYTHON_PREFIX}_REQUIRED_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) + if (DEFINED ${_PYTHON_PREFIX}_COMPILER + AND IS_ABSOLUTE "${${_PYTHON_PREFIX}_COMPILER}") + set (_${_PYTHON_PREFIX}_COMPILER "${${_PYTHON_PREFIX}_COMPILER}" CACHE INTERNAL "") + elseif (DEFINED _${_PYTHON_PREFIX}_COMPILER) + # compute compiler signature and check validity of definition + string (MD5 __${_PYTHON_PREFIX}_COMPILER_SIGNATURE "${_${_PYTHON_PREFIX}_SIGNATURE}:${_${_PYTHON_PREFIX}_COMPILER}") + if (__${_PYTHON_PREFIX}_COMPILER_SIGNATURE STREQUAL _${_PYTHON_PREFIX}_COMPILER_SIGNATURE) + # check version validity + if (${_PYTHON_PREFIX}_FIND_VERSION_EXACT) + _python_validate_compiler (${${_PYTHON_PREFIX}_FIND_VERSION} EXACT CHECK_EXISTS) + else() + _python_validate_compiler (${${_PYTHON_PREFIX}_FIND_VERSION} CHECK_EXISTS) + endif() + else() + unset (_${_PYTHON_PREFIX}_COMPILER CACHE) + unset (_${_PYTHON_PREFIX}_COMPILER_SIGNATURE CACHE) + endif() endif() - if (_${_PYTHON_PREFIX}_FIND_STRATEGY STREQUAL "LOCATION") - set (_${_PYTHON_PREFIX}_REGISTRY_PATHS) + if (NOT _${_PYTHON_PREFIX}_COMPILER) + # 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() - foreach (_${_PYTHON_PREFIX}_VERSION IN LISTS _${_PYTHON_PREFIX}_FIND_VERSIONS) - # Registry Paths - list (APPEND _${_PYTHON_PREFIX}_REGISTRY_PATHS - [HKEY_LOCAL_MACHINE\\SOFTWARE\\IronPython\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath]) - endforeach() + if (_${_PYTHON_PREFIX}_FIND_STRATEGY STREQUAL "LOCATION") + set (_${_PYTHON_PREFIX}_REGISTRY_PATHS) + + foreach (_${_PYTHON_PREFIX}_VERSION IN LISTS _${_PYTHON_PREFIX}_FIND_VERSIONS) + # Registry Paths + list (APPEND _${_PYTHON_PREFIX}_REGISTRY_PATHS + [HKEY_LOCAL_MACHINE\\SOFTWARE\\IronPython\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath]) + endforeach() + + while (TRUE) + if (_${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "FIRST") + find_program (_${_PYTHON_PREFIX}_COMPILER + NAMES ipyc + HINTS ${_${_PYTHON_PREFIX}_IRON_ROOT} ${_${_PYTHON_PREFIX}_HINTS} + PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS} + PATH_SUFFIXES ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES} + NO_SYSTEM_ENVIRONMENT_PATH + NO_CMAKE_SYSTEM_PATH) + _python_validate_compiler (${${_PYTHON_PREFIX}_FIND_VERSION}) + if (_${_PYTHON_PREFIX}_COMPILER) + break() + endif() + endif() - while (TRUE) - if (_${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "FIRST") - find_program (${_PYTHON_PREFIX}_COMPILER + find_program (_${_PYTHON_PREFIX}_COMPILER NAMES ipyc HINTS ${_${_PYTHON_PREFIX}_IRON_ROOT} ${_${_PYTHON_PREFIX}_HINTS} - PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS} PATH_SUFFIXES ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES} NO_SYSTEM_ENVIRONMENT_PATH NO_CMAKE_SYSTEM_PATH) _python_validate_compiler (${${_PYTHON_PREFIX}_FIND_VERSION}) - if (${_PYTHON_PREFIX}_COMPILER) + if (_${_PYTHON_PREFIX}_COMPILER) break() endif() - endif() - find_program (${_PYTHON_PREFIX}_COMPILER - NAMES ipyc - HINTS ${_${_PYTHON_PREFIX}_IRON_ROOT} ${_${_PYTHON_PREFIX}_HINTS} - PATH_SUFFIXES ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES} - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - _python_validate_compiler (${${_PYTHON_PREFIX}_FIND_VERSION}) - if (${_PYTHON_PREFIX}_COMPILER) - break() - endif() + if (_${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "LAST") + find_program (_${_PYTHON_PREFIX}_COMPILER + NAMES ipyc + PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS} + PATH_SUFFIXES ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES} + NO_DEFAULT_PATH) + endif() - if (_${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "LAST") - find_program (${_PYTHON_PREFIX}_COMPILER - NAMES ipyc - PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS} - PATH_SUFFIXES ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES} - NO_DEFAULT_PATH) - endif() + break() + endwhile() + else() + # try using root dir and registry + foreach (_${_PYTHON_PREFIX}_VERSION IN LISTS _${_PYTHON_PREFIX}_FIND_VERSIONS) + if (_${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "FIRST") + 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] + PATH_SUFFIXES ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES} + NO_SYSTEM_ENVIRONMENT_PATH + NO_CMAKE_SYSTEM_PATH) + _python_validate_compiler (${_${_PYTHON_PREFIX}_VERSION} EXACT) + if (_${_PYTHON_PREFIX}_COMPILER) + break() + endif() + endif() - break() - endwhile() - else() - # try using root dir and registry - foreach (_${_PYTHON_PREFIX}_VERSION IN LISTS _${_PYTHON_PREFIX}_FIND_VERSIONS) - if (_${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "FIRST") - find_program (${_PYTHON_PREFIX}_COMPILER + 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] PATH_SUFFIXES ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES} NO_SYSTEM_ENVIRONMENT_PATH NO_CMAKE_SYSTEM_PATH) _python_validate_compiler (${_${_PYTHON_PREFIX}_VERSION} EXACT) - if (${_PYTHON_PREFIX}_COMPILER) + if (_${_PYTHON_PREFIX}_COMPILER) break() endif() - endif() - - find_program (${_PYTHON_PREFIX}_COMPILER - NAMES ipyc - HINTS ${_${_PYTHON_PREFIX}_IRON_ROOT} ${_${_PYTHON_PREFIX}_HINTS} - PATH_SUFFIXES ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES} - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - _python_validate_compiler (${_${_PYTHON_PREFIX}_VERSION} EXACT) - if (${_PYTHON_PREFIX}_COMPILER) - break() - endif() - if (_${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "LAST") - find_program (${_PYTHON_PREFIX}_COMPILER - NAMES ipyc - PATHS [HKEY_LOCAL_MACHINE\\SOFTWARE\\IronPython\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] - PATH_SUFFIXES ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES} - NO_DEFAULT_PATH) - _python_validate_compiler (${_${_PYTHON_PREFIX}_VERSION} EXACT) - if (${_PYTHON_PREFIX}_COMPILER) - break() + if (_${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "LAST") + find_program (_${_PYTHON_PREFIX}_COMPILER + NAMES ipyc + PATHS [HKEY_LOCAL_MACHINE\\SOFTWARE\\IronPython\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] + PATH_SUFFIXES ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES} + NO_DEFAULT_PATH) + _python_validate_compiler (${_${_PYTHON_PREFIX}_VERSION} EXACT) + if (_${_PYTHON_PREFIX}_COMPILER) + break() + endif() endif() - endif() - endforeach() + endforeach() - # no specific version found, re-try in standard paths - find_program (${_PYTHON_PREFIX}_COMPILER - NAMES ipyc - HINTS ${_${_PYTHON_PREFIX}_IRON_ROOT} ${_${_PYTHON_PREFIX}_HINTS} - PATH_SUFFIXES ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES}) + # no specific version found, re-try in standard paths + find_program (_${_PYTHON_PREFIX}_COMPILER + NAMES ipyc + HINTS ${_${_PYTHON_PREFIX}_IRON_ROOT} ${_${_PYTHON_PREFIX}_HINTS} + PATH_SUFFIXES ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES}) + endif() endif() - if (${_PYTHON_PREFIX}_COMPILER) + set (${_PYTHON_PREFIX}_COMPILER "${_${_PYTHON_PREFIX}_COMPILER}") + + 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" + 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) @@ -1158,6 +1400,7 @@ if ("Compiler" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) OUTPUT_VARIABLE _${_PYTHON_PREFIX}_VERSION ERROR_QUIET) if (NOT _${_PYTHON_PREFIX}_RESULT) + set (_${_PYTHON_PREFIX}_COMPILER_USABLE TRUE) 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) @@ -1172,12 +1415,12 @@ if ("Compiler" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) endif() else() # compiler not usable - set_property (CACHE ${_PYTHON_PREFIX}_COMPILER PROPERTY VALUE "${_PYTHON_PREFIX}_COMPILER-NOTFOUND") + set (_${_PYTHON_PREFIX}_COMPILER_USABLE FALSE) endif() file (REMOVE_RECURSE "${_${_PYTHON_PREFIX}_VERSION_DIR}") endif() - if (${_PYTHON_PREFIX}_COMPILER) + if (_${_PYTHON_PREFIX}_COMPILER AND _${_PYTHON_PREFIX}_COMPILER_USABLE) 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}) @@ -1191,12 +1434,18 @@ if ("Compiler" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) endif() if (${_PYTHON_PREFIX}_Compiler_FOUND) + # compute and save compiler signature + string (MD5 __${_PYTHON_PREFIX}_COMPILER_SIGNATURE "${_${_PYTHON_PREFIX}_SIGNATURE}:${_${_PYTHON_PREFIX}_COMPILER}") + set (_${_PYTHON_PREFIX}_COMPILER_SIGNATURE "${__${_PYTHON_PREFIX}_COMPILER_SIGNATURE}" CACHE INTERNAL "") + set (${_PYTHON_PREFIX}_COMPILER_ID IronPython) else() + unset (_${_PYTHON_PREFIX}_COMPILER_SIGNATURE CACHE) unset (${_PYTHON_PREFIX}_COMPILER_ID) endif() - mark_as_advanced (${_PYTHON_PREFIX}_COMPILER) + mark_as_advanced (_${_PYTHON_PREFIX}_COMPILER + _${_PYTHON_PREFIX}_COMPILER_SIGNATURE) endif() @@ -1204,15 +1453,50 @@ endif() ## Development environment is not compatible with IronPython interpreter if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS AND NOT ${_PYTHON_PREFIX}_INTERPRETER_ID STREQUAL "IronPython") - list (APPEND _${_PYTHON_PREFIX}_CACHED_VARS ${_PYTHON_PREFIX}_LIBRARY - ${_PYTHON_PREFIX}_LIBRARY_RELEASE + list (APPEND _${_PYTHON_PREFIX}_CACHED_VARS _${_PYTHON_PREFIX}_LIBRARY_RELEASE ${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE - ${_PYTHON_PREFIX}_LIBRARY_DEBUG + _${_PYTHON_PREFIX}_LIBRARY_DEBUG ${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG - ${_PYTHON_PREFIX}_INCLUDE_DIR) + _${_PYTHON_PREFIX}_INCLUDE_DIR) if (${_PYTHON_PREFIX}_FIND_REQUIRED_Development) - list (APPEND _${_PYTHON_PREFIX}_REQUIRED_VARS ${_PYTHON_PREFIX}_LIBRARY - ${_PYTHON_PREFIX}_INCLUDE_DIR) + list (APPEND _${_PYTHON_PREFIX}_REQUIRED_VARS ${_PYTHON_PREFIX}_LIBRARIES + ${_PYTHON_PREFIX}_INCLUDE_DIRS) + endif() + + if (DEFINED _${_PYTHON_PREFIX}_LIBRARY_RELEASE OR DEFINED _${_PYTHON_PREFIX}_INCLUDE_DIR) + # compute development signature and check validity of definition + string (MD5 __${_PYTHON_PREFIX}_DEVELOPMENT_SIGNATURE "${_${_PYTHON_PREFIX}_SIGNATURE}:${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}:${_${_PYTHON_PREFIX}_INCLUDE_DIR}") + if (WIN32 AND NOT DEFINED _${_PYTHON_PREFIX}_LIBRARY_DEBUG) + set (_${_PYTHON_PREFIX}_LIBRARY_DEBUG "_${_PYTHON_PREFIX}_LIBRARY_DEBUG-NOTFOUND" CACHE INTERNAL "") + endif() + if (NOT DEFINED _${_PYTHON_PREFIX}_INCLUDE_DIR) + set (_${_PYTHON_PREFIX}_INCLUDE_DIR "_${_PYTHON_PREFIX}_INCLUDE_DIR-NOTFOUND" CACHE INTERNAL "") + endif() + if (__${_PYTHON_PREFIX}_DEVELOPMENT_SIGNATURE STREQUAL _${_PYTHON_PREFIX}_DEVELOPMENT_SIGNATURE) + # check version validity + if (${_PYTHON_PREFIX}_FIND_VERSION_EXACT) + _python_validate_library (${${_PYTHON_PREFIX}_FIND_VERSION} EXACT CHECK_EXISTS) + _python_validate_include_dir (${${_PYTHON_PREFIX}_FIND_VERSION} EXACT CHECK_EXISTS) + else() + _python_validate_library (${${_PYTHON_PREFIX}_FIND_VERSION} CHECK_EXISTS) + _python_validate_include_dir (${${_PYTHON_PREFIX}_FIND_VERSION} CHECK_EXISTS) + endif() + else() + unset (_${_PYTHON_PREFIX}_LIBRARY_RELEASE CACHE) + unset (_${_PYTHON_PREFIX}_LIBRARY_DEBUG CACHE) + unset (_${_PYTHON_PREFIX}_INCLUDE_DIR CACHE) + unset (_${_PYTHON_PREFIX}_DEVELOPMENT_SIGNATURE CACHE) + endif() + endif() + if (DEFINED ${_PYTHON_PREFIX}_LIBRARY + AND IS_ABSOLUTE "${${_PYTHON_PREFIX}_LIBRARY}") + set (_${_PYTHON_PREFIX}_LIBRARY_RELEASE "${${_PYTHON_PREFIX}_LIBRARY}" CACHE INTERNAL "") + unset (_${_PYTHON_PREFIX}_LIBRARY_DEBUG CACHE) + unset (_${_PYTHON_PREFIX}_INCLUDE_DIR CACHE) + endif() + if (DEFINED ${_PYTHON_PREFIX}_INCLUDE_DIR + AND IS_ABSOLUTE "${${_PYTHON_PREFIX}_INCLUDE_DIR}") + set (_${_PYTHON_PREFIX}_INCLUDE_DIR "${${_PYTHON_PREFIX}_INCLUDE_DIR}" CACHE INTERNAL "") endif() # Support preference of static libs by adjusting CMAKE_FIND_LIBRARY_SUFFIXES @@ -1226,116 +1510,33 @@ if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS endif() endif() - # if python interpreter is found, use it to ensure consistency - # between interpreter and development environment. - # If not, try to locate a compatible config tool - if (NOT ${_PYTHON_PREFIX}_Interpreter_FOUND OR CMAKE_CROSSCOMPILING) - set (_${_PYTHON_PREFIX}_HINTS "${${_PYTHON_PREFIX}_ROOT_DIR}" ENV ${_PYTHON_PREFIX}_ROOT_DIR) - unset (_${_PYTHON_PREFIX}_VIRTUALENV_PATHS) - if (_${_PYTHON_PREFIX}_FIND_VIRTUALENV MATCHES "^(FIRST|ONLY)$") - set (_${_PYTHON_PREFIX}_VIRTUALENV_PATHS ENV VIRTUAL_ENV) - endif() - unset (_${_PYTHON_PREFIX}_FRAMEWORK_PATHS) - - if (_${_PYTHON_PREFIX}_FIND_STRATEGY STREQUAL "LOCATION") - set (_${_PYTHON_PREFIX}_CONFIG_NAMES) - - foreach (_${_PYTHON_PREFIX}_VERSION IN LISTS _${_PYTHON_PREFIX}_FIND_VERSIONS) - _python_get_names (_${_PYTHON_PREFIX}_VERSION_NAMES VERSION ${_${_PYTHON_PREFIX}_VERSION} POSIX CONFIG) - list (APPEND _${_PYTHON_PREFIX}_CONFIG_NAMES ${_${_PYTHON_PREFIX}_VERSION_NAMES}) - - # Framework Paths - _python_get_frameworks (_${_PYTHON_PREFIX}_VERSION_PATHS ${_${_PYTHON_PREFIX}_VERSION}) - list (APPEND _${_PYTHON_PREFIX}_FRAMEWORK_PATHS ${_${_PYTHON_PREFIX}_VERSION_PATHS}) - endforeach() - - # Apple frameworks handling - if (CMAKE_HOST_APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "FIRST") - find_program (${_PYTHON_PREFIX}_CONFIG - NAMES ${_${_PYTHON_PREFIX}_CONFIG_NAMES} - NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATHS ${_${_PYTHON_PREFIX}_VIRTUALENV_PATHS} - ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS} - PATH_SUFFIXES bin - NO_CMAKE_PATH - NO_CMAKE_ENVIRONMENT_PATH - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - endif() - - find_program (_${_PYTHON_PREFIX}_CONFIG - NAMES ${_${_PYTHON_PREFIX}_CONFIG_NAMES} - NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATHS ${_${_PYTHON_PREFIX}_VIRTUALENV_PATHS} - PATH_SUFFIXES bin) - - # Apple frameworks handling - if (CMAKE_HOST_APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "LAST") - find_program (_${_PYTHON_PREFIX}_CONFIG - NAMES ${_${_PYTHON_PREFIX}_CONFIG_NAMES} - NAMES_PER_DIR - PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS} - PATH_SUFFIXES bin - NO_DEFAULT_PATH) - endif() - - if (_${_PYTHON_PREFIX}_CONFIG) - execute_process (COMMAND "${_${_PYTHON_PREFIX}_CONFIG}" --help - RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT - OUTPUT_VARIABLE __${_PYTHON_PREFIX}_HELP - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - if (_${_PYTHON_PREFIX}_RESULT) - # assume config tool is not usable - unset (_${_PYTHON_PREFIX}_CONFIG CACHE) - endif() + if (NOT _${_PYTHON_PREFIX}_LIBRARY_RELEASE OR NOT _${_PYTHON_PREFIX}_INCLUDE_DIR) + # if python interpreter is found, use it to look-up for artifacts + # to ensure consistency between interpreter and development environments. + # If not, try to locate a compatible config tool + if (NOT ${_PYTHON_PREFIX}_Interpreter_FOUND OR CMAKE_CROSSCOMPILING) + set (_${_PYTHON_PREFIX}_HINTS "${${_PYTHON_PREFIX}_ROOT_DIR}" ENV ${_PYTHON_PREFIX}_ROOT_DIR) + unset (_${_PYTHON_PREFIX}_VIRTUALENV_PATHS) + if (_${_PYTHON_PREFIX}_FIND_VIRTUALENV MATCHES "^(FIRST|ONLY)$") + set (_${_PYTHON_PREFIX}_VIRTUALENV_PATHS ENV VIRTUAL_ENV) endif() + unset (_${_PYTHON_PREFIX}_FRAMEWORK_PATHS) - if (_${_PYTHON_PREFIX}_CONFIG) - execute_process (COMMAND "${_${_PYTHON_PREFIX}_CONFIG}" --abiflags - RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT - OUTPUT_VARIABLE __${_PYTHON_PREFIX}_ABIFLAGS - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - if (_${_PYTHON_PREFIX}_RESULT) - # assume ABI is not supported - set (__${_PYTHON_PREFIX}_ABIFLAGS "") - endif() - if (DEFINED _${_PYTHON_PREFIX}_FIND_ABI AND NOT __${_PYTHON_PREFIX}_ABIFLAGS IN_LIST _${_PYTHON_PREFIX}_ABIFLAGS) - # Wrong ABI - unset (_${_PYTHON_PREFIX}_CONFIG CACHE) - endif() - endif() + if (_${_PYTHON_PREFIX}_FIND_STRATEGY STREQUAL "LOCATION") + set (_${_PYTHON_PREFIX}_CONFIG_NAMES) - if (_${_PYTHON_PREFIX}_CONFIG AND DEFINED CMAKE_LIBRARY_ARCHITECTURE) - # check that config tool match library architecture - execute_process (COMMAND "${_${_PYTHON_PREFIX}_CONFIG}" --configdir - RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT - OUTPUT_VARIABLE _${_PYTHON_PREFIX}_CONFIGDIR - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - if (_${_PYTHON_PREFIX}_RESULT) - unset (_${_PYTHON_PREFIX}_CONFIG CACHE) - else() - string(FIND "${_${_PYTHON_PREFIX}_CONFIGDIR}" "${CMAKE_LIBRARY_ARCHITECTURE}" _${_PYTHON_PREFIX}_RESULT) - if (_${_PYTHON_PREFIX}_RESULT EQUAL -1) - unset (_${_PYTHON_PREFIX}_CONFIG CACHE) - endif() - endif() - endif() - else() - foreach (_${_PYTHON_PREFIX}_VERSION IN LISTS _${_PYTHON_PREFIX}_FIND_VERSIONS) - # try to use pythonX.Y-config tool - _python_get_names (_${_PYTHON_PREFIX}_CONFIG_NAMES VERSION ${_${_PYTHON_PREFIX}_VERSION} POSIX CONFIG) + foreach (_${_PYTHON_PREFIX}_VERSION IN LISTS _${_PYTHON_PREFIX}_FIND_VERSIONS) + _python_get_names (_${_PYTHON_PREFIX}_VERSION_NAMES VERSION ${_${_PYTHON_PREFIX}_VERSION} POSIX CONFIG) + list (APPEND _${_PYTHON_PREFIX}_CONFIG_NAMES ${_${_PYTHON_PREFIX}_VERSION_NAMES}) - # Framework Paths - _python_get_frameworks (_${_PYTHON_PREFIX}_FRAMEWORK_PATHS ${_${_PYTHON_PREFIX}_VERSION}) + # Framework Paths + _python_get_frameworks (_${_PYTHON_PREFIX}_VERSION_PATHS ${_${_PYTHON_PREFIX}_VERSION}) + list (APPEND _${_PYTHON_PREFIX}_FRAMEWORK_PATHS ${_${_PYTHON_PREFIX}_VERSION_PATHS}) + endforeach() # Apple frameworks handling if (CMAKE_HOST_APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "FIRST") - find_program (${_PYTHON_PREFIX}_CONFIG + find_program (_${_PYTHON_PREFIX}_CONFIG NAMES ${_${_PYTHON_PREFIX}_CONFIG_NAMES} NAMES_PER_DIR HINTS ${_${_PYTHON_PREFIX}_HINTS} @@ -1365,8 +1566,6 @@ if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS NO_DEFAULT_PATH) endif() - unset (_${_PYTHON_PREFIX}_CONFIG_NAMES) - if (_${_PYTHON_PREFIX}_CONFIG) execute_process (COMMAND "${_${_PYTHON_PREFIX}_CONFIG}" --help RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT @@ -1379,23 +1578,20 @@ if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS endif() endif() - if (NOT _${_PYTHON_PREFIX}_CONFIG) - continue() - endif() - - execute_process (COMMAND "${_${_PYTHON_PREFIX}_CONFIG}" --abiflags - RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT - OUTPUT_VARIABLE __${_PYTHON_PREFIX}_ABIFLAGS - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - if (_${_PYTHON_PREFIX}_RESULT) - # assume ABI is not supported - set (__${_PYTHON_PREFIX}_ABIFLAGS "") - endif() - if (DEFINED _${_PYTHON_PREFIX}_FIND_ABI AND NOT __${_PYTHON_PREFIX}_ABIFLAGS IN_LIST _${_PYTHON_PREFIX}_ABIFLAGS) - # Wrong ABI - unset (_${_PYTHON_PREFIX}_CONFIG CACHE) - continue() + if (_${_PYTHON_PREFIX}_CONFIG) + execute_process (COMMAND "${_${_PYTHON_PREFIX}_CONFIG}" --abiflags + RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT + OUTPUT_VARIABLE __${_PYTHON_PREFIX}_ABIFLAGS + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE) + if (_${_PYTHON_PREFIX}_RESULT) + # assume ABI is not supported + set (__${_PYTHON_PREFIX}_ABIFLAGS "") + endif() + if (DEFINED _${_PYTHON_PREFIX}_FIND_ABI AND NOT __${_PYTHON_PREFIX}_ABIFLAGS IN_LIST _${_PYTHON_PREFIX}_ABIFLAGS) + # Wrong ABI + unset (_${_PYTHON_PREFIX}_CONFIG CACHE) + endif() endif() if (_${_PYTHON_PREFIX}_CONFIG AND DEFINED CMAKE_LIBRARY_ARCHITECTURE) @@ -1407,231 +1603,184 @@ if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS OUTPUT_STRIP_TRAILING_WHITESPACE) if (_${_PYTHON_PREFIX}_RESULT) unset (_${_PYTHON_PREFIX}_CONFIG CACHE) - continue() - endif() - string(FIND "${_${_PYTHON_PREFIX}_CONFIGDIR}" "${CMAKE_LIBRARY_ARCHITECTURE}" _${_PYTHON_PREFIX}_RESULT) - if (_${_PYTHON_PREFIX}_RESULT EQUAL -1) - unset (_${_PYTHON_PREFIX}_CONFIG CACHE) - continue() + else() + string(FIND "${_${_PYTHON_PREFIX}_CONFIGDIR}" "${CMAKE_LIBRARY_ARCHITECTURE}" _${_PYTHON_PREFIX}_RESULT) + if (_${_PYTHON_PREFIX}_RESULT EQUAL -1) + unset (_${_PYTHON_PREFIX}_CONFIG CACHE) + endif() endif() endif() + else() + foreach (_${_PYTHON_PREFIX}_VERSION IN LISTS _${_PYTHON_PREFIX}_FIND_VERSIONS) + # try to use pythonX.Y-config tool + _python_get_names (_${_PYTHON_PREFIX}_CONFIG_NAMES VERSION ${_${_PYTHON_PREFIX}_VERSION} POSIX CONFIG) - if (_${_PYTHON_PREFIX}_CONFIG) - break() - endif() - endforeach() - endif() - endif() - - if ((${_PYTHON_PREFIX}_Interpreter_FOUND AND NOT CMAKE_CROSSCOMPILING) OR _${_PYTHON_PREFIX}_CONFIG) - # retrieve root install directory - _python_get_config_var (_${_PYTHON_PREFIX}_PREFIX PREFIX) - - # enforce current ABI - _python_get_config_var (_${_PYTHON_PREFIX}_ABIFLAGS ABIFLAGS) - - set (_${_PYTHON_PREFIX}_HINTS "${_${_PYTHON_PREFIX}_PREFIX}") + # Framework Paths + _python_get_frameworks (_${_PYTHON_PREFIX}_FRAMEWORK_PATHS ${_${_PYTHON_PREFIX}_VERSION}) - # retrieve library - ## compute some paths and artifact names - if (_${_PYTHON_PREFIX}_CONFIG) - string (REGEX REPLACE "^.+python([0-9.]+)[a-z]*-config" "\\1" _${_PYTHON_PREFIX}_LIB_VERSION "${_${_PYTHON_PREFIX}_CONFIG}") - else() - set (_${_PYTHON_PREFIX}_LIB_VERSION "${${_PYTHON_PREFIX}_VERSION_MAJOR}.${${_PYTHON_PREFIX}_VERSION_MINOR}") - endif() - _python_get_path_suffixes (_${_PYTHON_PREFIX}_PATH_SUFFIXES VERSION ${_${_PYTHON_PREFIX}_LIB_VERSION} LIBRARY) - _python_get_names (_${_PYTHON_PREFIX}_LIB_NAMES VERSION ${_${_PYTHON_PREFIX}_LIB_VERSION} POSIX LIBRARY) + # Apple frameworks handling + if (CMAKE_HOST_APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "FIRST") + find_program (_${_PYTHON_PREFIX}_CONFIG + NAMES ${_${_PYTHON_PREFIX}_CONFIG_NAMES} + NAMES_PER_DIR + HINTS ${_${_PYTHON_PREFIX}_HINTS} + PATHS ${_${_PYTHON_PREFIX}_VIRTUALENV_PATHS} + ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS} + PATH_SUFFIXES bin + NO_CMAKE_PATH + NO_CMAKE_ENVIRONMENT_PATH + NO_SYSTEM_ENVIRONMENT_PATH + NO_CMAKE_SYSTEM_PATH) + endif() - _python_get_config_var (_${_PYTHON_PREFIX}_CONFIGDIR CONFIGDIR) - list (APPEND _${_PYTHON_PREFIX}_HINTS "${_${_PYTHON_PREFIX}_CONFIGDIR}") + find_program (_${_PYTHON_PREFIX}_CONFIG + NAMES ${_${_PYTHON_PREFIX}_CONFIG_NAMES} + NAMES_PER_DIR + HINTS ${_${_PYTHON_PREFIX}_HINTS} + PATHS ${_${_PYTHON_PREFIX}_VIRTUALENV_PATHS} + PATH_SUFFIXES bin) - list (APPEND _${_PYTHON_PREFIX}_HINTS "${${_PYTHON_PREFIX}_ROOT_DIR}" ENV ${_PYTHON_PREFIX}_ROOT_DIR) + # Apple frameworks handling + if (CMAKE_HOST_APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "LAST") + find_program (_${_PYTHON_PREFIX}_CONFIG + NAMES ${_${_PYTHON_PREFIX}_CONFIG_NAMES} + NAMES_PER_DIR + PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS} + PATH_SUFFIXES bin + NO_DEFAULT_PATH) + endif() - find_library (${_PYTHON_PREFIX}_LIBRARY_RELEASE - NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES} - NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES} - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - - # retrieve runtime library - if (${_PYTHON_PREFIX}_LIBRARY_RELEASE) - get_filename_component (_${_PYTHON_PREFIX}_PATH "${${_PYTHON_PREFIX}_LIBRARY_RELEASE}" DIRECTORY) - get_filename_component (_${_PYTHON_PREFIX}_PATH2 "${_${_PYTHON_PREFIX}_PATH}" DIRECTORY) - _python_find_runtime_library (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE - NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES} - NAMES_PER_DIR - HINTS "${_${_PYTHON_PREFIX}_PATH}" "${_${_PYTHON_PREFIX}_PATH2}" ${_${_PYTHON_PREFIX}_HINTS} - PATH_SUFFIXES bin - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - endif() + unset (_${_PYTHON_PREFIX}_CONFIG_NAMES) + + if (_${_PYTHON_PREFIX}_CONFIG) + execute_process (COMMAND "${_${_PYTHON_PREFIX}_CONFIG}" --help + RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT + OUTPUT_VARIABLE __${_PYTHON_PREFIX}_HELP + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE) + if (_${_PYTHON_PREFIX}_RESULT) + # assume config tool is not usable + unset (_${_PYTHON_PREFIX}_CONFIG CACHE) + endif() + endif() - # retrieve include directory - _python_get_config_var (_${_PYTHON_PREFIX}_INCLUDE_DIRS INCLUDES) + if (NOT _${_PYTHON_PREFIX}_CONFIG) + continue() + endif() - find_path (${_PYTHON_PREFIX}_INCLUDE_DIR - NAMES Python.h - HINTS ${_${_PYTHON_PREFIX}_INCLUDE_DIRS} - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - endif() + execute_process (COMMAND "${_${_PYTHON_PREFIX}_CONFIG}" --abiflags + RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT + OUTPUT_VARIABLE __${_PYTHON_PREFIX}_ABIFLAGS + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE) + if (_${_PYTHON_PREFIX}_RESULT) + # assume ABI is not supported + set (__${_PYTHON_PREFIX}_ABIFLAGS "") + endif() + if (DEFINED _${_PYTHON_PREFIX}_FIND_ABI AND NOT __${_PYTHON_PREFIX}_ABIFLAGS IN_LIST _${_PYTHON_PREFIX}_ABIFLAGS) + # Wrong ABI + unset (_${_PYTHON_PREFIX}_CONFIG CACHE) + continue() + endif() - # Rely on HINTS and standard paths if interpreter or config tool failed to locate artifacts - if (NOT ${_PYTHON_PREFIX}_LIBRARY_RELEASE OR NOT ${_PYTHON_PREFIX}_INCLUDE_DIR) - set (_${_PYTHON_PREFIX}_HINTS "${${_PYTHON_PREFIX}_ROOT_DIR}" ENV ${_PYTHON_PREFIX}_ROOT_DIR) + if (_${_PYTHON_PREFIX}_CONFIG AND DEFINED CMAKE_LIBRARY_ARCHITECTURE) + # check that config tool match library architecture + execute_process (COMMAND "${_${_PYTHON_PREFIX}_CONFIG}" --configdir + RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT + OUTPUT_VARIABLE _${_PYTHON_PREFIX}_CONFIGDIR + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE) + if (_${_PYTHON_PREFIX}_RESULT) + unset (_${_PYTHON_PREFIX}_CONFIG CACHE) + continue() + endif() + string (FIND "${_${_PYTHON_PREFIX}_CONFIGDIR}" "${CMAKE_LIBRARY_ARCHITECTURE}" _${_PYTHON_PREFIX}_RESULT) + if (_${_PYTHON_PREFIX}_RESULT EQUAL -1) + unset (_${_PYTHON_PREFIX}_CONFIG CACHE) + continue() + endif() + endif() - unset (_${_PYTHON_PREFIX}_VIRTUALENV_PATHS) - if (_${_PYTHON_PREFIX}_FIND_VIRTUALENV MATCHES "^(FIRST|ONLY)$") - set (_${_PYTHON_PREFIX}_VIRTUALENV_PATHS ENV VIRTUAL_ENV) + if (_${_PYTHON_PREFIX}_CONFIG) + break() + endif() + endforeach() + endif() endif() + endif() - if (_${_PYTHON_PREFIX}_FIND_STRATEGY STREQUAL "LOCATION") - unset (_${_PYTHON_PREFIX}_LIB_NAMES) - unset (_${_PYTHON_PREFIX}_LIB_NAMES_DEBUG) - unset (_${_PYTHON_PREFIX}_FRAMEWORK_PATHS) - unset (_${_PYTHON_PREFIX}_REGISTRY_PATHS) - unset (_${_PYTHON_PREFIX}_PATH_SUFFIXES) - - foreach (_${_PYTHON_PREFIX}_LIB_VERSION IN LISTS _${_PYTHON_PREFIX}_FIND_VERSIONS) - # library names - _python_get_names (_${_PYTHON_PREFIX}_VERSION_NAMES VERSION ${_${_PYTHON_PREFIX}_LIB_VERSION} WIN32 POSIX LIBRARY) - list (APPEND _${_PYTHON_PREFIX}_LIB_NAMES ${_${_PYTHON_PREFIX}_VERSION_NAMES}) - _python_get_names (_${_PYTHON_PREFIX}_VERSION_NAMES VERSION ${_${_PYTHON_PREFIX}_LIB_VERSION} WIN32 DEBUG) - list (APPEND _${_PYTHON_PREFIX}_LIB_NAMES_DEBUG ${_${_PYTHON_PREFIX}_VERSION_NAMES}) - - # Framework Paths - _python_get_frameworks (_${_PYTHON_PREFIX}_VERSION_PATHS ${_${_PYTHON_PREFIX}_LIB_VERSION}) - list (APPEND _${_PYTHON_PREFIX}_FRAMEWORK_PATHS ${_${_PYTHON_PREFIX}_VERSION_PATHS}) + if (NOT _${_PYTHON_PREFIX}_LIBRARY_RELEASE) + if ((${_PYTHON_PREFIX}_Interpreter_FOUND AND NOT CMAKE_CROSSCOMPILING) OR _${_PYTHON_PREFIX}_CONFIG) + # retrieve root install directory + _python_get_config_var (_${_PYTHON_PREFIX}_PREFIX PREFIX) - # Registry Paths - _python_get_registries (_${_PYTHON_PREFIX}_VERSION_PATHS ${_${_PYTHON_PREFIX}_LIB_VERSION}) - list (APPEND _${_PYTHON_PREFIX}_REGISTRY_PATHS ${_${_PYTHON_PREFIX}_VERSION_PATHS}) + # enforce current ABI + _python_get_config_var (_${_PYTHON_PREFIX}_ABIFLAGS ABIFLAGS) - # Paths suffixes - _python_get_path_suffixes (_${_PYTHON_PREFIX}_VERSION_PATHS VERSION ${_${_PYTHON_PREFIX}_LIB_VERSION} LIBRARY) - list (APPEND _${_PYTHON_PREFIX}_PATH_SUFFIXES ${_${_PYTHON_PREFIX}_VERSION_PATHS}) - endforeach() + set (_${_PYTHON_PREFIX}_HINTS "${_${_PYTHON_PREFIX}_PREFIX}") - if (APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "FIRST") - find_library (${_PYTHON_PREFIX}_LIBRARY_RELEASE - NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES} - NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATHS ${_${_PYTHON_PREFIX}_VIRTUALENV_PATHS} - ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS} - PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES} - NO_CMAKE_PATH - NO_CMAKE_ENVIRONMENT_PATH - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) + # retrieve library + ## compute some paths and artifact names + if (_${_PYTHON_PREFIX}_CONFIG) + string (REGEX REPLACE "^.+python([0-9.]+)[a-z]*-config" "\\1" _${_PYTHON_PREFIX}_VERSION "${_${_PYTHON_PREFIX}_CONFIG}") + else() + set (_${_PYTHON_PREFIX}_VERSION "${${_PYTHON_PREFIX}_VERSION_MAJOR}.${${_PYTHON_PREFIX}_VERSION_MINOR}") endif() + _python_get_path_suffixes (_${_PYTHON_PREFIX}_PATH_SUFFIXES VERSION ${_${_PYTHON_PREFIX}_VERSION} LIBRARY) + _python_get_names (_${_PYTHON_PREFIX}_LIB_NAMES VERSION ${_${_PYTHON_PREFIX}_VERSION} WIN32 POSIX LIBRARY) - if (WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "FIRST") - find_library (${_PYTHON_PREFIX}_LIBRARY_RELEASE - NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES} - NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATHS ${_${_PYTHON_PREFIX}_VIRTUALENV_PATHS} - ${_${_PYTHON_PREFIX}_REGISTRY_PATHS} - PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES} - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - endif() + _python_get_config_var (_${_PYTHON_PREFIX}_CONFIGDIR CONFIGDIR) + list (APPEND _${_PYTHON_PREFIX}_HINTS "${_${_PYTHON_PREFIX}_CONFIGDIR}") + + list (APPEND _${_PYTHON_PREFIX}_HINTS "${${_PYTHON_PREFIX}_ROOT_DIR}" ENV ${_PYTHON_PREFIX}_ROOT_DIR) - # search in HINTS locations - find_library (${_PYTHON_PREFIX}_LIBRARY_RELEASE + find_library (_${_PYTHON_PREFIX}_LIBRARY_RELEASE NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES} NAMES_PER_DIR HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATHS ${_${_PYTHON_PREFIX}_VIRTUALENV_PATHS} PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES} NO_SYSTEM_ENVIRONMENT_PATH NO_CMAKE_SYSTEM_PATH) + endif() - if (APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "LAST") - set (__${_PYTHON_PREFIX}_FRAMEWORK_PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS}) - else() - unset (__${_PYTHON_PREFIX}_FRAMEWORK_PATHS) - endif() - - if (WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "LAST") - set (__${_PYTHON_PREFIX}_REGISTRY_PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS}) - else() - unset (__${_PYTHON_PREFIX}_REGISTRY_PATHS) - endif() + # Rely on HINTS and standard paths if interpreter or config tool failed to locate artifacts + if (NOT _${_PYTHON_PREFIX}_LIBRARY_RELEASE) + set (_${_PYTHON_PREFIX}_HINTS "${${_PYTHON_PREFIX}_ROOT_DIR}" ENV ${_PYTHON_PREFIX}_ROOT_DIR) - # search in all default paths - find_library (${_PYTHON_PREFIX}_LIBRARY_RELEASE - NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES} - NAMES_PER_DIR - PATHS ${__${_PYTHON_PREFIX}_FRAMEWORK_PATHS} - ${__${_PYTHON_PREFIX}_REGISTRY_PATHS} - PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}) - - if (${_PYTHON_PREFIX}_LIBRARY_RELEASE) - # extract version from library name - if (${_PYTHON_PREFIX}_LIBRARY_RELEASE MATCHES "python([23])([0-9]+)") - set (_${_PYTHON_PREFIX}_VERSION "${CMAKE_MATCH_1}.${CMAKE_MATCH_2}") - elseif (${_PYTHON_PREFIX}_LIBRARY_RELEASE MATCHES "python([23])\\.([0-9]+)") - set (_${_PYTHON_PREFIX}_VERSION "${CMAKE_MATCH_1}.${CMAKE_MATCH_2}") - endif() + unset (_${_PYTHON_PREFIX}_VIRTUALENV_PATHS) + if (_${_PYTHON_PREFIX}_FIND_VIRTUALENV MATCHES "^(FIRST|ONLY)$") + set (_${_PYTHON_PREFIX}_VIRTUALENV_PATHS ENV VIRTUAL_ENV) endif() - if (WIN32) - # search for debug library - if (${_PYTHON_PREFIX}_LIBRARY_RELEASE) - # use library location as a hint - _python_get_names (_${_PYTHON_PREFIX}_LIB_NAMES_DEBUG VERSION ${_${_PYTHON_PREFIX}_VERSION} WIN32 DEBUG) - get_filename_component (_${_PYTHON_PREFIX}_PATH "${${_PYTHON_PREFIX}_LIBRARY_RELEASE}" DIRECTORY) - find_library (${_PYTHON_PREFIX}_LIBRARY_DEBUG - NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES_DEBUG} - NAMES_PER_DIR - HINTS "${_${_PYTHON_PREFIX}_PATH}" ${_${_PYTHON_PREFIX}_HINTS} - NO_DEFAULT_PATH) - else() - # search first in known locations - if (_${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "FIRST") - find_library (${_PYTHON_PREFIX}_LIBRARY_DEBUG - NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES_DEBUG} - NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATHS ${_${_PYTHON_PREFIX}_VIRTUALENV_PATHS} - ${_${_PYTHON_PREFIX}_REGISTRY_PATHS} - PATH_SUFFIXES lib libs - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - endif() - # search in all default paths - find_library (${_PYTHON_PREFIX}_LIBRARY_DEBUG - NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES_DEBUG} - NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATHS ${_${_PYTHON_PREFIX}_VIRTUALENV_PATHS} - ${__${_PYTHON_PREFIX}_REGISTRY_PATHS} - PATH_SUFFIXES lib libs) - - # extract version from library name - if (${_PYTHON_PREFIX}_LIBRARY_DEBUG MATCHES "python([23])([0-9]+)") - set (_${_PYTHON_PREFIX}_VERSION "${CMAKE_MATCH_1}.${CMAKE_MATCH_2}") - elseif (${_PYTHON_PREFIX}_LIBRARY_DEBUG MATCHES "python([23])\\.([0-9]+)") - set (_${_PYTHON_PREFIX}_VERSION "${CMAKE_MATCH_1}.${CMAKE_MATCH_2}") - endif() - endif() - endif() - else() - foreach (_${_PYTHON_PREFIX}_LIB_VERSION IN LISTS _${_PYTHON_PREFIX}_FIND_VERSIONS) - _python_get_names (_${_PYTHON_PREFIX}_LIB_NAMES VERSION ${_${_PYTHON_PREFIX}_LIB_VERSION} WIN32 POSIX LIBRARY) - _python_get_names (_${_PYTHON_PREFIX}_LIB_NAMES_DEBUG VERSION ${_${_PYTHON_PREFIX}_LIB_VERSION} WIN32 DEBUG) - - _python_get_frameworks (_${_PYTHON_PREFIX}_FRAMEWORK_PATHS ${_${_PYTHON_PREFIX}_LIB_VERSION}) - _python_get_registries (_${_PYTHON_PREFIX}_REGISTRY_PATHS ${_${_PYTHON_PREFIX}_LIB_VERSION}) - - _python_get_path_suffixes (_${_PYTHON_PREFIX}_PATH_SUFFIXES VERSION ${_${_PYTHON_PREFIX}_LIB_VERSION} LIBRARY) + if (_${_PYTHON_PREFIX}_FIND_STRATEGY STREQUAL "LOCATION") + unset (_${_PYTHON_PREFIX}_LIB_NAMES) + unset (_${_PYTHON_PREFIX}_LIB_NAMES_DEBUG) + unset (_${_PYTHON_PREFIX}_FRAMEWORK_PATHS) + unset (_${_PYTHON_PREFIX}_REGISTRY_PATHS) + unset (_${_PYTHON_PREFIX}_PATH_SUFFIXES) + + foreach (_${_PYTHON_PREFIX}_LIB_VERSION IN LISTS _${_PYTHON_PREFIX}_FIND_VERSIONS) + # library names + _python_get_names (_${_PYTHON_PREFIX}_VERSION_NAMES VERSION ${_${_PYTHON_PREFIX}_LIB_VERSION} WIN32 POSIX LIBRARY) + list (APPEND _${_PYTHON_PREFIX}_LIB_NAMES ${_${_PYTHON_PREFIX}_VERSION_NAMES}) + _python_get_names (_${_PYTHON_PREFIX}_VERSION_NAMES VERSION ${_${_PYTHON_PREFIX}_LIB_VERSION} WIN32 DEBUG) + list (APPEND _${_PYTHON_PREFIX}_LIB_NAMES_DEBUG ${_${_PYTHON_PREFIX}_VERSION_NAMES}) + + # Framework Paths + _python_get_frameworks (_${_PYTHON_PREFIX}_VERSION_PATHS ${_${_PYTHON_PREFIX}_LIB_VERSION}) + list (APPEND _${_PYTHON_PREFIX}_FRAMEWORK_PATHS ${_${_PYTHON_PREFIX}_VERSION_PATHS}) + + # Registry Paths + _python_get_registries (_${_PYTHON_PREFIX}_VERSION_PATHS ${_${_PYTHON_PREFIX}_LIB_VERSION}) + list (APPEND _${_PYTHON_PREFIX}_REGISTRY_PATHS ${_${_PYTHON_PREFIX}_VERSION_PATHS}) + + # Paths suffixes + _python_get_path_suffixes (_${_PYTHON_PREFIX}_VERSION_PATHS VERSION ${_${_PYTHON_PREFIX}_LIB_VERSION} LIBRARY) + list (APPEND _${_PYTHON_PREFIX}_PATH_SUFFIXES ${_${_PYTHON_PREFIX}_VERSION_PATHS}) + endforeach() if (APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "FIRST") - find_library (${_PYTHON_PREFIX}_LIBRARY_RELEASE + find_library (_${_PYTHON_PREFIX}_LIBRARY_RELEASE NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES} NAMES_PER_DIR HINTS ${_${_PYTHON_PREFIX}_HINTS} @@ -1645,7 +1794,7 @@ if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS endif() if (WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "FIRST") - find_library (${_PYTHON_PREFIX}_LIBRARY_RELEASE + find_library (_${_PYTHON_PREFIX}_LIBRARY_RELEASE NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES} NAMES_PER_DIR HINTS ${_${_PYTHON_PREFIX}_HINTS} @@ -1657,7 +1806,7 @@ if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS endif() # search in HINTS locations - find_library (${_PYTHON_PREFIX}_LIBRARY_RELEASE + find_library (_${_PYTHON_PREFIX}_LIBRARY_RELEASE NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES} NAMES_PER_DIR HINTS ${_${_PYTHON_PREFIX}_HINTS} @@ -1666,118 +1815,184 @@ if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS NO_SYSTEM_ENVIRONMENT_PATH NO_CMAKE_SYSTEM_PATH) - if (APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "LAST") - set (__${_PYTHON_PREFIX}_FRAMEWORK_PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS}) - else() - unset (__${_PYTHON_PREFIX}_FRAMEWORK_PATHS) - endif() + if (APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "LAST") + set (__${_PYTHON_PREFIX}_FRAMEWORK_PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS}) + else() + unset (__${_PYTHON_PREFIX}_FRAMEWORK_PATHS) + endif() - if (WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "LAST") - set (__${_PYTHON_PREFIX}_REGISTRY_PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS}) - else() - unset (__${_PYTHON_PREFIX}_REGISTRY_PATHS) - endif() + if (WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "LAST") + set (__${_PYTHON_PREFIX}_REGISTRY_PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS}) + else() + unset (__${_PYTHON_PREFIX}_REGISTRY_PATHS) + endif() - # search in all default paths - find_library (${_PYTHON_PREFIX}_LIBRARY_RELEASE + # search in all default paths + find_library (_${_PYTHON_PREFIX}_LIBRARY_RELEASE NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES} NAMES_PER_DIR PATHS ${__${_PYTHON_PREFIX}_FRAMEWORK_PATHS} ${__${_PYTHON_PREFIX}_REGISTRY_PATHS} PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}) + else() + foreach (_${_PYTHON_PREFIX}_LIB_VERSION IN LISTS _${_PYTHON_PREFIX}_FIND_VERSIONS) + _python_get_names (_${_PYTHON_PREFIX}_LIB_NAMES VERSION ${_${_PYTHON_PREFIX}_LIB_VERSION} WIN32 POSIX LIBRARY) + _python_get_names (_${_PYTHON_PREFIX}_LIB_NAMES_DEBUG VERSION ${_${_PYTHON_PREFIX}_LIB_VERSION} WIN32 DEBUG) + + _python_get_frameworks (_${_PYTHON_PREFIX}_FRAMEWORK_PATHS ${_${_PYTHON_PREFIX}_LIB_VERSION}) + _python_get_registries (_${_PYTHON_PREFIX}_REGISTRY_PATHS ${_${_PYTHON_PREFIX}_LIB_VERSION}) - 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_PREFIX}_LIB_NAMES_DEBUG} + _python_get_path_suffixes (_${_PYTHON_PREFIX}_PATH_SUFFIXES VERSION ${_${_PYTHON_PREFIX}_LIB_VERSION} LIBRARY) + + if (APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "FIRST") + find_library (_${_PYTHON_PREFIX}_LIBRARY_RELEASE + NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES} NAMES_PER_DIR - HINTS "${_${_PYTHON_PREFIX}_PATH}" ${_${_PYTHON_PREFIX}_HINTS} - NO_DEFAULT_PATH) - else() - # search first in known locations - if (_${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "FIRST") - find_library (${_PYTHON_PREFIX}_LIBRARY_DEBUG - NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES_DEBUG} - NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATHS ${_${_PYTHON_PREFIX}_VIRTUALENV_PATHS} - ${_${_PYTHON_PREFIX}_REGISTRY_PATHS} - PATH_SUFFIXES lib libs - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - endif() - # search in all default paths - find_library (${_PYTHON_PREFIX}_LIBRARY_DEBUG - NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES_DEBUG} + HINTS ${_${_PYTHON_PREFIX}_HINTS} + PATHS ${_${_PYTHON_PREFIX}_VIRTUALENV_PATHS} + ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS} + PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES} + NO_CMAKE_PATH + NO_CMAKE_ENVIRONMENT_PATH + NO_SYSTEM_ENVIRONMENT_PATH + NO_CMAKE_SYSTEM_PATH) + endif() + + if (WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "FIRST") + find_library (_${_PYTHON_PREFIX}_LIBRARY_RELEASE + NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES} NAMES_PER_DIR HINTS ${_${_PYTHON_PREFIX}_HINTS} PATHS ${_${_PYTHON_PREFIX}_VIRTUALENV_PATHS} - ${__${_PYTHON_PREFIX}_REGISTRY_PATHS} - PATH_SUFFIXES lib libs) + ${_${_PYTHON_PREFIX}_REGISTRY_PATHS} + PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES} + NO_SYSTEM_ENVIRONMENT_PATH + NO_CMAKE_SYSTEM_PATH) endif() - endif() - if (${_PYTHON_PREFIX}_LIBRARY_RELEASE OR ${_PYTHON_PREFIX}_LIBRARY_DEBUG) - set (_${_PYTHON_PREFIX}_VERSION ${_${_PYTHON_PREFIX}_LIB_VERSION}) - break() - endif() - endforeach() - endif() + # search in HINTS locations + find_library (_${_PYTHON_PREFIX}_LIBRARY_RELEASE + NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES} + NAMES_PER_DIR + HINTS ${_${_PYTHON_PREFIX}_HINTS} + PATHS ${_${_PYTHON_PREFIX}_VIRTUALENV_PATHS} + PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES} + NO_SYSTEM_ENVIRONMENT_PATH + NO_CMAKE_SYSTEM_PATH) - # retrieve runtime libraries - if (${_PYTHON_PREFIX}_LIBRARY_RELEASE) - _python_get_names (_${_PYTHON_PREFIX}_LIB_NAMES VERSION ${_${_PYTHON_PREFIX}_VERSION} WIN32 POSIX LIBRARY) - get_filename_component (_${_PYTHON_PREFIX}_PATH "${${_PYTHON_PREFIX}_LIBRARY_RELEASE}" DIRECTORY) - get_filename_component (_${_PYTHON_PREFIX}_PATH2 "${_${_PYTHON_PREFIX}_PATH}" DIRECTORY) - _python_find_runtime_library (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE - NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES} - NAMES_PER_DIR - HINTS "${_${_PYTHON_PREFIX}_PATH}" "${_${_PYTHON_PREFIX}_PATH2}" ${_${_PYTHON_PREFIX}_HINTS} - PATH_SUFFIXES bin) + if (APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "LAST") + set (__${_PYTHON_PREFIX}_FRAMEWORK_PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS}) + else() + unset (__${_PYTHON_PREFIX}_FRAMEWORK_PATHS) + endif() + + if (WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "LAST") + set (__${_PYTHON_PREFIX}_REGISTRY_PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS}) + else() + unset (__${_PYTHON_PREFIX}_REGISTRY_PATHS) + endif() + + # search in all default paths + find_library (_${_PYTHON_PREFIX}_LIBRARY_RELEASE + NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES} + NAMES_PER_DIR + PATHS ${__${_PYTHON_PREFIX}_FRAMEWORK_PATHS} + ${__${_PYTHON_PREFIX}_REGISTRY_PATHS} + PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}) + + if (_${_PYTHON_PREFIX}_LIBRARY_RELEASE) + break() + endif() + endforeach() + endif() endif() - if (${_PYTHON_PREFIX}_LIBRARY_DEBUG) - _python_get_names (_${_PYTHON_PREFIX}_LIB_NAMES_DEBUG VERSION ${_${_PYTHON_PREFIX}_VERSION} WIN32 DEBUG) - get_filename_component (_${_PYTHON_PREFIX}_PATH "${${_PYTHON_PREFIX}_LIBRARY_DEBUG}" DIRECTORY) - get_filename_component (_${_PYTHON_PREFIX}_PATH2 "${_${_PYTHON_PREFIX}_PATH}" DIRECTORY) - _python_find_runtime_library (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG - NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES_DEBUG} - NAMES_PER_DIR - HINTS "${_${_PYTHON_PREFIX}_PATH}" "${_${_PYTHON_PREFIX}_PATH2}" ${_${_PYTHON_PREFIX}_HINTS} - PATH_SUFFIXES bin) + endif() + + # finalize library version information + _python_get_version (LIBRARY PREFIX _${_PYTHON_PREFIX}_) + + set (${_PYTHON_PREFIX}_LIBRARY_RELEASE "${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}" CACHE FILEPATH "Path to a library." FORCE) + + if (_${_PYTHON_PREFIX}_LIBRARY_RELEASE AND NOT EXISTS "${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}") + set_property (CACHE _${_PYTHON_PREFIX}_LIBRARY_RELEASE PROPERTY VALUE "_${_PYTHON_PREFIX}_LIBRARY_RELEASE-NOTFOUND") + endif() + + set (_${_PYTHON_PREFIX}_HINTS "${${_PYTHON_PREFIX}_ROOT_DIR}" ENV ${_PYTHON_PREFIX}_ROOT_DIR) + + if (WIN32 AND _${_PYTHON_PREFIX}_LIBRARY_RELEASE) + # search for debug library + # use release library location as a hint + _python_get_names (_${_PYTHON_PREFIX}_LIB_NAMES_DEBUG VERSION ${_${_PYTHON_PREFIX}_VERSION} WIN32 DEBUG) + get_filename_component (_${_PYTHON_PREFIX}_PATH "${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}" DIRECTORY) + find_library (_${_PYTHON_PREFIX}_LIBRARY_DEBUG + NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES_DEBUG} + NAMES_PER_DIR + HINTS "${_${_PYTHON_PREFIX}_PATH}" ${_${_PYTHON_PREFIX}_HINTS} + NO_DEFAULT_PATH) + endif() + + # retrieve runtime libraries + if (_${_PYTHON_PREFIX}_LIBRARY_RELEASE) + _python_get_names (_${_PYTHON_PREFIX}_LIB_NAMES VERSION ${_${_PYTHON_PREFIX}_VERSION} WIN32 POSIX LIBRARY) + get_filename_component (_${_PYTHON_PREFIX}_PATH "${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}" DIRECTORY) + get_filename_component (_${_PYTHON_PREFIX}_PATH2 "${_${_PYTHON_PREFIX}_PATH}" DIRECTORY) + _python_find_runtime_library (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE + NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES} + NAMES_PER_DIR + HINTS "${_${_PYTHON_PREFIX}_PATH}" "${_${_PYTHON_PREFIX}_PATH2}" ${_${_PYTHON_PREFIX}_HINTS} + PATH_SUFFIXES bin) + endif() + if (_${_PYTHON_PREFIX}_LIBRARY_DEBUG) + _python_get_names (_${_PYTHON_PREFIX}_LIB_NAMES_DEBUG VERSION ${_${_PYTHON_PREFIX}_VERSION} WIN32 DEBUG) + get_filename_component (_${_PYTHON_PREFIX}_PATH "${_${_PYTHON_PREFIX}_LIBRARY_DEBUG}" DIRECTORY) + get_filename_component (_${_PYTHON_PREFIX}_PATH2 "${_${_PYTHON_PREFIX}_PATH}" DIRECTORY) + _python_find_runtime_library (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG + NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES_DEBUG} + NAMES_PER_DIR + HINTS "${_${_PYTHON_PREFIX}_PATH}" "${_${_PYTHON_PREFIX}_PATH2}" ${_${_PYTHON_PREFIX}_HINTS} + PATH_SUFFIXES bin) + endif() + + # Don't search for include dir if no library was founded + if (_${_PYTHON_PREFIX}_LIBRARY_RELEASE AND NOT _${_PYTHON_PREFIX}_INCLUDE_DIR) + if ((${_PYTHON_PREFIX}_Interpreter_FOUND AND NOT CMAKE_CROSSCOMPILING) OR _${_PYTHON_PREFIX}_CONFIG) + _python_get_config_var (_${_PYTHON_PREFIX}_INCLUDE_DIRS INCLUDES) + + find_path (_${_PYTHON_PREFIX}_INCLUDE_DIR + NAMES Python.h + HINTS ${_${_PYTHON_PREFIX}_INCLUDE_DIRS} + NO_SYSTEM_ENVIRONMENT_PATH + NO_CMAKE_SYSTEM_PATH) endif() - # Don't search for include dir if no library was founded - if (${_PYTHON_PREFIX}_LIBRARY_RELEASE OR ${_PYTHON_PREFIX}_LIBRARY_DEBUG) + # Rely on HINTS and standard paths if interpreter or config tool failed to locate artifacts + if (NOT _${_PYTHON_PREFIX}_INCLUDE_DIR) + unset (_${_PYTHON_PREFIX}_VIRTUALENV_PATHS) + if (_${_PYTHON_PREFIX}_FIND_VIRTUALENV MATCHES "^(FIRST|ONLY)$") + set (_${_PYTHON_PREFIX}_VIRTUALENV_PATHS ENV VIRTUAL_ENV) + endif() 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) + # Use the library's install prefix as a hint + if (${_${_PYTHON_PREFIX}_LIBRARY_RELEASE} MATCHES "^(.+/Frameworks/Python.framework/Versions/[0-9.]+)") + list (APPEND _${_PYTHON_PREFIX}_INCLUDE_HINTS "${CMAKE_MATCH_1}") + elseif (${_${_PYTHON_PREFIX}_LIBRARY_RELEASE} MATCHES "^(.+)/lib(64|32)?/python[0-9.]+/config") + list (APPEND _${_PYTHON_PREFIX}_INCLUDE_HINTS "${CMAKE_MATCH_1}") + elseif (DEFINED CMAKE_LIBRARY_ARCHITECTURE AND ${_${_PYTHON_PREFIX}_LIBRARY_RELEASE} MATCHES "^(.+)/lib/${CMAKE_LIBRARY_ARCHITECTURE}") + list (APPEND _${_PYTHON_PREFIX}_INCLUDE_HINTS "${CMAKE_MATCH_1}") + else() + # assume library is in a directory under root + get_filename_component (_${_PYTHON_PREFIX}_PREFIX "${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}" DIRECTORY) + get_filename_component (_${_PYTHON_PREFIX}_PREFIX "${_${_PYTHON_PREFIX}_PREFIX}" DIRECTORY) + list (APPEND _${_PYTHON_PREFIX}_INCLUDE_HINTS "${_${_PYTHON_PREFIX}_PREFIX}") + endif() _python_get_frameworks (_${_PYTHON_PREFIX}_FRAMEWORK_PATHS ${_${_PYTHON_PREFIX}_VERSION}) _python_get_registries (_${_PYTHON_PREFIX}_REGISTRY_PATHS ${_${_PYTHON_PREFIX}_VERSION}) _python_get_path_suffixes (_${_PYTHON_PREFIX}_PATH_SUFFIXES VERSION ${_${_PYTHON_PREFIX}_VERSION} INCLUDE) if (APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "FIRST") - find_path (${_PYTHON_PREFIX}_INCLUDE_DIR + find_path (_${_PYTHON_PREFIX}_INCLUDE_DIR NAMES Python.h HINTS ${_${_PYTHON_PREFIX}_INCLUDE_HINTS} ${_${_PYTHON_PREFIX}_HINTS} PATHS ${_${_PYTHON_PREFIX}_VIRTUALENV_PATHS} @@ -1790,7 +2005,7 @@ if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS endif() if (WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "FIRST") - find_path (${_PYTHON_PREFIX}_INCLUDE_DIR + find_path (_${_PYTHON_PREFIX}_INCLUDE_DIR NAMES Python.h HINTS ${_${_PYTHON_PREFIX}_INCLUDE_HINTS} ${_${_PYTHON_PREFIX}_HINTS} PATHS ${_${_PYTHON_PREFIX}_VIRTUALENV_PATHS} @@ -1812,7 +2027,7 @@ if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS unset (__${_PYTHON_PREFIX}_REGISTRY_PATHS) endif() - find_path (${_PYTHON_PREFIX}_INCLUDE_DIR + find_path (_${_PYTHON_PREFIX}_INCLUDE_DIR NAMES Python.h HINTS ${_${_PYTHON_PREFIX}_INCLUDE_HINTS} ${_${_PYTHON_PREFIX}_HINTS} PATHS ${_${_PYTHON_PREFIX}_VIRTUALENV_PATHS} @@ -1824,31 +2039,37 @@ if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS endif() # search header file in standard locations - find_path (${_PYTHON_PREFIX}_INCLUDE_DIR + find_path (_${_PYTHON_PREFIX}_INCLUDE_DIR NAMES Python.h) endif() - if (${_PYTHON_PREFIX}_INCLUDE_DIR) + set (${_PYTHON_PREFIX}_INCLUDE_DIRS "${_${_PYTHON_PREFIX}_INCLUDE_DIR}") + + if (_${_PYTHON_PREFIX}_INCLUDE_DIR AND NOT EXISTS "${_${_PYTHON_PREFIX}_INCLUDE_DIR}") + set_property (CACHE _${_PYTHON_PREFIX}_INCLUDE_DIR PROPERTY VALUE "_${_PYTHON_PREFIX}_INCLUDE_DIR-NOTFOUND") + 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}) + _python_get_version (INCLUDE PREFIX _${_PYTHON_PREFIX}_INC_) + + # update versioning + if (_${_PYTHON_PREFIX}_INC_VERSION VERSION_EQUAL ${_${_PYTHON_PREFIX}_VERSION}) + set (_${_PYTHON_PREFIX}_VERSION_PATCH ${_${_PYTHON_PREFIX}_INC_VERSION_PATCH}) endif() endif() + 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() + # define public variables + set (${_PYTHON_PREFIX}_LIBRARY_DEBUG "${_${_PYTHON_PREFIX}_LIBRARY_DEBUG}" CACHE FILEPATH "Path to a library." FORCE) + include (${CMAKE_CURRENT_LIST_DIR}/../SelectLibraryConfigurations.cmake) select_library_configurations (${_PYTHON_PREFIX}) if (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE) @@ -1856,14 +2077,13 @@ if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS 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") + 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}$") + if (${_PYTHON_PREFIX}_LIBRARY_RELEASE MATCHES "${CMAKE_SHARED_LIBRARY_SUFFIX}$") set (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DIRS ${${_PYTHON_PREFIX}_LIBRARY_DIRS}) endif() else() @@ -1871,66 +2091,114 @@ if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS ${_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}_LIBRARY_RELEASE AND _${_PYTHON_PREFIX}_INCLUDE_DIR) if (${_PYTHON_PREFIX}_Interpreter_FOUND OR ${_PYTHON_PREFIX}_Compiler_FOUND) # development environment must be compatible with interpreter/compiler - if (${_${_PYTHON_PREFIX}_VERSION_MAJOR}.${_${_PYTHON_PREFIX}_VERSION_MINOR} VERSION_EQUAL ${${_PYTHON_PREFIX}_VERSION_MAJOR}.${${_PYTHON_PREFIX}_VERSION_MINOR}) + if (${_${_PYTHON_PREFIX}_VERSION_MAJOR}.${_${_PYTHON_PREFIX}_VERSION_MINOR} VERSION_EQUAL ${${_PYTHON_PREFIX}_VERSION_MAJOR}.${${_PYTHON_PREFIX}_VERSION_MINOR} + AND ${_${_PYTHON_PREFIX}_INC_VERSION_MAJOR}.${_${_PYTHON_PREFIX}_INC_VERSION_MINOR} VERSION_EQUAL ${_${_PYTHON_PREFIX}_VERSION_MAJOR}.${_${_PYTHON_PREFIX}_VERSION_MINOR}) set (${_PYTHON_PREFIX}_Development_FOUND TRUE) endif() - elseif (${_PYTHON_PREFIX}_VERSION_MAJOR VERSION_EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR) + elseif (${_PYTHON_PREFIX}_VERSION_MAJOR VERSION_EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR + AND ${_${_PYTHON_PREFIX}_INC_VERSION_MAJOR}.${_${_PYTHON_PREFIX}_INC_VERSION_MINOR} VERSION_EQUAL ${_${_PYTHON_PREFIX}_VERSION_MAJOR}.${_${_PYTHON_PREFIX}_VERSION_MINOR}) set (${_PYTHON_PREFIX}_Development_FOUND TRUE) endif() + if (DEFINED _${_PYTHON_PREFIX}_FIND_ABI AND + (NOT _${_PYTHON_PREFIX}_ABI IN_LIST _${_PYTHON_PREFIX}_ABIFLAGS + OR NOT _${_PYTHON_PREFIX}_INC_ABI IN_LIST _${_PYTHON_PREFIX}_ABIFLAGS)) + set (${_PYTHON_PREFIX}_Development_FOUND FALSE) + endif() + endif() + + if (${_PYTHON_PREFIX}_Development_FOUND) + # compute and save development signature + string (MD5 __${_PYTHON_PREFIX}_DEVELOPMENT_SIGNATURE "${_${_PYTHON_PREFIX}_SIGNATURE}:${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}:${_${_PYTHON_PREFIX}_INCLUDE_DIR}") + set (_${_PYTHON_PREFIX}_DEVELOPMENT_SIGNATURE "${__${_PYTHON_PREFIX}_DEVELOPMENT_SIGNATURE}" CACHE INTERNAL "") + else() + unset (_${_PYTHON_PREFIX}_DEVELOPMENT_SIGNATURE CACHE) 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() + + mark_as_advanced (_${_PYTHON_PREFIX}_LIBRARY_RELEASE + _${_PYTHON_PREFIX}_LIBRARY_DEBUG + ${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE + ${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG + _${_PYTHON_PREFIX}_INCLUDE_DIR + _${_PYTHON_PREFIX}_DEVELOPMENT_SIGNATURE) endif() if ("NumPy" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS AND ${_PYTHON_PREFIX}_Interpreter_FOUND) - list (APPEND _${_PYTHON_PREFIX}_CACHED_VARS ${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR) + list (APPEND _${_PYTHON_PREFIX}_CACHED_VARS _${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR) if (${_PYTHON_PREFIX}_FIND_REQUIRED_NumPy) - list (APPEND _${_PYTHON_PREFIX}_REQUIRED_VARS ${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR) + list (APPEND _${_PYTHON_PREFIX}_REQUIRED_VARS ${_PYTHON_PREFIX}_NumPy_INCLUDE_DIRS) + endif() + + if (DEFINED ${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR + AND IS_ABSOLUTE "${${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR}") + set (_${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR "${${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR}" CACHE INTERNAL "") + elseif (DEFINED _${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR) + # compute numpy signature. Depends on interpreter and development signatures + string (MD5 __${_PYTHON_PREFIX}_NUMPY_SIGNATURE "${_${_PYTHON_PREFIX}_INTERPRETER_SIGNATURE}:${_${_PYTHON_PREFIX}_DEVELOPMENT_SIGNATURE}:${_${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR}") + if (NOT __${_PYTHON_PREFIX}_NUMPY_SIGNATURE STREQUAL _${_PYTHON_PREFIX}_NUMPY_SIGNATURE + OR NOT EXISTS "${_${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR}") + unset (_${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR CACHE) + unset (_${_PYTHON_PREFIX}_NUMPY_SIGNATURE CACHE) + endif() endif() - execute_process( + + if (NOT _${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR) + execute_process( COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -c "from __future__ import print_function\ntry: import numpy; print(numpy.get_include(), end='')\nexcept:pass\n" RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT OUTPUT_VARIABLE _${_PYTHON_PREFIX}_NumPy_PATH ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) - if (NOT _${_PYTHON_PREFIX}_RESULT) - find_path(${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR - NAMES "numpy/arrayobject.h" "numpy/numpyconfig.h" - HINTS "${_${_PYTHON_PREFIX}_NumPy_PATH}" - NO_DEFAULT_PATH) + + if (NOT _${_PYTHON_PREFIX}_RESULT) + find_path (_${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR + NAMES "numpy/arrayobject.h" "numpy/numpyconfig.h" + HINTS "${_${_PYTHON_PREFIX}_NumPy_PATH}" + NO_DEFAULT_PATH) + endif() endif() - if(${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR) - set(${_PYTHON_PREFIX}_NumPy_INCLUDE_DIRS "${${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR}") - set(${_PYTHON_PREFIX}_NumPy_FOUND TRUE) + + set (${_PYTHON_PREFIX}_NumPy_INCLUDE_DIRS "${_${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR}") + + if(_${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR AND NOT EXISTS "${_${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR}") + set_property (CACHE _${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR PROPERTY VALUE "_${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR-NOTFOUND") endif() - if(${_PYTHON_PREFIX}_NumPy_FOUND) - execute_process( + + if (_${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR) + execute_process ( COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -c "from __future__ import print_function\ntry: import numpy; print(numpy.__version__, end='')\nexcept:pass\n" RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT OUTPUT_VARIABLE _${_PYTHON_PREFIX}_NumPy_VERSION) if (NOT _${_PYTHON_PREFIX}_RESULT) - set(${_PYTHON_PREFIX}_NumPy_VERSION "${_${_PYTHON_PREFIX}_NumPy_VERSION}") + set (${_PYTHON_PREFIX}_NumPy_VERSION "${_${_PYTHON_PREFIX}_NumPy_VERSION}") + else() + unset (${_PYTHON_PREFIX}_NumPy_VERSION) endif() + + # final step: set NumPy founded only if Development component is founded as well + set(${_PYTHON_PREFIX}_NumPy_FOUND ${${_PYTHON_PREFIX}_Development_FOUND}) + else() + set (${_PYTHON_PREFIX}_NumPy_FOUND FALSE) endif() - # final step: set NumPy founded only if Development component is founded as well - if (NOT ${_PYTHON_PREFIX}_Development_FOUND) - set(${_PYTHON_PREFIX}_NumPy_FOUND FALSE) + + if (${_PYTHON_PREFIX}_NumPy_FOUND) + # compute and save numpy signature + string (MD5 __${_PYTHON_PREFIX}_NUMPY_SIGNATURE "${_${_PYTHON_PREFIX}_INTERPRETER_SIGNATURE}:${_${_PYTHON_PREFIX}_DEVELOPMENT_SIGNATURE}:${${_PYTHON_PREFIX}_NumPyINCLUDE_DIR}") + set (_${_PYTHON_PREFIX}_NUMPY_SIGNATURE "${__${_PYTHON_PREFIX}_NUMPY_SIGNATURE}" CACHE INTERNAL "") + else() + unset (_${_PYTHON_PREFIX}_NUMPY_SIGNATURE CACHE) endif() + + mark_as_advanced (_${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR) endif() # final validation @@ -1968,20 +2236,20 @@ if(_${_PYTHON_PREFIX}_CMAKE_ROLE STREQUAL "PROJECT") macro (__PYTHON_IMPORT_LIBRARY __name) 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) + OR ${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE) set (_${_PYTHON_PREFIX}_LIBRARY_TYPE SHARED) else() set (_${_PYTHON_PREFIX}_LIBRARY_TYPE STATIC) endif() - add_library (${__name} ${_${_PYTHON_PREFIX}_LIBRARY_TYPE} IMPORTED) + if (NOT TARGET ${__name}) + add_library (${__name} ${_${_PYTHON_PREFIX}_LIBRARY_TYPE} IMPORTED) + endif() set_property (TARGET ${__name} - PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${${_PYTHON_PREFIX}_INCLUDE_DIR}") + PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${${_PYTHON_PREFIX}_INCLUDE_DIRS}") - if ((${_PYTHON_PREFIX}_LIBRARY_RELEASE AND ${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE) - OR (${_PYTHON_PREFIX}_LIBRARY_DEBUG AND ${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG)) + if (${_PYTHON_PREFIX}_LIBRARY_RELEASE AND ${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE) # System manage shared libraries in two parts: import and runtime if (${_PYTHON_PREFIX}_LIBRARY_RELEASE AND ${_PYTHON_PREFIX}_LIBRARY_DEBUG) set_property (TARGET ${__name} PROPERTY IMPORTED_CONFIGURATIONS RELEASE DEBUG) @@ -2025,33 +2293,31 @@ if(_${_PYTHON_PREFIX}_CMAKE_ROLE STREQUAL "PROJECT") endif() endmacro() - if (NOT TARGET ${_PYTHON_PREFIX}::Python) - __python_import_library (${_PYTHON_PREFIX}::Python) - endif() + __python_import_library (${_PYTHON_PREFIX}::Python) - if (NOT TARGET ${_PYTHON_PREFIX}::Module) - if (CMAKE_SYSTEM_NAME MATCHES "^(Windows.*|CYGWIN|MSYS)$") - # On Windows/CYGWIN/MSYS, Python::Module is the same as Python::Python - # but ALIAS cannot be used because the imported library is not GLOBAL. - __python_import_library (${_PYTHON_PREFIX}::Module) - else() + if (CMAKE_SYSTEM_NAME MATCHES "^(Windows.*|CYGWIN|MSYS)$") + # On Windows/CYGWIN/MSYS, Python::Module is the same as Python::Python + # but ALIAS cannot be used because the imported library is not GLOBAL. + __python_import_library (${_PYTHON_PREFIX}::Module) + else() + if (NOT TARGET ${_PYTHON_PREFIX}::Module ) add_library (${_PYTHON_PREFIX}::Module INTERFACE IMPORTED) - set_property (TARGET ${_PYTHON_PREFIX}::Module - PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${${_PYTHON_PREFIX}_INCLUDE_DIR}") + endif() + set_property (TARGET ${_PYTHON_PREFIX}::Module + PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${${_PYTHON_PREFIX}_INCLUDE_DIRS}") - # When available, enforce shared library generation with undefined symbols - if (APPLE) - set_property (TARGET ${_PYTHON_PREFIX}::Module - PROPERTY INTERFACE_LINK_OPTIONS "LINKER:-undefined,dynamic_lookup") - endif() - if (CMAKE_SYSTEM_NAME STREQUAL "SunOS") - set_property (TARGET ${_PYTHON_PREFIX}::Module - PROPERTY INTERFACE_LINK_OPTIONS "LINKER:-z,nodefs") - endif() - if (CMAKE_SYSTEM_NAME STREQUAL "AIX") - set_property (TARGET ${_PYTHON_PREFIX}::Module - PROPERTY INTERFACE_LINK_OPTIONS "LINKER:-b,erok") - endif() + # When available, enforce shared library generation with undefined symbols + if (APPLE) + set_property (TARGET ${_PYTHON_PREFIX}::Module + PROPERTY INTERFACE_LINK_OPTIONS "LINKER:-undefined,dynamic_lookup") + endif() + if (CMAKE_SYSTEM_NAME STREQUAL "SunOS") + set_property (TARGET ${_PYTHON_PREFIX}::Module + PROPERTY INTERFACE_LINK_OPTIONS "LINKER:-z,nodefs") + endif() + if (CMAKE_SYSTEM_NAME STREQUAL "AIX") + set_property (TARGET ${_PYTHON_PREFIX}::Module + PROPERTY INTERFACE_LINK_OPTIONS "LINKER:-b,erok") endif() endif() @@ -2090,7 +2356,7 @@ if(_${_PYTHON_PREFIX}_CMAKE_ROLE STREQUAL "PROJECT") AND NOT TARGET ${_PYTHON_PREFIX}::NumPy AND TARGET ${_PYTHON_PREFIX}::Module) add_library (${_PYTHON_PREFIX}::NumPy INTERFACE IMPORTED) set_property (TARGET ${_PYTHON_PREFIX}::NumPy - PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR}") + PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${${_PYTHON_PREFIX}_NumPy_INCLUDE_DIRS}") target_link_libraries (${_PYTHON_PREFIX}::NumPy INTERFACE ${_PYTHON_PREFIX}::Module) endif() endif() diff --git a/Modules/FindPython2.cmake b/Modules/FindPython2.cmake index 82878ea..0cecdc6 100644 --- a/Modules/FindPython2.cmake +++ b/Modules/FindPython2.cmake @@ -199,6 +199,44 @@ Hints recommended to also include the component ``Interpreter`` to get expected result. +Artifacts Specification +^^^^^^^^^^^^^^^^^^^^^^^ + +To solve special cases, it is possible to specify directly the artifacts by +setting the following variables: + +``Python2_EXECUTABLE`` + The path to the interpreter. + +``Python2_COMPILER`` + The path to the compiler. + +``Python2_LIBRARY`` + The path to the library. It will be used to compute the + variables ``Python2_LIBRARIES``, ``Python2_LIBRAY_DIRS`` and + ``Python2_RUNTIME_LIBRARY_DIRS``. + +``Python2_INCLUDE_DIR`` + The path to the directory of the ``Python`` headers. It will be used to + compute the variable ``Python2_INCLUDE_DIRS``. + +``Python2_NumPy_INCLUDE_DIR`` + The path to the directory of the ``NumPy`` headers. It will be used to + compute the variable ``Python2_NumPy_INCLUDE_DIRS``. + +.. note:: + + All paths must be absolute. Any artifact specified with a relative path + will be ignored. + +.. note:: + + When an artifact is specified, all ``HINTS`` will be ignored and no search + will be performed for this artifact. + + If more than one artifact is specified, it is the user's responsability to + ensure the consistency of the various artifacts. + Commands ^^^^^^^^ diff --git a/Modules/FindPython3.cmake b/Modules/FindPython3.cmake index 417a789..1edb9c9 100644 --- a/Modules/FindPython3.cmake +++ b/Modules/FindPython3.cmake @@ -240,6 +240,44 @@ Hints recommended to also include the component ``Interpreter`` to get expected result. +Artifacts Specification +^^^^^^^^^^^^^^^^^^^^^^^ + +To solve special cases, it is possible to specify directly the artifacts by +setting the following variables: + +``Python3_EXECUTABLE`` + The path to the interpreter. + +``Python3_COMPILER`` + The path to the compiler. + +``Python3_LIBRARY`` + The path to the library. It will be used to compute the + variables ``Python3_LIBRARIES``, ``Python3_LIBRAY_DIRS`` and + ``Python3_RUNTIME_LIBRARY_DIRS``. + +``Python3_INCLUDE_DIR`` + The path to the directory of the ``Python`` headers. It will be used to + compute the variable ``Python3_INCLUDE_DIRS``. + +``Python3_NumPy_INCLUDE_DIR`` + The path to the directory of the ``NumPy`` headers. It will be used to + compute the variable ``Python3_NumPy_INCLUDE_DIRS``. + +.. note:: + + All paths must be absolute. Any artifact specified with a relative path + will be ignored. + +.. note:: + + When an artifact is specified, all ``HINTS`` will be ignored and no search + will be performed for this artifact. + + If more than one artifact is specified, it is the user's responsability to + ensure the consistency of the various artifacts. + Commands ^^^^^^^^ diff --git a/Modules/Platform/Windows-Clang.cmake b/Modules/Platform/Windows-Clang.cmake index 220649c..84b3a9b 100644 --- a/Modules/Platform/Windows-Clang.cmake +++ b/Modules/Platform/Windows-Clang.cmake @@ -47,15 +47,22 @@ macro(__windows_compiler_clang_gnu lang) set(CMAKE_${lang}_USE_RESPONSE_FILE_FOR_LIBRARIES 1) set(CMAKE_${lang}_USE_RESPONSE_FILE_FOR_INCLUDES 1) + set(CMAKE_${lang}_COMPILE_OPTIONS_IPO "-flto") + set(_CMAKE_${lang}_IPO_SUPPORTED_BY_CMAKE YES) + set(_CMAKE_${lang}_IPO_MAY_BE_SUPPORTED_BY_COMPILER YES) + set(CMAKE_${lang}_ARCHIVE_CREATE_IPO "<CMAKE_AR> cr <TARGET> <LINK_FLAGS> <OBJECTS>") + set(CMAKE_${lang}_ARCHIVE_APPEND_IPO "<CMAKE_AR> r <TARGET> <LINK_FLAGS> <OBJECTS>") + set(CMAKE_${lang}_ARCHIVE_FINISH_IPO "<CMAKE_RANLIB> <TARGET>") + # Create archiving rules to support large object file lists for static libraries. set(CMAKE_${lang}_ARCHIVE_CREATE "<CMAKE_AR> qc <TARGET> <LINK_FLAGS> <OBJECTS>") set(CMAKE_${lang}_ARCHIVE_APPEND "<CMAKE_AR> q <TARGET> <LINK_FLAGS> <OBJECTS>") set(CMAKE_${lang}_ARCHIVE_FINISH "<CMAKE_RANLIB> <TARGET>") set(CMAKE_${lang}_CREATE_SHARED_LIBRARY - "<CMAKE_${lang}_COMPILER> -nostartfiles -nostdlib <CMAKE_SHARED_LIBRARY_${lang}_FLAGS> <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS> -o <TARGET> ${CMAKE_GNULD_IMAGE_VERSION} -Xlinker /implib:<TARGET_IMPLIB> -Xlinker /pdb:<TARGET_PDB> -Xlinker /version:<TARGET_VERSION_MAJOR>.<TARGET_VERSION_MINOR> <OBJECTS> <LINK_LIBRARIES>") + "<CMAKE_${lang}_COMPILER> -fuse-ld=lld-link -nostartfiles -nostdlib <CMAKE_SHARED_LIBRARY_${lang}_FLAGS> <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS> -o <TARGET> ${CMAKE_GNULD_IMAGE_VERSION} -Xlinker /implib:<TARGET_IMPLIB> -Xlinker /pdb:<TARGET_PDB> -Xlinker /version:<TARGET_VERSION_MAJOR>.<TARGET_VERSION_MINOR> <OBJECTS> <LINK_LIBRARIES>") set(CMAKE_${lang}_CREATE_SHARED_MODULE ${CMAKE_${lang}_CREATE_SHARED_LIBRARY}) set(CMAKE_${lang}_LINK_EXECUTABLE - "<CMAKE_${lang}_COMPILER> -nostartfiles -nostdlib <FLAGS> <CMAKE_${lang}_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> -Xlinker /implib:<TARGET_IMPLIB> -Xlinker /pdb:<TARGET_PDB> -Xlinker /version:<TARGET_VERSION_MAJOR>.<TARGET_VERSION_MINOR> ${CMAKE_GNULD_IMAGE_VERSION} <LINK_LIBRARIES>") + "<CMAKE_${lang}_COMPILER> -fuse-ld=lld-link -nostartfiles -nostdlib <FLAGS> <CMAKE_${lang}_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> -Xlinker /implib:<TARGET_IMPLIB> -Xlinker /pdb:<TARGET_PDB> -Xlinker /version:<TARGET_VERSION_MAJOR>.<TARGET_VERSION_MINOR> ${CMAKE_GNULD_IMAGE_VERSION} <LINK_LIBRARIES>") set(CMAKE_${lang}_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreaded -Xclang -flto-visibility-public-std -D_MT -Xclang --dependent-lib=libcmt) set(CMAKE_${lang}_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDLL -D_DLL -D_MT -Xclang --dependent-lib=msvcrt) diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index 2ff6c8c..decb39a 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -978,12 +978,6 @@ set(CPACK_SRCS CPack/cmCPackNSISGenerator.cxx CPack/cmCPackNuGetGenerator.cxx CPack/cmCPackSTGZGenerator.cxx - CPack/cmCPackTGZGenerator.cxx - CPack/cmCPackTXZGenerator.cxx - CPack/cmCPackTarBZip2Generator.cxx - CPack/cmCPackTarCompressGenerator.cxx - CPack/cmCPackZIPGenerator.cxx - CPack/cmCPack7zGenerator.cxx ) # CPack IFW generator set(CPACK_SRCS ${CPACK_SRCS} diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 1b06e45..545b0a9 100644 --- a/Source/CMakeVersion.cmake +++ b/Source/CMakeVersion.cmake @@ -1,7 +1,7 @@ # CMake version number components. set(CMake_VERSION_MAJOR 3) set(CMake_VERSION_MINOR 15) -set(CMake_VERSION_PATCH 20190829) +set(CMake_VERSION_PATCH 20190905) #set(CMake_VERSION_RC 0) set(CMake_VERSION_IS_DIRTY 0) diff --git a/Source/CPack/IFW/cmCPackIFWCommon.cxx b/Source/CPack/IFW/cmCPackIFWCommon.cxx index f9ce822..aa9a457 100644 --- a/Source/CPack/IFW/cmCPackIFWCommon.cxx +++ b/Source/CPack/IFW/cmCPackIFWCommon.cxx @@ -11,6 +11,7 @@ #include "cmVersionConfig.h" #include "cmXMLWriter.h" +#include <cstddef> #include <sstream> #include <utility> #include <vector> diff --git a/Source/CPack/cmCPack7zGenerator.cxx b/Source/CPack/cmCPack7zGenerator.cxx deleted file mode 100644 index 7413770..0000000 --- a/Source/CPack/cmCPack7zGenerator.cxx +++ /dev/null @@ -1,13 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing for details. */ -#include "cmCPack7zGenerator.h" - -#include "cmArchiveWrite.h" -#include "cmCPackArchiveGenerator.h" - -cmCPack7zGenerator::cmCPack7zGenerator() - : cmCPackArchiveGenerator(cmArchiveWrite::CompressNone, "7zip") -{ -} - -cmCPack7zGenerator::~cmCPack7zGenerator() = default; diff --git a/Source/CPack/cmCPack7zGenerator.h b/Source/CPack/cmCPack7zGenerator.h deleted file mode 100644 index 8af4c4a..0000000 --- a/Source/CPack/cmCPack7zGenerator.h +++ /dev/null @@ -1,29 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing for details. */ -#ifndef cmCPack7zGenerator_h -#define cmCPack7zGenerator_h - -#include "cmConfigure.h" // IWYU pragma: keep - -#include "cmCPackArchiveGenerator.h" -#include "cmCPackGenerator.h" - -/** \class cmCPack7zGenerator - * \brief A generator for 7z files - */ -class cmCPack7zGenerator : public cmCPackArchiveGenerator -{ -public: - cmCPackTypeMacro(cmCPack7zGenerator, cmCPackArchiveGenerator); - - /** - * Construct generator - */ - cmCPack7zGenerator(); - ~cmCPack7zGenerator() override; - -protected: - const char* GetOutputExtension() override { return ".7z"; } -}; - -#endif diff --git a/Source/CPack/cmCPackArchiveGenerator.cxx b/Source/CPack/cmCPackArchiveGenerator.cxx index 6c9c6b9..1271b08 100644 --- a/Source/CPack/cmCPackArchiveGenerator.cxx +++ b/Source/CPack/cmCPackArchiveGenerator.cxx @@ -16,11 +16,54 @@ #include <utility> #include <vector> -cmCPackArchiveGenerator::cmCPackArchiveGenerator(cmArchiveWrite::Compress t, - std::string const& format) +cmCPackGenerator* cmCPackArchiveGenerator::Create7ZGenerator() +{ + return new cmCPackArchiveGenerator(cmArchiveWrite::CompressNone, "7zip", + ".7z"); +} + +cmCPackGenerator* cmCPackArchiveGenerator::CreateTBZ2Generator() +{ + return new cmCPackArchiveGenerator(cmArchiveWrite::CompressBZip2, "paxr", + ".tar.bz2"); +} + +cmCPackGenerator* cmCPackArchiveGenerator::CreateTGZGenerator() +{ + return new cmCPackArchiveGenerator(cmArchiveWrite::CompressGZip, "paxr", + ".tar.gz"); +} + +cmCPackGenerator* cmCPackArchiveGenerator::CreateTXZGenerator() +{ + return new cmCPackArchiveGenerator(cmArchiveWrite::CompressXZ, "paxr", + ".tar.xz"); +} + +cmCPackGenerator* cmCPackArchiveGenerator::CreateTZGenerator() +{ + return new cmCPackArchiveGenerator(cmArchiveWrite::CompressCompress, "paxr", + ".tar.Z"); +} + +cmCPackGenerator* cmCPackArchiveGenerator::CreateTZSTGenerator() +{ + return new cmCPackArchiveGenerator(cmArchiveWrite::CompressZstd, "paxr", + ".tar.zst"); +} + +cmCPackGenerator* cmCPackArchiveGenerator::CreateZIPGenerator() +{ + return new cmCPackArchiveGenerator(cmArchiveWrite::CompressNone, "zip", + ".zip"); +} + +cmCPackArchiveGenerator::cmCPackArchiveGenerator( + cmArchiveWrite::Compress compress, std::string format, std::string extension) + : Compress(compress) + , ArchiveFormat(std::move(format)) + , OutputExtension(std::move(extension)) { - this->Compress = t; - this->ArchiveFormat = format; } cmCPackArchiveGenerator::~cmCPackArchiveGenerator() = default; diff --git a/Source/CPack/cmCPackArchiveGenerator.h b/Source/CPack/cmCPackArchiveGenerator.h index 9983854..f5be0aa 100644 --- a/Source/CPack/cmCPackArchiveGenerator.h +++ b/Source/CPack/cmCPackArchiveGenerator.h @@ -24,10 +24,19 @@ class cmCPackArchiveGenerator : public cmCPackGenerator public: typedef cmCPackGenerator Superclass; + static cmCPackGenerator* Create7ZGenerator(); + static cmCPackGenerator* CreateTBZ2Generator(); + static cmCPackGenerator* CreateTGZGenerator(); + static cmCPackGenerator* CreateTXZGenerator(); + static cmCPackGenerator* CreateTZGenerator(); + static cmCPackGenerator* CreateTZSTGenerator(); + static cmCPackGenerator* CreateZIPGenerator(); + /** * Construct generator */ - cmCPackArchiveGenerator(cmArchiveWrite::Compress, std::string const& format); + cmCPackArchiveGenerator(cmArchiveWrite::Compress t, std::string format, + std::string extension); ~cmCPackArchiveGenerator() override; // Used to add a header to the archive virtual int GenerateHeader(std::ostream* os); @@ -68,9 +77,19 @@ protected: * components will be put in a single installer. */ int PackageComponentsAllInOne(); - const char* GetOutputExtension() override = 0; + +private: + const char* GetNameOfClass() override { return "cmCPackArchiveGenerator"; } + + const char* GetOutputExtension() override + { + return this->OutputExtension.c_str(); + } + +private: cmArchiveWrite::Compress Compress; std::string ArchiveFormat; + std::string OutputExtension; }; #endif diff --git a/Source/CPack/cmCPackCygwinBinaryGenerator.cxx b/Source/CPack/cmCPackCygwinBinaryGenerator.cxx index 553a677..22385055 100644 --- a/Source/CPack/cmCPackCygwinBinaryGenerator.cxx +++ b/Source/CPack/cmCPackCygwinBinaryGenerator.cxx @@ -12,6 +12,7 @@ #include "cmsys/SystemTools.hxx" cmCPackCygwinBinaryGenerator::cmCPackCygwinBinaryGenerator() + : cmCPackArchiveGenerator(cmArchiveWrite::CompressBZip2, "paxr", ".tar.bz2") { } diff --git a/Source/CPack/cmCPackCygwinBinaryGenerator.h b/Source/CPack/cmCPackCygwinBinaryGenerator.h index f87a134..47bd41e 100644 --- a/Source/CPack/cmCPackCygwinBinaryGenerator.h +++ b/Source/CPack/cmCPackCygwinBinaryGenerator.h @@ -3,15 +3,15 @@ #ifndef cmCPackCygwinBinaryGenerator_h #define cmCPackCygwinBinaryGenerator_h -#include "cmCPackTarBZip2Generator.h" +#include "cmCPackArchiveGenerator.h" /** \class cmCPackCygwinBinaryGenerator * \brief A generator for TarBZip2 files */ -class cmCPackCygwinBinaryGenerator : public cmCPackTarBZip2Generator +class cmCPackCygwinBinaryGenerator : public cmCPackArchiveGenerator { public: - cmCPackTypeMacro(cmCPackCygwinBinaryGenerator, cmCPackTarBZip2Generator); + cmCPackTypeMacro(cmCPackCygwinBinaryGenerator, cmCPackArchiveGenerator); /** * Construct generator diff --git a/Source/CPack/cmCPackCygwinSourceGenerator.cxx b/Source/CPack/cmCPackCygwinSourceGenerator.cxx index 8cae9b4..5f6aab0 100644 --- a/Source/CPack/cmCPackCygwinSourceGenerator.cxx +++ b/Source/CPack/cmCPackCygwinSourceGenerator.cxx @@ -20,6 +20,7 @@ #endif cmCPackCygwinSourceGenerator::cmCPackCygwinSourceGenerator() + : cmCPackArchiveGenerator(cmArchiveWrite::CompressBZip2, "paxr", ".tar.bz2") { } @@ -40,11 +41,8 @@ int cmCPackCygwinSourceGenerator::PackageFiles() cmStrCat(this->GetOption("CPACK_TEMPORARY_DIRECTORY"), ".tar.bz2"); packageFileNames[0] = packageDirFileName; std::string output; - // skip one parent up to the cmCPackTarBZip2Generator - // to create tar.bz2 file with the list of source - // files - this->Compress = cmArchiveWrite::CompressBZip2; - if (!this->cmCPackTarBZip2Generator::PackageFiles()) { + // create tar.bz2 file with the list of source files + if (!this->cmCPackArchiveGenerator::PackageFiles()) { return 0; } // Now create a tar file that contains the above .tar.bz2 file @@ -130,7 +128,7 @@ int cmCPackCygwinSourceGenerator::PackageFiles() packageFileNames[0] = outerTarFile; /* update the toplevel dir */ toplevel = tmpDir; - if (!this->cmCPackTarBZip2Generator::PackageFiles()) { + if (!this->cmCPackArchiveGenerator::PackageFiles()) { return 0; } return 1; diff --git a/Source/CPack/cmCPackCygwinSourceGenerator.h b/Source/CPack/cmCPackCygwinSourceGenerator.h index a909b15..98d8f0a 100644 --- a/Source/CPack/cmCPackCygwinSourceGenerator.h +++ b/Source/CPack/cmCPackCygwinSourceGenerator.h @@ -3,15 +3,15 @@ #ifndef cmCPackCygwinSourceGenerator_h #define cmCPackCygwinSourceGenerator_h -#include "cmCPackTarBZip2Generator.h" +#include "cmCPackArchiveGenerator.h" /** \class cmCPackCygwinSourceGenerator * \brief A generator for cygwin source files */ -class cmCPackCygwinSourceGenerator : public cmCPackTarBZip2Generator +class cmCPackCygwinSourceGenerator : public cmCPackArchiveGenerator { public: - cmCPackTypeMacro(cmCPackCygwinSourceGenerator, cmCPackTarBZip2Generator); + cmCPackTypeMacro(cmCPackCygwinSourceGenerator, cmCPackArchiveGenerator); /** * Construct generator diff --git a/Source/CPack/cmCPackFreeBSDGenerator.cxx b/Source/CPack/cmCPackFreeBSDGenerator.cxx index a35977c..3979000 100644 --- a/Source/CPack/cmCPackFreeBSDGenerator.cxx +++ b/Source/CPack/cmCPackFreeBSDGenerator.cxx @@ -21,7 +21,7 @@ #include <utility> cmCPackFreeBSDGenerator::cmCPackFreeBSDGenerator() - : cmCPackArchiveGenerator(cmArchiveWrite::CompressXZ, "paxr") + : cmCPackArchiveGenerator(cmArchiveWrite::CompressXZ, "paxr", ".txz") { } @@ -131,7 +131,7 @@ public: class ManifestKeyListValue : public ManifestKey { public: - typedef std::vector<std::string> VList; + using VList = std::vector<std::string>; VList value; ManifestKeyListValue(const std::string& k) @@ -276,12 +276,6 @@ void write_manifest_files(cmGeneratedFileStream& s, s << " },\n"; } -static bool has_suffix(const std::string& str, const std::string& suffix) -{ - return str.size() >= suffix.size() && - str.compare(str.size() - suffix.size(), suffix.size(), suffix) == 0; -} - int cmCPackFreeBSDGenerator::PackageFiles() { if (!this->ReadListFile("Internal/CPack/CPackFreeBSD.cmake")) { @@ -327,13 +321,13 @@ int cmCPackFreeBSDGenerator::PackageFiles() pkg_create_from_manifest(output_dir.c_str(), ::TXZ, toplevel.c_str(), manifestname.c_str(), nullptr); - std::string broken_suffix = std::string("-") + - var_lookup("CPACK_TOPLEVEL_TAG") + std::string(GetOutputExtension()); + std::string broken_suffix = + cmStrCat('-', var_lookup("CPACK_TOPLEVEL_TAG"), ".txz"); for (std::string& name : packageFileNames) { cmCPackLogger(cmCPackLog::LOG_DEBUG, "Packagefile " << name << std::endl); - if (has_suffix(name, broken_suffix)) { + if (cmHasSuffix(name, broken_suffix)) { name.replace(name.size() - broken_suffix.size(), std::string::npos, - GetOutputExtension()); + ".txz"); break; } } diff --git a/Source/CPack/cmCPackFreeBSDGenerator.h b/Source/CPack/cmCPackFreeBSDGenerator.h index 99d2e24..80c53b1 100644 --- a/Source/CPack/cmCPackFreeBSDGenerator.h +++ b/Source/CPack/cmCPackFreeBSDGenerator.h @@ -28,8 +28,6 @@ public: int PackageFiles() override; protected: - const char* GetOutputExtension() override { return ".txz"; } - std::string var_lookup(const char* var_name); void write_manifest_fields(cmGeneratedFileStream&); }; diff --git a/Source/CPack/cmCPackGenerator.cxx b/Source/CPack/cmCPackGenerator.cxx index 288d5d8..a96c1c8 100644 --- a/Source/CPack/cmCPackGenerator.cxx +++ b/Source/CPack/cmCPackGenerator.cxx @@ -594,11 +594,37 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects( componentsVector.push_back(project.Component); } - const char* buildConfigCstr = this->GetOption("CPACK_BUILD_CONFIG"); - std::string buildConfig = buildConfigCstr ? buildConfigCstr : ""; - cmGlobalGenerator* globalGenerator = + std::vector<std::string> buildConfigs; + + // Try get configuration names given via `-C` CLI option + { + const char* const buildConfigCstr = + this->GetOption("CPACK_BUILD_CONFIG"); + auto buildConfig = buildConfigCstr ? buildConfigCstr : std::string{}; + cmExpandList(buildConfig, buildConfigs); + } + + // Try get configurations requested by the user explicitly + { + const char* const configsCstr = + this->GetOption("CPACK_INSTALL_CMAKE_CONFIGURATIONS"); + auto configs = configsCstr ? configsCstr : std::string{}; + cmExpandList(configs, buildConfigs); + } + + // Remove duplicates + std::sort(buildConfigs.begin(), buildConfigs.end()); + buildConfigs.erase(std::unique(buildConfigs.begin(), buildConfigs.end()), + buildConfigs.end()); + + // Ensure we have at least one configuration. + if (buildConfigs.empty()) { + buildConfigs.emplace_back(); + } + + std::unique_ptr<cmGlobalGenerator> globalGenerator( this->MakefileMap->GetCMakeInstance()->CreateGlobalGenerator( - cmakeGenerator); + cmakeGenerator)); if (!globalGenerator) { cmCPackLogger(cmCPackLog::LOG_ERROR, "Specified package generator not found. " @@ -611,27 +637,29 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects( // on windows. cmSystemTools::SetForceUnixPaths(globalGenerator->GetForceUnixPaths()); - if (!this->RunPreinstallTarget(project.ProjectName, project.Directory, - globalGenerator, buildConfig)) { - return 0; - } - - delete globalGenerator; - - cmCPackLogger(cmCPackLog::LOG_OUTPUT, - "- Install project: " << project.ProjectName << std::endl); - - // Run the installation for each component - for (std::string const& component : componentsVector) { - if (!this->InstallCMakeProject( - setDestDir, project.Directory, baseTempInstallDirectory, - default_dir_mode, component, componentInstall, - project.SubDirectory, buildConfig, absoluteDestFiles)) { + // Run the installation for the selected build configurations + for (auto const& buildConfig : buildConfigs) { + if (!this->RunPreinstallTarget(project.ProjectName, project.Directory, + globalGenerator.get(), buildConfig)) { return 0; } + + cmCPackLogger(cmCPackLog::LOG_OUTPUT, + "- Install project: " << project.ProjectName << " [" + << buildConfig << ']' + << std::endl); + // Run the installation for each component + for (std::string const& component : componentsVector) { + if (!this->InstallCMakeProject( + setDestDir, project.Directory, baseTempInstallDirectory, + default_dir_mode, component, componentInstall, + project.SubDirectory, buildConfig, absoluteDestFiles)) { + return 0; + } + } } - this->CMakeProjects.push_back(project); + this->CMakeProjects.emplace_back(std::move(project)); } } this->SetOption("CPACK_ABSOLUTE_DESTINATION_FILES", diff --git a/Source/CPack/cmCPackGeneratorFactory.cxx b/Source/CPack/cmCPackGeneratorFactory.cxx index 2c5ab4d..4d41049 100644 --- a/Source/CPack/cmCPackGeneratorFactory.cxx +++ b/Source/CPack/cmCPackGeneratorFactory.cxx @@ -7,10 +7,10 @@ #include "IFW/cmCPackIFWGenerator.h" #include "cmAlgorithms.h" -#include "cmCPack7zGenerator.h" #ifdef HAVE_FREEBSD_PKG # include "cmCPackFreeBSDGenerator.h" #endif +#include "cmCPackArchiveGenerator.h" #include "cmCPackDebGenerator.h" #include "cmCPackExternalGenerator.h" #include "cmCPackGenerator.h" @@ -18,11 +18,6 @@ #include "cmCPackNSISGenerator.h" #include "cmCPackNuGetGenerator.h" #include "cmCPackSTGZGenerator.h" -#include "cmCPackTGZGenerator.h" -#include "cmCPackTXZGenerator.h" -#include "cmCPackTarBZip2Generator.h" -#include "cmCPackTarCompressGenerator.h" -#include "cmCPackZIPGenerator.h" #ifdef __APPLE__ # include "cmCPackBundleGenerator.h" @@ -48,13 +43,21 @@ cmCPackGeneratorFactory::cmCPackGeneratorFactory() { - if (cmCPackTGZGenerator::CanGenerate()) { + if (cmCPackArchiveGenerator::CanGenerate()) { + this->RegisterGenerator("7Z", "7-Zip file format", + cmCPackArchiveGenerator::Create7ZGenerator); + this->RegisterGenerator("TBZ2", "Tar BZip2 compression", + cmCPackArchiveGenerator::CreateTBZ2Generator); this->RegisterGenerator("TGZ", "Tar GZip compression", - cmCPackTGZGenerator::CreateGenerator); - } - if (cmCPackTXZGenerator::CanGenerate()) { + cmCPackArchiveGenerator::CreateTGZGenerator); this->RegisterGenerator("TXZ", "Tar XZ compression", - cmCPackTXZGenerator::CreateGenerator); + cmCPackArchiveGenerator::CreateTXZGenerator); + this->RegisterGenerator("TZ", "Tar Compress compression", + cmCPackArchiveGenerator::CreateTZGenerator); + this->RegisterGenerator("TZST", "Tar Zstandard compression", + cmCPackArchiveGenerator::CreateTZSTGenerator); + this->RegisterGenerator("ZIP", "ZIP file format", + cmCPackArchiveGenerator::CreateZIPGenerator); } if (cmCPackSTGZGenerator::CanGenerate()) { this->RegisterGenerator("STGZ", "Self extracting Tar GZip compression", @@ -80,29 +83,12 @@ cmCPackGeneratorFactory::cmCPackGeneratorFactory() cmCPackCygwinSourceGenerator::CreateGenerator); } #endif - - if (cmCPackZIPGenerator::CanGenerate()) { - this->RegisterGenerator("ZIP", "ZIP file format", - cmCPackZIPGenerator::CreateGenerator); - } - if (cmCPack7zGenerator::CanGenerate()) { - this->RegisterGenerator("7Z", "7-Zip file format", - cmCPack7zGenerator::CreateGenerator); - } #if defined(_WIN32) || (defined(__CYGWIN__) && defined(HAVE_LIBUUID)) if (cmCPackWIXGenerator::CanGenerate()) { this->RegisterGenerator("WIX", "MSI file format via WiX tools", cmCPackWIXGenerator::CreateGenerator); } #endif - if (cmCPackTarBZip2Generator::CanGenerate()) { - this->RegisterGenerator("TBZ2", "Tar BZip2 compression", - cmCPackTarBZip2Generator::CreateGenerator); - } - if (cmCPackTarCompressGenerator::CanGenerate()) { - this->RegisterGenerator("TZ", "Tar Compress compression", - cmCPackTarCompressGenerator::CreateGenerator); - } if (cmCPackDebGenerator::CanGenerate()) { this->RegisterGenerator("DEB", "Debian packages", cmCPackDebGenerator::CreateGenerator); diff --git a/Source/CPack/cmCPackSTGZGenerator.cxx b/Source/CPack/cmCPackSTGZGenerator.cxx index 4666dc2..3092508 100644 --- a/Source/CPack/cmCPackSTGZGenerator.cxx +++ b/Source/CPack/cmCPackSTGZGenerator.cxx @@ -8,12 +8,16 @@ #include <string> #include <vector> +#include "cmArchiveWrite.h" #include "cmCPackGenerator.h" #include "cmCPackLog.h" #include "cmSystemTools.h" #include "cm_sys_stat.h" -cmCPackSTGZGenerator::cmCPackSTGZGenerator() = default; +cmCPackSTGZGenerator::cmCPackSTGZGenerator() + : cmCPackArchiveGenerator(cmArchiveWrite::CompressGZip, "paxr", ".sh") +{ +} cmCPackSTGZGenerator::~cmCPackSTGZGenerator() = default; diff --git a/Source/CPack/cmCPackSTGZGenerator.h b/Source/CPack/cmCPackSTGZGenerator.h index 9cf184b..55e4779 100644 --- a/Source/CPack/cmCPackSTGZGenerator.h +++ b/Source/CPack/cmCPackSTGZGenerator.h @@ -5,8 +5,8 @@ #include "cmConfigure.h" // IWYU pragma: keep +#include "cmCPackArchiveGenerator.h" #include "cmCPackGenerator.h" -#include "cmCPackTGZGenerator.h" #include <iosfwd> @@ -14,10 +14,10 @@ * \brief A generator for Self extractable TGZ files * */ -class cmCPackSTGZGenerator : public cmCPackTGZGenerator +class cmCPackSTGZGenerator : public cmCPackArchiveGenerator { public: - cmCPackTypeMacro(cmCPackSTGZGenerator, cmCPackTGZGenerator); + cmCPackTypeMacro(cmCPackSTGZGenerator, cmCPackArchiveGenerator); /** * Construct generator @@ -29,7 +29,6 @@ protected: int PackageFiles() override; int InitializeInternal() override; int GenerateHeader(std::ostream* os) override; - const char* GetOutputExtension() override { return ".sh"; } }; #endif diff --git a/Source/CPack/cmCPackTGZGenerator.cxx b/Source/CPack/cmCPackTGZGenerator.cxx deleted file mode 100644 index 6f4676e..0000000 --- a/Source/CPack/cmCPackTGZGenerator.cxx +++ /dev/null @@ -1,13 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing for details. */ -#include "cmCPackTGZGenerator.h" - -#include "cmArchiveWrite.h" -#include "cmCPackArchiveGenerator.h" - -cmCPackTGZGenerator::cmCPackTGZGenerator() - : cmCPackArchiveGenerator(cmArchiveWrite::CompressGZip, "paxr") -{ -} - -cmCPackTGZGenerator::~cmCPackTGZGenerator() = default; diff --git a/Source/CPack/cmCPackTGZGenerator.h b/Source/CPack/cmCPackTGZGenerator.h deleted file mode 100644 index 7be3d9d..0000000 --- a/Source/CPack/cmCPackTGZGenerator.h +++ /dev/null @@ -1,29 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing for details. */ -#ifndef cmCPackTGZGenerator_h -#define cmCPackTGZGenerator_h - -#include "cmConfigure.h" // IWYU pragma: keep - -#include "cmCPackArchiveGenerator.h" -#include "cmCPackGenerator.h" - -/** \class cmCPackTGZGenerator - * \brief A generator for TGZ files - * - */ -class cmCPackTGZGenerator : public cmCPackArchiveGenerator -{ -public: - cmCPackTypeMacro(cmCPackTGZGenerator, cmCPackArchiveGenerator); - /** - * Construct generator - */ - cmCPackTGZGenerator(); - ~cmCPackTGZGenerator() override; - -protected: - const char* GetOutputExtension() override { return ".tar.gz"; } -}; - -#endif diff --git a/Source/CPack/cmCPackTXZGenerator.cxx b/Source/CPack/cmCPackTXZGenerator.cxx deleted file mode 100644 index ccbccde..0000000 --- a/Source/CPack/cmCPackTXZGenerator.cxx +++ /dev/null @@ -1,13 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing for details. */ -#include "cmCPackTXZGenerator.h" - -#include "cmArchiveWrite.h" -#include "cmCPackArchiveGenerator.h" - -cmCPackTXZGenerator::cmCPackTXZGenerator() - : cmCPackArchiveGenerator(cmArchiveWrite::CompressXZ, "paxr") -{ -} - -cmCPackTXZGenerator::~cmCPackTXZGenerator() = default; diff --git a/Source/CPack/cmCPackTXZGenerator.h b/Source/CPack/cmCPackTXZGenerator.h deleted file mode 100644 index 4aa5973..0000000 --- a/Source/CPack/cmCPackTXZGenerator.h +++ /dev/null @@ -1,29 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing for details. */ -#ifndef cmCPackTXZGenerator_h -#define cmCPackTXZGenerator_h - -#include "cmConfigure.h" // IWYU pragma: keep - -#include "cmCPackArchiveGenerator.h" -#include "cmCPackGenerator.h" - -/** \class cmCPackTXZGenerator - * \brief A generator for TXZ files - * - */ -class cmCPackTXZGenerator : public cmCPackArchiveGenerator -{ -public: - cmCPackTypeMacro(cmCPackTXZGenerator, cmCPackArchiveGenerator); - /** - * Construct generator - */ - cmCPackTXZGenerator(); - ~cmCPackTXZGenerator() override; - -protected: - const char* GetOutputExtension() override { return ".tar.xz"; } -}; - -#endif diff --git a/Source/CPack/cmCPackTarBZip2Generator.cxx b/Source/CPack/cmCPackTarBZip2Generator.cxx deleted file mode 100644 index 85abeb1..0000000 --- a/Source/CPack/cmCPackTarBZip2Generator.cxx +++ /dev/null @@ -1,13 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing for details. */ -#include "cmCPackTarBZip2Generator.h" - -#include "cmArchiveWrite.h" -#include "cmCPackArchiveGenerator.h" - -cmCPackTarBZip2Generator::cmCPackTarBZip2Generator() - : cmCPackArchiveGenerator(cmArchiveWrite::CompressBZip2, "paxr") -{ -} - -cmCPackTarBZip2Generator::~cmCPackTarBZip2Generator() = default; diff --git a/Source/CPack/cmCPackTarBZip2Generator.h b/Source/CPack/cmCPackTarBZip2Generator.h deleted file mode 100644 index 7975dda..0000000 --- a/Source/CPack/cmCPackTarBZip2Generator.h +++ /dev/null @@ -1,28 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing for details. */ -#ifndef cmCPackTarBZip2Generator_h -#define cmCPackTarBZip2Generator_h - -#include "cmConfigure.h" // IWYU pragma: keep - -#include "cmCPackArchiveGenerator.h" -#include "cmCPackGenerator.h" - -/** \class cmCPackTarBZip2Generator - * \brief A generator for TarBZip2 files - */ -class cmCPackTarBZip2Generator : public cmCPackArchiveGenerator -{ -public: - cmCPackTypeMacro(cmCPackTarBZip2Generator, cmCPackArchiveGenerator); - /** - * Construct generator - */ - cmCPackTarBZip2Generator(); - ~cmCPackTarBZip2Generator() override; - -protected: - const char* GetOutputExtension() override { return ".tar.bz2"; } -}; - -#endif diff --git a/Source/CPack/cmCPackTarCompressGenerator.cxx b/Source/CPack/cmCPackTarCompressGenerator.cxx deleted file mode 100644 index 55a6de5..0000000 --- a/Source/CPack/cmCPackTarCompressGenerator.cxx +++ /dev/null @@ -1,13 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing for details. */ -#include "cmCPackTarCompressGenerator.h" - -#include "cmArchiveWrite.h" -#include "cmCPackArchiveGenerator.h" - -cmCPackTarCompressGenerator::cmCPackTarCompressGenerator() - : cmCPackArchiveGenerator(cmArchiveWrite::CompressCompress, "paxr") -{ -} - -cmCPackTarCompressGenerator::~cmCPackTarCompressGenerator() = default; diff --git a/Source/CPack/cmCPackTarCompressGenerator.h b/Source/CPack/cmCPackTarCompressGenerator.h deleted file mode 100644 index 37c7f48..0000000 --- a/Source/CPack/cmCPackTarCompressGenerator.h +++ /dev/null @@ -1,28 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing for details. */ -#ifndef cmCPackTarCompressGenerator_h -#define cmCPackTarCompressGenerator_h - -#include "cmConfigure.h" // IWYU pragma: keep - -#include "cmCPackArchiveGenerator.h" -#include "cmCPackGenerator.h" - -/** \class cmCPackTarCompressGenerator - * \brief A generator for TarCompress files - */ -class cmCPackTarCompressGenerator : public cmCPackArchiveGenerator -{ -public: - cmCPackTypeMacro(cmCPackTarCompressGenerator, cmCPackArchiveGenerator); - /** - * Construct generator - */ - cmCPackTarCompressGenerator(); - ~cmCPackTarCompressGenerator() override; - -protected: - const char* GetOutputExtension() override { return ".tar.Z"; } -}; - -#endif diff --git a/Source/CPack/cmCPackZIPGenerator.cxx b/Source/CPack/cmCPackZIPGenerator.cxx deleted file mode 100644 index f06494c..0000000 --- a/Source/CPack/cmCPackZIPGenerator.cxx +++ /dev/null @@ -1,13 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing for details. */ -#include "cmCPackZIPGenerator.h" - -#include "cmArchiveWrite.h" -#include "cmCPackArchiveGenerator.h" - -cmCPackZIPGenerator::cmCPackZIPGenerator() - : cmCPackArchiveGenerator(cmArchiveWrite::CompressNone, "zip") -{ -} - -cmCPackZIPGenerator::~cmCPackZIPGenerator() = default; diff --git a/Source/CPack/cmCPackZIPGenerator.h b/Source/CPack/cmCPackZIPGenerator.h deleted file mode 100644 index 58ec79e..0000000 --- a/Source/CPack/cmCPackZIPGenerator.h +++ /dev/null @@ -1,29 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing for details. */ -#ifndef cmCPackZIPGenerator_h -#define cmCPackZIPGenerator_h - -#include "cmConfigure.h" // IWYU pragma: keep - -#include "cmCPackArchiveGenerator.h" -#include "cmCPackGenerator.h" - -/** \class cmCPackZIPGenerator - * \brief A generator for ZIP files - */ -class cmCPackZIPGenerator : public cmCPackArchiveGenerator -{ -public: - cmCPackTypeMacro(cmCPackZIPGenerator, cmCPackArchiveGenerator); - - /** - * Construct generator - */ - cmCPackZIPGenerator(); - ~cmCPackZIPGenerator() override; - -protected: - const char* GetOutputExtension() override { return ".zip"; } -}; - -#endif diff --git a/Source/CPack/cpack.cxx b/Source/CPack/cpack.cxx index 69dac88..b4b320d 100644 --- a/Source/CPack/cpack.cxx +++ b/Source/CPack/cpack.cxx @@ -157,7 +157,7 @@ int main(int argc, char const* const* argv) cmsys::CommandLineArguments arg; arg.Initialize(argc, argv); - typedef cmsys::CommandLineArguments argT; + using argT = cmsys::CommandLineArguments; // Help arguments arg.AddArgument("--help", argT::NO_ARGUMENT, &help, "CPack help"); arg.AddArgument("--help-full", argT::SPACE_ARGUMENT, &helpFull, diff --git a/Source/CTest/cmCTestBZR.cxx b/Source/CTest/cmCTestBZR.cxx index b957856..52dc0ac 100644 --- a/Source/CTest/cmCTestBZR.cxx +++ b/Source/CTest/cmCTestBZR.cxx @@ -200,8 +200,8 @@ public: private: cmCTestBZR* BZR; - typedef cmCTestBZR::Revision Revision; - typedef cmCTestBZR::Change Change; + using Revision = cmCTestBZR::Revision; + using Change = cmCTestBZR::Change; Revision Rev; std::vector<Change> Changes; Change CurChange; diff --git a/Source/CTest/cmCTestCVS.cxx b/Source/CTest/cmCTestCVS.cxx index 560c169..b9b90c8 100644 --- a/Source/CTest/cmCTestCVS.cxx +++ b/Source/CTest/cmCTestCVS.cxx @@ -105,7 +105,7 @@ bool cmCTestCVS::UpdateImpl() class cmCTestCVS::LogParser : public cmCTestVC::LineParser { public: - typedef cmCTestCVS::Revision Revision; + using Revision = cmCTestCVS::Revision; LogParser(cmCTestCVS* cvs, const char* prefix, std::vector<Revision>& revs) : CVS(cvs) , Revisions(revs) diff --git a/Source/CTest/cmCTestGIT.cxx b/Source/CTest/cmCTestGIT.cxx index f7319ef..3ae464d 100644 --- a/Source/CTest/cmCTestGIT.cxx +++ b/Source/CTest/cmCTestGIT.cxx @@ -333,7 +333,7 @@ public: this->SetLog(&git->Log, prefix); } - typedef cmCTestGIT::Change Change; + using Change = cmCTestGIT::Change; std::vector<Change> Changes; protected: @@ -456,7 +456,7 @@ public: } private: - typedef cmCTestGIT::Revision Revision; + using Revision = cmCTestGIT::Revision; enum SectionType { SectionHeader, diff --git a/Source/CTest/cmCTestHG.cxx b/Source/CTest/cmCTestHG.cxx index ba2252a..297077e 100644 --- a/Source/CTest/cmCTestHG.cxx +++ b/Source/CTest/cmCTestHG.cxx @@ -174,8 +174,8 @@ public: private: cmCTestHG* HG; - typedef cmCTestHG::Revision Revision; - typedef cmCTestHG::Change Change; + using Revision = cmCTestHG::Revision; + using Change = cmCTestHG::Change; Revision Rev; std::vector<Change> Changes; Change CurChange; diff --git a/Source/CTest/cmCTestP4.cxx b/Source/CTest/cmCTestP4.cxx index 64354e8..9bca7cb 100644 --- a/Source/CTest/cmCTestP4.cxx +++ b/Source/CTest/cmCTestP4.cxx @@ -204,8 +204,8 @@ private: cmsys::RegularExpression RegexDiff; cmCTestP4* P4; - typedef cmCTestP4::Revision Revision; - typedef cmCTestP4::Change Change; + using Revision = cmCTestP4::Revision; + using Change = cmCTestP4::Change; std::vector<Change> Changes; enum SectionType { diff --git a/Source/CTest/cmCTestSVN.cxx b/Source/CTest/cmCTestSVN.cxx index dc1472b..6d8077f 100644 --- a/Source/CTest/cmCTestSVN.cxx +++ b/Source/CTest/cmCTestSVN.cxx @@ -307,8 +307,8 @@ private: cmCTestSVN* SVN; cmCTestSVN::SVNInfo& SVNRepo; - typedef cmCTestSVN::Revision Revision; - typedef cmCTestSVN::Change Change; + using Revision = cmCTestSVN::Revision; + using Change = cmCTestSVN::Change; Revision Rev; std::vector<Change> Changes; Change CurChange; diff --git a/Source/CTest/cmCTestSubmitHandler.cxx b/Source/CTest/cmCTestSubmitHandler.cxx index a178b44..f215911 100644 --- a/Source/CTest/cmCTestSubmitHandler.cxx +++ b/Source/CTest/cmCTestSubmitHandler.cxx @@ -26,7 +26,7 @@ #define SUBMIT_TIMEOUT_IN_SECONDS_DEFAULT 120 -typedef std::vector<char> cmCTestSubmitHandlerVectorOfChar; +using cmCTestSubmitHandlerVectorOfChar = std::vector<char>; class cmCTestSubmitHandler::ResponseParser : public cmXMLParser { diff --git a/Source/CTest/cmCTestTestHandler.cxx b/Source/CTest/cmCTestTestHandler.cxx index 9181daa..2b5a406 100644 --- a/Source/CTest/cmCTestTestHandler.cxx +++ b/Source/CTest/cmCTestTestHandler.cxx @@ -1,22 +1,6 @@ /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmCTestTestHandler.h" -#include <algorithm> -#include <chrono> -#include <cmath> -#include <cmsys/Base64.h> -#include <cmsys/Directory.hxx> -#include <cmsys/RegularExpression.hxx> -#include <cstring> -#include <functional> -#include <iomanip> -#include <iterator> -#include <set> -#include <sstream> -#include <stdio.h> -#include <stdlib.h> -#include <time.h> -#include <utility> #include "cm_memory.hxx" @@ -38,6 +22,24 @@ #include "cmake.h" #include "cmsys/FStream.hxx" +#include <algorithm> +#include <chrono> +#include <cmath> +#include <cmsys/Base64.h> +#include <cmsys/Directory.hxx> +#include <cmsys/RegularExpression.hxx> +#include <cstddef> +#include <cstring> +#include <functional> +#include <iomanip> +#include <iterator> +#include <set> +#include <sstream> +#include <stdio.h> +#include <stdlib.h> +#include <time.h> +#include <utility> + class cmExecutionStatus; class cmCTestSubdirCommand : public cmCommand @@ -937,9 +939,9 @@ void cmCTestTestHandler::UpdateForFixtures(ListOfTests& tests) const // Prepare some maps to help us find setup and cleanup tests for // any given fixture - typedef ListOfTests::const_iterator TestIterator; + using TestIterator = ListOfTests::const_iterator; typedef std::multimap<std::string, TestIterator> FixtureDependencies; - typedef FixtureDependencies::const_iterator FixtureDepsIterator; + using FixtureDepsIterator = FixtureDependencies::const_iterator; FixtureDependencies fixtureSetups; FixtureDependencies fixtureCleanups; diff --git a/Source/CTest/cmParseBlanketJSCoverage.cxx b/Source/CTest/cmParseBlanketJSCoverage.cxx index b74decb..191100c 100644 --- a/Source/CTest/cmParseBlanketJSCoverage.cxx +++ b/Source/CTest/cmParseBlanketJSCoverage.cxx @@ -13,8 +13,8 @@ class cmParseBlanketJSCoverage::JSONParser { public: - typedef cmCTestCoverageHandlerContainer::SingleFileCoverageVector - FileLinesType; + using FileLinesType = + cmCTestCoverageHandlerContainer::SingleFileCoverageVector; JSONParser(cmCTestCoverageHandlerContainer& cont) : Coverage(cont) { diff --git a/Source/CTest/cmParseCoberturaCoverage.cxx b/Source/CTest/cmParseCoberturaCoverage.cxx index e0186c9..e4f353b 100644 --- a/Source/CTest/cmParseCoberturaCoverage.cxx +++ b/Source/CTest/cmParseCoberturaCoverage.cxx @@ -142,8 +142,8 @@ private: bool InSource = false; bool SkipThisClass = false; std::vector<std::string> FilePaths; - typedef cmCTestCoverageHandlerContainer::SingleFileCoverageVector - FileLinesType; + using FileLinesType = + cmCTestCoverageHandlerContainer::SingleFileCoverageVector; cmCTest* CTest; cmCTestCoverageHandlerContainer& Coverage; std::string CurFileName; diff --git a/Source/CTest/cmParseDelphiCoverage.cxx b/Source/CTest/cmParseDelphiCoverage.cxx index 9eda6f8..e8a184a 100644 --- a/Source/CTest/cmParseDelphiCoverage.cxx +++ b/Source/CTest/cmParseDelphiCoverage.cxx @@ -12,8 +12,8 @@ class cmParseDelphiCoverage::HTMLParser { public: - typedef cmCTestCoverageHandlerContainer::SingleFileCoverageVector - FileLinesType; + using FileLinesType = + cmCTestCoverageHandlerContainer::SingleFileCoverageVector; HTMLParser(cmCTest* ctest, cmCTestCoverageHandlerContainer& cont) : CTest(ctest) , Coverage(cont) diff --git a/Source/CTest/cmParseJacocoCoverage.cxx b/Source/CTest/cmParseJacocoCoverage.cxx index 374acad..6a2d0cc 100644 --- a/Source/CTest/cmParseJacocoCoverage.cxx +++ b/Source/CTest/cmParseJacocoCoverage.cxx @@ -133,8 +133,8 @@ private: std::string FilePath; std::string PackagePath; std::string PackageName; - typedef cmCTestCoverageHandlerContainer::SingleFileCoverageVector - FileLinesType; + using FileLinesType = + cmCTestCoverageHandlerContainer::SingleFileCoverageVector; cmCTest* CTest; cmCTestCoverageHandlerContainer& Coverage; }; diff --git a/Source/bindexplib.cxx b/Source/bindexplib.cxx index a107294..7e5db26 100644 --- a/Source/bindexplib.cxx +++ b/Source/bindexplib.cxx @@ -64,9 +64,12 @@ */ #include "bindexplib.h" +#include "cmSystemTools.h" #include "cmsys/Encoding.hxx" #include "cmsys/FStream.hxx" #include <iostream> +#include <sstream> +#include <vector> #include <windows.h> #ifndef IMAGE_FILE_MACHINE_ARM @@ -301,7 +304,63 @@ private: bool IsI386; }; -bool DumpFile(const char* filename, std::set<std::string>& symbols, +bool DumpFileWithLlvmNm(std::string const& nmPath, const char* filename, + std::set<std::string>& symbols, + std::set<std::string>& dataSymbols) +{ + std::string output; + // break up command line into a vector + std::vector<std::string> command; + command.push_back(nmPath); + command.push_back("--no-weak"); + command.push_back("--defined-only"); + command.push_back("--format=posix"); + command.push_back(filename); + + // run the command + int exit_code = 0; + cmSystemTools::RunSingleCommand(command, &output, &output, &exit_code, "", + cmSystemTools::OUTPUT_NONE); + + if (exit_code != 0) { + fprintf(stderr, "llvm-nm returned an error: %s\n", output.c_str()); + return false; + } + + std::istringstream ss(output); + std::string line; + while (std::getline(ss, line)) { + if (line.empty()) { // last line + continue; + } + size_t sym_end = line.find(" "); + if (sym_end == std::string::npos) { + fprintf(stderr, "Couldn't parse llvm-nm output line: %s\n", + line.c_str()); + return false; + } + if (line.size() < sym_end + 1) { + fprintf(stderr, "Couldn't parse llvm-nm output line: %s\n", + line.c_str()); + return false; + } + const std::string sym = line.substr(0, sym_end); + const char sym_type = line[sym_end + 1]; + switch (sym_type) { + case 'D': + dataSymbols.insert(sym); + break; + case 'T': + symbols.insert(sym); + break; + } + } + + return true; +} + +bool DumpFile(std::string const& nmPath, const char* filename, + std::set<std::string>& symbols, std::set<std::string>& dataSymbols) { HANDLE hFile; @@ -356,16 +415,26 @@ bool DumpFile(const char* filename, std::set<std::string>& symbols, (imageHeader->Machine == IMAGE_FILE_MACHINE_I386)); symbolDumper.DumpObjFile(); } else { - // check for /bigobj format + // check for /bigobj and llvm LTO format cmANON_OBJECT_HEADER_BIGOBJ* h = (cmANON_OBJECT_HEADER_BIGOBJ*)lpFileBase; if (h->Sig1 == 0x0 && h->Sig2 == 0xffff) { + // bigobj DumpSymbols<cmANON_OBJECT_HEADER_BIGOBJ, cmIMAGE_SYMBOL_EX> symbolDumper((cmANON_OBJECT_HEADER_BIGOBJ*)lpFileBase, symbols, dataSymbols, (h->Machine == IMAGE_FILE_MACHINE_I386)); symbolDumper.DumpObjFile(); + } else if ( + // BCexCODE - llvm bitcode + (h->Sig1 == 0x4342 && h->Sig2 == 0xDEC0) || + // 0x0B17C0DE - llvm bitcode BC wrapper + (h->Sig1 == 0x0B17 && h->Sig2 == 0xC0DE)) { + + return DumpFileWithLlvmNm(nmPath, filename, symbols, dataSymbols); + } else { - printf("unrecognized file format in '%s'\n", filename); + printf("unrecognized file format in '%s, %u'\n", filename, + imageHeader->Machine); return false; } } @@ -378,7 +447,7 @@ bool DumpFile(const char* filename, std::set<std::string>& symbols, bool bindexplib::AddObjectFile(const char* filename) { - return DumpFile(filename, this->Symbols, this->DataSymbols); + return DumpFile(NmPath, filename, this->Symbols, this->DataSymbols); } bool bindexplib::AddDefinitionFile(const char* filename) @@ -419,3 +488,8 @@ void bindexplib::WriteFile(FILE* file) fprintf(file, "\t%s\n", s.c_str()); } } + +void bindexplib::SetNmPath(std::string const& nm) +{ + NmPath = nm; +} diff --git a/Source/bindexplib.h b/Source/bindexplib.h index 3e22ac7..6c066c5 100644 --- a/Source/bindexplib.h +++ b/Source/bindexplib.h @@ -12,13 +12,16 @@ class bindexplib { public: - bindexplib() {} + bindexplib() { NmPath = "nm"; } bool AddDefinitionFile(const char* filename); bool AddObjectFile(const char* filename); void WriteFile(FILE* file); + void SetNmPath(std::string const& nm); + private: std::set<std::string> Symbols; std::set<std::string> DataSymbols; + std::string NmPath; }; #endif diff --git a/Source/cmAffinity.cxx b/Source/cmAffinity.cxx index 09b0298..fa5e4b9 100644 --- a/Source/cmAffinity.cxx +++ b/Source/cmAffinity.cxx @@ -20,7 +20,7 @@ # include <sys/param.h> # endif # if defined(__linux__) -typedef cpu_set_t cm_cpuset_t; +using cm_cpuset_t = cpu_set_t; # else typedef cpuset_t cm_cpuset_t; # endif diff --git a/Source/cmAlgorithms.h b/Source/cmAlgorithms.h index 59aa86f..6775f9d 100644 --- a/Source/cmAlgorithms.h +++ b/Source/cmAlgorithms.h @@ -115,7 +115,7 @@ FwdIt RemoveN(FwdIt i1, FwdIt i2, size_t n) template <typename Range> struct BinarySearcher { - typedef typename Range::value_type argument_type; + using argument_type = typename Range::value_type; BinarySearcher(Range const& r) : m_range(r) { @@ -132,8 +132,8 @@ private: } class cmListFileBacktrace; -typedef cmRange<std::vector<cmListFileBacktrace>::const_iterator> - cmBacktraceRange; +using cmBacktraceRange = + cmRange<std::vector<cmListFileBacktrace>::const_iterator>; template <typename Range> void cmDeleteAll(Range const& r) diff --git a/Source/cmArchiveWrite.cxx b/Source/cmArchiveWrite.cxx index a063fd9..a6c25e1 100644 --- a/Source/cmArchiveWrite.cxx +++ b/Source/cmArchiveWrite.cxx @@ -333,7 +333,7 @@ bool cmArchiveWrite::AddData(const char* file, size_t size) char buffer[16384]; size_t nleft = size; while (nleft > 0) { - typedef std::streamsize ssize_type; + using ssize_type = std::streamsize; size_t const nnext = nleft > sizeof(buffer) ? sizeof(buffer) : nleft; ssize_type const nnext_s = static_cast<ssize_type>(nnext); fin.read(buffer, nnext_s); diff --git a/Source/cmCPluginAPI.cxx b/Source/cmCPluginAPI.cxx index f0c1845..e814d67 100644 --- a/Source/cmCPluginAPI.cxx +++ b/Source/cmCPluginAPI.cxx @@ -490,9 +490,9 @@ class cmCPluginAPISourceFileMap : public std::map<cmSourceFile*, cmCPluginAPISourceFile*> { public: - typedef std::map<cmSourceFile*, cmCPluginAPISourceFile*> derived; - typedef derived::iterator iterator; - typedef derived::value_type value_type; + using derived = std::map<cmSourceFile*, cmCPluginAPISourceFile*>; + using iterator = derived::iterator; + using value_type = derived::value_type; cmCPluginAPISourceFileMap() = default; ~cmCPluginAPISourceFileMap() { @@ -536,7 +536,7 @@ void CCONV* cmGetSource(void* arg, const char* name) // Create a proxy source file object for this source. cmCPluginAPISourceFile* sf = new cmCPluginAPISourceFile; sf->RealSourceFile = rsf; - sf->FullPath = rsf->GetFullPath(); + sf->FullPath = rsf->ResolveFullPath(); sf->SourceName = cmSystemTools::GetFilenameWithoutLastExtension(sf->FullPath); sf->SourceExtension = diff --git a/Source/cmCTest.h b/Source/cmCTest.h index 7fe3455..41dac85 100644 --- a/Source/cmCTest.h +++ b/Source/cmCTest.h @@ -41,7 +41,7 @@ class cmXMLWriter; class cmCTest { public: - typedef cmProcessOutput::Encoding Encoding; + using Encoding = cmProcessOutput::Encoding; /** Enumerate parts of the testing and submission process. */ enum Part { diff --git a/Source/cmComputeComponentGraph.h b/Source/cmComputeComponentGraph.h index 8cd4fe7..5493769 100644 --- a/Source/cmComputeComponentGraph.h +++ b/Source/cmComputeComponentGraph.h @@ -24,9 +24,9 @@ class cmComputeComponentGraph { public: // Represent the graph with an adjacency list. - typedef cmGraphNodeList NodeList; - typedef cmGraphEdgeList EdgeList; - typedef cmGraphAdjacencyList Graph; + using NodeList = cmGraphNodeList; + using EdgeList = cmGraphEdgeList; + using Graph = cmGraphAdjacencyList; cmComputeComponentGraph(Graph const& input); ~cmComputeComponentGraph(); diff --git a/Source/cmComputeLinkDepends.h b/Source/cmComputeLinkDepends.h index 839c27a..f0ac771 100644 --- a/Source/cmComputeLinkDepends.h +++ b/Source/cmComputeLinkDepends.h @@ -44,7 +44,7 @@ public: bool IsFlag = false; }; - typedef std::vector<LinkEntry> EntryVector; + using EntryVector = std::vector<LinkEntry>; EntryVector const& Compute(); void SetOldLinkDirMode(bool b); @@ -111,9 +111,9 @@ private: void InferDependencies(); // Ordering constraint graph adjacency list. - typedef cmGraphNodeList NodeList; - typedef cmGraphEdgeList EdgeList; - typedef cmGraphAdjacencyList Graph; + using NodeList = cmGraphNodeList; + using EdgeList = cmGraphEdgeList; + using Graph = cmGraphAdjacencyList; Graph EntryConstraintGraph; void CleanConstraintGraph(); void DisplayConstraintGraph(); diff --git a/Source/cmComputeLinkInformation.h b/Source/cmComputeLinkInformation.h index 784d3fa..0f71381 100644 --- a/Source/cmComputeLinkInformation.h +++ b/Source/cmComputeLinkInformation.h @@ -42,7 +42,7 @@ public: bool IsPath = true; cmGeneratorTarget const* Target = nullptr; }; - typedef std::vector<Item> ItemVector; + using ItemVector = std::vector<Item>; ItemVector const& GetItems() const; std::vector<std::string> const& GetDirectories() const; std::vector<std::string> const& GetDepends() const; diff --git a/Source/cmComputeTargetDepends.cxx b/Source/cmComputeTargetDepends.cxx index 01d4c07..6bf2f2d 100644 --- a/Source/cmComputeTargetDepends.cxx +++ b/Source/cmComputeTargetDepends.cxx @@ -197,11 +197,8 @@ void cmComputeTargetDepends::CollectTargetDepends(int depender_index) { std::set<cmLinkItem> emitted; - std::vector<std::string> configs; - depender->Makefile->GetConfigurations(configs); - if (configs.empty()) { - configs.emplace_back(); - } + std::vector<std::string> const& configs = + depender->Makefile->GetGeneratorConfigs(); for (std::string const& it : configs) { std::vector<cmSourceFile const*> objectFiles; depender->GetExternalObjects(objectFiles, it); diff --git a/Source/cmComputeTargetDepends.h b/Source/cmComputeTargetDepends.h index 3840bd7..6087574 100644 --- a/Source/cmComputeTargetDepends.h +++ b/Source/cmComputeTargetDepends.h @@ -70,9 +70,9 @@ private: // Represent the target dependency graph. The entry at each // top-level index corresponds to a depender whose dependencies are // listed. - typedef cmGraphNodeList NodeList; - typedef cmGraphEdgeList EdgeList; - typedef cmGraphAdjacencyList Graph; + using NodeList = cmGraphNodeList; + using EdgeList = cmGraphEdgeList; + using Graph = cmGraphAdjacencyList; Graph InitialGraph; Graph FinalGraph; void DisplayGraph(Graph const& graph, const std::string& name); diff --git a/Source/cmConditionEvaluator.h b/Source/cmConditionEvaluator.h index 59e1396..082534c 100644 --- a/Source/cmConditionEvaluator.h +++ b/Source/cmConditionEvaluator.h @@ -19,7 +19,7 @@ class cmMakefile; class cmConditionEvaluator { public: - typedef std::list<cmExpandedCommandArgument> cmArgumentList; + using cmArgumentList = std::list<cmExpandedCommandArgument>; cmConditionEvaluator(cmMakefile& makefile, cmListFileContext context, cmListFileBacktrace bt); diff --git a/Source/cmCustomCommandLines.h b/Source/cmCustomCommandLines.h index 36838f2..35a15ba 100644 --- a/Source/cmCustomCommandLines.h +++ b/Source/cmCustomCommandLines.h @@ -12,18 +12,18 @@ class cmCustomCommandLine : public std::vector<std::string> { public: - typedef std::vector<std::string> Superclass; - typedef Superclass::iterator iterator; - typedef Superclass::const_iterator const_iterator; + using Superclass = std::vector<std::string>; + using iterator = Superclass::iterator; + using const_iterator = Superclass::const_iterator; }; /** Data structure to represent a list of command lines. */ class cmCustomCommandLines : public std::vector<cmCustomCommandLine> { public: - typedef std::vector<cmCustomCommandLine> Superclass; - typedef Superclass::iterator iterator; - typedef Superclass::const_iterator const_iterator; + using Superclass = std::vector<cmCustomCommandLine>; + using iterator = Superclass::iterator; + using const_iterator = Superclass::const_iterator; }; #endif diff --git a/Source/cmDefinitions.h b/Source/cmDefinitions.h index b4d6419..008821d 100644 --- a/Source/cmDefinitions.h +++ b/Source/cmDefinitions.h @@ -24,7 +24,7 @@ */ class cmDefinitions { - typedef cmLinkedTree<cmDefinitions>::iterator StackIter; + using StackIter = cmLinkedTree<cmDefinitions>::iterator; public: // -- Static member functions diff --git a/Source/cmDependsFortran.cxx b/Source/cmDependsFortran.cxx index 6c77db9..8df9938 100644 --- a/Source/cmDependsFortran.cxx +++ b/Source/cmDependsFortran.cxx @@ -170,7 +170,7 @@ bool cmDependsFortran::Finalize(std::ostream& makeDepends, } // Actually write dependencies to the streams. - typedef cmDependsFortranInternals::ObjectInfoMap ObjectInfoMap; + using ObjectInfoMap = cmDependsFortranInternals::ObjectInfoMap; ObjectInfoMap const& objInfo = this->Internal->ObjectInfo; for (auto const& i : objInfo) { if (!this->WriteDependenciesReal(i.first, i.second, mod_dir, stamp_dir, @@ -222,7 +222,7 @@ bool cmDependsFortran::Finalize(std::ostream& makeDepends, void cmDependsFortran::LocateModules() { // Collect the set of modules provided and required by all sources. - typedef cmDependsFortranInternals::ObjectInfoMap ObjectInfoMap; + using ObjectInfoMap = cmDependsFortranInternals::ObjectInfoMap; ObjectInfoMap const& objInfo = this->Internal->ObjectInfo; for (auto const& infoI : objInfo) { cmFortranSourceInfo const& info = infoI.second; @@ -303,7 +303,7 @@ void cmDependsFortran::ConsiderModule(const std::string& name, const std::string& stampDir) { // Locate each required module. - typedef cmDependsFortranInternals::TargetRequiresMap TargetRequiresMap; + using TargetRequiresMap = cmDependsFortranInternals::TargetRequiresMap; TargetRequiresMap::iterator required = this->Internal->TargetRequires.find(name); if (required != this->Internal->TargetRequires.end() && @@ -321,7 +321,7 @@ bool cmDependsFortran::WriteDependenciesReal(std::string const& obj, std::ostream& makeDepends, std::ostream& internalDepends) { - typedef cmDependsFortranInternals::TargetRequiresMap TargetRequiresMap; + using TargetRequiresMap = cmDependsFortranInternals::TargetRequiresMap; // Get the source file for this object. std::string const& src = info.Source; diff --git a/Source/cmELF.cxx b/Source/cmELF.cxx index 096016d..425f1a8 100644 --- a/Source/cmELF.cxx +++ b/Source/cmELF.cxx @@ -102,7 +102,7 @@ void cmELFByteSwap(T& x) class cmELFInternal { public: - typedef cmELF::StringEntry StringEntry; + using StringEntry = cmELF::StringEntry; enum ByteOrderType { ByteOrderMSB, @@ -200,11 +200,11 @@ protected: // Configure the implementation template for 32-bit ELF files. struct cmELFTypes32 { - typedef Elf32_Ehdr ELF_Ehdr; - typedef Elf32_Shdr ELF_Shdr; - typedef Elf32_Dyn ELF_Dyn; - typedef Elf32_Half ELF_Half; - typedef KWIML_INT_uint32_t tagtype; + using ELF_Ehdr = Elf32_Ehdr; + using ELF_Shdr = Elf32_Shdr; + using ELF_Dyn = Elf32_Dyn; + using ELF_Half = Elf32_Half; + using tagtype = ::uint32_t; static const char* GetName() { return "32-bit"; } }; @@ -212,11 +212,11 @@ struct cmELFTypes32 #ifndef _SCO_DS struct cmELFTypes64 { - typedef Elf64_Ehdr ELF_Ehdr; - typedef Elf64_Shdr ELF_Shdr; - typedef Elf64_Dyn ELF_Dyn; - typedef Elf64_Half ELF_Half; - typedef KWIML_INT_uint64_t tagtype; + using ELF_Ehdr = Elf64_Ehdr; + using ELF_Shdr = Elf64_Shdr; + using ELF_Dyn = Elf64_Dyn; + using ELF_Half = Elf64_Half; + using tagtype = ::uint64_t; static const char* GetName() { return "64-bit"; } }; #endif @@ -227,11 +227,11 @@ class cmELFInternalImpl : public cmELFInternal { public: // Copy the ELF file format types from our configuration parameter. - typedef typename Types::ELF_Ehdr ELF_Ehdr; - typedef typename Types::ELF_Shdr ELF_Shdr; - typedef typename Types::ELF_Dyn ELF_Dyn; - typedef typename Types::ELF_Half ELF_Half; - typedef typename Types::tagtype tagtype; + using ELF_Ehdr = typename Types::ELF_Ehdr; + using ELF_Shdr = typename Types::ELF_Shdr; + using ELF_Dyn = typename Types::ELF_Dyn; + using ELF_Half = typename Types::ELF_Half; + using tagtype = typename Types::tagtype; // Construct with a stream and byte swap indicator. cmELFInternalImpl(cmELF* external, std::unique_ptr<std::istream> fin, diff --git a/Source/cmExecProgramCommand.cxx b/Source/cmExecProgramCommand.cxx index 7f41640..74e9c55 100644 --- a/Source/cmExecProgramCommand.cxx +++ b/Source/cmExecProgramCommand.cxx @@ -11,7 +11,7 @@ #include "cmStringAlgorithms.h" #include "cmSystemTools.h" -typedef cmProcessOutput::Encoding Encoding; +using Encoding = cmProcessOutput::Encoding; namespace { bool RunCommand(std::string command, std::string& output, int& retVal, diff --git a/Source/cmExtraCodeBlocksGenerator.cxx b/Source/cmExtraCodeBlocksGenerator.cxx index 487d0de..6b16b93 100644 --- a/Source/cmExtraCodeBlocksGenerator.cxx +++ b/Source/cmExtraCodeBlocksGenerator.cxx @@ -371,7 +371,7 @@ void cmExtraCodeBlocksGenerator::CreateNewProjectFile( isCFile = cm->IsSourceExtension(srcext); } - std::string const& fullPath = s->GetFullPath(); + std::string const& fullPath = s->ResolveFullPath(); // Check file position relative to project root dir. const std::string relative = diff --git a/Source/cmExtraCodeLiteGenerator.cxx b/Source/cmExtraCodeLiteGenerator.cxx index 7f71a2c..0956729 100644 --- a/Source/cmExtraCodeLiteGenerator.cxx +++ b/Source/cmExtraCodeLiteGenerator.cxx @@ -223,7 +223,7 @@ std::string cmExtraCodeLiteGenerator::CollectSourceFiles( gt->GetSourceFiles(sources, makefile->GetSafeDefinition("CMAKE_BUILD_TYPE")); for (cmSourceFile* s : sources) { - std::string const& fullPath = s->GetFullPath(); + std::string const& fullPath = s->ResolveFullPath(); std::string const& extLower = cmSystemTools::LowerCase(s->GetExtension()); // check whether it is a source or a include file diff --git a/Source/cmExtraEclipseCDT4Generator.cxx b/Source/cmExtraEclipseCDT4Generator.cxx index 6c94aae..43f1e12 100644 --- a/Source/cmExtraEclipseCDT4Generator.cxx +++ b/Source/cmExtraEclipseCDT4Generator.cxx @@ -524,7 +524,7 @@ void cmExtraEclipseCDT4Generator::CreateLinksForTargets(cmXMLWriter& xml) makefile->GetSafeDefinition("CMAKE_BUILD_TYPE")); for (cmSourceFile* sf : files) { // Add the file to the list of sources. - std::string const& source = sf->GetFullPath(); + std::string const& source = sf->ResolveFullPath(); cmSourceGroup* sourceGroup = makefile->FindSourceGroup(source, sourceGroups); sourceGroup->AssignSource(sf); diff --git a/Source/cmExtraKateGenerator.cxx b/Source/cmExtraKateGenerator.cxx index 2bfbb0d..7ac73cf 100644 --- a/Source/cmExtraKateGenerator.cxx +++ b/Source/cmExtraKateGenerator.cxx @@ -254,7 +254,7 @@ std::string cmExtraKateGenerator::GenerateFilesString( continue; } - tmp = sf->GetFullPath(); + tmp = sf->ResolveFullPath(); files.insert(tmp); } } diff --git a/Source/cmExtraSublimeTextGenerator.cxx b/Source/cmExtraSublimeTextGenerator.cxx index 6f4472b..52ba968 100644 --- a/Source/cmExtraSublimeTextGenerator.cxx +++ b/Source/cmExtraSublimeTextGenerator.cxx @@ -243,12 +243,12 @@ void cmExtraSublimeTextGenerator::AppendTarget( makefile->GetSafeDefinition("CMAKE_BUILD_TYPE")); for (cmSourceFile* sourceFile : sourceFiles) { MapSourceFileFlags::iterator sourceFileFlagsIter = - sourceFileFlags.find(sourceFile->GetFullPath()); + sourceFileFlags.find(sourceFile->ResolveFullPath()); if (sourceFileFlagsIter == sourceFileFlags.end()) { sourceFileFlagsIter = sourceFileFlags - .insert(MapSourceFileFlags::value_type(sourceFile->GetFullPath(), - std::vector<std::string>())) + .insert(MapSourceFileFlags::value_type( + sourceFile->ResolveFullPath(), std::vector<std::string>())) .first; } std::vector<std::string>& flags = sourceFileFlagsIter->second; diff --git a/Source/cmFLTKWrapUICommand.cxx b/Source/cmFLTKWrapUICommand.cxx index 2150051..ea9e672 100644 --- a/Source/cmFLTKWrapUICommand.cxx +++ b/Source/cmFLTKWrapUICommand.cxx @@ -112,7 +112,7 @@ bool cmFLTKWrapUICommand::InitialPass(std::vector<std::string> const& args, if (classNum) { sourceListValue += ";"; } - sourceListValue += generatedSourcesClasses[classNum]->GetFullPath(); + sourceListValue += generatedSourcesClasses[classNum]->ResolveFullPath(); } std::string const varName = target + "_FLTK_UI_SRCS"; diff --git a/Source/cmFileAPI.cxx b/Source/cmFileAPI.cxx index 5d9181a..8161191 100644 --- a/Source/cmFileAPI.cxx +++ b/Source/cmFileAPI.cxx @@ -17,6 +17,7 @@ #include <algorithm> #include <cassert> #include <chrono> +#include <cstddef> #include <ctime> #include <iomanip> #include <sstream> diff --git a/Source/cmFileAPICodemodel.cxx b/Source/cmFileAPICodemodel.cxx index 08db7c7..3ac769c 100644 --- a/Source/cmFileAPICodemodel.cxx +++ b/Source/cmFileAPICodemodel.cxx @@ -423,20 +423,17 @@ Json::Value Codemodel::DumpPaths() Json::Value Codemodel::DumpConfigurations() { - std::vector<std::string> configs; + Json::Value configurations = Json::arrayValue; cmGlobalGenerator* gg = this->FileAPI.GetCMakeInstance()->GetGlobalGenerator(); auto makefiles = gg->GetMakefiles(); if (!makefiles.empty()) { - makefiles[0]->GetConfigurations(configs); - if (configs.empty()) { - configs.emplace_back(); + std::vector<std::string> const& configs = + makefiles[0]->GetGeneratorConfigs(); + for (std::string const& config : configs) { + configurations.append(this->DumpConfiguration(config)); } } - Json::Value configurations = Json::arrayValue; - for (std::string const& config : configs) { - configurations.append(this->DumpConfiguration(config)); - } return configurations; } @@ -582,6 +579,12 @@ Json::Value CodemodelConfig::DumpTarget(cmGeneratorTarget* gt, { Target t(gt, this->Config); std::string prefix = "target-" + gt->GetName(); + for (char& c : prefix) { + // CMP0037 OLD behavior allows slashes in target names. Remove them. + if (c == '/' || c == '\\') { + c = '_'; + } + } if (!this->Config.empty()) { prefix += "-" + this->Config; } @@ -999,7 +1002,7 @@ Json::Value Target::DumpSource(cmGeneratorTarget::SourceAndKind const& sk, { Json::Value source = Json::objectValue; - std::string const path = sk.Source.Value->GetFullPath(); + std::string const path = sk.Source.Value->ResolveFullPath(); source["path"] = RelativeIfUnder(this->TopSource, path); if (sk.Source.Value->GetIsGenerated()) { source["isGenerated"] = true; diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx index 5589537..36a7dc3 100644 --- a/Source/cmFileCommand.cxx +++ b/Source/cmFileCommand.cxx @@ -1421,7 +1421,7 @@ bool HandleNativePathCommand(std::vector<std::string> const& args, #if !defined(CMAKE_BOOTSTRAP) // Stuff for curl download/upload -typedef std::vector<char> cmFileCommandVectorOfChar; +using cmFileCommandVectorOfChar = std::vector<char>; size_t cmWriteToFileCallback(void* ptr, size_t size, size_t nmemb, void* data) { diff --git a/Source/cmFileLockPool.h b/Source/cmFileLockPool.h index 41203ba..dae68dd 100644 --- a/Source/cmFileLockPool.h +++ b/Source/cmFileLockPool.h @@ -72,17 +72,17 @@ private: bool IsAlreadyLocked(const std::string& filename) const; private: - typedef std::vector<cmFileLock*> List; - typedef List::iterator It; - typedef List::const_iterator CIt; + using List = std::vector<cmFileLock*>; + using It = List::iterator; + using CIt = List::const_iterator; List Locks; }; - typedef std::vector<ScopePool*> List; + using List = std::vector<ScopePool*>; - typedef List::iterator It; - typedef List::const_iterator CIt; + using It = List::iterator; + using CIt = List::const_iterator; List FunctionScopes; List FileScopes; diff --git a/Source/cmFileLockResult.h b/Source/cmFileLockResult.h index 8b4929a..c452814 100644 --- a/Source/cmFileLockResult.h +++ b/Source/cmFileLockResult.h @@ -21,7 +21,7 @@ public: #if defined(_WIN32) typedef DWORD Error; #else - typedef int Error; + using Error = int; #endif /** diff --git a/Source/cmFileTime.h b/Source/cmFileTime.h index d4de4e0..e9a8559 100644 --- a/Source/cmFileTime.h +++ b/Source/cmFileTime.h @@ -14,7 +14,7 @@ class cmFileTime { public: - typedef long long NSC; + using NSC = long long; static constexpr NSC NsPerS = 1000000000; cmFileTime() = default; diff --git a/Source/cmFindLibraryCommand.cxx b/Source/cmFindLibraryCommand.cxx index 924a14e..92c64c8 100644 --- a/Source/cmFindLibraryCommand.cxx +++ b/Source/cmFindLibraryCommand.cxx @@ -191,7 +191,7 @@ struct cmFindLibraryHelper std::string SuffixRegexStr; // Keep track of the best library file found so far. - typedef std::vector<std::string>::size_type size_type; + using size_type = std::vector<std::string>::size_type; std::string BestPath; // Support for OpenBSD shared library naming: lib<name>.so.<major>.<minor> diff --git a/Source/cmFindPackageCommand.h b/Source/cmFindPackageCommand.h index f6645ae..d57b38a 100644 --- a/Source/cmFindPackageCommand.h +++ b/Source/cmFindPackageCommand.h @@ -235,8 +235,8 @@ namespace std { template <> struct hash<cmFindPackageCommand::ConfigFileInfo> { - typedef cmFindPackageCommand::ConfigFileInfo argument_type; - typedef size_t result_type; + using argument_type = cmFindPackageCommand::ConfigFileInfo; + using result_type = size_t; result_type operator()(argument_type const& s) const noexcept { diff --git a/Source/cmFortranParser.h b/Source/cmFortranParser.h index 6a33be5..825876c 100644 --- a/Source/cmFortranParser.h +++ b/Source/cmFortranParser.h @@ -15,7 +15,7 @@ #include <stddef.h> /* size_t */ /* Forward declare parser object type. */ -typedef struct cmFortranParser_s cmFortranParser; +using cmFortranParser = struct cmFortranParser_s; /* Functions to enter/exit #include'd files in order. */ bool cmFortranParser_FilePush(cmFortranParser* parser, const char* fname); diff --git a/Source/cmGeneratedFileStream.h b/Source/cmGeneratedFileStream.h index 5b1eb51..3d94cdc 100644 --- a/Source/cmGeneratedFileStream.h +++ b/Source/cmGeneratedFileStream.h @@ -72,8 +72,8 @@ class cmGeneratedFileStream , public cmsys::ofstream { public: - typedef cmsys::ofstream Stream; - typedef codecvt::Encoding Encoding; + using Stream = cmsys::ofstream; + using Encoding = codecvt::Encoding; /** * This constructor prepares a default stream. The open method must diff --git a/Source/cmGeneratorExpressionParser.cxx b/Source/cmGeneratorExpressionParser.cxx index 304378d..e7effca 100644 --- a/Source/cmGeneratorExpressionParser.cxx +++ b/Source/cmGeneratorExpressionParser.cxx @@ -174,8 +174,8 @@ void cmGeneratorExpressionParser::ParseGeneratorExpression( if (!parameters.empty()) { extendText(result, colonToken); - typedef std::vector<cmGeneratorExpressionEvaluator*> EvaluatorVector; - typedef std::vector<cmGeneratorExpressionToken> TokenVector; + using EvaluatorVector = std::vector<cmGeneratorExpressionEvaluator*>; + using TokenVector = std::vector<cmGeneratorExpressionToken>; std::vector<EvaluatorVector>::const_iterator pit = parameters.begin(); const std::vector<EvaluatorVector>::const_iterator pend = parameters.end(); diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index cc37232..48ffcec 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -5,6 +5,7 @@ #include "cmsys/RegularExpression.hxx" #include <algorithm> #include <assert.h> +#include <cstddef> #include <errno.h> #include <iterator> #include <memory> @@ -786,11 +787,8 @@ void cmGeneratorTarget::ComputeObjectMapping() return; } - std::vector<std::string> configs; - this->Makefile->GetConfigurations(configs); - if (configs.empty()) { - configs.emplace_back(); - } + std::vector<std::string> const& configs = + this->Makefile->GetGeneratorConfigs(); for (std::string const& c : configs) { std::vector<cmSourceFile const*> sourceFiles; this->GetObjectSources(sourceFiles, c); @@ -1351,7 +1349,7 @@ bool processSources(cmGeneratorTarget const* tgt, for (std::string& src : entry.Values) { cmSourceFile* sf = mf->GetOrCreateSource(src); std::string e; - std::string fullPath = sf->GetFullPath(&e); + std::string fullPath = sf->ResolveFullPath(&e); if (fullPath.empty()) { if (!e.empty()) { cmake* cm = tgt->GetLocalGenerator()->GetCMakeInstance(); @@ -1619,7 +1617,7 @@ void cmGeneratorTarget::ComputeKindedSources(KindedSources& files, // Both names would have been auto generated from Visual Studio // where the user supplied the file name and Visual Studio // appended the suffix. - std::string resx = sf->GetFullPath(); + std::string resx = sf->ResolveFullPath(); std::string hFileName = resx.substr(0, resx.find_last_of('.')) + ".h"; files.ExpectedResxHeaders.insert(hFileName); } else if (ext == "appxmanifest") { @@ -1635,12 +1633,12 @@ void cmGeneratorTarget::ComputeKindedSources(KindedSources& files, // Both names would have been auto generated from Visual Studio // where the user supplied the file name and Visual Studio // appended the suffix. - std::string xaml = sf->GetFullPath(); + std::string xaml = sf->ResolveFullPath(); std::string hFileName = xaml + ".h"; std::string cppFileName = xaml + ".cpp"; files.ExpectedXamlHeaders.insert(hFileName); files.ExpectedXamlSources.insert(cppFileName); - } else if (header_regex.find(sf->GetFullPath())) { + } else if (header_regex.find(sf->ResolveFullPath())) { kind = SourceKindHeader; } else { kind = SourceKindExtra; @@ -2604,7 +2602,7 @@ private: cmMakefile* Makefile; cmLocalGenerator* LocalGenerator; cmGlobalGenerator const* GlobalGenerator; - typedef cmGeneratorTarget::SourceEntry SourceEntry; + using SourceEntry = cmGeneratorTarget::SourceEntry; SourceEntry* CurrentEntry; std::queue<cmSourceFile*> SourceQueue; std::set<cmSourceFile*> SourcesQueued; @@ -2634,12 +2632,9 @@ cmTargetTraceDependencies::cmTargetTraceDependencies(cmGeneratorTarget* target) // Queue all the source files already specified for the target. if (target->GetType() != cmStateEnums::INTERFACE_LIBRARY) { - std::vector<std::string> configs; - this->Makefile->GetConfigurations(configs); - if (configs.empty()) { - configs.emplace_back(); - } std::set<cmSourceFile*> emitted; + std::vector<std::string> const& configs = + this->Makefile->GetGeneratorConfigs(); for (std::string const& c : configs) { std::vector<cmSourceFile*> sources; this->GeneratorTarget->GetSourceFiles(sources, c); @@ -2648,7 +2643,7 @@ cmTargetTraceDependencies::cmTargetTraceDependencies(cmGeneratorTarget* target) this->GlobalGenerator->GetFilenameTargetDepends(sf); if (cmContains(tgts, this->GeneratorTarget)) { std::ostringstream e; - e << "Evaluation output file\n \"" << sf->GetFullPath() + e << "Evaluation output file\n \"" << sf->ResolveFullPath() << "\"\ndepends on the sources of a target it is used in. This " "is a dependency loop and is not allowed."; this->GeneratorTarget->LocalGenerator->IssueMessage( @@ -2690,7 +2685,7 @@ void cmTargetTraceDependencies::Trace() } // Queue the source needed to generate this file, if any. - this->FollowName(sf->GetFullPath()); + this->FollowName(sf->ResolveFullPath()); // Queue dependencies added programmatically by commands. this->FollowNames(sf->GetDepends()); @@ -2711,7 +2706,7 @@ void cmTargetTraceDependencies::QueueSource(cmSourceFile* sf) this->SourceQueue.push(sf); // Make sure this file is in the target at the end. - this->NewSources.push_back(sf->GetFullPath()); + this->NewSources.push_back(sf->ResolveFullPath()); } } @@ -2825,12 +2820,9 @@ void cmTargetTraceDependencies::CheckCustomCommand(cmCustomCommand const& cc) } // Queue the custom command dependencies. - std::vector<std::string> configs; std::set<std::string> emitted; - this->Makefile->GetConfigurations(configs); - if (configs.empty()) { - configs.emplace_back(); - } + std::vector<std::string> const& configs = + this->Makefile->GetGeneratorConfigs(); for (std::string const& conf : configs) { this->FollowCommandDepends(cc, conf, emitted); } @@ -6077,11 +6069,8 @@ const cmLinkImplementation* cmGeneratorTarget::GetLinkImplementation( bool cmGeneratorTarget::GetConfigCommonSourceFiles( std::vector<cmSourceFile*>& files) const { - std::vector<std::string> configs; - this->Makefile->GetConfigurations(configs); - if (configs.empty()) { - configs.emplace_back(); - } + std::vector<std::string> const& configs = + this->Makefile->GetGeneratorConfigs(); std::vector<std::string>::const_iterator it = configs.begin(); const std::string& firstConfig = *it; @@ -6095,7 +6084,7 @@ bool cmGeneratorTarget::GetConfigCommonSourceFiles( const char* sep = ""; for (cmSourceFile* f : files) { firstConfigFiles += sep; - firstConfigFiles += f->GetFullPath(); + firstConfigFiles += f->ResolveFullPath(); sep = "\n "; } @@ -6103,7 +6092,7 @@ bool cmGeneratorTarget::GetConfigCommonSourceFiles( sep = ""; for (cmSourceFile* f : configFiles) { thisConfigFiles += sep; - thisConfigFiles += f->GetFullPath(); + thisConfigFiles += f->ResolveFullPath(); sep = "\n "; } std::ostringstream e; diff --git a/Source/cmGhsMultiTargetGenerator.cxx b/Source/cmGhsMultiTargetGenerator.cxx index e7b20ed..658f65d 100644 --- a/Source/cmGhsMultiTargetGenerator.cxx +++ b/Source/cmGhsMultiTargetGenerator.cxx @@ -488,7 +488,7 @@ void cmGhsMultiTargetGenerator::WriteSources(std::ostream& fout_proj) std::set<std::string> groupNames; for (auto& sf : sources) { cmSourceGroup* sourceGroup = - this->Makefile->FindSourceGroup(sf->GetFullPath(), sourceGroups); + this->Makefile->FindSourceGroup(sf->ResolveFullPath(), sourceGroups); std::string gn = sourceGroup->GetFullName(); groupFiles[gn].push_back(sf); groupNames.insert(std::move(gn)); @@ -543,7 +543,7 @@ void cmGhsMultiTargetGenerator::WriteSources(std::ostream& fout_proj) for (auto& n : groupFilesList) { std::sort(groupFiles[n].begin(), groupFiles[n].end(), [](cmSourceFile* l, cmSourceFile* r) { - return l->GetFullPath() < r->GetFullPath(); + return l->ResolveFullPath() < r->ResolveFullPath(); }); } diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index 4342e9f..9479424 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -337,12 +337,8 @@ bool cmGlobalGenerator::CheckTargetsForType() const for (cmGeneratorTarget* target : generator->GetGeneratorTargets()) { if (target->GetType() == cmStateEnums::EXECUTABLE && target->GetPropertyAsBool("WIN32_EXECUTABLE")) { - std::vector<std::string> configs; - target->Makefile->GetConfigurations(configs); - if (configs.empty()) { - configs.emplace_back(); - } - + std::vector<std::string> const& configs = + target->Makefile->GetGeneratorConfigs(); for (std::string const& config : configs) { if (target->GetLinkerLanguage(config) == "Swift") { this->GetCMakeInstance()->IssueMessage( @@ -2963,18 +2959,15 @@ void cmGlobalGenerator::WriteSummary(cmGeneratorTarget* target) // List the source files with any per-source labels. fout << "# Source files and their labels\n"; std::vector<cmSourceFile*> sources; - std::vector<std::string> configs; - target->Target->GetMakefile()->GetConfigurations(configs); - if (configs.empty()) { - configs.emplace_back(); - } + std::vector<std::string> const& configs = + target->Target->GetMakefile()->GetGeneratorConfigs(); for (std::string const& c : configs) { target->GetSourceFiles(sources, c); } auto const sourcesEnd = cmRemoveDuplicates(sources); for (cmSourceFile* sf : cmMakeRange(sources.cbegin(), sourcesEnd)) { Json::Value& lj_source = lj_sources.append(Json::objectValue); - std::string const& sfp = sf->GetFullPath(); + std::string const& sfp = sf->ResolveFullPath(); fout << sfp << "\n"; lj_source["file"] = sfp; if (const char* svalue = sf->GetProperty("LABELS")) { diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h index 830974d..36e5d0e 100644 --- a/Source/cmGlobalGenerator.h +++ b/Source/cmGlobalGenerator.h @@ -376,7 +376,7 @@ public: virtual std::string GetEditCacheCommand() const { return ""; } // Class to track a set of dependencies. - typedef cmTargetDependSet TargetDependSet; + using TargetDependSet = cmTargetDependSet; // what targets does the specified target depend on directly // via a target_link_libraries or add_dependencies @@ -476,7 +476,7 @@ public: int RecursionDepth; protected: - typedef std::vector<cmLocalGenerator*> GeneratorVector; + using GeneratorVector = std::vector<cmLocalGenerator*>; // for a project collect all its targets by following depend // information, and also collect all the targets void GetTargetSets(TargetDependSet& projectTargets, diff --git a/Source/cmGlobalGhsMultiGenerator.h b/Source/cmGlobalGhsMultiGenerator.h index 98358c7..9b5bf63 100644 --- a/Source/cmGlobalGhsMultiGenerator.h +++ b/Source/cmGlobalGhsMultiGenerator.h @@ -153,7 +153,7 @@ class cmGlobalGhsMultiGenerator::OrderedTargetDependSet derived; public: - typedef cmGlobalGenerator::TargetDependSet TargetDependSet; + using TargetDependSet = cmGlobalGenerator::TargetDependSet; OrderedTargetDependSet(TargetDependSet const&, std::string const& first); }; diff --git a/Source/cmGlobalVisualStudio10Generator.cxx b/Source/cmGlobalVisualStudio10Generator.cxx index 48b17c0..7d437f3 100644 --- a/Source/cmGlobalVisualStudio10Generator.cxx +++ b/Source/cmGlobalVisualStudio10Generator.cxx @@ -232,7 +232,15 @@ bool cmGlobalVisualStudio10Generator::SetGeneratorToolset( if (this->GeneratorToolsetCuda.empty()) { // Find the highest available version of the CUDA tools. std::vector<std::string> cudaTools; - std::string const bcDir = this->VCTargetsPath + "/BuildCustomizations"; + std::string bcDir; + if (this->GeneratorToolsetCudaCustomDir.empty()) { + bcDir = this->VCTargetsPath + "/BuildCustomizations"; + } else { + bcDir = this->GetPlatformToolsetCudaCustomDirString() + + "CUDAVisualStudioIntegration\\extras\\" + "visual_studio_integration\\MSBuildExtensions"; + cmSystemTools::ConvertToUnixSlashes(bcDir); + } cmsys::Glob gl; gl.SetRelative(bcDir.c_str()); if (gl.FindFiles(bcDir + "/CUDA *.props")) { @@ -243,6 +251,24 @@ bool cmGlobalVisualStudio10Generator::SetGeneratorToolset( std::sort(cudaTools.begin(), cudaTools.end(), cmSystemTools::VersionCompareGreater); this->GeneratorToolsetCuda = cudaTools.at(0); + } else if (!this->GeneratorToolsetCudaCustomDir.empty()) { + // Generate an error if Visual Studio integration files are not found + // inside of custom cuda toolset. + std::ostringstream e; + /* clang-format off */ + e << + "Generator\n" + " " << this->GetName() << "\n" + "given toolset\n" + " cuda=" << this->GeneratorToolsetCudaCustomDir << "\n" + "cannot detect Visual Studio integration files in path\n" + " " << bcDir; + + /* clang-format on */ + mf->IssueMessage(MessageType::FATAL_ERROR, e.str()); + + // Clear the configured tool-set + this->GeneratorToolsetCuda.clear(); } } @@ -319,6 +345,9 @@ bool cmGlobalVisualStudio10Generator::SetGeneratorToolset( if (const char* cuda = this->GetPlatformToolsetCuda()) { mf->AddDefinition("CMAKE_VS_PLATFORM_TOOLSET_CUDA", cuda); } + if (const char* cudaDir = this->GetPlatformToolsetCudaCustomDir()) { + mf->AddDefinition("CMAKE_VS_PLATFORM_TOOLSET_CUDA_CUSTOM_DIR", cudaDir); + } return true; } @@ -395,7 +424,17 @@ bool cmGlobalVisualStudio10Generator::ProcessGeneratorToolsetField( std::string const& key, std::string const& value) { if (key == "cuda") { - this->GeneratorToolsetCuda = value; + /* test if cuda toolset is path to custom dir or cuda version */ + auto pos = value.find_first_not_of("0123456789."); + if (pos != std::string::npos) { + this->GeneratorToolsetCudaCustomDir = value; + /* ensure trailing backslash for easy path joining */ + if (this->GeneratorToolsetCudaCustomDir.back() != '\\') { + this->GeneratorToolsetCudaCustomDir.push_back('\\'); + } + } else { + this->GeneratorToolsetCuda = value; + } return true; } if (key == "version") { @@ -643,6 +682,21 @@ cmGlobalVisualStudio10Generator::GetPlatformToolsetCudaString() const return this->GeneratorToolsetCuda; } +const char* cmGlobalVisualStudio10Generator::GetPlatformToolsetCudaCustomDir() + const +{ + if (!this->GeneratorToolsetCudaCustomDir.empty()) { + return this->GeneratorToolsetCudaCustomDir.c_str(); + } + return nullptr; +} + +std::string const& +cmGlobalVisualStudio10Generator::GetPlatformToolsetCudaCustomDirString() const +{ + return this->GeneratorToolsetCudaCustomDir; +} + bool cmGlobalVisualStudio10Generator::IsDefaultToolset( const std::string&) const { diff --git a/Source/cmGlobalVisualStudio10Generator.h b/Source/cmGlobalVisualStudio10Generator.h index 1d30cd6..9adcf08 100644 --- a/Source/cmGlobalVisualStudio10Generator.h +++ b/Source/cmGlobalVisualStudio10Generator.h @@ -61,6 +61,10 @@ public: const char* GetPlatformToolsetCuda() const; std::string const& GetPlatformToolsetCudaString() const; + /** The custom cuda install directory */ + const char* GetPlatformToolsetCudaCustomDir() const; + std::string const& GetPlatformToolsetCudaCustomDirString() const; + /** Return whether we need to use No/Debug instead of false/true for GenerateDebugInformation. */ bool GetPlatformToolsetNeedsDebugEnum() const @@ -152,6 +156,7 @@ protected: std::string GeneratorToolsetVersion; std::string GeneratorToolsetHostArchitecture; std::string GeneratorToolsetCuda; + std::string GeneratorToolsetCudaCustomDir; std::string DefaultPlatformToolset; std::string DefaultPlatformToolsetHostArchitecture; std::string WindowsTargetPlatformVersion; diff --git a/Source/cmGlobalVisualStudio7Generator.cxx b/Source/cmGlobalVisualStudio7Generator.cxx index 26ceedd..b355775 100644 --- a/Source/cmGlobalVisualStudio7Generator.cxx +++ b/Source/cmGlobalVisualStudio7Generator.cxx @@ -3,6 +3,7 @@ #include "cmGlobalVisualStudio7Generator.h" #include "cmGeneratedFileStream.h" +#include "cmGeneratorExpression.h" #include "cmGeneratorTarget.h" #include "cmLocalVisualStudio7Generator.h" #include "cmMakefile.h" diff --git a/Source/cmGlobalVisualStudio8Generator.cxx b/Source/cmGlobalVisualStudio8Generator.cxx index b0c065f..5e60108 100644 --- a/Source/cmGlobalVisualStudio8Generator.cxx +++ b/Source/cmGlobalVisualStudio8Generator.cxx @@ -4,6 +4,7 @@ #include "cmDocumentationEntry.h" #include "cmGeneratedFileStream.h" +#include "cmGeneratorExpression.h" #include "cmGeneratorTarget.h" #include "cmLocalVisualStudio7Generator.h" #include "cmMakefile.h" @@ -195,7 +196,7 @@ bool cmGlobalVisualStudio8Generator::AddCheckTarget() if (cmSourceFile* file = mf->AddCustomCommandToOutput( stamps, no_byproducts, listFiles, no_main_dependency, commandLines, "Checking Build System", no_working_directory, true, false)) { - gt->AddSource(file->GetFullPath()); + gt->AddSource(file->ResolveFullPath()); } else { cmSystemTools::Error("Error adding rule for " + stamps[0]); } diff --git a/Source/cmInstallTargetGenerator.h b/Source/cmInstallTargetGenerator.h index 9ccad63..3097bec 100644 --- a/Source/cmInstallTargetGenerator.h +++ b/Source/cmInstallTargetGenerator.h @@ -74,9 +74,9 @@ protected: void GenerateScriptForConfigObjectLibrary(std::ostream& os, const std::string& config, Indent indent); - typedef void (cmInstallTargetGenerator::*TweakMethod)(std::ostream&, Indent, - const std::string&, - std::string const&); + using TweakMethod = void (cmInstallTargetGenerator::*)(std::ostream&, Indent, + const std::string&, + const std::string&); void AddTweak(std::ostream& os, Indent indent, const std::string& config, std::string const& file, TweakMethod tweak); void AddTweak(std::ostream& os, Indent indent, const std::string& config, diff --git a/Source/cmInstalledFile.cxx b/Source/cmInstalledFile.cxx index 1e6c385..11f6efb 100644 --- a/Source/cmInstalledFile.cxx +++ b/Source/cmInstalledFile.cxx @@ -3,6 +3,7 @@ #include "cmInstalledFile.h" #include "cmAlgorithms.h" +#include "cmGeneratorExpression.h" #include "cmListFileCache.h" #include "cmMakefile.h" #include "cmStringAlgorithms.h" diff --git a/Source/cmInstalledFile.h b/Source/cmInstalledFile.h index eb827be..e00e666 100644 --- a/Source/cmInstalledFile.h +++ b/Source/cmInstalledFile.h @@ -5,13 +5,12 @@ #include "cmConfigure.h" // IWYU pragma: keep -#include "cmGeneratorExpression.h" - #include <map> #include <memory> #include <string> #include <vector> +class cmCompiledGeneratorExpression; class cmMakefile; /** \class cmInstalledFile @@ -22,10 +21,10 @@ class cmMakefile; class cmInstalledFile { public: - typedef std::unique_ptr<cmCompiledGeneratorExpression> - CompiledGeneratorExpressionPtrType; + using CompiledGeneratorExpressionPtrType = + std::unique_ptr<cmCompiledGeneratorExpression>; - typedef std::vector<cmCompiledGeneratorExpression*> ExpressionVectorType; + using ExpressionVectorType = std::vector<cmCompiledGeneratorExpression*>; struct Property { diff --git a/Source/cmJsonObjects.cxx b/Source/cmJsonObjects.cxx index 4948b01..52e28d3 100644 --- a/Source/cmJsonObjects.cxx +++ b/Source/cmJsonObjects.cxx @@ -327,7 +327,7 @@ static Json::Value DumpSourceFilesList( fileData.IsGenerated = file->GetIsGenerated(); std::vector<std::string>& groupFileList = fileGroups[fileData]; - groupFileList.push_back(file->GetFullPath()); + groupFileList.push_back(file->ResolveFullPath()); } const std::string& baseDir = target->Makefile->GetCurrentSourceDirectory(); diff --git a/Source/cmLinkLineComputer.cxx b/Source/cmLinkLineComputer.cxx index 5e3c790..91c551f 100644 --- a/Source/cmLinkLineComputer.cxx +++ b/Source/cmLinkLineComputer.cxx @@ -56,7 +56,7 @@ std::string cmLinkLineComputer::ConvertToLinkReference( std::string cmLinkLineComputer::ComputeLinkLibs(cmComputeLinkInformation& cli) { std::string linkLibs; - typedef cmComputeLinkInformation::ItemVector ItemVector; + using ItemVector = cmComputeLinkInformation::ItemVector; ItemVector const& items = cli.GetItems(); for (auto const& item : items) { if (item.Target && diff --git a/Source/cmLinkLineDeviceComputer.cxx b/Source/cmLinkLineDeviceComputer.cxx index 96af388..9c0e20f 100644 --- a/Source/cmLinkLineDeviceComputer.cxx +++ b/Source/cmLinkLineDeviceComputer.cxx @@ -51,7 +51,7 @@ bool cmLinkLineDeviceComputer::ComputeRequiresDeviceLinking( { // Determine if this item might requires device linking. // For this we only consider targets - typedef cmComputeLinkInformation::ItemVector ItemVector; + using ItemVector = cmComputeLinkInformation::ItemVector; ItemVector const& items = cli.GetItems(); std::string config = cli.GetConfig(); for (auto const& item : items) { @@ -78,7 +78,7 @@ std::string cmLinkLineDeviceComputer::ComputeLinkLibraries( // with device symbols only needs to be listed once as it doesn't // care about link order. std::set<std::string> emitted; - typedef cmComputeLinkInformation::ItemVector ItemVector; + using ItemVector = cmComputeLinkInformation::ItemVector; ItemVector const& items = cli.GetItems(); std::string config = cli.GetConfig(); bool skipItemAfterFramework = false; diff --git a/Source/cmLinkedTree.h b/Source/cmLinkedTree.h index 099fb6d..8b91162 100644 --- a/Source/cmLinkedTree.h +++ b/Source/cmLinkedTree.h @@ -27,9 +27,9 @@ template <typename T> class cmLinkedTree { - typedef typename std::vector<T>::size_type PositionType; - typedef T* PointerType; - typedef T& ReferenceType; + using PositionType = typename std::vector<T>::size_type; + using PointerType = T*; + using ReferenceType = T&; public: class iterator diff --git a/Source/cmListCommand.cxx b/Source/cmListCommand.cxx index 91dea58..57eeedb 100644 --- a/Source/cmListCommand.cxx +++ b/Source/cmListCommand.cxx @@ -5,6 +5,7 @@ #include "cmsys/RegularExpression.hxx" #include <algorithm> #include <assert.h> +#include <cstddef> #include <functional> #include <iterator> #include <set> @@ -1079,7 +1080,7 @@ public: }; protected: - typedef std::string (*StringFilter)(const std::string& in); + using StringFilter = std::string (*)(const std::string&); StringFilter GetCompareFilter(Compare compare) { return (compare == Compare::FILE_BASENAME) ? cmSystemTools::GetFilenameName diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index c85ee2d..e2402ad 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -258,11 +258,8 @@ static void MoveSystemIncludesToEnd(std::vector<BT<std::string>>& includeDirs, void cmLocalGenerator::TraceDependencies() { - std::vector<std::string> configs; - this->Makefile->GetConfigurations(configs); - if (configs.empty()) { - configs.emplace_back(); - } + std::vector<std::string> const& configs = + this->Makefile->GetGeneratorConfigs(); for (std::string const& c : configs) { this->GlobalGenerator->CreateEvaluationSourceFiles(c); } @@ -327,7 +324,7 @@ void cmLocalGenerator::GenerateTestFiles() tester->Compute(this); tester->Generate(fout, config, configurationTypes); } - typedef std::vector<cmStateSnapshot> vec_t; + using vec_t = std::vector<cmStateSnapshot>; vec_t const& children = this->Makefile->GetStateSnapshot().GetChildren(); std::string parentBinDir = this->GetCurrentBinaryDirectory(); for (cmStateSnapshot const& i : children) { @@ -1180,7 +1177,7 @@ void cmLocalGenerator::GetTargetFlags( if (sf->GetExtension() == "def") { linkFlags += defFlag; linkFlags += this->ConvertToOutputFormat( - cmSystemTools::CollapseFullPath(sf->GetFullPath()), SHELL); + cmSystemTools::CollapseFullPath(sf->ResolveFullPath()), SHELL); linkFlags += " "; } } @@ -1728,7 +1725,7 @@ bool cmLocalGenerator::GetRealDependency(const std::string& inName, // Check for a source file in this directory that matches the // dependency. if (cmSourceFile* sf = this->Makefile->GetSource(inName)) { - dep = sf->GetFullPath(); + dep = sf->ResolveFullPath(); return true; } diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx index e9335c6..74f4777 100644 --- a/Source/cmLocalVisualStudio7Generator.cxx +++ b/Source/cmLocalVisualStudio7Generator.cxx @@ -4,6 +4,7 @@ #include "cmCustomCommand.h" #include "cmCustomCommandGenerator.h" +#include "cmGeneratorExpression.h" #include "cmGeneratorTarget.h" #include "cmGlobalVisualStudio7Generator.h" #include "cmMakefile.h" @@ -102,7 +103,7 @@ void cmLocalVisualStudio7Generator::FixGlobalTargets() if (cmSourceFile* file = this->Makefile->AddCustomCommandToOutput( force.c_str(), no_depends, no_main_dependency, force_commands, " ", 0, true)) { - l->AddSource(file->GetFullPath()); + l->AddSource(file->ResolveFullPath()); } } } @@ -268,7 +269,7 @@ cmSourceFile* cmLocalVisualStudio7Generator::CreateVCProjBuildRule() if (cmSourceFile* file = this->Makefile->GetSource(makefileIn.c_str())) { // Finalize the source file path now since we're adding this after // the generator validated all project-named sources. - file->GetFullPath(); + file->ResolveFullPath(); return file; } else { cmSystemTools::Error("Error adding rule for " + makefileIn); diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index f101cdc..dfe0086 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -1112,7 +1112,7 @@ void cmMakefile::AddCustomCommandOldStyle( if (sf && !sf->GetPropertyAsBool("__CMAKE_RULE")) { cmTargetMap::iterator ti = this->Targets.find(target); if (ti != this->Targets.end()) { - ti->second.AddSource(sf->GetFullPath()); + ti->second.AddSource(sf->ResolveFullPath()); } else { cmSystemTools::Error("Attempt to add a custom rule to a target " "that does not exist yet for target " + @@ -3057,6 +3057,16 @@ std::string cmMakefile::GetConfigurations(std::vector<std::string>& configs, return buildType; } +std::vector<std::string> cmMakefile::GetGeneratorConfigs() const +{ + std::vector<std::string> configs; + GetConfigurations(configs); + if (configs.empty()) { + configs.emplace_back(); + } + return configs; +} + bool cmMakefile::IsFunctionBlocked(const cmListFileFunction& lff, cmExecutionStatus& status) { @@ -3322,7 +3332,7 @@ void cmMakefile::AddTargetObject(std::string const& tgtName, sf->SetProperty("EXTERNAL_OBJECT", "1"); #if !defined(CMAKE_BOOTSTRAP) this->SourceGroups[this->ObjectLibrariesSourceGroupIndex].AddGroupFile( - sf->GetFullPath()); + sf->ResolveFullPath()); #endif } @@ -4311,7 +4321,7 @@ bool cmMakefile::HasCMP0054AlreadyBeenReported( void cmMakefile::RecordPolicies(cmPolicies::PolicyMap& pm) { /* Record the setting of every policy. */ - typedef cmPolicies::PolicyID PolicyID; + using PolicyID = cmPolicies::PolicyID; for (PolicyID pid = cmPolicies::CMP0000; pid != cmPolicies::CMPCOUNT; pid = PolicyID(pid + 1)) { pm.Set(pid, this->GetPolicyStatus(pid)); diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h index dcc4e77..09f53c9 100644 --- a/Source/cmMakefile.h +++ b/Source/cmMakefile.h @@ -292,6 +292,9 @@ public: std::string GetConfigurations(std::vector<std::string>& configs, bool single = true) const; + /** Get the configurations for dependency checking. */ + std::vector<std::string> GetGeneratorConfigs() const; + /** * Set the name of the library. */ @@ -382,7 +385,7 @@ public: } // -- List of targets - typedef std::unordered_map<std::string, cmTarget> cmTargetMap; + using cmTargetMap = std::unordered_map<std::string, cmTarget>; /** Get the target map */ cmTargetMap& GetTargets() { return this->Targets; } /** Get the target map - const version */ @@ -911,7 +914,7 @@ protected: mutable cmTargetMap Targets; std::map<std::string, std::string> AliasTargets; - typedef std::vector<cmSourceFile*> SourceFileVec; + using SourceFileVec = std::vector<cmSourceFile*>; SourceFileVec SourceFiles; // Because cmSourceFile names are compared in a fuzzy way (see @@ -920,7 +923,7 @@ protected: // Name portion of the cmSourceFileLocation and then compare on the list of // cmSourceFiles that might match that name. Note that on platforms which // have a case-insensitive filesystem we store the key in all lowercase. - typedef std::unordered_map<std::string, SourceFileVec> SourceFileMap; + using SourceFileMap = std::unordered_map<std::string, SourceFileVec>; SourceFileMap SourceFileSearchIndex; // For "Known" paths we can store a direct filename to cmSourceFile map @@ -994,7 +997,7 @@ private: friend class cmParseFileScope; std::vector<cmTarget*> ImportedTargetsOwned; - typedef std::unordered_map<std::string, cmTarget*> TargetMap; + using TargetMap = std::unordered_map<std::string, cmTarget*>; TargetMap ImportedTargets; // Internal policy stack management. @@ -1036,7 +1039,7 @@ private: cmSourceFile* LinearGetSourceFileWithOutput(const std::string& cname) const; // A map for fast output to input look up. - typedef std::unordered_map<std::string, cmSourceFile*> OutputToSourceMap; + using OutputToSourceMap = std::unordered_map<std::string, cmSourceFile*>; OutputToSourceMap OutputToSource; void UpdateOutputToSourceMap(std::vector<std::string> const& outputs, diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx index 90d8ea9..4a60aa9 100644 --- a/Source/cmMakefileTargetGenerator.cxx +++ b/Source/cmMakefileTargetGenerator.cxx @@ -15,6 +15,7 @@ #include "cmGeneratorExpression.h" #include "cmGeneratorTarget.h" #include "cmGlobalUnixMakefileGenerator3.h" +#include "cmLocalCommonGenerator.h" #include "cmLocalUnixMakefileGenerator3.h" #include "cmMakefile.h" #include "cmMakefileExecutableTargetGenerator.h" @@ -1756,6 +1757,12 @@ void cmMakefileTargetGenerator::GenDefFile( this->LocalGenerator->MaybeConvertToRelativePath( this->LocalGenerator->GetCurrentBinaryDirectory(), objlist_file), cmOutputConverter::SHELL); + const char* nm_executable = this->Makefile->GetDefinition("CMAKE_NM"); + if (nm_executable && *nm_executable) { + cmd += " --nm="; + cmd += this->LocalCommonGenerator->ConvertToOutputFormat( + nm_executable, cmOutputConverter::SHELL); + } real_link_commands.insert(real_link_commands.begin(), cmd); // create a list of obj files for the -E __create_def to read cmGeneratedFileStream fout(objlist_file); diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx index a4e1d61..bc2506e 100644 --- a/Source/cmNinjaNormalTargetGenerator.cxx +++ b/Source/cmNinjaNormalTargetGenerator.cxx @@ -20,6 +20,7 @@ #include "cmGlobalNinjaGenerator.h" #include "cmLinkLineComputer.h" #include "cmLinkLineDeviceComputer.h" +#include "cmLocalCommonGenerator.h" #include "cmLocalGenerator.h" #include "cmLocalNinjaGenerator.h" #include "cmMakefile.h" @@ -977,6 +978,13 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement() std::string obj_list_file = mdi->DefFile + ".objs"; cmd += this->GetLocalGenerator()->ConvertToOutputFormat( obj_list_file, cmOutputConverter::SHELL); + + const char* nm_executable = GetMakefile()->GetDefinition("CMAKE_NM"); + if (nm_executable && *nm_executable) { + cmd += " --nm="; + cmd += this->LocalCommonGenerator->ConvertToOutputFormat( + nm_executable, cmOutputConverter::SHELL); + } preLinkCmdLines.push_back(std::move(cmd)); // create a list of obj files for the -E __create_def to read diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx index 29e8b74..90b59e7 100644 --- a/Source/cmNinjaTargetGenerator.cxx +++ b/Source/cmNinjaTargetGenerator.cxx @@ -108,6 +108,13 @@ bool cmNinjaTargetGenerator::UsePreprocessedSource( return lang == "Fortran"; } +bool cmNinjaTargetGenerator::CompilePreprocessedSourceWithDefines( + std::string const& lang) const +{ + return this->Makefile->IsOn( + cmStrCat("CMAKE_", lang, "_COMPILE_WITH_DEFINES")); +} + std::string cmNinjaTargetGenerator::LanguageDyndepRule( const std::string& lang) const { @@ -458,12 +465,14 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang) vars.ObjectDir = "$OBJECT_DIR"; vars.ObjectFileDir = "$OBJECT_FILE_DIR"; + cmMakefile* mf = this->GetMakefile(); + // For some cases we do an explicit preprocessor invocation. bool const explicitPP = this->NeedExplicitPreprocessing(lang); + bool const compilePPWithDefines = this->UsePreprocessedSource(lang) && + this->CompilePreprocessedSourceWithDefines(lang); bool const needDyndep = this->NeedDyndep(lang); - cmMakefile* mf = this->GetMakefile(); - std::string flags = "$FLAGS"; std::string responseFlag; @@ -517,9 +526,14 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang) // Preprocessing and compilation use the same flags. std::string ppFlags = flags; - // Move preprocessor definitions to the preprocessor rule. - ppVars.Defines = vars.Defines; - vars.Defines = ""; + if (!compilePPWithDefines) { + // Move preprocessor definitions to the preprocessor rule. + ppVars.Defines = vars.Defines; + vars.Defines = ""; + } else { + // Copy preprocessor definitions to the preprocessor rule. + ppVars.Defines = vars.Defines; + } // Copy include directories to the preprocessor rule. The Fortran // compilation rule still needs them for the INCLUDE directive. @@ -1011,6 +1025,8 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement( ppBuild.RspFile = ppFileName + ".rsp"; bool const compilePP = this->UsePreprocessedSource(language); + bool const compilePPWithDefines = + compilePP && this->CompilePreprocessedSourceWithDefines(language); if (compilePP) { // Move compilation dependencies to the preprocessing build statement. std::swap(ppBuild.ExplicitDeps, objBuild.ExplicitDeps); @@ -1039,7 +1055,7 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement( this->LocalGenerator->AppendFlags(vars["FLAGS"], postFlag); } - if (compilePP) { + if (compilePP && !compilePPWithDefines) { // Move preprocessor definitions to the preprocessor build statement. std::swap(ppBuild.Variables["DEFINES"], vars["DEFINES"]); } else { diff --git a/Source/cmNinjaTargetGenerator.h b/Source/cmNinjaTargetGenerator.h index a99d8e7..e304bc7 100644 --- a/Source/cmNinjaTargetGenerator.h +++ b/Source/cmNinjaTargetGenerator.h @@ -70,6 +70,7 @@ protected: std::string LanguageDyndepRule(std::string const& lang) const; bool NeedDyndep(std::string const& lang) const; bool UsePreprocessedSource(std::string const& lang) const; + bool CompilePreprocessedSourceWithDefines(std::string const& lang) const; std::string OrderDependsTargetForTarget(); diff --git a/Source/cmNinjaTypes.h b/Source/cmNinjaTypes.h index 52c05b6..89afbbd 100644 --- a/Source/cmNinjaTypes.h +++ b/Source/cmNinjaTypes.h @@ -17,8 +17,8 @@ enum cmNinjaTargetDepends DependOnTargetOrdering }; -typedef std::vector<std::string> cmNinjaDeps; -typedef std::set<std::string> cmNinjaOuts; +using cmNinjaDeps = std::vector<std::string>; +using cmNinjaOuts = std::set<std::string>; typedef std::map<std::string, std::string> cmNinjaVars; class cmNinjaRule diff --git a/Source/cmOutputRequiredFilesCommand.cxx b/Source/cmOutputRequiredFilesCommand.cxx index 3d8ebc3..1a854dc 100644 --- a/Source/cmOutputRequiredFilesCommand.cxx +++ b/Source/cmOutputRequiredFilesCommand.cxx @@ -36,7 +36,7 @@ public: /** * The set of files on which this one depends. */ - typedef std::set<cmDependInformation*> DependencySetType; + using DependencySetType = std::set<cmDependInformation*>; DependencySetType DependencySet; /** @@ -325,7 +325,7 @@ protected: cmSourceFile* srcFile = this->Makefile->GetSource( cmSystemTools::GetFilenameWithoutExtension(path)); if (srcFile) { - if (srcFile->GetFullPath() == path) { + if (srcFile->ResolveFullPath() == path) { found = true; } else { // try to guess which include path to use @@ -334,7 +334,7 @@ protected: incpath += "/"; } incpath += path; - if (srcFile->GetFullPath() == incpath) { + if (srcFile->ResolveFullPath() == incpath) { // set the path to the guessed path info->FullPath = incpath; found = true; diff --git a/Source/cmParseArgumentsCommand.cxx b/Source/cmParseArgumentsCommand.cxx index aad9f74..a4dd70d 100644 --- a/Source/cmParseArgumentsCommand.cxx +++ b/Source/cmParseArgumentsCommand.cxx @@ -37,10 +37,10 @@ static std::string JoinList(std::vector<std::string> const& arg, bool escape) namespace { -typedef std::map<std::string, bool> options_map; -typedef std::map<std::string, std::string> single_map; -typedef std::map<std::string, std::vector<std::string>> multi_map; -typedef std::set<std::string> options_set; +using options_map = std::map<std::string, bool>; +using single_map = std::map<std::string, std::string>; +using multi_map = std::map<std::string, std::vector<std::string>>; +using options_set = std::set<std::string>; struct UserArgumentParser : public cmArgumentParser<void> { diff --git a/Source/cmProcessTools.h b/Source/cmProcessTools.h index 7616316..c205a8f 100644 --- a/Source/cmProcessTools.h +++ b/Source/cmProcessTools.h @@ -17,7 +17,7 @@ class cmProcessTools { public: - typedef cmProcessOutput::Encoding Encoding; + using Encoding = cmProcessOutput::Encoding; /** Abstract interface for process output parsers. */ class OutputParser { diff --git a/Source/cmProjectCommand.cxx b/Source/cmProjectCommand.cxx index f8c5ada..e74fff6 100644 --- a/Source/cmProjectCommand.cxx +++ b/Source/cmProjectCommand.cxx @@ -4,6 +4,7 @@ #include "cmsys/RegularExpression.hxx" #include <array> +#include <cstddef> #include <cstdio> #include <functional> #include <limits> diff --git a/Source/cmQtAutoGen.cxx b/Source/cmQtAutoGen.cxx index d890f8e..83df335 100644 --- a/Source/cmQtAutoGen.cxx +++ b/Source/cmQtAutoGen.cxx @@ -24,8 +24,8 @@ void MergeOptions(std::vector<std::string>& baseOpts, std::vector<std::string> const& newOpts, std::initializer_list<cm::string_view> valueOpts, bool isQt5) { - typedef std::vector<std::string>::iterator Iter; - typedef std::vector<std::string>::const_iterator CIter; + using Iter = std::vector<std::string>::iterator; + using CIter = std::vector<std::string>::const_iterator; if (newOpts.empty()) { return; } diff --git a/Source/cmQtAutoGen.h b/Source/cmQtAutoGen.h index 939ceb3..fb15586 100644 --- a/Source/cmQtAutoGen.h +++ b/Source/cmQtAutoGen.h @@ -50,7 +50,7 @@ public: std::string HelpOutput; std::vector<std::string> ListOptions; }; - typedef std::shared_ptr<CompilerFeatures> CompilerFeaturesHandle; + using CompilerFeaturesHandle = std::shared_ptr<CompilerFeatures>; /// @brief AutoGen generator type enum class GenT diff --git a/Source/cmQtAutoGenInitializer.cxx b/Source/cmQtAutoGenInitializer.cxx index bd96c08..d6916b0 100644 --- a/Source/cmQtAutoGenInitializer.cxx +++ b/Source/cmQtAutoGenInitializer.cxx @@ -29,6 +29,7 @@ #include "cmsys/SystemInformation.hxx" #include <algorithm> +#include <cstddef> #include <deque> #include <initializer_list> #include <map> @@ -647,7 +648,7 @@ bool cmQtAutoGenInitializer::InitScanFiles() // Since we're iterating over source files that might be not in the // target we need to check for path errors (not existing files). std::string pathError; - std::string const& fullPath = sf->GetFullPath(&pathError); + std::string const& fullPath = sf->ResolveFullPath(&pathError); if (!pathError.empty() || fullPath.empty()) { continue; } @@ -703,7 +704,7 @@ bool cmQtAutoGenInitializer::InitScanFiles() MUFile const& muf = *pair.second; if (muf.MocIt || muf.UicIt) { // Search for the default header file and a private header - std::string const& srcPath = muf.SF->GetFullPath(); + std::string const& srcPath = muf.SF->ResolveFullPath(); std::string basePath = cmStrCat(cmQtAutoGen::SubDirPrefix(srcPath), cmSystemTools::GetFilenameWithoutLastExtension(srcPath)); @@ -761,7 +762,7 @@ bool cmQtAutoGenInitializer::InitScanFiles() // Since we're iterating over source files that might be not in the // target we need to check for path errors (not existing files). std::string pathError; - std::string const& fullPath = sf->GetFullPath(&pathError); + std::string const& fullPath = sf->ResolveFullPath(&pathError); if (!pathError.empty() || fullPath.empty()) { continue; } diff --git a/Source/cmQtAutoGenInitializer.h b/Source/cmQtAutoGenInitializer.h index 65666a6..84a27e4 100644 --- a/Source/cmQtAutoGenInitializer.h +++ b/Source/cmQtAutoGenInitializer.h @@ -55,7 +55,7 @@ public: bool MocIt = false; bool UicIt = false; }; - typedef std::unique_ptr<MUFile> MUFileHandle; + using MUFileHandle = std::unique_ptr<MUFile>; /// @brief Abstract moc/uic/rcc generator variables base class struct GenVarsT diff --git a/Source/cmQtAutoGenerator.cxx b/Source/cmQtAutoGenerator.cxx index 3bcc1c9..80b8741 100644 --- a/Source/cmQtAutoGenerator.cxx +++ b/Source/cmQtAutoGenerator.cxx @@ -169,7 +169,7 @@ bool cmQtAutoGenerator::FileRead(std::string& content, return false; } content.reserve(length); - typedef std::istreambuf_iterator<char> IsIt; + using IsIt = std::istreambuf_iterator<char>; content.assign(IsIt{ ifs }, IsIt{}); if (!ifs) { content.clear(); diff --git a/Source/cmQtAutoMocUic.h b/Source/cmQtAutoMocUic.h index f676c57..076e460 100644 --- a/Source/cmQtAutoMocUic.h +++ b/Source/cmQtAutoMocUic.h @@ -106,7 +106,7 @@ public: std::vector<std::string> Depends; } Uic; }; - typedef std::shared_ptr<FileT> FileHandleT; + using FileHandleT = std::shared_ptr<FileT>; typedef std::pair<FileHandleT, bool> GetOrInsertT; public: @@ -146,7 +146,7 @@ public: bool Moc = false; bool Uic = false; }; - typedef std::shared_ptr<SourceFileT> SourceFileHandleT; + using SourceFileHandleT = std::shared_ptr<SourceFileT>; typedef std::map<std::string, SourceFileHandleT> SourceFileMapT; /** @@ -159,7 +159,7 @@ public: std::string IncludeString; std::vector<SourceFileHandleT> IncluderFiles; }; - typedef std::shared_ptr<MappingT> MappingHandleT; + using MappingHandleT = std::shared_ptr<MappingT>; typedef std::map<std::string, MappingHandleT> MappingMapT; /** diff --git a/Source/cmScriptGenerator.h b/Source/cmScriptGenerator.h index e334d5b..eee331f 100644 --- a/Source/cmScriptGenerator.h +++ b/Source/cmScriptGenerator.h @@ -56,7 +56,7 @@ public: std::vector<std::string> const& configurationTypes); protected: - typedef cmScriptGeneratorIndent Indent; + using Indent = cmScriptGeneratorIndent; virtual void GenerateScript(std::ostream& os); virtual void GenerateScriptConfigs(std::ostream& os, Indent indent); virtual void GenerateScriptActions(std::ostream& os, Indent indent); diff --git a/Source/cmSourceFile.cxx b/Source/cmSourceFile.cxx index 5d738d5..4deb94a 100644 --- a/Source/cmSourceFile.cxx +++ b/Source/cmSourceFile.cxx @@ -65,7 +65,7 @@ std::string const& cmSourceFile::GetOrDetermineLanguage() this->Location.DirectoryIsAmbiguous()) { // Finalize the file location to get the extension and set the // language. - this->GetFullPath(); + this->ResolveFullPath(); } else { // Use the known extension to get the language if possible. std::string ext = @@ -94,7 +94,7 @@ cmSourceFileLocation const& cmSourceFile::GetLocation() const return this->Location; } -std::string const& cmSourceFile::GetFullPath(std::string* error) +std::string const& cmSourceFile::ResolveFullPath(std::string* error) { if (this->FullPath.empty()) { if (this->FindFullPath(error)) { @@ -269,7 +269,7 @@ const char* cmSourceFile::GetPropertyForUser(const std::string& prop) // LOCATION property we must commit now. if (prop == propLOCATION) { // Commit to a location. - this->GetFullPath(); + this->ResolveFullPath(); } // Similarly, LANGUAGE can be determined by the file extension diff --git a/Source/cmSourceFile.h b/Source/cmSourceFile.h index ccd5b62..774cb28 100644 --- a/Source/cmSourceFile.h +++ b/Source/cmSourceFile.h @@ -63,14 +63,15 @@ public: bool GetIsGenerated() const { return this->IsGenerated; } /** - * The full path to the file. The non-const version of this method - * may attempt to locate the file on disk and finalize its location. - * The const version of this method may return an empty string if - * the non-const version has not yet been called (yes this is a - * horrible interface, but is necessary for backwards - * compatibility). + * Resolves the full path to the file. Attempts to locate the file on disk + * and finalizes its location. + */ + std::string const& ResolveFullPath(std::string* error = nullptr); + + /** + * The resolved full path to the file. The returned file name might be empty + * if the path has not yet been resolved. */ - std::string const& GetFullPath(std::string* error = nullptr); std::string const& GetFullPath() const; /** diff --git a/Source/cmSourceGroupCommand.h b/Source/cmSourceGroupCommand.h index eec4ec0..45438a9 100644 --- a/Source/cmSourceGroupCommand.h +++ b/Source/cmSourceGroupCommand.h @@ -41,7 +41,7 @@ public: private: typedef std::map<std::string, std::vector<std::string>> ParsedArguments; - typedef std::vector<std::string> ExpectedOptions; + using ExpectedOptions = std::vector<std::string>; ExpectedOptions getExpectedOptions() const; diff --git a/Source/cmStatePrivate.h b/Source/cmStatePrivate.h index ec0ed6c..4efaf97 100644 --- a/Source/cmStatePrivate.h +++ b/Source/cmStatePrivate.h @@ -48,7 +48,7 @@ struct cmStateDetail::SnapshotDataType struct cmStateDetail::PolicyStackEntry : public cmPolicies::PolicyMap { - typedef cmPolicies::PolicyMap derived; + using derived = cmPolicies::PolicyMap; PolicyStackEntry(bool w = false) : Weak(w) { diff --git a/Source/cmStateTypes.h b/Source/cmStateTypes.h index 7d6158e..d089ea7 100644 --- a/Source/cmStateTypes.h +++ b/Source/cmStateTypes.h @@ -10,7 +10,7 @@ namespace cmStateDetail { struct SnapshotDataType; -typedef cmLinkedTree<cmStateDetail::SnapshotDataType>::iterator PositionType; +using PositionType = cmLinkedTree<cmStateDetail::SnapshotDataType>::iterator; } namespace cmStateEnums { diff --git a/Source/cmString.hxx b/Source/cmString.hxx index 49bad78..050a2fd 100644 --- a/Source/cmString.hxx +++ b/Source/cmString.hxx @@ -9,6 +9,7 @@ #include "cm_string_view.hxx" #include <algorithm> +#include <cstddef> #include <functional> #include <initializer_list> #include <memory> @@ -713,7 +714,7 @@ template <typename T> struct StringAdd { static const bool value = AsStringView<T>::value; - typedef string_view temp_type; + using temp_type = string_view; template <typename S> static temp_type temp(S&& s) { @@ -801,8 +802,8 @@ namespace std { template <> struct hash<cm::String> { - typedef cm::String argument_type; - typedef size_t result_type; + using argument_type = cm::String; + using result_type = size_t; result_type operator()(argument_type const& s) const noexcept { diff --git a/Source/cmStringAlgorithms.cxx b/Source/cmStringAlgorithms.cxx index c686aa0..131a01e 100644 --- a/Source/cmStringAlgorithms.cxx +++ b/Source/cmStringAlgorithms.cxx @@ -3,6 +3,7 @@ #include "cmStringAlgorithms.h" #include <algorithm> +#include <cstddef> #include <cstdio> #include <errno.h> #include <stdlib.h> diff --git a/Source/cmStringAlgorithms.h b/Source/cmStringAlgorithms.h index 5b8b878..7f442d8 100644 --- a/Source/cmStringAlgorithms.h +++ b/Source/cmStringAlgorithms.h @@ -16,7 +16,7 @@ #include <vector> /** String range type. */ -typedef cmRange<std::vector<std::string>::const_iterator> cmStringRange; +using cmStringRange = cmRange<std::vector<std::string>::const_iterator>; /** Callable string comparison struct. */ struct cmStrCmp diff --git a/Source/cmSystemTools.h b/Source/cmSystemTools.h index 953a358..863db3f 100644 --- a/Source/cmSystemTools.h +++ b/Source/cmSystemTools.h @@ -25,8 +25,8 @@ class cmSystemTools : public cmsys::SystemTools { public: - typedef cmsys::SystemTools Superclass; - typedef cmProcessOutput::Encoding Encoding; + using Superclass = cmsys::SystemTools; + using Encoding = cmProcessOutput::Encoding; /** * Look for and replace registry values in a string diff --git a/Source/cmTarget.h b/Source/cmTarget.h index 783c278..fa420af 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h @@ -108,7 +108,7 @@ public: //! how we identify a library, by name and type typedef std::pair<std::string, cmTargetLinkLibraryType> LibraryID; - typedef std::vector<LibraryID> LinkLibraryVectorType; + using LinkLibraryVectorType = std::vector<LibraryID>; LinkLibraryVectorType const& GetOriginalLinkLibraries() const; //! Clear the dependency information recorded for this target, if any. diff --git a/Source/cmUVHandlePtr.h b/Source/cmUVHandlePtr.h index c09e4bf..3083b60 100644 --- a/Source/cmUVHandlePtr.h +++ b/Source/cmUVHandlePtr.h @@ -240,8 +240,8 @@ struct uv_tty_ptr : public uv_handle_ptr_<uv_tty_t> int init(uv_loop_t& loop, int fd, int readable, void* data = nullptr); }; -typedef uv_handle_ptr_<uv_stream_t> uv_stream_ptr; -typedef uv_handle_ptr_<uv_handle_t> uv_handle_ptr; +using uv_stream_ptr = uv_handle_ptr_<uv_stream_t>; +using uv_handle_ptr = uv_handle_ptr_<uv_handle_t>; #ifndef cmUVHandlePtr_cxx diff --git a/Source/cmUVProcessChain.h b/Source/cmUVProcessChain.h index 75f8f66..76a9c40 100644 --- a/Source/cmUVProcessChain.h +++ b/Source/cmUVProcessChain.h @@ -6,6 +6,7 @@ #include "cm_uv.h" #include <array> +#include <cstddef> #include <iosfwd> #include <memory> #include <string> diff --git a/Source/cmUuid.cxx b/Source/cmUuid.cxx index 0dc6ca7..91c8af3 100644 --- a/Source/cmUuid.cxx +++ b/Source/cmUuid.cxx @@ -53,7 +53,7 @@ void cmUuid::CreateHashInput(std::vector<unsigned char> const& uuidNamespace, std::string cmUuid::FromDigest(const unsigned char* digest, unsigned char version) const { - typedef unsigned char byte_t; + using byte_t = unsigned char; byte_t uuid[16] = { 0 }; memcpy(uuid, digest, 16); diff --git a/Source/cmVariableWatch.h b/Source/cmVariableWatch.h index acac2c1..32445d5 100644 --- a/Source/cmVariableWatch.h +++ b/Source/cmVariableWatch.h @@ -20,10 +20,9 @@ class cmMakefile; class cmVariableWatch { public: - typedef void (*WatchMethod)(const std::string& variable, int access_type, - void* client_data, const char* newValue, - const cmMakefile* mf); - typedef void (*DeleteData)(void* client_data); + using WatchMethod = void (*)(const std::string&, int, void*, const char*, + const cmMakefile*); + using DeleteData = void (*)(void*); cmVariableWatch(); ~cmVariableWatch(); @@ -77,7 +76,7 @@ protected: Pair& operator=(const Pair&) = delete; }; - typedef std::vector<std::shared_ptr<Pair>> VectorOfPairs; + using VectorOfPairs = std::vector<std::shared_ptr<Pair>>; typedef std::map<std::string, VectorOfPairs> StringToVectorOfPairs; StringToVectorOfPairs WatchMap; diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index 08ad1c0..29ebe02 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -528,6 +528,13 @@ void cmVisualStudio10TargetGenerator::Generate() } e1.Element("TargetFrameworkTargetsVersion", targetFrameworkVer); } + if (!this->GlobalGenerator->GetPlatformToolsetCudaCustomDirString() + .empty()) { + e1.Element( + "CudaToolkitCustomDir", + this->GlobalGenerator->GetPlatformToolsetCudaCustomDirString() + + "nvcc"); + } } // Disable the project upgrade prompt that is displayed the first time a @@ -614,10 +621,17 @@ void cmVisualStudio10TargetGenerator::Generate() e1.SetHasElements(); if (this->GlobalGenerator->IsCudaEnabled()) { + auto customDir = + this->GlobalGenerator->GetPlatformToolsetCudaCustomDirString(); + std::string cudaPath = customDir.empty() + ? "$(VCTargetsPath)\\BuildCustomizations\\" + : customDir + + "CUDAVisualStudioIntegration\\extras\\" + "visual_studio_integration\\MSBuildExtensions\\"; Elem(e1, "Import") .Attribute("Project", - "$(VCTargetsPath)\\BuildCustomizations\\CUDA " + - this->GlobalGenerator->GetPlatformToolsetCudaString() + + std::move(cudaPath) + "CUDA " + + this->GlobalGenerator->GetPlatformToolsetCuda() + ".props"); } if (this->GlobalGenerator->IsMasmEnabled()) { @@ -699,10 +713,17 @@ void cmVisualStudio10TargetGenerator::Generate() e1.SetHasElements(); this->WriteTargetsFileReferences(e1); if (this->GlobalGenerator->IsCudaEnabled()) { + auto customDir = + this->GlobalGenerator->GetPlatformToolsetCudaCustomDirString(); + std::string cudaPath = customDir.empty() + ? "$(VCTargetsPath)\\BuildCustomizations\\" + : customDir + + "CUDAVisualStudioIntegration\\extras\\" + "visual_studio_integration\\MSBuildExtensions\\"; Elem(e1, "Import") .Attribute("Project", - "$(VCTargetsPath)\\BuildCustomizations\\CUDA " + - this->GlobalGenerator->GetPlatformToolsetCudaString() + + std::move(cudaPath) + "CUDA " + + this->GlobalGenerator->GetPlatformToolsetCuda() + ".targets"); } if (this->GlobalGenerator->IsMasmEnabled()) { diff --git a/Source/cmWorkerPool.cxx b/Source/cmWorkerPool.cxx index baf326a..2e4d00b 100644 --- a/Source/cmWorkerPool.cxx +++ b/Source/cmWorkerPool.cxx @@ -25,10 +25,10 @@ class cmUVPipeBuffer { public: - typedef cmRange<char const*> DataRange; - typedef std::function<void(DataRange)> DataFunction; + using DataRange = cmRange<const char*>; + using DataFunction = std::function<void(DataRange)>; /// On error the ssize_t argument is a non zero libuv error code - typedef std::function<void(ssize_t)> EndFunction; + using EndFunction = std::function<void(ssize_t)>; public: /** diff --git a/Source/cmWorkerPool.h b/Source/cmWorkerPool.h index d708118..b541ce3 100644 --- a/Source/cmWorkerPool.h +++ b/Source/cmWorkerPool.h @@ -126,7 +126,7 @@ public: /** * Job handle type */ - typedef std::unique_ptr<JobT> JobHandleT; + using JobHandleT = std::unique_ptr<JobT>; /** * Fence job base class diff --git a/Source/cmXMLParser.h b/Source/cmXMLParser.h index 98ba049..1bc8d64 100644 --- a/Source/cmXMLParser.h +++ b/Source/cmXMLParser.h @@ -42,7 +42,7 @@ public: virtual int ParseChunk(const char* inputString, std::string::size_type length); virtual int CleanupParser(); - typedef void (*ReportFunction)(int, const char*, void*); + using ReportFunction = void (*)(int, const char*, void*); void SetErrorCallback(ReportFunction f, void* d) { this->ReportCallback = f; diff --git a/Source/cmXMLWriter.h b/Source/cmXMLWriter.h index 512e103..a5b06af 100644 --- a/Source/cmXMLWriter.h +++ b/Source/cmXMLWriter.h @@ -8,6 +8,7 @@ #include "cmXMLSafe.h" #include <chrono> +#include <cstddef> #include <ctime> #include <ostream> #include <stack> diff --git a/Source/cmake.h b/Source/cmake.h index 081e120..cc44b92 100644 --- a/Source/cmake.h +++ b/Source/cmake.h @@ -503,10 +503,10 @@ protected: void RunCheckForUnusedVariables(); int HandleDeleteCacheVariables(const std::string& var); - typedef std::vector<cmGlobalGeneratorFactory*> RegisteredGeneratorsVector; + using RegisteredGeneratorsVector = std::vector<cmGlobalGeneratorFactory*>; RegisteredGeneratorsVector Generators; - typedef std::vector<cmExternalMakefileProjectGeneratorFactory*> - RegisteredExtraGeneratorsVector; + using RegisteredExtraGeneratorsVector = + std::vector<cmExternalMakefileProjectGeneratorFactory*>; RegisteredExtraGeneratorsVector ExtraGenerators; void AddScriptingCommands(); void AddProjectCommands(); diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx index 2be8bae..a79a2ff 100644 --- a/Source/cmcmd.cxx +++ b/Source/cmcmd.cxx @@ -339,8 +339,8 @@ static int HandleCppCheck(const std::string& runCmd, return ret; } -typedef int (*CoCompileHandler)(const std::string&, const std::string&, - const std::vector<std::string>&); +using CoCompileHandler = int (*)(const std::string&, const std::string&, + const std::vector<std::string>&); struct CoCompiler { @@ -558,8 +558,8 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args) #if defined(_WIN32) && !defined(CMAKE_BOOTSTRAP) else if (args[1] == "__create_def") { if (args.size() < 4) { - std::cerr - << "__create_def Usage: -E __create_def outfile.def objlistfile\n"; + std::cerr << "__create_def Usage: -E __create_def outfile.def " + "objlistfile [-nm=nm-path]\n"; return 1; } FILE* fout = cmsys::SystemTools::Fopen(args[2].c_str(), "w+"); @@ -576,6 +576,15 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args) } std::string file; bindexplib deffile; + if (args.size() >= 5) { + auto a = args[4]; + if (cmHasLiteralPrefix(a, "--nm=")) { + deffile.SetNmPath(a.substr(5)); + std::cerr << a.substr(5) << "\n"; + } else { + std::cerr << "unknown argument: " << a << "\n"; + } + } while (cmSystemTools::GetLineFromStream(fin, file)) { std::string const& ext = cmSystemTools::GetFilenameLastExtension(file); if (cmSystemTools::LowerCase(ext) == ".def") { @@ -673,10 +682,17 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args) // If an error occurs, we want to continue removing directories. bool return_value = false; for (auto const& arg : cmMakeRange(args).advance(2)) { - if (cmSystemTools::FileIsDirectory(arg) && - !cmSystemTools::RemoveADirectory(arg)) { - std::cerr << "Error removing directory \"" << arg << "\".\n"; - return_value = true; + if (cmSystemTools::FileIsDirectory(arg)) { + if (cmSystemTools::FileIsSymlink(arg)) { + if (!cmSystemTools::RemoveFile(arg)) { + std::cerr << "Error removing directory symlink \"" << arg + << "\".\n"; + return_value = true; + } + } else if (!cmSystemTools::RemoveADirectory(arg)) { + std::cerr << "Error removing directory \"" << arg << "\".\n"; + return_value = true; + } } } return return_value; diff --git a/Source/kwsys/CMakeLists.txt b/Source/kwsys/CMakeLists.txt index 79e813e..09bcdb9 100644 --- a/Source/kwsys/CMakeLists.txt +++ b/Source/kwsys/CMakeLists.txt @@ -121,8 +121,8 @@ if(KWSYS_CXX_STANDARD) set(CMAKE_CXX_STANDARD "${KWSYS_CXX_STANDARD}") elseif(NOT DEFINED CMAKE_CXX_STANDARD AND NOT DEFINED KWSYS_CXX_STANDARD) if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang" - AND "x${CMAKE_CXX_SIMULATE_ID}" STREQUAL "xMSVC" - AND "x${CMAKE_CXX_COMPILER_FRONTEND_VARIANT}" STREQUAL "xGNU" + AND CMAKE_CXX_SIMULATE_ID STREQUAL "MSVC" + AND CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "GNU" ) set(CMAKE_CXX_STANDARD 14) else() @@ -1013,7 +1013,7 @@ ADD_DEFINITIONS("-DKWSYS_NAMESPACE=${KWSYS_NAMESPACE}") # Disable deprecation warnings for standard C functions. IF(MSVC OR (WIN32 AND (CMAKE_C_COMPILER_ID STREQUAL "Intel" OR - (CMAKE_C_COMPILER_ID STREQUAL "Clang" AND "x${CMAKE_CXX_SIMULATE_ID}" STREQUAL "xMSVC")))) + (CMAKE_C_COMPILER_ID STREQUAL "Clang" AND CMAKE_CXX_SIMULATE_ID STREQUAL "MSVC")))) ADD_DEFINITIONS( -D_CRT_NONSTDC_NO_DEPRECATE -D_CRT_SECURE_NO_DEPRECATE @@ -1104,7 +1104,7 @@ IF(KWSYS_STANDALONE OR CMake_SOURCE_DIR) SET(KWSYS_CXX_TESTS ${KWSYS_CXX_TESTS} testConsoleBuf.cxx ) - IF("x${CMAKE_CXX_COMPILER_ID}" STREQUAL "xMSVC" AND + IF(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC" AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER "19.0.23506") set_property(SOURCE testConsoleBuf.cxx testConsoleBufChild.cxx PROPERTY COMPILE_FLAGS /utf-8) ENDIF() diff --git a/Source/kwsys/SystemTools.cxx b/Source/kwsys/SystemTools.cxx index 36f24c7..8571477 100644 --- a/Source/kwsys/SystemTools.cxx +++ b/Source/kwsys/SystemTools.cxx @@ -2169,24 +2169,24 @@ std::string SystemTools::ConvertToWindowsOutputPath(const std::string& path) return ret; } +/** + * Append the filename from the path source to the directory name dir. + */ +static std::string FileInDir(const std::string& source, const std::string& dir) +{ + std::string new_destination = dir; + SystemTools::ConvertToUnixSlashes(new_destination); + return new_destination + '/' + SystemTools::GetFilenameName(source); +} + bool SystemTools::CopyFileIfDifferent(const std::string& source, const std::string& destination) { // special check for a destination that is a directory // FilesDiffer does not handle file to directory compare if (SystemTools::FileIsDirectory(destination)) { - std::string new_destination = destination; - SystemTools::ConvertToUnixSlashes(new_destination); - new_destination += '/'; - std::string source_name = source; - new_destination += SystemTools::GetFilenameName(source_name); - if (SystemTools::FilesDiffer(source, new_destination)) { - return SystemTools::CopyFileAlways(source, destination); - } else { - // the files are the same so the copy is done return - // true - return true; - } + const std::string new_destination = FileInDir(source, destination); + return SystemTools::CopyFileIfDifferent(source, new_destination); } // source and destination are files so do a copy if they // are different @@ -2612,101 +2612,6 @@ std::string SystemTools::GetLastSystemError() return strerror(e); } -#ifdef _WIN32 - -static bool IsJunction(const std::wstring& source) -{ -# ifdef FSCTL_GET_REPARSE_POINT - const DWORD JUNCTION_ATTRS = - FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT; - DWORD attrs = GetFileAttributesW(source.c_str()); - if (attrs == INVALID_FILE_ATTRIBUTES) { - return false; - } - if ((attrs & JUNCTION_ATTRS) != JUNCTION_ATTRS) { - return false; - } - - // Adjust privileges so that we can succefully open junction points. - HANDLE token; - TOKEN_PRIVILEGES privs; - OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &token); - LookupPrivilegeValue(NULL, SE_BACKUP_NAME, &privs.Privileges[0].Luid); - privs.PrivilegeCount = 1; - privs.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; - AdjustTokenPrivileges(token, FALSE, &privs, sizeof(TOKEN_PRIVILEGES), NULL, - NULL); - CloseHandle(token); - - HANDLE dir = CreateFileW( - source.c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING, - FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS, NULL); - if (dir == INVALID_HANDLE_VALUE) { - return false; - } - - // Query whether this is a reparse point or not. - BYTE buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE]; - REPARSE_GUID_DATA_BUFFER* reparse_buffer = (REPARSE_GUID_DATA_BUFFER*)buffer; - DWORD sentinel; - - BOOL success = - DeviceIoControl(dir, FSCTL_GET_REPARSE_POINT, NULL, 0, reparse_buffer, - MAXIMUM_REPARSE_DATA_BUFFER_SIZE, &sentinel, NULL); - - CloseHandle(dir); - - return (success && - (reparse_buffer->ReparseTag == IO_REPARSE_TAG_MOUNT_POINT)); -# else - return false; -# endif -} - -static bool DeleteJunction(const std::wstring& source) -{ -# ifdef FSCTL_DELETE_REPARSE_POINT - // Adjust privileges so that we can succefully open junction points as - // read/write. - HANDLE token; - TOKEN_PRIVILEGES privs; - OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &token); - LookupPrivilegeValue(NULL, SE_RESTORE_NAME, &privs.Privileges[0].Luid); - privs.PrivilegeCount = 1; - privs.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; - AdjustTokenPrivileges(token, FALSE, &privs, sizeof(TOKEN_PRIVILEGES), NULL, - NULL); - CloseHandle(token); - - HANDLE dir = CreateFileW( - source.c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, - FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS, NULL); - if (dir == INVALID_HANDLE_VALUE) { - return false; - } - - // Set up the structure so that we can delete the junction. - std::vector<BYTE> buffer(REPARSE_GUID_DATA_BUFFER_HEADER_SIZE, 0); - REPARSE_GUID_DATA_BUFFER* reparse_buffer = - (REPARSE_GUID_DATA_BUFFER*)&buffer[0]; - DWORD sentinel; - - reparse_buffer->ReparseTag = IO_REPARSE_TAG_MOUNT_POINT; - - BOOL success = DeviceIoControl( - dir, FSCTL_DELETE_REPARSE_POINT, reparse_buffer, - REPARSE_GUID_DATA_BUFFER_HEADER_SIZE, NULL, 0, &sentinel, NULL); - - CloseHandle(dir); - - return !!success; -# else - return false; -# endif -} - -#endif - bool SystemTools::RemoveFile(const std::string& source) { #ifdef _WIN32 @@ -2728,9 +2633,7 @@ bool SystemTools::RemoveFile(const std::string& source) SetLastError(err); return false; } - if (IsJunction(ws) && DeleteJunction(ws)) { - return true; - } + const DWORD DIRECTORY_SOFT_LINK_ATTRS = FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT; DWORD attrs = GetFileAttributesW(ws.c_str()); diff --git a/Source/kwsys/testSystemTools.cxx b/Source/kwsys/testSystemTools.cxx index ffa6a29..88277de 100644 --- a/Source/kwsys/testSystemTools.cxx +++ b/Source/kwsys/testSystemTools.cxx @@ -999,30 +999,45 @@ static bool writeFile(const char* fileName, const char* data) return true; } +static std::string readFile(const char* fileName) +{ + kwsys::ifstream in(fileName, std::ios::binary); + std::stringstream sstr; + sstr << in.rdbuf(); + std::string data = sstr.str(); + if (!in) { + std::cerr << "Failed to read file: " << fileName << std::endl; + return std::string(); + } + return data; +} + +struct +{ + const char* a; + const char* b; + bool differ; +} diff_test_cases[] = { { "one", "one", false }, + { "one", "two", true }, + { "", "", false }, + { "\n", "\r\n", false }, + { "one\n", "one\n", false }, + { "one\r\n", "one\n", false }, + { "one\n", "one", false }, + { "one\ntwo", "one\ntwo", false }, + { "one\ntwo", "one\r\ntwo", false } }; + static bool CheckTextFilesDiffer() { - struct - { - const char* a; - const char* b; - bool differ; - } test_cases[] = { { "one", "one", false }, - { "one", "two", true }, - { "", "", false }, - { "\n", "\r\n", false }, - { "one\n", "one\n", false }, - { "one\r\n", "one\n", false }, - { "one\n", "one", false }, - { "one\ntwo", "one\ntwo", false }, - { "one\ntwo", "one\r\ntwo", false } }; - const int num_test_cases = sizeof(test_cases) / sizeof(test_cases[0]); + const int num_test_cases = + sizeof(diff_test_cases) / sizeof(diff_test_cases[0]); for (int i = 0; i < num_test_cases; ++i) { - if (!writeFile("file_a", test_cases[i].a) || - !writeFile("file_b", test_cases[i].b)) { + if (!writeFile("file_a", diff_test_cases[i].a) || + !writeFile("file_b", diff_test_cases[i].b)) { return false; } if (kwsys::SystemTools::TextFilesDiffer("file_a", "file_b") != - test_cases[i].differ) { + diff_test_cases[i].differ) { std::cerr << "Incorrect TextFilesDiffer result for test case " << i + 1 << "." << std::endl; return false; @@ -1032,6 +1047,36 @@ static bool CheckTextFilesDiffer() return true; } +static bool CheckCopyFileIfDifferent() +{ + bool ret = true; + const int num_test_cases = + sizeof(diff_test_cases) / sizeof(diff_test_cases[0]); + for (int i = 0; i < num_test_cases; ++i) { + if (!writeFile("file_a", diff_test_cases[i].a) || + !writeFile("file_b", diff_test_cases[i].b)) { + return false; + } + const char* cptarget = + i < 4 ? TEST_SYSTEMTOOLS_BINARY_DIR "/file_b" : "file_b"; + if (!kwsys::SystemTools::CopyFileIfDifferent("file_a", cptarget)) { + std::cerr << "CopyFileIfDifferent() returned false for test case " + << i + 1 << "." << std::endl; + ret = false; + continue; + } + std::string bdata = readFile("file_b"); + if (diff_test_cases[i].a != bdata) { + std::cerr << "Incorrect CopyFileIfDifferent file contents in test case " + << i + 1 << "." << std::endl; + ret = false; + continue; + } + } + + return ret; +} + int testSystemTools(int, char* []) { bool res = true; @@ -1077,5 +1122,7 @@ int testSystemTools(int, char* []) res &= CheckTextFilesDiffer(); + res &= CheckCopyFileIfDifferent(); + return res ? 0 : 1; } diff --git a/Tests/BundleTest/BundleSubDir/CMakeLists.txt b/Tests/BundleTest/BundleSubDir/CMakeLists.txt index 2f7f2c4..5f91f20 100644 --- a/Tests/BundleTest/BundleSubDir/CMakeLists.txt +++ b/Tests/BundleTest/BundleSubDir/CMakeLists.txt @@ -35,7 +35,11 @@ install(TARGETS SecondBundle DESTINATION Applications) # installed into a location that uses this output name this will fail if the # bundle does not respect the name. Also the executable will not be found by # the test driver if this does not work. -set_target_properties(SecondBundle PROPERTIES OUTPUT_NAME SecondBundleExe) +set_target_properties(SecondBundle PROPERTIES + OUTPUT_NAME SecondBundleExe + XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "" + XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED "NO" + ) # Express one app bundle in terms of another's SOURCES to verify that # the generators do not expose the Info.plist of one to the other. diff --git a/Tests/BundleTest/CMakeLists.txt b/Tests/BundleTest/CMakeLists.txt index 853da35..1bedc70 100644 --- a/Tests/BundleTest/CMakeLists.txt +++ b/Tests/BundleTest/CMakeLists.txt @@ -56,7 +56,11 @@ install(TARGETS BundleTest DESTINATION Applications) # installed into a location that uses this output name this will fail if the # bundle does not respect the name. Also the executable will not be found by # the test driver if this does not work. -set_target_properties(BundleTest PROPERTIES OUTPUT_NAME BundleTestExe) +set_target_properties(BundleTest PROPERTIES + OUTPUT_NAME BundleTestExe + XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "" + XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED "NO" + ) # Test executable versioning if it is supported. if(NOT XCODE) diff --git a/Tests/CFBundleTest/CMakeLists.txt b/Tests/CFBundleTest/CMakeLists.txt index 0fe6bb7..b2b1b73 100644 --- a/Tests/CFBundleTest/CMakeLists.txt +++ b/Tests/CFBundleTest/CMakeLists.txt @@ -50,6 +50,8 @@ set_source_files_properties( set_target_properties(CFBundleTest PROPERTIES BUNDLE 1 BUNDLE_EXTENSION plugin + XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "" + XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED "NO" XCODE_ATTRIBUTE_MACH_O_TYPE mh_bundle XCODE_ATTRIBUTE_INFOPLIST_FILE ${CMAKE_CURRENT_BINARY_DIR}/Info.plist MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_BINARY_DIR}/Info.plist diff --git a/Tests/CMakeLib/run_compile_commands.cxx b/Tests/CMakeLib/run_compile_commands.cxx index b49803b..b1541e2 100644 --- a/Tests/CMakeLib/run_compile_commands.cxx +++ b/Tests/CMakeLib/run_compile_commands.cxx @@ -26,7 +26,7 @@ public: return emptyString; } }; - typedef std::vector<CommandType> TranslationUnitsType; + using TranslationUnitsType = std::vector<CommandType>; CompileCommandParser(std::istream& input) : Input(input) diff --git a/Tests/CMakeLib/testString.cxx b/Tests/CMakeLib/testString.cxx index af5e41e..075892f 100644 --- a/Tests/CMakeLib/testString.cxx +++ b/Tests/CMakeLib/testString.cxx @@ -6,6 +6,7 @@ #include "cm_static_string_view.hxx" #include "cm_string_view.hxx" +#include <cstddef> #include <cstring> #include <iostream> #include <iterator> diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index 02e28d4..c14107a 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -416,7 +416,6 @@ if(BUILD_TESTING) ADD_TEST_MACRO(COnly COnly) ADD_TEST_MACRO(CxxOnly CxxOnly) ADD_TEST_MACRO(CxxSubdirC CxxSubdirC) - ADD_TEST_MACRO(IPO COnly/COnly) ADD_TEST_MACRO(OutDir runtime/OutDir) ADD_TEST_MACRO(OutName exe.OutName.exe) ADD_TEST_MACRO(ObjectLibrary UseCshared) @@ -764,7 +763,8 @@ if(BUILD_TESTING) set(_TEST_DIR "${CMake_BINARY_DIR}/Tests/${name}") file(MAKE_DIRECTORY "${_TEST_DIR}") file(WRITE "${_TEST_DIR}/nightly-cmake.sh" - "cd ${_TEST_DIR} + "set -e +cd ${_TEST_DIR} ${CMake_BINARY_DIR}/bin/cmake -DCMAKE_CREATE_VERSION=nightly -P ${CMake_SOURCE_DIR}/Utilities/Release/${script} ${CMake_SOURCE_DIR}/Utilities/Release/push.bash --dir dev -- '${CMake_BUILD_NIGHTLY_RELEASES}' ") diff --git a/Tests/FindPython/CMakeLists.txt b/Tests/FindPython/CMakeLists.txt index 4be2f22..868cfe0 100644 --- a/Tests/FindPython/CMakeLists.txt +++ b/Tests/FindPython/CMakeLists.txt @@ -121,6 +121,19 @@ if(CMake_TEST_FindPython) --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION> ) + add_test(NAME FindPython.RequiredArtifacts COMMAND + ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION> + --build-and-test + "${CMake_SOURCE_DIR}/Tests/FindPython/RequiredArtifacts" + "${CMake_BINARY_DIR}/Tests/FindPython/RequiredArtifacts" + ${build_generator_args} + --build-project TestRequiredArtifacts + --build-options ${build_options} "-Dbuild_generator_args=${build_generator_args}" + "-DCMake_SOURCE_DIR=${CMake_SOURCE_DIR}" + "-DCMake_BINARY_DIR=${CMake_BINARY_DIR}" + --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION> + ) + endif() if(CMake_TEST_FindPython_NumPy) diff --git a/Tests/FindPython/RequiredArtifacts/CMakeLists.txt b/Tests/FindPython/RequiredArtifacts/CMakeLists.txt new file mode 100644 index 0000000..39e8ea5 --- /dev/null +++ b/Tests/FindPython/RequiredArtifacts/CMakeLists.txt @@ -0,0 +1,110 @@ +cmake_minimum_required(VERSION 3.1) + +project(TestRequiredArtifacts LANGUAGES C) + +include(CTest) + +find_package(Python2 REQUIRED COMPONENTS Interpreter Development) +if (NOT Python2_FOUND) + message (FATAL_ERROR "Fail to found Python 2") +endif() +find_package(Python3 REQUIRED COMPONENTS Interpreter Development) +if (NOT Python3_FOUND) + message (FATAL_ERROR "Fail to found Python 3") +endif() + + +add_test(NAME FindPython.RequiredArtifacts.Interpreter.VALID COMMAND + ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION> + --build-and-test + "${CMake_SOURCE_DIR}/Tests/FindPython/RequiredArtifacts/Check" + "${CMake_BINARY_DIR}/Tests/FindPython/RequiredArtifacts/Interpreter.VALID" + ${build_generator_args} + --build-project TestRequiredArtifacts.Check + --build-options -DPYTHON_IS_FOUND=TRUE -DCHECK_INTERPRETER=ON + "-DPython3_EXECUTABLE=${Python3_EXECUTABLE}" + --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION> + ) +add_test(NAME FindPython.RequiredArtifacts.Interpreter.INVALID COMMAND + ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION> + --build-and-test + "${CMake_SOURCE_DIR}/Tests/FindPython/RequiredArtifacts/Check" + "${CMake_BINARY_DIR}/Tests/FindPython/RequiredArtifacts/Interpreter.INVALID" + ${build_generator_args} + --build-project TestRequiredArtifacts.Check + --build-options -DPYTHON_IS_FOUND=FALSE -DCHECK_INTERPRETER=ON + "-DPython3_EXECUTABLE=${Python3_EXECUTABLE}-bad${CMAKE_EXECUTABLE_SUFFIX}" + --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION> + ) + +add_test(NAME FindPython.RequiredArtifacts.Library.VALID COMMAND + ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION> + --build-and-test + "${CMake_SOURCE_DIR}/Tests/FindPython/RequiredArtifacts/Check" + "${CMake_BINARY_DIR}/Tests/FindPython/RequiredArtifacts/Library.VALID" + ${build_generator_args} + --build-project TestRequiredArtifacts.Check + --build-options -DPYTHON_IS_FOUND=TRUE -DCHECK_LIBRARY=ON + "-DPython3_LIBRARY=${Python3_LIBRARY_RELEASE}" + --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION> + ) +add_test(NAME FindPython.RequiredArtifacts.Library.INVALID COMMAND + ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION> + --build-and-test + "${CMake_SOURCE_DIR}/Tests/FindPython/RequiredArtifacts/Check" + "${CMake_BINARY_DIR}/Tests/FindPython/RequiredArtifacts/Library.INVALID" + ${build_generator_args} + --build-project TestRequiredArtifacts.Check + --build-options -DPYTHON_IS_FOUND=FALSE -DCHECK_LIBRARY=ON + "-DPython3_LIBRARY=${Python2_LIBRARY_RELEASE}" + --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION> + ) + +add_test(NAME FindPython.RequiredArtifacts.Include.VALID COMMAND + ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION> + --build-and-test + "${CMake_SOURCE_DIR}/Tests/FindPython/RequiredArtifacts/Check" + "${CMake_BINARY_DIR}/Tests/FindPython/RequiredArtifacts/Include.VALID" + ${build_generator_args} + --build-project TestRequiredArtifacts.Check + --build-options -DPYTHON_IS_FOUND=TRUE -DCHECK_INCLUDE=ON + "-DPython3_INCLUDE_DIR=${Python3_INCLUDE_DIRS}" + --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION> + ) +add_test(NAME FindPython.RequiredArtifacts.Include.INVALID COMMAND + ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION> + --build-and-test + "${CMake_SOURCE_DIR}/Tests/FindPython/RequiredArtifacts/Check" + "${CMake_BINARY_DIR}/Tests/FindPython/RequiredArtifacts/Include.INVALID" + ${build_generator_args} + --build-project TestRequiredArtifacts.Check + --build-options -DPYTHON_IS_FOUND=FALSE -DCHECK_INCLUDE=ON + "-DPython3_INCLUDE_DIR=${Python2_INCLUDE_DIRS}" + --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION> + ) + +add_test(NAME FindPython.RequiredArtifacts.Interpreter-Library.INVALID COMMAND + ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION> + --build-and-test + "${CMake_SOURCE_DIR}/Tests/FindPython/RequiredArtifacts/Check" + "${CMake_BINARY_DIR}/Tests/FindPython/RequiredArtifacts/Interpreter-Library.INVALID" + ${build_generator_args} + --build-project TestRequiredArtifacts.Check + --build-options -DPYTHON_IS_FOUND=FALSE -DCHECK_INTERPRETER=ON -DCHECK_LIBRARY=ON + "-DPython3_EXECUTABLE=${Python3_EXECUTABLE}" + "-DPython3_LIBRARY=${Python2_LIBRARY_RELEASE}" + --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION> + ) + +add_test(NAME FindPython.RequiredArtifacts.Library-Include.INVALID COMMAND + ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION> + --build-and-test + "${CMake_SOURCE_DIR}/Tests/FindPython/RequiredArtifacts/Check" + "${CMake_BINARY_DIR}/Tests/FindPython/RequiredArtifacts/Library-Include.INVALID" + ${build_generator_args} + --build-project TestRequiredArtifacts.Check + --build-options -DPYTHON_IS_FOUND=FALSE -DCHECK_LIBRARY=ON -DCHECK_INCLUDE=ON + "-DPython3_LIBRARY=${Python3_LIBRARY_RELEASE}" + "-DPython3_INCLUDE_DIR=${Python2_INCLUDE_DIRS}" + --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION> + ) diff --git a/Tests/FindPython/RequiredArtifacts/Check/CMakeLists.txt b/Tests/FindPython/RequiredArtifacts/Check/CMakeLists.txt new file mode 100644 index 0000000..b859ac5 --- /dev/null +++ b/Tests/FindPython/RequiredArtifacts/Check/CMakeLists.txt @@ -0,0 +1,41 @@ +cmake_minimum_required(VERSION 3.1) + +project(TestRequiredArtifacts.Check LANGUAGES C) + +set (components) +if (CHECK_INTERPRETER) + set (required_interpreter "${Python3_EXECUTABLE}") + list (APPEND components Interpreter) +endif() +if (CHECK_LIBRARY OR CHECK_INCLUDE) + list (APPEND components Development) + if (CHECK_LIBRARY) + set (required_library "${Python3_LIBRARY}") + endif() + if (CHECK_INCLUDE) + set (required_include "${Python3_INCLUDE_DIR}") + endif() +endif() + +find_package (Python3 COMPONENTS ${components}) + + +if (PYTHON_IS_FOUND AND NOT Python3_FOUND) + message (FATAL_ERROR "Python3 unexpectedly not found") +endif() +if (NOT PYTHON_IS_FOUND AND Python3_FOUND) + message (FATAL_ERROR "Python3 unexpectedly found") +endif() + + +if (CHECK_INTERPRETER AND NOT Python3_EXECUTABLE STREQUAL required_interpreter) + message (FATAL_ERROR "Fail to use input variable Python3_EXECUTABLE") +endif() + +if (CHECK_LIBRARY AND NOT Python3_LIBRARY_RELEASE STREQUAL required_library) + message (FATAL_ERROR "Fail to use input variable Python3_LIBRARY") +endif() + +if (CHECK_INCLUDE AND NOT Python3_INCLUDE_DIRS STREQUAL required_include) + message (FATAL_ERROR "Fail to use input variable Python3_INCLUDE_DIR") +endif() diff --git a/Tests/FortranOnly/CMakeLists.txt b/Tests/FortranOnly/CMakeLists.txt index 45372dd..de887fa 100644 --- a/Tests/FortranOnly/CMakeLists.txt +++ b/Tests/FortranOnly/CMakeLists.txt @@ -112,3 +112,11 @@ if("${CMAKE_GENERATOR}" MATCHES "Makefile" AND CMAKE_MAKE_PROGRAM) ) endif() endif() + +# Test that with Intel Fortran we always compile with preprocessor +# defines even if splitting the preprocessing and compilation steps. +if(CMAKE_Fortran_COMPILER_ID STREQUAL "Intel") + add_executable(IntelIfDef IntelIfDef.f) + set_property(TARGET IntelIfDef PROPERTY Fortran_FORMAT FIXED) + target_compile_definitions(IntelIfDef PRIVATE SOME_DEF) +endif() diff --git a/Tests/FortranOnly/IntelIfDef.f b/Tests/FortranOnly/IntelIfDef.f new file mode 100644 index 0000000..d7a73d1 --- /dev/null +++ b/Tests/FortranOnly/IntelIfDef.f @@ -0,0 +1,3 @@ + INCLUDE 'IntelIfDef.inc' + PROGRAM IntelIfDef + END diff --git a/Tests/FortranOnly/IntelIfDef.inc b/Tests/FortranOnly/IntelIfDef.inc new file mode 100644 index 0000000..52edafa --- /dev/null +++ b/Tests/FortranOnly/IntelIfDef.inc @@ -0,0 +1,3 @@ +CDEC$ IF .NOT. DEFINED(SOME_DEF) +CDEC$ INCLUDE 'SOME_DEF not defined' +CDEC$ END IF diff --git a/Tests/IPO/CMakeLists.txt b/Tests/IPO/CMakeLists.txt deleted file mode 100644 index 6dabf86..0000000 --- a/Tests/IPO/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -cmake_minimum_required (VERSION 2.8) -project(IPO NONE) - -set_property(DIRECTORY PROPERTY INTERPROCEDURAL_OPTIMIZATION 1) - -add_subdirectory(../COnly COnly) -add_subdirectory(../CxxOnly CxxOnly) diff --git a/Tests/Module/CheckIPOSupported-C/CMakeLists.txt b/Tests/Module/CheckIPOSupported-C/CMakeLists.txt index 4a41a98..c5cd03e 100644 --- a/Tests/Module/CheckIPOSupported-C/CMakeLists.txt +++ b/Tests/Module/CheckIPOSupported-C/CMakeLists.txt @@ -13,8 +13,18 @@ elseif(CMake_TEST_IPO_WORKS_C) endif() add_library(foo foo.c) +if(NOT CYGWIN AND (NOT WIN32 OR "x${CMAKE_C_COMPILER_ID}" STREQUAL "xClang")) + add_library(bar SHARED bar.c) + if(WIN32) + # Bindexplib for clang supports LTO objects + set_target_properties(bar PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS ON) + endif() +else() + # TODO: bindexplib doesn't support exporting IPO symbols with other compilers on Windows + add_library(bar STATIC bar.c) +endif() add_executable(CheckIPOSupported-C main.c) -target_link_libraries(CheckIPOSupported-C PUBLIC foo) +target_link_libraries(CheckIPOSupported-C PUBLIC foo bar) enable_testing() add_test(NAME CheckIPOSupported-C COMMAND CheckIPOSupported-C) diff --git a/Tests/Module/CheckIPOSupported-C/bar.c b/Tests/Module/CheckIPOSupported-C/bar.c new file mode 100644 index 0000000..680f213 --- /dev/null +++ b/Tests/Module/CheckIPOSupported-C/bar.c @@ -0,0 +1,4 @@ +int bar() +{ + return 0x42; +} diff --git a/Tests/Module/CheckIPOSupported-C/main.c b/Tests/Module/CheckIPOSupported-C/main.c index 99204ab..28ab26f 100644 --- a/Tests/Module/CheckIPOSupported-C/main.c +++ b/Tests/Module/CheckIPOSupported-C/main.c @@ -1,8 +1,9 @@ int foo(); +int bar(); int main() { - if (foo() == 0) { + if (foo() != bar()) { return 1; } return 0; diff --git a/Tests/Module/CheckIPOSupported-CXX/CMakeLists.txt b/Tests/Module/CheckIPOSupported-CXX/CMakeLists.txt index 1bb2b84..237bf1d 100644 --- a/Tests/Module/CheckIPOSupported-CXX/CMakeLists.txt +++ b/Tests/Module/CheckIPOSupported-CXX/CMakeLists.txt @@ -12,9 +12,20 @@ elseif(CMake_TEST_IPO_WORKS_CXX) message(FATAL_ERROR "IPO expected to work, but the check failed:\n ${ipo_output}") endif() -add_library(foo foo.cpp) + +add_library(foo STATIC foo.cpp) +if(NOT CYGWIN AND (NOT WIN32 OR "x${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")) + add_library(bar SHARED bar.cpp) + if(WIN32) + # Bindexplib for clang supports LTO objects + set_target_properties(bar PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS ON) + endif() +else() + # TODO: bindexplib doesn't support exporting IPO symbols with other compilers on Windows + add_library(bar STATIC bar.cpp) +endif() add_executable(CheckIPOSupported-CXX main.cpp) -target_link_libraries(CheckIPOSupported-CXX PUBLIC foo) +target_link_libraries(CheckIPOSupported-CXX PUBLIC foo bar) enable_testing() add_test(NAME CheckIPOSupported-CXX COMMAND CheckIPOSupported-CXX) diff --git a/Tests/Module/CheckIPOSupported-CXX/bar.cpp b/Tests/Module/CheckIPOSupported-CXX/bar.cpp new file mode 100644 index 0000000..680f213 --- /dev/null +++ b/Tests/Module/CheckIPOSupported-CXX/bar.cpp @@ -0,0 +1,4 @@ +int bar() +{ + return 0x42; +} diff --git a/Tests/Module/CheckIPOSupported-CXX/main.cpp b/Tests/Module/CheckIPOSupported-CXX/main.cpp index 99204ab..28ab26f 100644 --- a/Tests/Module/CheckIPOSupported-CXX/main.cpp +++ b/Tests/Module/CheckIPOSupported-CXX/main.cpp @@ -1,8 +1,9 @@ int foo(); +int bar(); int main() { - if (foo() == 0) { + if (foo() != bar()) { return 1; } return 0; diff --git a/Tests/RunCMake/CPack/RunCMakeTest.cmake b/Tests/RunCMake/CPack/RunCMakeTest.cmake index d93f280..8e98961 100644 --- a/Tests/RunCMake/CPack/RunCMakeTest.cmake +++ b/Tests/RunCMake/CPack/RunCMakeTest.cmake @@ -36,3 +36,6 @@ run_cpack_test(MD5SUMS "DEB.MD5SUMS" false "MONOLITHIC;COMPONENT") run_cpack_test_subtests(CPACK_INSTALL_SCRIPTS "singular;plural;both" "ZIP" false "MONOLITHIC") run_cpack_test(DEB_PACKAGE_VERSION_BACK_COMPATIBILITY "DEB.DEB_PACKAGE_VERSION_BACK_COMPATIBILITY" false "MONOLITHIC;COMPONENT") run_cpack_test_subtests(EXTERNAL "none;good;good_multi;bad_major;bad_minor;invalid_good;invalid_bad;stage_and_package" "External" false "MONOLITHIC;COMPONENT") +if(RunCMake_GENERATOR MATCHES "Visual Studio|Xcode") + run_cpack_test(CPACK_INSTALL_CMAKE_CONFIGURATIONS "ZIP" false "MONOLITHIC") +endif() diff --git a/Tests/RunCMake/CPack/tests/CPACK_INSTALL_CMAKE_CONFIGURATIONS/ExpectedFiles.cmake b/Tests/RunCMake/CPack/tests/CPACK_INSTALL_CMAKE_CONFIGURATIONS/ExpectedFiles.cmake new file mode 100644 index 0000000..34c7f8a --- /dev/null +++ b/Tests/RunCMake/CPack/tests/CPACK_INSTALL_CMAKE_CONFIGURATIONS/ExpectedFiles.cmake @@ -0,0 +1,3 @@ +set(EXPECTED_FILES_COUNT "1") + +set(EXPECTED_FILE_CONTENT_1_LIST "foo;foo/debug.txt;foo/release.txt") diff --git a/Tests/RunCMake/CPack/tests/CPACK_INSTALL_CMAKE_CONFIGURATIONS/ZIP-stdout.txt b/Tests/RunCMake/CPack/tests/CPACK_INSTALL_CMAKE_CONFIGURATIONS/ZIP-stdout.txt new file mode 100644 index 0000000..2a3aa9e --- /dev/null +++ b/Tests/RunCMake/CPack/tests/CPACK_INSTALL_CMAKE_CONFIGURATIONS/ZIP-stdout.txt @@ -0,0 +1,3 @@ +CPack: Install projects +CPack: - Install project: CPACK_INSTALL_CMAKE_CONFIGURATIONS-MONOLITHIC-type \[Debug\] +CPack: - Install project: CPACK_INSTALL_CMAKE_CONFIGURATIONS-MONOLITHIC-type \[Release\] diff --git a/Tests/RunCMake/CPack/tests/CPACK_INSTALL_CMAKE_CONFIGURATIONS/test.cmake b/Tests/RunCMake/CPack/tests/CPACK_INSTALL_CMAKE_CONFIGURATIONS/test.cmake new file mode 100644 index 0000000..4f562cf --- /dev/null +++ b/Tests/RunCMake/CPack/tests/CPACK_INSTALL_CMAKE_CONFIGURATIONS/test.cmake @@ -0,0 +1,9 @@ +set(CMAKE_CONFIGURATION_TYPES Debug Release) + +file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/debug.txt" "debug content") +file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/release.txt" "release content") + +install(FILES "${CMAKE_CURRENT_BINARY_DIR}/debug.txt" DESTINATION "foo" CONFIGURATIONS Debug) +install(FILES "${CMAKE_CURRENT_BINARY_DIR}/release.txt" DESTINATION "foo" CONFIGURATIONS Release) + +set(CPACK_INSTALL_CMAKE_CONFIGURATIONS ${CMAKE_CONFIGURATION_TYPES}) diff --git a/Tests/RunCMake/CommandLine/E_remove_directory-symlink-dir-check.cmake b/Tests/RunCMake/CommandLine/E_remove_directory-symlink-dir-check.cmake new file mode 100644 index 0000000..f70312c --- /dev/null +++ b/Tests/RunCMake/CommandLine/E_remove_directory-symlink-dir-check.cmake @@ -0,0 +1,6 @@ +if(EXISTS ${out}/link_dir) + set(RunCMake_TEST_FAILED "did not remove ${out}/link_dir") +endif() +if(NOT EXISTS ${out}/dir) + set(RunCMake_TEST_FAILED "should not have removed ${out}/dir") +endif() diff --git a/Tests/RunCMake/CommandLine/E_remove_directory-symlink-dir-stderr.txt b/Tests/RunCMake/CommandLine/E_remove_directory-symlink-dir-stderr.txt new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/Tests/RunCMake/CommandLine/E_remove_directory-symlink-dir-stderr.txt diff --git a/Tests/RunCMake/CommandLine/E_remove_directory-symlink-file-check.cmake b/Tests/RunCMake/CommandLine/E_remove_directory-symlink-file-check.cmake new file mode 100644 index 0000000..23d7c6d --- /dev/null +++ b/Tests/RunCMake/CommandLine/E_remove_directory-symlink-file-check.cmake @@ -0,0 +1,6 @@ +if(NOT EXISTS ${outfile}) + set(RunCMake_TEST_FAILED "removed non-directory ${outfile}") +endif() +if(NOT EXISTS ${out}/link_file_for_test.txt) + set(RunCMake_TEST_FAILED "removed non-directory symlink ${out}/link_file_for_test.txt") +endif() diff --git a/Tests/RunCMake/CommandLine/E_remove_directory-symlink-file-stderr.txt b/Tests/RunCMake/CommandLine/E_remove_directory-symlink-file-stderr.txt new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/Tests/RunCMake/CommandLine/E_remove_directory-symlink-file-stderr.txt diff --git a/Tests/RunCMake/CommandLine/RunCMakeTest.cmake b/Tests/RunCMake/CommandLine/RunCMakeTest.cmake index 71a3843..efd1cc2 100644 --- a/Tests/RunCMake/CommandLine/RunCMakeTest.cmake +++ b/Tests/RunCMake/CommandLine/RunCMakeTest.cmake @@ -348,6 +348,17 @@ run_cmake_command(E_make_directory-two-directories-and-file ${CMAKE_COMMAND} -E make_directory ${out}/d1 ${out}/d2 ${outfile}) run_cmake_command(E_remove_directory-two-directories-and-file ${CMAKE_COMMAND} -E remove_directory ${out}/d1 ${out}/d2 ${outfile}) + +if(UNIX) + file(MAKE_DIRECTORY ${out}/dir) + file(CREATE_LINK ${out}/dir ${out}/link_dir SYMBOLIC) + file(CREATE_LINK ${outfile} ${out}/link_file_for_test.txt SYMBOLIC) + run_cmake_command(E_remove_directory-symlink-dir + ${CMAKE_COMMAND} -E remove_directory ${out}/link_dir) + run_cmake_command(E_remove_directory-symlink-file + ${CMAKE_COMMAND} -E remove_directory ${out}/link_file_for_test.txt) +endif() + unset(out) unset(outfile) diff --git a/Tests/RunCMake/FindBoost/CMakePackage_New/BoostConfig.cmake b/Tests/RunCMake/FindBoost/CMakePackage_New/BoostConfig.cmake index 3a88f26..1151514 100644 --- a/Tests/RunCMake/FindBoost/CMakePackage_New/BoostConfig.cmake +++ b/Tests/RunCMake/FindBoost/CMakePackage_New/BoostConfig.cmake @@ -8,6 +8,7 @@ set_target_properties(Boost::date_time PROPERTIES IMPORTED_CONFIGURATIONS RELEASE IMPORTED_LOCATION_RELEASE "${CMAKE_CURRENT_LIST_DIR}/lib/libboost_date_time.a" ) + set(Boost_python37_FOUND 1) add_library(Boost::python UNKNOWN IMPORTED) set_target_properties(Boost::python PROPERTIES @@ -15,6 +16,10 @@ set_target_properties(Boost::python PROPERTIES IMPORTED_LOCATION_RELEASE "${CMAKE_CURRENT_LIST_DIR}/lib/libboost_python_release.a" IMPORTED_LOCATION_DEBUG "${CMAKE_CURRENT_LIST_DIR}/lib/libboost_python.a" ) +# Versioned target alias for compatibility (added by upstream BoostConfig). +add_library(Boost::python37 INTERFACE IMPORTED) +set_property(TARGET Boost::python37 APPEND PROPERTY INTERFACE_LINK_LIBRARIES Boost::python) + set(Boost_mpi_python2_FOUND 1) add_library(Boost::mpi_python UNKNOWN IMPORTED) set_target_properties(Boost::mpi_python PROPERTIES diff --git a/Tests/RunCMake/FindPkgConfig/FindPkgConfig_GET_MATCHING_MODULE_NAME.cmake b/Tests/RunCMake/FindPkgConfig/FindPkgConfig_GET_MATCHING_MODULE_NAME.cmake new file mode 100644 index 0000000..fc3a766 --- /dev/null +++ b/Tests/RunCMake/FindPkgConfig/FindPkgConfig_GET_MATCHING_MODULE_NAME.cmake @@ -0,0 +1,28 @@ +# Prepare environment to reuse bletch.pc +file(TO_NATIVE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/pc-bletch/lib/pkgconfig" PC_PATH) +if(UNIX) + string(REPLACE "\\ " " " PC_PATH "${PC_PATH}") +endif() +set(ENV{PKG_CONFIG_PATH} "${PC_PATH}") + +find_package(PkgConfig REQUIRED) +pkg_search_module(FOO REQUIRED foo bletch bar) + +if(NOT FOO_MODULE_NAME STREQUAL "bletch") + message(FATAL_ERROR "Wrong value for FOO_MODULE_NAME. Expected: bletch, got: ${FOO_MODULE_NAME}") +endif() + +pkg_get_variable(FOO_JACKPOT ${FOO_MODULE_NAME} jackpot) + +if(NOT FOO_JACKPOT STREQUAL "bletch-lives") + message(FATAL_ERROR "Wrong value for FOO_JACKPOT. Expected: bletch-lives, got: ${FOO_JACKPOT}") +endif() + +unset(FOO_MODULE_NAME) + +# verify variable get's also set on subsequent run +pkg_search_module(FOO REQUIRED foo bletch bar) + +if(NOT FOO_MODULE_NAME STREQUAL "bletch") + message(FATAL_ERROR "Wrong value for FOO_MODULE_NAME on second run. Expected: bletch, got: ${FOO_MODULE_NAME}") +endif() diff --git a/Tests/RunCMake/FindPkgConfig/RunCMakeTest.cmake b/Tests/RunCMake/FindPkgConfig/RunCMakeTest.cmake index 414d9b6..b77bb54 100644 --- a/Tests/RunCMake/FindPkgConfig/RunCMakeTest.cmake +++ b/Tests/RunCMake/FindPkgConfig/RunCMakeTest.cmake @@ -19,4 +19,5 @@ if (PKG_CONFIG_FOUND) run_cmake(FindPkgConfig_cache_variables) run_cmake(FindPkgConfig_IMPORTED_TARGET) run_cmake(FindPkgConfig_VERSION_OPERATORS) + run_cmake(FindPkgConfig_GET_MATCHING_MODULE_NAME) endif () diff --git a/Tests/RunCMake/GeneratorToolset/RunCMakeTest.cmake b/Tests/RunCMake/GeneratorToolset/RunCMakeTest.cmake index ef8fd25..ae75561 100644 --- a/Tests/RunCMake/GeneratorToolset/RunCMakeTest.cmake +++ b/Tests/RunCMake/GeneratorToolset/RunCMakeTest.cmake @@ -6,12 +6,14 @@ run_cmake(NoToolset) if("${RunCMake_GENERATOR}" MATCHES "Visual Studio 1[012456]") set(RunCMake_GENERATOR_TOOLSET "Test Toolset") run_cmake(TestToolset) - set(RunCMake_GENERATOR_TOOLSET "Test Toolset,cuda=Test Cuda") + set(RunCMake_GENERATOR_TOOLSET "Test Toolset,cuda=0.0") run_cmake(TestToolsetCudaBoth) - set(RunCMake_GENERATOR_TOOLSET ",cuda=Test Cuda") - run_cmake(TestToolsetCudaOnly) - set(RunCMake_GENERATOR_TOOLSET "cuda=Test Cuda") - run_cmake(TestToolsetCudaOnly) + set(RunCMake_GENERATOR_TOOLSET ",cuda=0.0") + run_cmake(TestToolsetCudaVersionOnly) + set(RunCMake_GENERATOR_TOOLSET "cuda=0.0") + run_cmake(TestToolsetCudaVersionOnly) + set(RunCMake_GENERATOR_TOOLSET "cuda=C:\\dummy\\cuda") + run_cmake(TestToolsetCudaPathOnly) if("${RunCMake_GENERATOR}" MATCHES "Visual Studio 1[2456]") set(RunCMake_GENERATOR_TOOLSET "Test Toolset,host=x64") run_cmake(TestToolsetHostArchBoth) diff --git a/Tests/RunCMake/GeneratorToolset/TestToolsetCudaBoth-stdout.txt b/Tests/RunCMake/GeneratorToolset/TestToolsetCudaBoth-stdout.txt index 90503e2..f12c123 100644 --- a/Tests/RunCMake/GeneratorToolset/TestToolsetCudaBoth-stdout.txt +++ b/Tests/RunCMake/GeneratorToolset/TestToolsetCudaBoth-stdout.txt @@ -1,2 +1,2 @@ -- CMAKE_VS_PLATFORM_TOOLSET='Test Toolset' --- CMAKE_VS_PLATFORM_TOOLSET_CUDA='Test Cuda' +-- CMAKE_VS_PLATFORM_TOOLSET_CUDA='0.0' diff --git a/Tests/RunCMake/GeneratorToolset/TestToolsetCudaPathOnly-result.txt b/Tests/RunCMake/GeneratorToolset/TestToolsetCudaPathOnly-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/GeneratorToolset/TestToolsetCudaPathOnly-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/GeneratorToolset/TestToolsetCudaPathOnly-stderr.txt b/Tests/RunCMake/GeneratorToolset/TestToolsetCudaPathOnly-stderr.txt new file mode 100644 index 0000000..b17745f --- /dev/null +++ b/Tests/RunCMake/GeneratorToolset/TestToolsetCudaPathOnly-stderr.txt @@ -0,0 +1,12 @@ +CMake Error at CMakeLists.txt:[0-9]+ \(project\): + Generator + + Visual Studio .* + + given toolset + + cuda=C:\\dummy\\cuda\\ + + cannot detect Visual Studio integration files in path + + C:/dummy/cuda/CUDAVisualStudioIntegration/extras/visual_studio_integration/MSBuildExtensions diff --git a/Tests/RunCMake/GeneratorToolset/TestToolsetCudaPathOnly.cmake b/Tests/RunCMake/GeneratorToolset/TestToolsetCudaPathOnly.cmake new file mode 100644 index 0000000..2fc38e5 --- /dev/null +++ b/Tests/RunCMake/GeneratorToolset/TestToolsetCudaPathOnly.cmake @@ -0,0 +1 @@ +message(FATAL_ERROR "This should not be reached!") diff --git a/Tests/RunCMake/GeneratorToolset/TestToolsetCudaOnly-stdout.txt b/Tests/RunCMake/GeneratorToolset/TestToolsetCudaVersionOnly-stdout.txt index 94e1e43..1717ff8 100644 --- a/Tests/RunCMake/GeneratorToolset/TestToolsetCudaOnly-stdout.txt +++ b/Tests/RunCMake/GeneratorToolset/TestToolsetCudaVersionOnly-stdout.txt @@ -1,2 +1,2 @@ -- CMAKE_VS_PLATFORM_TOOLSET='(v[0-9]+|Windows7.1SDK)' --- CMAKE_VS_PLATFORM_TOOLSET_CUDA='Test Cuda' +-- CMAKE_VS_PLATFORM_TOOLSET_CUDA='0.0' diff --git a/Tests/RunCMake/GeneratorToolset/TestToolsetCudaOnly.cmake b/Tests/RunCMake/GeneratorToolset/TestToolsetCudaVersionOnly.cmake index befa0af..befa0af 100644 --- a/Tests/RunCMake/GeneratorToolset/TestToolsetCudaOnly.cmake +++ b/Tests/RunCMake/GeneratorToolset/TestToolsetCudaVersionOnly.cmake diff --git a/Tests/RunCMake/VS10Project/VsPrecompileHeaders-check.cmake b/Tests/RunCMake/VS10Project/VsPrecompileHeaders-check.cmake index 82ca421..27842f9 100644 --- a/Tests/RunCMake/VS10Project/VsPrecompileHeaders-check.cmake +++ b/Tests/RunCMake/VS10Project/VsPrecompileHeaders-check.cmake @@ -1,13 +1,11 @@ -set(pch_header "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/tgt.dir/cmake_pch.hxx") -set(pch_source "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/tgt.dir/cmake_pch.cxx") +set(pch_header "CMakeFiles/tgt.dir/cmake_pch.hxx") +set(pch_source [=[CMakeFiles\\tgt.dir\\cmake_pch.cxx]=]) -file(TO_NATIVE_PATH "${pch_source}" pch_source_win) - -if(NOT EXISTS "${pch_header}") +if(NOT EXISTS "${RunCMake_TEST_BINARY_DIR}/${pch_header}") set(RunCMake_TEST_FAILED "Generated PCH header ${pch_header} does not exist.") return() endif() -if(NOT EXISTS "${pch_source}") +if(NOT EXISTS "${RunCMake_TEST_BINARY_DIR}/${pch_source}") set(RunCMake_TEST_FAILED "Generated PCH header ${pch_source} does not exist.") return() endif() @@ -29,16 +27,15 @@ foreach(line IN LISTS tgt_projects_strings) set(have_pch_create ON) endif() - if (line MATCHES "<PrecompiledHeaderFile.*>${pch_header}</PrecompiledHeaderFile>") + if (line MATCHES "<PrecompiledHeaderFile.*>.*${pch_header}</PrecompiledHeaderFile>") set(have_pch_header ON) endif() - if (line MATCHES "<ForcedIncludeFiles.*>${pch_header}</ForcedIncludeFiles>") + if (line MATCHES "<ForcedIncludeFiles.*>.*${pch_header}</ForcedIncludeFiles>") set(have_force_pch_header ON) endif() - string(FIND "${line}" "<ClCompile Include=\"${pch_source_win}\">" find_pos) - if (NOT find_pos EQUAL "-1") + if (line MATCHES "<ClCompile Include=.*${pch_source}\">") set(have_pch_source_compile ON) endif() endforeach() @@ -64,6 +61,6 @@ if (NOT have_force_pch_header) endif() if (NOT have_pch_source_compile) - set(RunCMake_TEST_FAILED "Generated project should have the <ClCompile Include=\"${pch_source_win}\"> block.") + set(RunCMake_TEST_FAILED "Generated project should have the <ClCompile Include=\"${pch_source}\"> block.") return() endif() diff --git a/Utilities/Release/README.rst b/Utilities/Release/README.rst index e7f0eb3..de294d1 100644 --- a/Utilities/Release/README.rst +++ b/Utilities/Release/README.rst @@ -34,7 +34,7 @@ may use to produce Linux binaries for CMake: -f cmake-src/Utilities/Release/linux/$arch/Dockerfile cmake-src $ docker container create --name cmake-build cmake:build $ docker cp cmake-build:/out . - $ ls out/cmake-*-Linux-$arch.tar.gz + $ ls out/cmake-*-Linux-$arch.* * ``linux/<arch>/test/Dockerfile``: Produces a base image with a test environment for packaged CMake binaries. diff --git a/Utilities/Release/linux/x86_64/Dockerfile b/Utilities/Release/linux/x86_64/Dockerfile index f3ba69c..1ba753c 100644 --- a/Utilities/Release/linux/x86_64/Dockerfile +++ b/Utilities/Release/linux/x86_64/Dockerfile @@ -29,7 +29,8 @@ RUN : \ bin/ctest --output-on-failure -j 8 -R '^(CMake\.|CMakeLib\.|CMakeServerLib\.|RunCMake\.ctest_memcheck)'; \ fi \ && bin/cpack -G TGZ \ + && bin/cpack -G STGZ \ && set +x \ && mkdir /out \ - && mv cmake-*-Linux-x86_64.tar.gz /out \ + && mv cmake-*-Linux-x86_64.* /out \ && : |