diff options
87 files changed, 1070 insertions, 192 deletions
diff --git a/Help/command/if.rst b/Help/command/if.rst index f04f233..5294ce8 100644 --- a/Help/command/if.rst +++ b/Help/command/if.rst @@ -148,23 +148,33 @@ Possible expressions are: ``if(<variable|string> VERSION_LESS <variable|string>)`` Component-wise integer version number comparison (version format is - ``major[.minor[.patch[.tweak]]]``). + ``major[.minor[.patch[.tweak]]]``, omitted components are treated as zero). + Any non-integer version component or non-integer trailing part of a version + component effectively truncates the string at that point. ``if(<variable|string> VERSION_GREATER <variable|string>)`` Component-wise integer version number comparison (version format is - ``major[.minor[.patch[.tweak]]]``). + ``major[.minor[.patch[.tweak]]]``, omitted components are treated as zero). + Any non-integer version component or non-integer trailing part of a version + component effectively truncates the string at that point. ``if(<variable|string> VERSION_EQUAL <variable|string>)`` Component-wise integer version number comparison (version format is - ``major[.minor[.patch[.tweak]]]``). + ``major[.minor[.patch[.tweak]]]``, omitted components are treated as zero). + Any non-integer version component or non-integer trailing part of a version + component effectively truncates the string at that point. ``if(<variable|string> VERSION_LESS_EQUAL <variable|string>)`` Component-wise integer version number comparison (version format is - ``major[.minor[.patch[.tweak]]]``). + ``major[.minor[.patch[.tweak]]]``, omitted components are treated as zero). + Any non-integer version component or non-integer trailing part of a version + component effectively truncates the string at that point. ``if(<variable|string> VERSION_GREATER_EQUAL <variable|string>)`` Component-wise integer version number comparison (version format is - ``major[.minor[.patch[.tweak]]]``). + ``major[.minor[.patch[.tweak]]]``, omitted components are treated as zero). + Any non-integer version component or non-integer trailing part of a version + component effectively truncates the string at that point. ``if(<variable|string> IN_LIST <variable>)`` True if the given element is contained in the named list variable. diff --git a/Help/command/target_link_libraries.rst b/Help/command/target_link_libraries.rst index 1f0d69e..e1c374e 100644 --- a/Help/command/target_link_libraries.rst +++ b/Help/command/target_link_libraries.rst @@ -18,10 +18,13 @@ All of them have the general form:: target_link_libraries(<target> ... <item>... ...) -The named ``<target>`` must have been created in the current directory by -a command such as :command:`add_executable` or :command:`add_library` and -must not be an :ref:`ALIAS target <Alias Targets>`. -Repeated calls for the same ``<target>`` append items in the order called. +The named ``<target>`` must have been created by a command such as +:command:`add_executable` or :command:`add_library` and must not be an +:ref:`ALIAS target <Alias Targets>`. If policy :policy:`CMP0079` is not +set to ``NEW`` then the target must have been created in the current +directory. Repeated calls for the same ``<target>`` append items in +the order called. + Each ``<item>`` may be: * **A library target name**: The generated link line will have the diff --git a/Help/manual/cmake-generator-expressions.7.rst b/Help/manual/cmake-generator-expressions.7.rst index c3428d1..76fd3d9 100644 --- a/Help/manual/cmake-generator-expressions.7.rst +++ b/Help/manual/cmake-generator-expressions.7.rst @@ -68,10 +68,13 @@ Available logical expressions are: target. ``$<PLATFORM_ID:comp>`` ``1`` if the CMake-id of the platform matches ``comp``, otherwise ``0``. + See also the :variable:`CMAKE_SYSTEM_NAME` variable. ``$<C_COMPILER_ID:comp>`` ``1`` if the CMake-id of the C compiler matches ``comp``, otherwise ``0``. + See also the :variable:`CMAKE_<LANG>_COMPILER_ID` variable. ``$<CXX_COMPILER_ID:comp>`` ``1`` if the CMake-id of the CXX compiler matches ``comp``, otherwise ``0``. + See also the :variable:`CMAKE_<LANG>_COMPILER_ID` variable. ``$<VERSION_LESS:v1,v2>`` ``1`` if ``v1`` is a version less than ``v2``, else ``0``. ``$<VERSION_GREATER:v1,v2>`` @@ -84,8 +87,10 @@ Available logical expressions are: ``1`` if ``v1`` is a version greater than or equal to ``v2``, else ``0``. ``$<C_COMPILER_VERSION:ver>`` ``1`` if the version of the C compiler matches ``ver``, otherwise ``0``. + See also the :variable:`CMAKE_<LANG>_COMPILER_VERSION` variable. ``$<CXX_COMPILER_VERSION:ver>`` ``1`` if the version of the CXX compiler matches ``ver``, otherwise ``0``. + See also the :variable:`CMAKE_<LANG>_COMPILER_VERSION` variable. ``$<TARGET_POLICY:pol>`` ``1`` if the policy ``pol`` was NEW when the 'head' target was created, else ``0``. If the policy was not set, the warning message for the policy diff --git a/Help/manual/cmake-policies.7.rst b/Help/manual/cmake-policies.7.rst index 32a0118..8ecca4d 100644 --- a/Help/manual/cmake-policies.7.rst +++ b/Help/manual/cmake-policies.7.rst @@ -57,6 +57,7 @@ Policies Introduced by CMake 3.13 .. toctree:: :maxdepth: 1 + CMP0079: target_link_libraries allows use with targets in other directories. </policy/CMP0079> CMP0078: UseSWIG generates standard target names. </policy/CMP0078> CMP0077: option() honors normal variables. </policy/CMP0077> CMP0076: target_sources() command converts relative paths to absolute. </policy/CMP0076> diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst index d8a5def..6071999 100644 --- a/Help/manual/cmake-variables.7.rst +++ b/Help/manual/cmake-variables.7.rst @@ -78,6 +78,7 @@ Variables that Provide Information /variable/CMAKE_PROJECT_VERSION_TWEAK /variable/CMAKE_RANLIB /variable/CMAKE_ROOT + /variable/CMAKE_RULE_MESSAGES /variable/CMAKE_SCRIPT_MODE_FILE /variable/CMAKE_SHARED_LIBRARY_PREFIX /variable/CMAKE_SHARED_LIBRARY_SUFFIX diff --git a/Help/policy/CMP0079.rst b/Help/policy/CMP0079.rst new file mode 100644 index 0000000..0244d6c --- /dev/null +++ b/Help/policy/CMP0079.rst @@ -0,0 +1,40 @@ +CMP0079 +------- + +:command:`target_link_libraries` allows use with targets in other directories. + +Prior to CMake 3.13 the :command:`target_link_libraries` command did not +accept targets not created in the calling directory as its first argument +for calls that update the :prop_tgt:`LINK_LIBRARIES` of the target itself. +It did accidentally accept targets from other directories on calls that +only update the :prop_tgt:`INTERFACE_LINK_LIBRARIES`, but would simply +add entries to the property as if the call were made in the original +directory. Thus link interface libraries specified this way were always +looked up by generators in the scope of the original target rather than +in the scope that called :command:`target_link_libraries`. + +CMake 3.13 now allows the :command:`target_link_libraries` command to +be called from any directory to add link dependencies and link interface +libraries to targets created in other directories. The entries are added +to :prop_tgt:`LINK_LIBRARIES` and :prop_tgt:`INTERFACE_LINK_LIBRARIES` +using a special (internal) suffix to tell the generators to look up the +names in the calling scope rather than the scope that created the target. + +This policy provides compatibility with projects that already use +:command:`target_link_libraries` with the ``INTERFACE`` keyword +on a target in another directory to add :prop_tgt:`INTERFACE_LINK_LIBRARIES` +entries to be looked up in the target's directory. Such projects should +be updated to be aware of the new scoping rules in that case. + +The ``OLD`` behavior of this policy is to disallow +:command:`target_link_libraries` calls naming targets from another directory +except in the previously accidentally allowed case of using the ``INTERFACE`` +keyword only. The ``NEW`` behavior of this policy is to allow all such +calls but use the new scoping rules. + +This policy was introduced in CMake version 3.13. CMake version +|release| warns when the policy is not set and uses ``OLD`` behavior. +Use the :command:`cmake_policy` command to set it to ``OLD`` or ``NEW`` +explicitly. + +.. include:: DEPRECATED.txt diff --git a/Help/prop_gbl/RULE_MESSAGES.rst b/Help/prop_gbl/RULE_MESSAGES.rst index 87a5ca6..a9734a7 100644 --- a/Help/prop_gbl/RULE_MESSAGES.rst +++ b/Help/prop_gbl/RULE_MESSAGES.rst @@ -8,6 +8,6 @@ progress message describing what each build rule does. If the property is not set the default is ON. Set the property to OFF to disable granular messages and report only as each target completes. This is intended to allow scripted builds to avoid the build time cost -of detailed reports. If a ``CMAKE_RULE_MESSAGES`` cache entry exists +of detailed reports. If a :variable:`CMAKE_RULE_MESSAGES` cache entry exists its value initializes the value of this property. Non-Makefile generators currently ignore this property. diff --git a/Help/prop_tgt/INTERFACE_LINK_LIBRARIES.rst b/Help/prop_tgt/INTERFACE_LINK_LIBRARIES.rst index 832d12b..bf7f72f 100644 --- a/Help/prop_tgt/INTERFACE_LINK_LIBRARIES.rst +++ b/Help/prop_tgt/INTERFACE_LINK_LIBRARIES.rst @@ -17,6 +17,8 @@ with the syntax ``$<...>``. See the :manual:`cmake-generator-expressions(7)` manual for available expressions. See the :manual:`cmake-buildsystem(7)` manual for more on defining buildsystem properties. +.. include:: LINK_LIBRARIES_INDIRECTION.txt + Creating Relocatable Packages ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/Help/prop_tgt/LINK_LIBRARIES.rst b/Help/prop_tgt/LINK_LIBRARIES.rst index aa4b9f5..d88e798 100644 --- a/Help/prop_tgt/LINK_LIBRARIES.rst +++ b/Help/prop_tgt/LINK_LIBRARIES.rst @@ -15,3 +15,5 @@ Contents of ``LINK_LIBRARIES`` may use "generator expressions" with the syntax ``$<...>``. See the :manual:`cmake-generator-expressions(7)` manual for available expressions. See the :manual:`cmake-buildsystem(7)` manual for more on defining buildsystem properties. + +.. include:: LINK_LIBRARIES_INDIRECTION.txt diff --git a/Help/prop_tgt/LINK_LIBRARIES_INDIRECTION.txt b/Help/prop_tgt/LINK_LIBRARIES_INDIRECTION.txt new file mode 100644 index 0000000..1fdb6ad --- /dev/null +++ b/Help/prop_tgt/LINK_LIBRARIES_INDIRECTION.txt @@ -0,0 +1,10 @@ +.. note:: + A call to :command:`target_link_libraries(<target> ...)` may update this + property on ``<target>``. If ``<target>`` was not created in the same + directory as the call then :command:`target_link_libraries` will add a + suffix of the form ``::@<directory-id>`` to each entry, where the + ``::@`` is a separator and the ``<directory-id>`` is unspecified. + This tells the generators that the named libraries must be looked up in + the scope of the caller rather than in the scope in which the + ``<target>`` was created. Valid directory ids are stripped on export + by the :command:`install(EXPORT)` and :command:`export` commands. diff --git a/Help/release/dev/FindPython-lookup-strategy.rst b/Help/release/dev/FindPython-lookup-strategy.rst new file mode 100644 index 0000000..f6d6db5 --- /dev/null +++ b/Help/release/dev/FindPython-lookup-strategy.rst @@ -0,0 +1,6 @@ +FindPython-lookup-strategy +-------------------------- + +* Modules :module:`FindPython3`, :module:`FindPython2` and :module:`FindPython` + gain capability to control order of resource lookup on macOS (Framework) and + Windows (Registry). diff --git a/Help/release/dev/out-of-dir-linking.rst b/Help/release/dev/out-of-dir-linking.rst new file mode 100644 index 0000000..6166be6 --- /dev/null +++ b/Help/release/dev/out-of-dir-linking.rst @@ -0,0 +1,6 @@ +out-of-dir-linking +------------------ + +* The :command:`target_link_libraries` command may now be called + to modify targets created outside the current directory. + See policy :policy:`CMP0079`. diff --git a/Help/variable/CMAKE_RULE_MESSAGES.rst b/Help/variable/CMAKE_RULE_MESSAGES.rst new file mode 100644 index 0000000..7460a81 --- /dev/null +++ b/Help/variable/CMAKE_RULE_MESSAGES.rst @@ -0,0 +1,8 @@ +CMAKE_RULE_MESSAGES +------------------- + +Specify whether to report a message for each make rule. + +If set in the cache it is used to initialize the value of the :prop_gbl:`RULE_MESSAGES` property. +Users may disable the option in their local build tree to disable granular messages +and report only as each target completes in Makefile builds. diff --git a/Modules/CMakeIOSInstallCombined.cmake b/Modules/CMakeIOSInstallCombined.cmake index fad2e8f..418bafd 100644 --- a/Modules/CMakeIOSInstallCombined.cmake +++ b/Modules/CMakeIOSInstallCombined.cmake @@ -1,6 +1,8 @@ # Distributed under the OSI-approved BSD 3-Clause License. See accompanying # file Copyright.txt or https://cmake.org/licensing for details. +cmake_policy(PUSH) +cmake_policy(SET CMP0057 NEW) # if IN_LIST # Function to print messages of this module function(_ios_install_combined_message) @@ -57,6 +59,7 @@ endfunction() # Get architectures of given SDK (iphonesimulator/iphoneos) function(_ios_install_combined_get_valid_archs sdk resultvar) + cmake_policy(PUSH) cmake_policy(SET CMP0007 NEW) if("${resultvar}" STREQUAL "") @@ -73,6 +76,8 @@ function(_ios_install_combined_get_valid_archs sdk resultvar) _ios_install_combined_message("Architectures (${sdk}): ${printable}") set("${resultvar}" "${valid_archs}" PARENT_SCOPE) + + cmake_policy(POP) endfunction() # Final target can contain more architectures that specified by SDK. This @@ -161,8 +166,6 @@ function(_ios_install_combined_keep_archs lib archs) endfunction() function(_ios_install_combined_detect_sdks this_sdk_var corr_sdk_var) - cmake_policy(SET CMP0057 NEW) - set(this_sdk "$ENV{PLATFORM_NAME}") if("${this_sdk}" STREQUAL "") message(FATAL_ERROR "Environment variable PLATFORM_NAME is empty") @@ -305,3 +308,5 @@ function(ios_install_combined target destination) _ios_install_combined_message("Install done: ${destination}") endfunction() + +cmake_policy(POP) diff --git a/Modules/CSharpUtilities.cmake b/Modules/CSharpUtilities.cmake index e9e1510..6a4b5c7 100644 --- a/Modules/CSharpUtilities.cmake +++ b/Modules/CSharpUtilities.cmake @@ -184,6 +184,9 @@ Helper functions which are used by the above ones #]=======================================================================] +cmake_policy(PUSH) +cmake_policy(SET CMP0057 NEW) # if IN_LIST + function(csharp_get_filename_keys OUT) set(${OUT} "") foreach(f ${ARGN}) @@ -304,3 +307,5 @@ function(csharp_set_xaml_cs_properties) endif() endforeach() endfunction() + +cmake_policy(POP) diff --git a/Modules/FindBoost.cmake b/Modules/FindBoost.cmake index 24ee1f2..37539ba 100644 --- a/Modules/FindBoost.cmake +++ b/Modules/FindBoost.cmake @@ -573,7 +573,7 @@ function(_Boost_COMPONENT_DEPENDENCIES component _ret) endif() set(_Boost_IMPORTED_TARGETS TRUE) - if(Boost_VERSION VERSION_LESS 103300) + if(Boost_VERSION AND Boost_VERSION VERSION_LESS 103300) message(WARNING "Imported targets and dependency information not available for Boost version ${Boost_VERSION} (all versions older than 1.33)") set(_Boost_IMPORTED_TARGETS FALSE) elseif(NOT Boost_VERSION VERSION_LESS 103300 AND Boost_VERSION VERSION_LESS 103500) diff --git a/Modules/FindCUDA.cmake b/Modules/FindCUDA.cmake index 1650e55..5547dee 100644 --- a/Modules/FindCUDA.cmake +++ b/Modules/FindCUDA.cmake @@ -43,7 +43,7 @@ # matches what is needed by the CUDA runtime version. # # The following variables affect the behavior of the macros in the -# script (in alphebetical order). Note that any of these flags can be +# script (in alphabetical order). Note that any of these flags can be # changed multiple times in the same directory before calling # ``CUDA_ADD_EXECUTABLE``, ``CUDA_ADD_LIBRARY``, ``CUDA_COMPILE``, # ``CUDA_COMPILE_PTX``, ``CUDA_COMPILE_FATBIN``, ``CUDA_COMPILE_CUBIN`` @@ -147,7 +147,7 @@ # VERBOSE=1 to see output), although setting CUDA_VERBOSE_BUILD to ON will # always print the output. # -# The script creates the following macros (in alphebetical order):: +# The script creates the following macros (in alphabetical order):: # # CUDA_ADD_CUFFT_TO_TARGET( cuda_target ) # -- Adds the cufft library to the target (can be any target). Handles whether diff --git a/Modules/FindPython.cmake b/Modules/FindPython.cmake index 8139e53..0bf0b4f 100644 --- a/Modules/FindPython.cmake +++ b/Modules/FindPython.cmake @@ -116,6 +116,25 @@ Hints * If set to TRUE, search **only** for static libraries. * If set to FALSE, search **only** for shared libraries. +``Python_FIND_REGISTRY`` + On Windows the ``Python_FIND_REGISTRY`` variable determine the order + of preference between registry and environment variables. + the ``Python_FIND_REGISTRY`` variable can be set to empty or one of the + following: + + * ``FIRST``: Try to use registry before environment variables. + This is the default. + * ``LAST``: Try to use registry after environment variables. + * ``NEVER``: Never try to use registry. + +``CMAKE_FIND_FRAMEWORK`` + On OS X the :variable:`CMAKE_FIND_FRAMEWORK` variable determine the order of + preference between Apple-style and unix-style package components. + + .. note:: + + Value ``ONLY`` is not supported so ``FIRST`` will be used instead. + Commands ^^^^^^^^ diff --git a/Modules/FindPython/Support.cmake b/Modules/FindPython/Support.cmake index fe3df91..1834591 100644 --- a/Modules/FindPython/Support.cmake +++ b/Modules/FindPython/Support.cmake @@ -44,9 +44,28 @@ macro (_PYTHON_DISPLAY_FAILURE _PYTHON_MSG) endmacro() +macro (_PYTHON_FIND_FRAMEWORKS) + set (${_PYTHON_PREFIX}_FRAMEWORKS) + if (APPLE) + set (_pff_frameworks ${CMAKE_FRAMEWORK_PATH} + $ENV{CMAKE_FRAMEWORK_PATH} + ~/Library/Frameworks + /usr/local/Frameworks + ${CMAKE_SYSTEM_FRAMEWORK_PATH}) + list (REMOVE_DUPLICATES _pff_frameworks) + foreach (_pff_framework IN LISTS _pff_frameworks) + if (EXISTS ${_pff_framework}/Python.framework) + list (APPEND ${_PYTHON_PREFIX}_FRAMEWORKS ${_pff_framework}/Python.framework) + endif() + endforeach() + unset (_pff_frameworks) + unset (_pff_framework) + endif() +endmacro() + function (_PYTHON_GET_FRAMEWORKS _PYTHON_PGF_FRAMEWORK_PATHS _PYTHON_VERSION) set (_PYTHON_FRAMEWORK_PATHS) - foreach (_PYTHON_FRAMEWORK IN LISTS Python_FRAMEWORKS) + foreach (_PYTHON_FRAMEWORK IN LISTS ${_PYTHON_PREFIX}_FRAMEWORKS) list (APPEND _PYTHON_FRAMEWORK_PATHS "${_PYTHON_FRAMEWORK}/Versions/${_PYTHON_VERSION}") endforeach() @@ -59,20 +78,43 @@ function (_PYTHON_VALIDATE_INTERPRETER) return() endif() - if (${_PYTHON_PREFIX}_EXECUTABLE MATCHES "python${CMAKE_EXECUTABLE_SUFFIX}$") - # executable found do not have version in name - # ensure major version is OK + if (ARGC EQUAL 1) + set (expected_version ${ARGV0}) + else() + unset (expected_version) + endif() + + get_filename_component (python_name "${${_PYTHON_PREFIX}_EXECUTABLE}" NAME) + + if (expected_version AND NOT python_name STREQUAL "python${expected_version}${CMAKE_EXECUTABLE_SUFFIX}") + # executable found must have a specific version execute_process (COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -c - "import sys; sys.stdout.write(str(sys.version_info[0]))" + "import sys; sys.stdout.write('.'.join([str(x) for x in sys.version_info[:2]]))" RESULT_VARIABLE result OUTPUT_VARIABLE version ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) - if (result OR NOT version EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR) + if (result OR NOT version EQUAL expected_version) # interpreter not usable or has wrong major version set (${_PYTHON_PREFIX}_EXECUTABLE ${_PYTHON_PREFIX}_EXECUTABLE-NOTFOUND CACHE INTERNAL "" FORCE) 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 + "import sys; sys.stdout.write(str(sys.version_info[0]))" + RESULT_VARIABLE result + OUTPUT_VARIABLE version + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE) + if (result OR NOT version EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR) + # interpreter not usable or has wrong major version + set (${_PYTHON_PREFIX}_EXECUTABLE ${_PYTHON_PREFIX}_EXECUTABLE-NOTFOUND CACHE INTERNAL "" FORCE) + return() + endif() + endif() endif() if (CMAKE_SIZEOF_VOID_P AND "Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS @@ -93,6 +135,33 @@ function (_PYTHON_VALIDATE_INTERPRETER) endfunction() +function (_PYTHON_VALIDATE_COMPILER expected_version) + if (NOT ${_PYTHON_PREFIX}_COMPILER) + return() + endif() + + # retrieve python environment version from compiler + set (working_dir "${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/PythonCompilerVersion.dir") + file (WRITE "${working_dir}/version.py" "import sys; sys.stdout.write('.'.join([str(x) for x in sys.version_info[:2]]))\n") + execute_process (COMMAND "${${_PYTHON_PREFIX}_COMPILER}" /target:exe /embed "${working_dir}/version.py" + WORKING_DIRECTORY "${working_dir}" + OUTPUT_QUIET + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE) + execute_process (COMMAND "${working_dir}/version" + WORKING_DIRECTORY "${working_dir}" + RESULT_VARIABLE result + OUTPUT_VARIABLE version + ERROR_QUIET) + file (REMOVE_RECURSE "${_${_PYTHON_PREFIX}_VERSION_DIR}") + + if (result OR NOT version EQUAL expected_version) + # Compiler not usable or has wrong major version + set (${_PYTHON_PREFIX}_COMPILER ${_PYTHON_PREFIX}_COMPILER-NOTFOUND CACHE INTERNAL "" FORCE) + endif() +endfunction() + + function (_PYTHON_FIND_RUNTIME_LIBRARY _PYTHON_LIB) string (REPLACE "_RUNTIME" "" _PYTHON_LIB "${_PYTHON_LIB}") # look at runtime part on systems supporting it @@ -181,19 +250,47 @@ else() # architecture unknown, search for natural interpreter set (_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES ipy) endif() +set (_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES net45 net40) # Apple frameworks handling -include (${CMAKE_CURRENT_LIST_DIR}/../CMakeFindFrameworks.cmake) -cmake_find_frameworks (Python) +_python_find_frameworks () + +# Save CMAKE_FIND_APPBUNDLE +if (DEFINED CMAKE_FIND_APPBUNDLE) + set (_${_PYTHON_PREFIX}_CMAKE_FIND_APPBUNDLE ${CMAKE_FIND_APPBUNDLE}) +else() + unset (_${_PYTHON_PREFIX}_CMAKE_FIND_APPBUNDLE) +endif() +# To avoid app bundle lookup +set (CMAKE_FIND_APPBUNDLE "NEVER") # Save CMAKE_FIND_FRAMEWORK if (DEFINED CMAKE_FIND_FRAMEWORK) set (_${_PYTHON_PREFIX}_CMAKE_FIND_FRAMEWORK ${CMAKE_FIND_FRAMEWORK}) + if (CMAKE_FIND_FRAMEWORK STREQUAL "ONLY") + message (AUTHOR_WARNING "Find${_PYTHON_PREFIX}: CMAKE_FIND_FRAMEWORK: 'ONLY' value is not supported. 'FIRST' will be used instead.") + set (_${_PYTHON_PREFIX}_FIND_FRAMEWORK "FIRST") + else() + set (_${_PYTHON_PREFIX}_FIND_FRAMEWORK ${CMAKE_FIND_FRAMEWORK}) + endif() else() unset (_${_PYTHON_PREFIX}_CMAKE_FIND_FRAMEWORK) + set (_${_PYTHON_PREFIX}_FIND_FRAMEWORK "FIRST") +endif() +# To avoid framework lookup +set (CMAKE_FIND_FRAMEWORK "NEVER") + +# Windows Registry handling +if (DEFINED ${_PYTHON_PREFIX}_FIND_REGISTRY) + if (NOT ${_PYTHON_PREFIX}_FIND_REGISTRY MATCHES "^(FIRST|LAST|NEVER)$") + message (AUTHOR_WARNING "Find${_PYTHON_PREFIX}: ${${_PYTHON_PREFIX}_FIND_REGISTRY}: invalid value for '${_PYTHON_PREFIX}_FIND_REGISTRY'. 'FIRST', 'LAST' or 'NEVER' expected.") + set (_${_PYTHON_PREFIX}_FIND_REGISTRY "FIRST") + else() + set (_${_PYTHON_PREFIX}_FIND_REGISTRY ${${_PYTHON_PREFIX}_FIND_REGISTRY}) + endif() +else() + set (_${_PYTHON_PREFIX}_FIND_REGISTRY "FIRST") endif() -# To avoid picking up the system elements pre-maturely. -set (CMAKE_FIND_FRAMEWORK LAST) unset (_${_PYTHON_PREFIX}_REQUIRED_VARS) @@ -215,22 +312,83 @@ if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) _python_get_frameworks (_${_PYTHON_PREFIX}_FRAMEWORK_PATHS ${_${_PYTHON_PREFIX}_VERSION}) + # Apple frameworks handling + if (APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "FIRST") + find_program (${_PYTHON_PREFIX}_EXECUTABLE + NAMES python${_${_PYTHON_PREFIX}_VERSION} + python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR} + NAMES_PER_DIR + PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS} + PATH_SUFFIXES bin + NO_CMAKE_PATH + NO_CMAKE_ENVIRONMENT_PATH + NO_SYSTEM_ENVIRONMENT_PATH + NO_CMAKE_SYSTEM_PATH) + endif() + + # Windows registry + if (WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "FIRST") + find_program (${_PYTHON_PREFIX}_EXECUTABLE + NAMES python${_${_PYTHON_PREFIX}_VERSION} + python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR} + python + ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES} + NAMES_PER_DIR + HINTS ${_${_PYTHON_PREFIX}_HINTS} + PATHS [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] + [HKEY_CURRENT_USER\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath] + [HKEY_CURRENT_USER\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH2}\\InstallPath] + [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] + [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath] + [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH2}\\InstallPath] + [HKEY_LOCAL_MACHINE\\SOFTWARE\\IronPython\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] + PATH_SUFFIXES bin ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES} + NO_SYSTEM_ENVIRONMENT_PATH + NO_CMAKE_SYSTEM_PATH) + endif() + # try using HINTS find_program (${_PYTHON_PREFIX}_EXECUTABLE NAMES python${_${_PYTHON_PREFIX}_VERSION} + python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR} + python + ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES} NAMES_PER_DIR HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS} PATH_SUFFIXES bin NO_SYSTEM_ENVIRONMENT_PATH NO_CMAKE_SYSTEM_PATH) - # try using registry - if (WIN32) + # try using standard paths. + # NAMES_PER_DIR is not defined on purpose to have a chance to find + # expected version. + # For example, typical systems have 'python' for version 2.* and 'python3' + # for version 3.*. So looking for names per dir will find, potentially, + # systematically 'python' (i.e. version 2) even if version 3 is searched. + find_program (${_PYTHON_PREFIX}_EXECUTABLE + NAMES python${_${_PYTHON_PREFIX}_VERSION} + python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR} + python + ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES}) + + # Apple frameworks handling + if (APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "LAST") find_program (${_PYTHON_PREFIX}_EXECUTABLE - NAMES python${_${_PYTHON_PREFIX}_VERSION} python + NAMES python${_${_PYTHON_PREFIX}_VERSION} + python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR} + NAMES_PER_DIR + PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS} + PATH_SUFFIXES bin + NO_DEFAULT_PATH) + endif() + + # Windows registry + if (WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "LAST") + find_program (${_PYTHON_PREFIX}_EXECUTABLE + NAMES python${_${_PYTHON_PREFIX}_VERSION} + python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR} + python ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES} NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_HINTS} PATHS [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] [HKEY_CURRENT_USER\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath] [HKEY_CURRENT_USER\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH2}\\InstallPath] @@ -238,27 +396,37 @@ if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath] [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH2}\\InstallPath] [HKEY_LOCAL_MACHINE\\SOFTWARE\\IronPython\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] - PATH_SUFFIXES bin - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) + PATH_SUFFIXES bin ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES} + NO_DEFAULT_PATH) endif() - # try in standard paths - find_program (${_PYTHON_PREFIX}_EXECUTABLE - NAMES python${_${_PYTHON_PREFIX}_VERSION}) - _python_validate_interpreter () + _python_validate_interpreter (${_${_PYTHON_PREFIX}_VERSION}) if (${_PYTHON_PREFIX}_EXECUTABLE) break() endif() endforeach() - # try more generic names if (NOT ${_PYTHON_PREFIX}_EXECUTABLE) + # No specific version found. Retry with generic names + # try using HINTS find_program (${_PYTHON_PREFIX}_EXECUTABLE - NAMES python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR} python + NAMES python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR} + python ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES} HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATH_SUFFIXES bin) + PATH_SUFFIXES bin ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES} + NO_SYSTEM_ENVIRONMENT_PATH + NO_CMAKE_SYSTEM_PATH) + # try using standard paths. + # NAMES_PER_DIR is not defined on purpose to have a chance to find + # expected version. + # For example, typical systems have 'python' for version 2.* and 'python3' + # for version 3.*. So looking for names per dir will find, potentially, + # systematically 'python' (i.e. version 2) even if version 3 is searched. + find_program (${_PYTHON_PREFIX}_EXECUTABLE + NAMES python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR} + python + ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES}) _python_validate_interpreter () endif() @@ -359,19 +527,42 @@ if ("Compiler" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) # 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) + endif() + 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) + + 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) + endif() + + _python_validate_compiler (${_${_PYTHON_PREFIX}_VERSION}) if (${_PYTHON_PREFIX}_COMPILER) break() endif() endforeach() - # try in standard paths + + # no specific version found, re-try in standard paths find_program (${_PYTHON_PREFIX}_COMPILER - NAMES ipyc) + NAMES ipyc + HINTS ${_${_PYTHON_PREFIX}_IRON_ROOT} ${_${_PYTHON_PREFIX}_HINTS} + PATH_SUFFIXES ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES}) if (${_PYTHON_PREFIX}_COMPILER) # retrieve python environment version from compiler @@ -483,6 +674,7 @@ if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS list (APPEND _${_PYTHON_PREFIX}_CONFIG_NAMES "python${_${_PYTHON_PREFIX}_VERSION}-config") find_program (_${_PYTHON_PREFIX}_CONFIG NAMES ${_${_PYTHON_PREFIX}_CONFIG_NAMES} + NAMES_PER_DIR HINTS ${_${_PYTHON_PREFIX}_HINTS} PATH_SUFFIXES bin) unset (_${_PYTHON_PREFIX}_CONFIG_NAMES) @@ -571,7 +763,54 @@ if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS _python_get_frameworks (_${_PYTHON_PREFIX}_FRAMEWORK_PATHS ${_${_PYTHON_PREFIX}_VERSION}) - # search first in known locations + set (_${_PYTHON_PREFIX}_REGISTRY_PATHS + [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] + [HKEY_CURRENT_USER\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath] + [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] + [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath]) + + if (APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "FIRST") + find_library (${_PYTHON_PREFIX}_LIBRARY_RELEASE + NAMES python${_${_PYTHON_PREFIX}_VERSION_NO_DOTS} + python${_${_PYTHON_PREFIX}_VERSION}mu + python${_${_PYTHON_PREFIX}_VERSION}m + python${_${_PYTHON_PREFIX}_VERSION}u + python${_${_PYTHON_PREFIX}_VERSION} + NAMES_PER_DIR + PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS} + PATH_SUFFIXES lib/${CMAKE_LIBRARY_ARCHITECTURE} lib libs + lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}mu + lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}m + lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}u + lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION} + lib/python${_${_PYTHON_PREFIX}_VERSION}/config + NO_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${_${_PYTHON_PREFIX}_VERSION_NO_DOTS} + python${_${_PYTHON_PREFIX}_VERSION}mu + python${_${_PYTHON_PREFIX}_VERSION}m + python${_${_PYTHON_PREFIX}_VERSION}u + python${_${_PYTHON_PREFIX}_VERSION} + NAMES_PER_DIR + HINTS ${_${_PYTHON_PREFIX}_HINTS} + PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS} + PATH_SUFFIXES lib/${CMAKE_LIBRARY_ARCHITECTURE} lib libs + lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}mu + lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}m + lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}u + lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION} + lib/python${_${_PYTHON_PREFIX}_VERSION}/config + NO_SYSTEM_ENVIRONMENT_PATH + NO_CMAKE_SYSTEM_PATH) + endif() + + # search in HINTS locations find_library (${_PYTHON_PREFIX}_LIBRARY_RELEASE NAMES python${_${_PYTHON_PREFIX}_VERSION_NO_DOTS} python${_${_PYTHON_PREFIX}_VERSION}mu @@ -580,11 +819,6 @@ if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS python${_${_PYTHON_PREFIX}_VERSION} NAMES_PER_DIR HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS} - [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] - [HKEY_CURRENT_USER\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath] - [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] - [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath] PATH_SUFFIXES lib/${CMAKE_LIBRARY_ARCHITECTURE} lib libs lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}mu lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}m @@ -593,6 +827,19 @@ if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS lib/python${_${_PYTHON_PREFIX}_VERSION}/config NO_SYSTEM_ENVIRONMENT_PATH NO_CMAKE_SYSTEM_PATH) + + if (APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "LAST") + set (__${_PYTHON_PREFIX}_FRAMEWORK_PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS}) + else() + unset (__${_PYTHON_PREFIX}_FRAMEWORK_PATHS) + endif() + + if (WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "LAST") + set (__${_PYTHON_PREFIX}_REGISTRY_PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS}) + else() + unset (__${_PYTHON_PREFIX}_REGISTRY_PATHS) + endif() + # search in all default paths find_library (${_PYTHON_PREFIX}_LIBRARY_RELEASE NAMES python${_${_PYTHON_PREFIX}_VERSION_NO_DOTS} @@ -601,6 +848,8 @@ if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS python${_${_PYTHON_PREFIX}_VERSION}u python${_${_PYTHON_PREFIX}_VERSION} NAMES_PER_DIR + PATHS ${__${_PYTHON_PREFIX}_FRAMEWORK_PATHS} + ${__${_PYTHON_PREFIX}_REGISTRY_PATHS} PATH_SUFFIXES lib/${CMAKE_LIBRARY_ARCHITECTURE} lib libs lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}mu lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}m @@ -618,11 +867,6 @@ if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS python${_${_PYTHON_PREFIX}_VERSION} NAMES_PER_DIR HINTS "${_${_PYTHON_PREFIX}_PATH}" ${_${_PYTHON_PREFIX}_HINTS} - PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS} - [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] - [HKEY_CURRENT_USER\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath] - [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] - [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath] PATH_SUFFIXES bin) endif() @@ -632,27 +876,28 @@ if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS # use library location as a hint get_filename_component (_${_PYTHON_PREFIX}_PATH "${${_PYTHON_PREFIX}_LIBRARY_RELEASE}" DIRECTORY) find_library (${_PYTHON_PREFIX}_LIBRARY_DEBUG - NAMES python${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}_d - NAMES_PER_DIR - HINTS "${_${_PYTHON_PREFIX}_PATH}" ${_${_PYTHON_PREFIX}_HINTS} - NO_DEFAULT_PATH) - else() - # search first in known locations - find_library (${_PYTHON_PREFIX}_LIBRARY_DEBUG NAMES python${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}_d NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATHS [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] - [HKEY_CURRENT_USER\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath] - [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] - [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath] - PATH_SUFFIXES lib libs - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) + 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${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}_d + NAMES_PER_DIR + HINTS ${_${_PYTHON_PREFIX}_HINTS} + 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${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}_d NAMES_PER_DIR + HINTS ${_${_PYTHON_PREFIX}_HINTS} + PATHS ${__${_PYTHON_PREFIX}_REGISTRY_PATHS} PATH_SUFFIXES lib libs) endif() if (${_PYTHON_PREFIX}_LIBRARY_DEBUG) @@ -661,10 +906,6 @@ if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS NAMES python${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}_d NAMES_PER_DIR HINTS "${_${_PYTHON_PREFIX}_PATH}" ${_${_PYTHON_PREFIX}_HINTS} - PATHS [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] - [HKEY_CURRENT_USER\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath] - [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] - [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath] PATH_SUFFIXES bin) endif() endif() @@ -672,6 +913,21 @@ if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS # Don't search for include dir until library location is known if (${_PYTHON_PREFIX}_LIBRARY_RELEASE OR ${_PYTHON_PREFIX}_LIBRARY_DEBUG) unset (_${_PYTHON_PREFIX}_INCLUDE_HINTS) + + if (${_PYTHON_PREFIX}_EXECUTABLE) + # pick up include directory from configuration + execute_process (COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -c + "import sys; import sysconfig; sys.stdout.write(sysconfig.get_path('include'))" + RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT + OUTPUT_VARIABLE _${_PYTHON_PREFIX}_PATH + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE) + if (NOT _${_PYTHON_PREFIX}_RESULT) + file (TO_CMAKE_PATH "${_${_PYTHON_PREFIX}_PATH}" _${_PYTHON_PREFIX}_PATH) + list (APPEND _${_PYTHON_PREFIX}_INCLUDE_HINTS "${_${_PYTHON_PREFIX}_PATH}") + endif() + endif() + 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 @@ -691,14 +947,41 @@ if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS endforeach() list (REMOVE_DUPLICATES _${_PYTHON_PREFIX}_INCLUDE_HINTS) + if (APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "FIRST") + find_path (${_PYTHON_PREFIX}_INCLUDE_DIR + NAMES Python.h + HINTS ${_${_PYTHON_PREFIX}_HINTS} + PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS} + PATH_SUFFIXES include/python${_${_PYTHON_PREFIX}_VERSION}mu + include/python${_${_PYTHON_PREFIX}_VERSION}m + include/python${_${_PYTHON_PREFIX}_VERSION}u + include/python${_${_PYTHON_PREFIX}_VERSION} + include + NO_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_path (${_PYTHON_PREFIX}_INCLUDE_DIR + NAMES Python.h + HINTS ${_${_PYTHON_PREFIX}_INCLUDE_HINTS} ${_${_PYTHON_PREFIX}_HINTS} + PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS} + PATH_SUFFIXES include/python${_${_PYTHON_PREFIX}_VERSION}mu + include/python${_${_PYTHON_PREFIX}_VERSION}m + include/python${_${_PYTHON_PREFIX}_VERSION}u + include/python${_${_PYTHON_PREFIX}_VERSION} + include + NO_SYSTEM_ENVIRONMENT_PATH + NO_CMAKE_SYSTEM_PATH) + endif() + find_path (${_PYTHON_PREFIX}_INCLUDE_DIR NAMES Python.h HINTS ${_${_PYTHON_PREFIX}_INCLUDE_HINTS} ${_${_PYTHON_PREFIX}_HINTS} - PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS} - [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] - [HKEY_CURRENT_USER\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath] - [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] - [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath] + PATHS ${__${_PYTHON_PREFIX}_FRAMEWORK_PATHS} + ${__${_PYTHON_PREFIX}_REGISTRY_PATHS} PATH_SUFFIXES include/python${_${_PYTHON_PREFIX}_VERSION}mu include/python${_${_PYTHON_PREFIX}_VERSION}m include/python${_${_PYTHON_PREFIX}_VERSION}u @@ -914,6 +1197,13 @@ endif() # final clean-up +# Restore CMAKE_FIND_APPBUNDLE +if (DEFINED _${_PYTHON_PREFIX}_CMAKE_FIND_APPBUNDLE) + set (CMAKE_FIND_APPBUNDLE ${_${_PYTHON_PREFIX}_CMAKE_FIND_APPBUNDLE}) + unset (_${_PYTHON_PREFIX}_CMAKE_FIND_APPBUNDLE) +else() + unset (CMAKE_FIND_APPBUNDLE) +endif() # Restore CMAKE_FIND_FRAMEWORK if (DEFINED _${_PYTHON_PREFIX}_CMAKE_FIND_FRAMEWORK) set (CMAKE_FIND_FRAMEWORK ${_${_PYTHON_PREFIX}_CMAKE_FIND_FRAMEWORK}) diff --git a/Modules/FindPython2.cmake b/Modules/FindPython2.cmake index 22e9a8f..2735a25 100644 --- a/Modules/FindPython2.cmake +++ b/Modules/FindPython2.cmake @@ -117,6 +117,25 @@ Hints * If set to TRUE, search **only** for static libraries. * If set to FALSE, search **only** for shared libraries. +``Python2_FIND_REGISTRY`` + On Windows the ``Python2_FIND_REGISTRY`` variable determine the order + of preference between registry and environment variables. + the ``Python2_FIND_REGISTRY`` variable can be set to empty or one of the + following: + + * ``FIRST``: Try to use registry before environment variables. + This is the default. + * ``LAST``: Try to use registry after environment variables. + * ``NEVER``: Never try to use registry. + +``CMAKE_FIND_FRAMEWORK`` + On macOS the :variable:`CMAKE_FIND_FRAMEWORK` variable determine the order of + preference between Apple-style and unix-style package components. + + .. note:: + + Value ``ONLY`` is not supported so ``FIRST`` will be used instead. + Commands ^^^^^^^^ diff --git a/Modules/FindPython3.cmake b/Modules/FindPython3.cmake index 99c159b..ed7e1a3 100644 --- a/Modules/FindPython3.cmake +++ b/Modules/FindPython3.cmake @@ -117,6 +117,25 @@ Hints * If set to TRUE, search **only** for static libraries. * If set to FALSE, search **only** for shared libraries. +``Python3_FIND_REGISTRY`` + On Windows the ``Python3_FIND_REGISTRY`` variable determine the order + of preference between registry and environment variables. + the ``Python3_FIND_REGISTRY`` variable can be set to empty or one of the + following: + + * ``FIRST``: Try to use registry before environment variables. + This is the default. + * ``LAST``: Try to use registry after environment variables. + * ``NEVER``: Never try to use registry. + +``CMAKE_FIND_FRAMEWORK`` + On OS X the :variable:`CMAKE_FIND_FRAMEWORK` variable determine the order of + preference between Apple-style and unix-style package components. + + .. note:: + + Value ``ONLY`` is not supported so ``FIRST`` will be used instead. + Commands ^^^^^^^^ diff --git a/Modules/Internal/CPack/CPackDeb.cmake b/Modules/Internal/CPack/CPackDeb.cmake index 4ef4539..ca3a004 100644 --- a/Modules/Internal/CPack/CPackDeb.cmake +++ b/Modules/Internal/CPack/CPackDeb.cmake @@ -10,6 +10,9 @@ if(CMAKE_BINARY_DIR) message(FATAL_ERROR "CPackDeb.cmake may only be used by CPack internally.") endif() +cmake_policy(PUSH) +cmake_policy(SET CMP0057 NEW) # if IN_LIST + function(cpack_deb_variable_fallback OUTPUT_VAR_NAME) set(FALLBACK_VAR_NAMES ${ARGN}) @@ -579,3 +582,5 @@ function(cpack_deb_prepare_package_vars) endfunction() cpack_deb_prepare_package_vars() + +cmake_policy(POP) diff --git a/Modules/Internal/CPack/CPackRPM.cmake b/Modules/Internal/CPack/CPackRPM.cmake index 06298d7..3bd5147 100644 --- a/Modules/Internal/CPack/CPackRPM.cmake +++ b/Modules/Internal/CPack/CPackRPM.cmake @@ -3,6 +3,9 @@ # Author: Eric Noulard with the help of Alexander Neundorf. +cmake_policy(PUSH) +cmake_policy(SET CMP0057 NEW) # if IN_LIST + function(get_file_permissions FILE RETURN_VAR) execute_process(COMMAND ls -l ${FILE} OUTPUT_VARIABLE permissions_ @@ -1865,3 +1868,5 @@ mv %_topdir/tmpBBroot $RPM_BUILD_ROOT endfunction() cpack_rpm_generate_package() + +cmake_policy(POP) diff --git a/Modules/Platform/Android-Determine.cmake b/Modules/Platform/Android-Determine.cmake index e623902..bb42eed 100644 --- a/Modules/Platform/Android-Determine.cmake +++ b/Modules/Platform/Android-Determine.cmake @@ -18,6 +18,9 @@ if(CMAKE_SYSTEM_VERSION EQUAL 1) return() endif() +cmake_policy(PUSH) +cmake_policy(SET CMP0057 NEW) # if IN_LIST + # If the user provided CMAKE_SYSROOT for us, extract information from it. set(_ANDROID_SYSROOT_NDK "") set(_ANDROID_SYSROOT_API "") @@ -371,3 +374,5 @@ endif() # Report the chosen architecture. message(STATUS "Android: Targeting API '${CMAKE_SYSTEM_VERSION}' with architecture '${CMAKE_ANDROID_ARCH}', ABI '${CMAKE_ANDROID_ARCH_ABI}', and processor '${CMAKE_SYSTEM_PROCESSOR}'") + +cmake_policy(POP) diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 1819564..d0cce8b 100644 --- a/Source/CMakeVersion.cmake +++ b/Source/CMakeVersion.cmake @@ -1,5 +1,5 @@ # CMake version number components. set(CMake_VERSION_MAJOR 3) set(CMake_VERSION_MINOR 12) -set(CMake_VERSION_PATCH 20180912) +set(CMake_VERSION_PATCH 20180918) #set(CMake_VERSION_RC 1) diff --git a/Source/CTest/cmCTestMultiProcessHandler.cxx b/Source/CTest/cmCTestMultiProcessHandler.cxx index 54b4be2..3e0c1ac 100644 --- a/Source/CTest/cmCTestMultiProcessHandler.cxx +++ b/Source/CTest/cmCTestMultiProcessHandler.cxx @@ -56,7 +56,6 @@ cmCTestMultiProcessHandler::cmCTestMultiProcessHandler() this->RunningCount = 0; this->ProcessorsAvailable = cmAffinity::GetProcessorsAvailable(); this->HaveAffinity = this->ProcessorsAvailable.size(); - this->StopTimePassed = false; this->HasCycles = false; this->SerialTestRunning = false; } @@ -130,17 +129,6 @@ void cmCTestMultiProcessHandler::RunTests() bool cmCTestMultiProcessHandler::StartTestProcess(int test) { - std::chrono::system_clock::time_point stop_time = this->CTest->GetStopTime(); - if (stop_time != std::chrono::system_clock::time_point() && - stop_time <= std::chrono::system_clock::now()) { - cmCTestLog(this->CTest, ERROR_MESSAGE, - "The stop time has been passed. " - "Stopping all tests." - << std::endl); - this->StopTimePassed = true; - return false; - } - if (this->HaveAffinity && this->Properties[test]->WantAffinity) { size_t needProcessors = this->GetProcessorsUsed(test); if (needProcessors > this->ProcessorsAvailable.size()) { @@ -199,6 +187,30 @@ bool cmCTestMultiProcessHandler::StartTestProcess(int test) return false; } +bool cmCTestMultiProcessHandler::CheckStopTimePassed() +{ + if (!this->StopTimePassed) { + std::chrono::system_clock::time_point stop_time = + this->CTest->GetStopTime(); + if (stop_time != std::chrono::system_clock::time_point() && + stop_time <= std::chrono::system_clock::now()) { + this->SetStopTimePassed(); + } + } + return this->StopTimePassed; +} + +void cmCTestMultiProcessHandler::SetStopTimePassed() +{ + if (!this->StopTimePassed) { + cmCTestLog(this->CTest, ERROR_MESSAGE, + "The stop time has been passed. " + "Stopping all tests." + << std::endl); + this->StopTimePassed = true; + } +} + void cmCTestMultiProcessHandler::LockResources(int index) { this->LockedResources.insert( @@ -279,6 +291,10 @@ void cmCTestMultiProcessHandler::StartNextTests() return; } + if (this->CheckStopTimePassed()) { + return; + } + size_t numToStart = 0; if (this->RunningCount < this->ParallelLevel) { @@ -358,10 +374,6 @@ void cmCTestMultiProcessHandler::StartNextTests() } if (testLoadOk && processors <= numToStart && this->StartTest(test)) { - if (this->StopTimePassed) { - return; - } - numToStart -= processors; } else if (numToStart == 0) { break; @@ -424,8 +436,11 @@ void cmCTestMultiProcessHandler::FinishTestProcess(cmCTestRunTest* runner, auto properties = runner->GetTestProperties(); bool testResult = runner->EndTest(this->Completed, this->Total, started); + if (runner->TimedOutForStopTime()) { + this->SetStopTimePassed(); + } if (started) { - if (runner->StartAgain()) { + if (!this->StopTimePassed && runner->StartAgain()) { this->Completed--; // remove the completed test because run again return; } diff --git a/Source/CTest/cmCTestMultiProcessHandler.h b/Source/CTest/cmCTestMultiProcessHandler.h index 07a5fe7..3927a8a 100644 --- a/Source/CTest/cmCTestMultiProcessHandler.h +++ b/Source/CTest/cmCTestMultiProcessHandler.h @@ -113,6 +113,9 @@ protected: inline size_t GetProcessorsUsed(int index); std::string GetName(int index); + bool CheckStopTimePassed(); + void SetStopTimePassed(); + void LockResources(int index); void UnlockResources(int index); // map from test number to set of depend tests @@ -125,7 +128,7 @@ protected: size_t RunningCount; std::set<size_t> ProcessorsAvailable; size_t HaveAffinity; - bool StopTimePassed; + bool StopTimePassed = false; // list of test properties (indices concurrent to the test map) PropertiesMap Properties; std::map<int, bool> TestRunningMap; diff --git a/Source/CTest/cmCTestRunTest.cxx b/Source/CTest/cmCTestRunTest.cxx index ef0a49d..23d4616 100644 --- a/Source/CTest/cmCTestRunTest.cxx +++ b/Source/CTest/cmCTestRunTest.cxx @@ -140,6 +140,9 @@ bool cmCTestRunTest::EndTest(size_t completed, size_t total, bool started) bool passed = true; cmProcess::State res = started ? this->TestProcess->GetProcessStatus() : cmProcess::State::Error; + if (res != cmProcess::State::Expired) { + this->TimeoutIsForStopTime = false; + } int retVal = this->TestProcess->GetExitValue(); bool forceFail = false; bool skipped = false; @@ -537,6 +540,7 @@ bool cmCTestRunTest::StartTest(size_t total) auto timeout = this->TestProperties->Timeout; + this->TimeoutIsForStopTime = false; std::chrono::system_clock::time_point stop_time = this->CTest->GetStopTime(); if (stop_time != std::chrono::system_clock::time_point()) { std::chrono::duration<double> stop_timeout = @@ -547,6 +551,7 @@ bool cmCTestRunTest::StartTest(size_t total) } if (timeout == std::chrono::duration<double>::zero() || stop_timeout < timeout) { + this->TimeoutIsForStopTime = true; timeout = stop_timeout; } } diff --git a/Source/CTest/cmCTestRunTest.h b/Source/CTest/cmCTestRunTest.h index 3b1d674..7e80157 100644 --- a/Source/CTest/cmCTestRunTest.h +++ b/Source/CTest/cmCTestRunTest.h @@ -80,6 +80,8 @@ public: void FinalizeTest(); + bool TimedOutForStopTime() const { return this->TimeoutIsForStopTime; } + private: bool NeedsToRerun(); void DartProcessing(); @@ -92,6 +94,7 @@ private: void MemCheckPostProcess(); cmCTestTestHandler::cmCTestTestProperties* TestProperties; + bool TimeoutIsForStopTime = false; // Pointer back to the "parent"; the handler that invoked this test run cmCTestTestHandler* TestHandler; cmCTest* CTest; diff --git a/Source/cmExportBuildAndroidMKGenerator.cxx b/Source/cmExportBuildAndroidMKGenerator.cxx index 3d32b84..d12ad7f 100644 --- a/Source/cmExportBuildAndroidMKGenerator.cxx +++ b/Source/cmExportBuildAndroidMKGenerator.cxx @@ -8,11 +8,8 @@ #include <utility> #include "cmAlgorithms.h" -#include "cmGeneratorExpression.h" -#include "cmGeneratorExpressionDAGChecker.h" #include "cmGeneratorTarget.h" #include "cmLinkItem.h" -#include "cmLocalGenerator.h" #include "cmMakefile.h" #include "cmPolicies.h" #include "cmStateTypes.h" @@ -104,27 +101,14 @@ void cmExportBuildAndroidMKGenerator::GenerateInterfaceProperties( os << "LOCAL_CPP_FEATURES += "; os << (property.second) << "\n"; } else if (property.first == "INTERFACE_LINK_LIBRARIES") { - // evaluate any generator expressions with the current - // build type of the makefile - cmGeneratorExpression ge; - cmGeneratorExpressionDAGChecker dagChecker( - target, "INTERFACE_LINK_LIBRARIES", nullptr, nullptr); - std::unique_ptr<cmCompiledGeneratorExpression> cge = - ge.Parse(property.second); - std::string evaluated = cge->Evaluate( - target->GetLocalGenerator(), config, false, target, &dagChecker); - // need to look at list in pi->second and see if static or shared - // FindTargetToLink - // target->GetLocalGenerator()->FindGeneratorTargetToUse() - // then add to LOCAL_CPPFLAGS - std::vector<std::string> libraries; - cmSystemTools::ExpandListArgument(evaluated, libraries); std::string staticLibs; std::string sharedLibs; std::string ldlibs; - for (std::string const& lib : libraries) { - cmGeneratorTarget* gt = - target->GetLocalGenerator()->FindGeneratorTargetToUse(lib); + cmLinkInterfaceLibraries const* linkIFace = + target->GetLinkInterfaceLibraries(config, target, false); + for (cmLinkItem const& item : linkIFace->Libraries) { + cmGeneratorTarget const* gt = item.Target; + std::string const& lib = item.AsStr(); if (gt) { if (gt->GetType() == cmStateEnums::SHARED_LIBRARY || diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx index d440080..d6573b8 100644 --- a/Source/cmExportFileGenerator.cxx +++ b/Source/cmExportFileGenerator.cxx @@ -567,14 +567,17 @@ bool cmExportFileGenerator::AddTargetNamespace( std::string& input, cmGeneratorTarget* target, std::vector<std::string>& missingTargets) { - cmLocalGenerator* lg = target->GetLocalGenerator(); + cmGeneratorTarget::TargetOrString resolved = + target->ResolveTargetReference(input); - cmGeneratorTarget* tgt = lg->FindGeneratorTargetToUse(input); + cmGeneratorTarget* tgt = resolved.Target; if (!tgt) { + input = resolved.String; return false; } if (tgt->IsImported()) { + input = tgt->GetName(); return true; } if (this->ExportedTargets.find(tgt) != this->ExportedTargets.end()) { @@ -584,6 +587,8 @@ bool cmExportFileGenerator::AddTargetNamespace( this->HandleMissingTarget(namespacedTarget, missingTargets, target, tgt); if (!namespacedTarget.empty()) { input = namespacedTarget; + } else { + input = tgt->GetName(); } } return true; diff --git a/Source/cmGeneratorExpressionNode.cxx b/Source/cmGeneratorExpressionNode.cxx index 54e33c5..f901215 100644 --- a/Source/cmGeneratorExpressionNode.cxx +++ b/Source/cmGeneratorExpressionNode.cxx @@ -1056,7 +1056,9 @@ std::string getLinkedTargetsContent( // Don't follow such link interface entries so as not to create a // self-referencing loop. if (l.Target && l.Target != target) { - depString += sep + "$<TARGET_PROPERTY:" + l.Target->GetName() + "," + + std::string uniqueName = + target->GetGlobalGenerator()->IndexGeneratorTargetUniquely(l.Target); + depString += sep + "$<TARGET_PROPERTY:" + std::move(uniqueName) + "," + interfacePropertyName + ">"; sep = ";"; } diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index f563dd8..e2824e8 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -818,8 +818,11 @@ static void AddInterfaceEntries( thisTarget->GetLinkImplementationLibraries(config)) { for (cmLinkImplItem const& lib : impl->Libraries) { if (lib.Target) { + std::string uniqueName = + thisTarget->GetGlobalGenerator()->IndexGeneratorTargetUniquely( + lib.Target); std::string genex = - "$<TARGET_PROPERTY:" + lib.AsStr() + "," + prop + ">"; + "$<TARGET_PROPERTY:" + std::move(uniqueName) + "," + prop + ">"; cmGeneratorExpression ge(lib.Backtrace); std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(genex); cge->SetEvaluateForBuildsystem(true); @@ -839,7 +842,10 @@ static void AddObjectEntries( for (cmLinkImplItem const& lib : impl->Libraries) { if (lib.Target && lib.Target->GetType() == cmStateEnums::OBJECT_LIBRARY) { - std::string genex = "$<TARGET_OBJECTS:" + lib.AsStr() + ">"; + std::string uniqueName = + thisTarget->GetGlobalGenerator()->IndexGeneratorTargetUniquely( + lib.Target); + std::string genex = "$<TARGET_OBJECTS:" + std::move(uniqueName) + ">"; cmGeneratorExpression ge(lib.Backtrace); std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(genex); cge->SetEvaluateForBuildsystem(true); @@ -5639,24 +5645,65 @@ void cmGeneratorTarget::ComputeLinkImplementationLibraries( } } +cmGeneratorTarget::TargetOrString cmGeneratorTarget::ResolveTargetReference( + std::string const& name) const +{ + cmLocalGenerator const* lg = this->LocalGenerator; + std::string const* lookupName = &name; + + // When target_link_libraries() is called with a LHS target that is + // not created in the calling directory it adds a directory id suffix + // that we can use to look up the calling directory. It is that scope + // in which the item name is meaningful. This case is relatively rare + // so we allocate a separate string only when the directory id is present. + std::string::size_type pos = name.find(CMAKE_DIRECTORY_ID_SEP); + std::string plainName; + if (pos != std::string::npos) { + // We will look up the plain name without the directory id suffix. + plainName = name.substr(0, pos); + + // We will look up in the scope of the directory id. + // If we do not recognize the id then leave the original + // syntax in place to produce an indicative error later. + cmDirectoryId const dirId = + name.substr(pos + sizeof(CMAKE_DIRECTORY_ID_SEP) - 1); + if (cmLocalGenerator const* otherLG = + this->GlobalGenerator->FindLocalGenerator(dirId)) { + lg = otherLG; + lookupName = &plainName; + } + } + + TargetOrString resolved; + + if (cmGeneratorTarget* tgt = lg->FindGeneratorTargetToUse(*lookupName)) { + resolved.Target = tgt; + } else if (lookupName == &plainName) { + resolved.String = std::move(plainName); + } else { + resolved.String = name; + } + + return resolved; +} + cmLinkItem cmGeneratorTarget::ResolveLinkItem(std::string const& name) const { - cmGeneratorTarget* tgt = - this->LocalGenerator->FindGeneratorTargetToUse(name); + TargetOrString resolved = this->ResolveTargetReference(name); + + if (!resolved.Target) { + return cmLinkItem(resolved.String); + } // Skip targets that will not really be linked. This is probably a // name conflict between an external library and an executable // within the project. - if (tgt && tgt->GetType() == cmStateEnums::EXECUTABLE && - !tgt->IsExecutableWithExports()) { - tgt = nullptr; - } - - if (tgt) { - return cmLinkItem(tgt); + if (resolved.Target->GetType() == cmStateEnums::EXECUTABLE && + !resolved.Target->IsExecutableWithExports()) { + return cmLinkItem(resolved.Target->GetName()); } - return cmLinkItem(name); + return cmLinkItem(resolved.Target); } std::string cmGeneratorTarget::GetPDBDirectory(const std::string& config) const diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h index a847e21..9d8c9f5 100644 --- a/Source/cmGeneratorTarget.h +++ b/Source/cmGeneratorTarget.h @@ -357,6 +357,13 @@ public: cmOptionalLinkImplementation& impl, const cmGeneratorTarget* head) const; + struct TargetOrString + { + std::string String; + cmGeneratorTarget* Target = nullptr; + }; + TargetOrString ResolveTargetReference(std::string const& name) const; + cmLinkItem ResolveLinkItem(std::string const& name) const; // Compute the set of languages compiled by the target. This is diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index f504b9f..1dd20b6 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -1140,11 +1140,14 @@ void cmGlobalGenerator::ClearEnabledLanguages() void cmGlobalGenerator::CreateLocalGenerators() { + this->LocalGeneratorSearchIndex.clear(); cmDeleteAll(this->LocalGenerators); this->LocalGenerators.clear(); this->LocalGenerators.reserve(this->Makefiles.size()); for (cmMakefile* m : this->Makefiles) { - this->LocalGenerators.push_back(this->CreateLocalGenerator(m)); + cmLocalGenerator* lg = this->CreateLocalGenerator(m); + this->LocalGenerators.push_back(lg); + this->IndexLocalGenerator(lg); } } @@ -1662,6 +1665,7 @@ void cmGlobalGenerator::ClearGeneratorMembers() this->TargetSearchIndex.clear(); this->GeneratorTargetSearchIndex.clear(); this->MakefileSearchIndex.clear(); + this->LocalGeneratorSearchIndex.clear(); this->ProjectMap.clear(); this->RuleHashes.clear(); this->DirectoryContentMap.clear(); @@ -2131,15 +2135,13 @@ cmMakefile* cmGlobalGenerator::FindMakefile(const std::string& start_dir) const return nullptr; } -///! Find a local generator by its startdirectory cmLocalGenerator* cmGlobalGenerator::FindLocalGenerator( - const std::string& start_dir) const + cmDirectoryId const& id) const { - for (cmLocalGenerator* lg : this->LocalGenerators) { - std::string sd = lg->GetCurrentSourceDirectory(); - if (sd == start_dir) { - return lg; - } + LocalGeneratorMap::const_iterator i = + this->LocalGeneratorSearchIndex.find(id.String); + if (i != this->LocalGeneratorSearchIndex.end()) { + return i->second; } return nullptr; } @@ -2169,6 +2171,24 @@ void cmGlobalGenerator::IndexGeneratorTarget(cmGeneratorTarget* gt) } } +std::string cmGlobalGenerator::IndexGeneratorTargetUniquely( + cmGeneratorTarget const* gt) +{ + // Use the pointer value to uniquely identify the target instance. + // Use a "T" prefix to indicate that this identifier is for a target. + // We must satisfy cmGeneratorExpression::IsValidTargetName so use no + // other special characters. + char buf[64]; + sprintf(buf, "::T%p", + static_cast<void const*>(gt)); // cast avoids format warning + std::string id = gt->GetName() + buf; + // We internally index pointers to non-const generator targets + // but our callers only have pointers to const generator targets. + // They will give up non-const privileges when looking up anyway. + this->GeneratorTargetSearchIndex[id] = const_cast<cmGeneratorTarget*>(gt); + return id; +} + void cmGlobalGenerator::IndexMakefile(cmMakefile* mf) { // FIXME: add_subdirectory supports multiple build directories @@ -2180,6 +2200,12 @@ void cmGlobalGenerator::IndexMakefile(cmMakefile* mf) MakefileMap::value_type(mf->GetCurrentSourceDirectory(), mf)); } +void cmGlobalGenerator::IndexLocalGenerator(cmLocalGenerator* lg) +{ + cmDirectoryId id = lg->GetMakefile()->GetDirectoryId(); + this->LocalGeneratorSearchIndex[id.String] = lg; +} + cmTarget* cmGlobalGenerator::FindTargetImpl(std::string const& name) const { TargetMap::const_iterator i = this->TargetSearchIndex.find(name); diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h index 8924772..1ea2d24 100644 --- a/Source/cmGlobalGenerator.h +++ b/Source/cmGlobalGenerator.h @@ -26,6 +26,9 @@ # include "cmFileLockPool.h" #endif +#define CMAKE_DIRECTORY_ID_SEP "::@" + +class cmDirectoryId; class cmExportBuildFileGenerator; class cmExternalMakefileProjectGenerator; class cmGeneratorTarget; @@ -284,8 +287,7 @@ public: bool NameResolvesToFramework(const std::string& libname) const; cmMakefile* FindMakefile(const std::string& start_dir) const; - ///! Find a local generator by its startdirectory - cmLocalGenerator* FindLocalGenerator(const std::string& start_dir) const; + cmLocalGenerator* FindLocalGenerator(cmDirectoryId const& id) const; /** Append the subdirectory for the given configuration. If anything is appended the given prefix and suffix will be appended around it, which @@ -305,6 +307,10 @@ public: void IndexTarget(cmTarget* t); void IndexGeneratorTarget(cmGeneratorTarget* gt); + // Index the target using a name that is unique to that target + // even if other targets have the same name. + std::string IndexGeneratorTargetUniquely(cmGeneratorTarget const* gt); + static bool IsReservedTarget(std::string const& name); virtual const char* GetAllTargetName() const { return "ALL_BUILD"; } @@ -514,6 +520,7 @@ private: typedef std::unordered_map<std::string, cmGeneratorTarget*> GeneratorTargetMap; typedef std::unordered_map<std::string, cmMakefile*> MakefileMap; + typedef std::unordered_map<std::string, cmLocalGenerator*> LocalGeneratorMap; // Map efficiently from target name to cmTarget instance. // Do not use this structure for looping over all targets. // It contains both normal and globally visible imported targets. @@ -525,6 +532,11 @@ private: // It may not contain all of them (see note in IndexMakefile method). MakefileMap MakefileSearchIndex; + // Map efficiently from source directory path to cmLocalGenerator instance. + // Do not use this structure for looping over all directories. + // Its order is not deterministic. + LocalGeneratorMap LocalGeneratorSearchIndex; + cmMakefile* TryCompileOuterMakefile; // If you add a new map here, make sure it is copied // in EnableLanguagesFromGenerator @@ -583,6 +595,7 @@ private: std::string const& reason) const; void IndexMakefile(cmMakefile* mf); + void IndexLocalGenerator(cmLocalGenerator* lg); virtual const char* GetBuildIgnoreErrorsFlag() const { return nullptr; } diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index 26cc10d..ec5ce92 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -11,6 +11,7 @@ #include <iterator> #include <memory> // IWYU pragma: keep #include <sstream> +#include <stdio.h> #include <stdlib.h> #include <utility> @@ -48,6 +49,11 @@ class cmMessenger; +cmDirectoryId::cmDirectoryId(std::string s) + : String(std::move(s)) +{ +} + // default is not to be building executables cmMakefile::cmMakefile(cmGlobalGenerator* globalGenerator, cmStateSnapshot const& snapshot) @@ -111,6 +117,17 @@ cmMakefile::~cmMakefile() cmDeleteAll(this->EvaluationFiles); } +cmDirectoryId cmMakefile::GetDirectoryId() const +{ + // Use the instance pointer value to uniquely identify this directory. + // If we ever need to expose this to CMake language code we should + // add a read-only property in cmMakefile::GetProperty. + char buf[32]; + sprintf(buf, "<%p>", + static_cast<void const*>(this)); // cast avoids format warning + return std::string(buf); +} + void cmMakefile::IssueMessage(cmake::MessageType t, std::string const& text) const { diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h index 8c7eb31..bb01c0b 100644 --- a/Source/cmMakefile.h +++ b/Source/cmMakefile.h @@ -47,6 +47,14 @@ class cmTest; class cmTestGenerator; class cmVariableWatch; +/** A type-safe wrapper for a string representing a directory id. */ +class cmDirectoryId +{ +public: + cmDirectoryId(std::string s); + std::string String; +}; + /** \class cmMakefile * \brief Process the input CMakeLists.txt file. * @@ -75,6 +83,8 @@ public: */ ~cmMakefile(); + cmDirectoryId GetDirectoryId() const; + bool ReadListFile(const char* filename); bool ReadDependentFile(const char* filename, bool noPolicyScope = true); diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h index 91ed924..4ffe803 100644 --- a/Source/cmPolicies.h +++ b/Source/cmPolicies.h @@ -230,7 +230,11 @@ class cmMakefile; SELECT(POLICY, CMP0077, "option() honors normal variables.", 3, 13, 0, \ cmPolicies::WARN) \ SELECT(POLICY, CMP0078, "UseSWIG generates standard target names.", 3, 13, \ - 0, cmPolicies::WARN) + 0, cmPolicies::WARN) \ + SELECT( \ + POLICY, CMP0079, \ + "target_link_libraries allows use with targets in other directories.", 3, \ + 13, 0, cmPolicies::WARN) #define CM_SELECT_ID(F, A1, A2, A3, A4, A5, A6) F(A1) #define CM_FOR_EACH_POLICY_ID(POLICY) \ diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 703c552..4e353c7 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -743,20 +743,27 @@ void cmTarget::GetTllSignatureTraces(std::ostream& s, TLLSignature sig) const void cmTarget::AddLinkLibrary(cmMakefile& mf, const std::string& lib, cmTargetLinkLibraryType llt) { - cmTarget* tgt = this->Makefile->FindTargetToUse(lib); + this->AddLinkLibrary(mf, lib, lib, llt); +} + +void cmTarget::AddLinkLibrary(cmMakefile& mf, std::string const& lib, + std::string const& libRef, + cmTargetLinkLibraryType llt) +{ + cmTarget* tgt = mf.FindTargetToUse(lib); { const bool isNonImportedTarget = tgt && !tgt->IsImported(); const std::string libName = (isNonImportedTarget && llt != GENERAL_LibraryType) - ? targetNameGenex(lib) - : lib; + ? targetNameGenex(libRef) + : libRef; this->AppendProperty( "LINK_LIBRARIES", this->GetDebugGeneratorExpressions(libName, llt).c_str()); } - if (cmGeneratorExpression::Find(lib) != std::string::npos || + if (cmGeneratorExpression::Find(lib) != std::string::npos || lib != libRef || (tgt && (tgt->GetType() == cmStateEnums::INTERFACE_LIBRARY || tgt->GetType() == cmStateEnums::OBJECT_LIBRARY)) || diff --git a/Source/cmTarget.h b/Source/cmTarget.h index 7a3ab65..1f380df 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h @@ -142,6 +142,9 @@ public: void AddLinkLibrary(cmMakefile& mf, const std::string& lib, cmTargetLinkLibraryType llt); + void AddLinkLibrary(cmMakefile& mf, std::string const& lib, + std::string const& libRef, cmTargetLinkLibraryType llt); + enum TLLSignature { KeywordTLLSignature, diff --git a/Source/cmTargetLinkLibrariesCommand.cxx b/Source/cmTargetLinkLibrariesCommand.cxx index 1bbcf46..ad33f98 100644 --- a/Source/cmTargetLinkLibrariesCommand.cxx +++ b/Source/cmTargetLinkLibrariesCommand.cxx @@ -359,30 +359,53 @@ bool cmTargetLinkLibrariesCommand::HandleLibrary(const std::string& lib, } } + bool warnRemoteInterface = false; + bool rejectRemoteLinking = false; + bool encodeRemoteReference = false; + if (this->Makefile != this->Target->GetMakefile()) { + // The LHS target was created in another directory. + switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0079)) { + case cmPolicies::WARN: + warnRemoteInterface = true; + CM_FALLTHROUGH; + case cmPolicies::OLD: + rejectRemoteLinking = true; + break; + case cmPolicies::REQUIRED_ALWAYS: + case cmPolicies::REQUIRED_IF_USED: + case cmPolicies::NEW: + encodeRemoteReference = true; + break; + } + } + + std::string libRef; + if (encodeRemoteReference && !cmSystemTools::FileIsFullPath(lib)) { + // This is a library name added by a caller that is not in the + // same directory as the target was created. Add a suffix to + // the name to tell ResolveLinkItem to look up the name in the + // caller's directory. + cmDirectoryId const dirId = this->Makefile->GetDirectoryId(); + libRef = lib + CMAKE_DIRECTORY_ID_SEP + dirId.String; + } else { + // This is an absolute path or a library name added by a caller + // in the same directory as the target was created. We can use + // the original name directly. + libRef = lib; + } + // Handle normal case where the command was called with another keyword than // INTERFACE / LINK_INTERFACE_LIBRARIES or none at all. (The "LINK_LIBRARIES" // property of the target on the LHS shall be populated.) if (this->CurrentProcessingState != ProcessingKeywordLinkInterface && this->CurrentProcessingState != ProcessingPlainLinkInterface) { - // Assure that the target on the LHS was created in the current directory. - cmTarget* t = - this->Makefile->FindLocalNonAliasTarget(this->Target->GetName()); - if (!t) { - const std::vector<cmTarget*>& importedTargets = - this->Makefile->GetOwnedImportedTargets(); - for (cmTarget* importedTarget : importedTargets) { - if (importedTarget->GetName() == this->Target->GetName()) { - t = importedTarget; - break; - } - } - } - if (!t) { + if (rejectRemoteLinking) { std::ostringstream e; e << "Attempt to add link library \"" << lib << "\" to target \"" << this->Target->GetName() - << "\" which is not built in this directory."; + << "\" which is not built in this directory.\n" + << "This is allowed only when policy CMP0079 is set to NEW."; this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str()); return false; } @@ -404,7 +427,20 @@ bool cmTargetLinkLibrariesCommand::HandleLibrary(const std::string& lib, this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str()); } - this->Target->AddLinkLibrary(*this->Makefile, lib, llt); + this->Target->AddLinkLibrary(*this->Makefile, lib, libRef, llt); + } + + if (warnRemoteInterface) { + std::ostringstream w; + /* clang-format off */ + w << cmPolicies::GetPolicyWarning(cmPolicies::CMP0079) << "\n" + "Target\n " << this->Target->GetName() << "\nis not created in this " + "directory. For compatibility with older versions of CMake, link " + "library\n " << lib << "\nwill be looked up in the directory in " + "which the target was created rather than in this calling " + "directory."; + /* clang-format on */ + this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, w.str()); } // Handle (additional) case where the command was called with PRIVATE / @@ -415,9 +451,9 @@ bool cmTargetLinkLibrariesCommand::HandleLibrary(const std::string& lib, this->CurrentProcessingState == ProcessingPlainPrivateInterface) { if (this->Target->GetType() == cmStateEnums::STATIC_LIBRARY) { std::string configLib = - this->Target->GetDebugGeneratorExpressions(lib, llt); - if (cmGeneratorExpression::IsValidTargetName(lib) || - cmGeneratorExpression::Find(lib) != std::string::npos) { + this->Target->GetDebugGeneratorExpressions(libRef, llt); + if (cmGeneratorExpression::IsValidTargetName(libRef) || + cmGeneratorExpression::Find(libRef) != std::string::npos) { configLib = "$<LINK_ONLY:" + configLib + ">"; } this->Target->AppendProperty("INTERFACE_LINK_LIBRARIES", @@ -431,7 +467,7 @@ bool cmTargetLinkLibrariesCommand::HandleLibrary(const std::string& lib, // property of the target on the LHS shall be populated.) this->Target->AppendProperty( "INTERFACE_LINK_LIBRARIES", - this->Target->GetDebugGeneratorExpressions(lib, llt).c_str()); + this->Target->GetDebugGeneratorExpressions(libRef, llt).c_str()); // Stop processing if called without any keyword. if (this->CurrentProcessingState == ProcessingLinkLibraries) { @@ -464,12 +500,12 @@ bool cmTargetLinkLibrariesCommand::HandleLibrary(const std::string& lib, for (std::string const& dc : debugConfigs) { prop = "LINK_INTERFACE_LIBRARIES_"; prop += dc; - this->Target->AppendProperty(prop, lib.c_str()); + this->Target->AppendProperty(prop, libRef.c_str()); } } if (llt == OPTIMIZED_LibraryType || llt == GENERAL_LibraryType) { // Put in the non-DEBUG configuration interfaces. - this->Target->AppendProperty("LINK_INTERFACE_LIBRARIES", lib.c_str()); + this->Target->AppendProperty("LINK_INTERFACE_LIBRARIES", libRef.c_str()); // Make sure the DEBUG configuration interfaces exist so that the // general one will not be used as a fall-back. diff --git a/Source/cmTargetLinkOptionsCommand.cxx b/Source/cmTargetLinkOptionsCommand.cxx index f0f13fd..d6ed5ae 100644 --- a/Source/cmTargetLinkOptionsCommand.cxx +++ b/Source/cmTargetLinkOptionsCommand.cxx @@ -33,9 +33,9 @@ std::string cmTargetLinkOptionsCommand::Join( } bool cmTargetLinkOptionsCommand::HandleDirectContent( - cmTarget* tgt, const std::vector<std::string>& content, bool, bool) + cmTarget* tgt, const std::vector<std::string>& content, bool prepend, bool) { cmListFileBacktrace lfbt = this->Makefile->GetBacktrace(); - tgt->InsertLinkOption(this->Join(content), lfbt); + tgt->InsertLinkOption(this->Join(content), lfbt, prepend); return true; // Successfully handled. } diff --git a/Source/kwsys/ProcessWin32.c b/Source/kwsys/ProcessWin32.c index 9fa0cb1..2a2e737 100644 --- a/Source/kwsys/ProcessWin32.c +++ b/Source/kwsys/ProcessWin32.c @@ -973,8 +973,8 @@ void kwsysProcess_Execute(kwsysProcess* cp) wchar_t* wstdin = kwsysEncoding_DupToWide(cp->PipeFileSTDIN); DWORD error; cp->PipeChildStd[0] = - CreateFileW(wstdin, GENERIC_READ | GENERIC_WRITE, - FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0); + CreateFileW(wstdin, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, + OPEN_EXISTING, 0, 0); error = GetLastError(); /* Check now in case free changes this. */ free(wstdin); if (cp->PipeChildStd[0] == INVALID_HANDLE_VALUE) { diff --git a/Source/kwsys/SystemTools.cxx b/Source/kwsys/SystemTools.cxx index 476fe08..0a4ad7a 100644 --- a/Source/kwsys/SystemTools.cxx +++ b/Source/kwsys/SystemTools.cxx @@ -3640,11 +3640,11 @@ bool SystemTools::Split(const std::string& str, while (lpos < data.length()) { std::string::size_type rpos = data.find_first_of(separator, lpos); if (rpos == std::string::npos) { - // Line ends at end of string without a newline. + // String ends at end of string without a separator. lines.push_back(data.substr(lpos)); return false; } else { - // Line ends in a "\n", remove the character. + // String ends in a separator, remove the character. lines.push_back(data.substr(lpos, rpos - lpos)); } lpos = rpos + 1; @@ -3658,7 +3658,7 @@ bool SystemTools::Split(const std::string& str, std::string data(str); std::string::size_type lpos = 0; while (lpos < data.length()) { - std::string::size_type rpos = data.find_first_of("\n", lpos); + std::string::size_type rpos = data.find_first_of('\n', lpos); if (rpos == std::string::npos) { // Line ends at end of string without a newline. lines.push_back(data.substr(lpos)); diff --git a/Tests/CMakeCommands/target_link_libraries/CMakeLists.txt b/Tests/CMakeCommands/target_link_libraries/CMakeLists.txt index e11f980..85ce1f7 100644 --- a/Tests/CMakeCommands/target_link_libraries/CMakeLists.txt +++ b/Tests/CMakeCommands/target_link_libraries/CMakeLists.txt @@ -130,3 +130,15 @@ target_link_libraries(newsignature1 PRIVATE depC INTERFACE depD PUBLIC depB PRIV assert_property(newsignature1 INTERFACE_LINK_LIBRARIES "depD;depB") assert_property(newsignature1 LINK_LIBRARIES "depC;depB;subdirlib") + +#---------------------------------------------------------------------------- +# Test cross-directory linking. +cmake_policy(PUSH) +cmake_policy(SET CMP0079 NEW) +add_executable(TopDir TopDir.c) +add_subdirectory(SubDirA) +add_subdirectory(SubDirB) +target_link_libraries(SubDirB TopDirImported) +add_library(TopDirImported IMPORTED INTERFACE) +target_compile_definitions(TopDirImported INTERFACE DEF_TopDirImported) +cmake_policy(POP) diff --git a/Tests/CMakeCommands/target_link_libraries/SubDirA/CMakeLists.txt b/Tests/CMakeCommands/target_link_libraries/SubDirA/CMakeLists.txt new file mode 100644 index 0000000..4dae103 --- /dev/null +++ b/Tests/CMakeCommands/target_link_libraries/SubDirA/CMakeLists.txt @@ -0,0 +1,15 @@ +add_executable(SubDirA SubDirA.c) + +# Link to a target imported in this directory that would not normally +# be visible to the directory in which TopDir is defined. +target_link_libraries(TopDir PUBLIC SameNameImported) + +# Link SubDirA to a target imported in this directory that has the same +# name as a target imported in SubDirB's directory. SubDirB will also +# tell us to link its copy. At compile time we verify both are linked. +target_link_libraries(SubDirA PRIVATE SameNameImported) + +# Import a target with the same name as a target imported in SubDirB. +# Distinguish this copy by having a unique usage requirement. +add_library(SameNameImported IMPORTED INTERFACE) +target_compile_definitions(SameNameImported INTERFACE DEF_SameNameImportedSubDirA) diff --git a/Tests/CMakeCommands/target_link_libraries/SubDirA/SubDirA.c b/Tests/CMakeCommands/target_link_libraries/SubDirA/SubDirA.c new file mode 100644 index 0000000..4706bb9 --- /dev/null +++ b/Tests/CMakeCommands/target_link_libraries/SubDirA/SubDirA.c @@ -0,0 +1,14 @@ +#ifndef DEF_SameNameImportedSubDirA +# error "DEF_SameNameImportedSubDirA is not defined but should be!" +#endif +#ifndef DEF_SameNameImportedSubDirB +# error "DEF_SameNameImportedSubDirB is not defined but should be!" +#endif +#ifdef DEF_TopDirImported +# error "DEF_TopDirImported is defined but should not be!" +#endif + +int main(void) +{ + return 0; +} diff --git a/Tests/CMakeCommands/target_link_libraries/SubDirB/CMakeLists.txt b/Tests/CMakeCommands/target_link_libraries/SubDirB/CMakeLists.txt new file mode 100644 index 0000000..7c918e6 --- /dev/null +++ b/Tests/CMakeCommands/target_link_libraries/SubDirB/CMakeLists.txt @@ -0,0 +1,15 @@ +add_executable(SubDirB SubDirB.c) + +# Link to a target imported in this directory that would not normally +# be visible to the directory in which TopDir is defined. +target_link_libraries(TopDir PUBLIC SameNameImported) + +# Link SubDirA to a target imported in this directory that has the same +# name as a target imported in SubDirA's directory. We verify when +# compiling SubDirA that it sees our target and its own. +target_link_libraries(SubDirA PRIVATE SameNameImported) + +# Import a target with the same name as a target imported in SubDirA. +# Distinguish this copy by having a unique usage requirement. +add_library(SameNameImported IMPORTED INTERFACE) +target_compile_definitions(SameNameImported INTERFACE DEF_SameNameImportedSubDirB) diff --git a/Tests/CMakeCommands/target_link_libraries/SubDirB/SubDirB.c b/Tests/CMakeCommands/target_link_libraries/SubDirB/SubDirB.c new file mode 100644 index 0000000..6e56729 --- /dev/null +++ b/Tests/CMakeCommands/target_link_libraries/SubDirB/SubDirB.c @@ -0,0 +1,14 @@ +#ifdef DEF_SameNameImportedSubDirA +# error "DEF_SameNameImportedSubDirA is defined but should not be!" +#endif +#ifdef DEF_SameNameImportedSubDirB +# error "DEF_SameNameImportedSubDirB is defined but should not be!" +#endif +#ifndef DEF_TopDirImported +# error "DEF_TopDirImported is not defined but should be!" +#endif + +int main(void) +{ + return 0; +} diff --git a/Tests/CMakeCommands/target_link_libraries/TopDir.c b/Tests/CMakeCommands/target_link_libraries/TopDir.c new file mode 100644 index 0000000..4706bb9 --- /dev/null +++ b/Tests/CMakeCommands/target_link_libraries/TopDir.c @@ -0,0 +1,14 @@ +#ifndef DEF_SameNameImportedSubDirA +# error "DEF_SameNameImportedSubDirA is not defined but should be!" +#endif +#ifndef DEF_SameNameImportedSubDirB +# error "DEF_SameNameImportedSubDirB is not defined but should be!" +#endif +#ifdef DEF_TopDirImported +# error "DEF_TopDirImported is defined but should not be!" +#endif + +int main(void) +{ + return 0; +} diff --git a/Tests/CMakeCommands/target_link_options/CMakeLists.txt b/Tests/CMakeCommands/target_link_options/CMakeLists.txt index 3bb6ff3..e84d041 100644 --- a/Tests/CMakeCommands/target_link_options/CMakeLists.txt +++ b/Tests/CMakeCommands/target_link_options/CMakeLists.txt @@ -24,3 +24,11 @@ get_target_property(result target_link_options_3 INTERFACE_LINK_OPTIONS) if (NOT result MATCHES "-INTERFACE_FLAG") message(SEND_ERROR "target_link_options not populated the INTERFACE_LINK_OPTIONS target property of static library") endif() + +add_library(target_link_options_4 SHARED EXCLUDE_FROM_ALL LinkOptionsLib.c) +target_link_options(target_link_options_4 PRIVATE -PRIVATE_FLAG) +target_link_options(target_link_options_4 BEFORE PRIVATE -BEFORE_PRIVATE_FLAG) +get_target_property(result target_link_options_4 LINK_OPTIONS) +if (NOT result MATCHES "-BEFORE_PRIVATE_FLAG.*-PRIVATE_FLAG") + message(SEND_ERROR "target_link_options not managing correctly 'BEFORE' keyword") +endif() diff --git a/Tests/ExportImport/Export/CMakeLists.txt b/Tests/ExportImport/Export/CMakeLists.txt index fdb2fa1..cb048be 100644 --- a/Tests/ExportImport/Export/CMakeLists.txt +++ b/Tests/ExportImport/Export/CMakeLists.txt @@ -155,6 +155,13 @@ add_library(testStaticLibRequiredPrivate testStaticLibRequiredPrivate.c) target_link_libraries(testLibDepends PRIVATE testStaticLibRequiredPrivate) cmake_policy(POP) +cmake_policy(PUSH) +cmake_policy(SET CMP0079 NEW) +add_library(TopDirLib STATIC testTopDirLib.c) +add_subdirectory(SubDirLinkA) +add_subdirectory(SubDirLinkB) +cmake_policy(POP) + macro(add_include_lib _libName) file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/${_libName}.c" "/* no content */\n") add_library(${_libName} "${CMAKE_CURRENT_BINARY_DIR}/${_libName}.c") @@ -508,6 +515,7 @@ install( testLibCycleA testLibCycleB testLibNoSONAME cmp0022NEW cmp0022OLD + TopDirLib SubDirLinkA systemlib EXPORT exp RUNTIME DESTINATION $<1:bin>$<0:/wrong> @@ -566,6 +574,7 @@ export(TARGETS testExe1 testLib1 testLib2 testLib3 testSharedLibRequired testSharedLibRequiredUser testSharedLibRequiredUser2 testSharedLibDepends renamed_on_export cmp0022NEW cmp0022OLD + TopDirLib SubDirLinkA systemlib NAMESPACE bld_ FILE ExportBuildTree.cmake diff --git a/Tests/ExportImport/Export/SubDirLinkA/CMakeLists.txt b/Tests/ExportImport/Export/SubDirLinkA/CMakeLists.txt new file mode 100644 index 0000000..1c3c9dc --- /dev/null +++ b/Tests/ExportImport/Export/SubDirLinkA/CMakeLists.txt @@ -0,0 +1,6 @@ +add_library(SubDirLinkAImported IMPORTED INTERFACE) +target_compile_definitions(SubDirLinkAImported INTERFACE DEF_SubDirLinkAImportedForExport) + +target_link_libraries(TopDirLib PUBLIC SubDirLinkAImported) + +add_library(SubDirLinkA STATIC SubDirLinkA.c) diff --git a/Tests/ExportImport/Export/SubDirLinkA/SubDirLinkA.c b/Tests/ExportImport/Export/SubDirLinkA/SubDirLinkA.c new file mode 100644 index 0000000..abf76f5 --- /dev/null +++ b/Tests/ExportImport/Export/SubDirLinkA/SubDirLinkA.c @@ -0,0 +1,11 @@ +#ifdef DEF_SubDirLinkAImportedForExport +# error "DEF_SubDirLinkAImportedForExport is defined but should not be!" +#endif +#ifndef DEF_SubDirLinkBImportedForExport +# error "DEF_SubDirLinkBImportedForExport is not defined but should be!" +#endif + +int testSubDirLinkA(void) +{ + return 0; +} diff --git a/Tests/ExportImport/Export/SubDirLinkB/CMakeLists.txt b/Tests/ExportImport/Export/SubDirLinkB/CMakeLists.txt new file mode 100644 index 0000000..22e168f --- /dev/null +++ b/Tests/ExportImport/Export/SubDirLinkB/CMakeLists.txt @@ -0,0 +1,4 @@ +add_library(SubDirLinkBImported IMPORTED INTERFACE) +target_compile_definitions(SubDirLinkBImported INTERFACE DEF_SubDirLinkBImportedForExport) + +target_link_libraries(SubDirLinkA PUBLIC SubDirLinkBImported) diff --git a/Tests/ExportImport/Export/testTopDirLib.c b/Tests/ExportImport/Export/testTopDirLib.c new file mode 100644 index 0000000..1ec68de --- /dev/null +++ b/Tests/ExportImport/Export/testTopDirLib.c @@ -0,0 +1,11 @@ +#ifndef DEF_SubDirLinkAImportedForExport +# error "DEF_SubDirLinkAImportedForExport is not defined but should be!" +#endif +#ifdef DEF_SubDirLinkBImportedForExport +# error "DEF_SubDirLinkBImportedForExport is defined but should not be!" +#endif + +int testTopDirLib(void) +{ + return 0; +} diff --git a/Tests/ExportImport/Import/A/CMakeLists.txt b/Tests/ExportImport/Import/A/CMakeLists.txt index 7510d7e..8791a19 100644 --- a/Tests/ExportImport/Import/A/CMakeLists.txt +++ b/Tests/ExportImport/Import/A/CMakeLists.txt @@ -1,3 +1,9 @@ +# Prepare imported targets that the exported project itself imported. +add_library(SubDirLinkAImported IMPORTED INTERFACE) +target_compile_definitions(SubDirLinkAImported INTERFACE DEF_SubDirLinkAImportedForImport) +add_library(SubDirLinkBImported IMPORTED INTERFACE) +target_compile_definitions(SubDirLinkBImported INTERFACE DEF_SubDirLinkBImportedForImport) + # Import targets from the exported build tree. include(${Import_BINARY_DIR}/../Export/ExportBuildTree.cmake) @@ -158,6 +164,11 @@ target_link_libraries(cmp0022OLD_exp_test exp_cmp0022OLD) add_executable(cmp0022NEW_exp_test cmp0022NEW_test_vs6_2.cpp) target_link_libraries(cmp0022NEW_exp_test exp_cmp0022NEW) +add_executable(SubDirLink_bld SubDirLink.c) +target_link_libraries(SubDirLink_bld PRIVATE bld_TopDirLib bld_SubDirLinkA) +add_executable(SubDirLink_exp SubDirLink.c) +target_link_libraries(SubDirLink_exp PRIVATE exp_TopDirLib exp_SubDirLinkA) + # Try building a plugin to an executable imported from the build tree. add_library(imp_mod1b MODULE imp_mod1.c) target_link_libraries(imp_mod1b bld_testExe2) diff --git a/Tests/ExportImport/Import/A/SubDirLink.c b/Tests/ExportImport/Import/A/SubDirLink.c new file mode 100644 index 0000000..eb4b860 --- /dev/null +++ b/Tests/ExportImport/Import/A/SubDirLink.c @@ -0,0 +1,14 @@ +#ifndef DEF_SubDirLinkAImportedForImport +# error "DEF_SubDirLinkAImportedForImport is not defined but should be!" +#endif +#ifndef DEF_SubDirLinkBImportedForImport +# error "DEF_SubDirLinkBImportedForImport is not defined but should be!" +#endif + +extern int testTopDirLib(void); +extern int testSubDirLinkA(void); + +int main(void) +{ + return (testTopDirLib() + testSubDirLinkA() + 0); +} diff --git a/Tests/RunCMake/Ninja/RunCMakeTest.cmake b/Tests/RunCMake/Ninja/RunCMakeTest.cmake index e0ddc9c..4b366a8 100644 --- a/Tests/RunCMake/Ninja/RunCMakeTest.cmake +++ b/Tests/RunCMake/Ninja/RunCMakeTest.cmake @@ -205,15 +205,16 @@ function(run_sub_cmake test ninja_output_path_prefix) set(cmd_prefix "") set(cmd_suffix "") endif() + set(fs_delay 3) # We assume the system as 1 sec timestamp resolution. file(WRITE "${top_build_ninja}" "\ subninja ${escaped_ninja_output_path_prefix}/build.ninja default ${escaped_ninja_output_path_prefix}/all -# Sleep for 1 second before to regenerate to make sure the timestamp of +# Sleep for long enough before regenerating to make sure the timestamp of # the top build.ninja will be strictly greater than the timestamp of the -# sub/build.ninja file. We assume the system as 1 sec timestamp resolution. +# sub/build.ninja file. rule RERUN - command = ${cmd_prefix}\"${escaped_CMAKE_COMMAND}\" -E sleep 1 && \"${escaped_CMAKE_COMMAND}\" -E touch \"${escaped_top_build_ninja}\"${cmd_suffix} + command = ${cmd_prefix}\"${escaped_CMAKE_COMMAND}\" -E sleep ${fs_delay} && \"${escaped_CMAKE_COMMAND}\" -E touch \"${escaped_top_build_ninja}\"${cmd_suffix} description = Testing regeneration generator = 1 @@ -239,7 +240,7 @@ build build.ninja: RERUN ${escaped_build_ninja_dep} || ${escaped_ninja_output_pa # Test regeneration rules run in order. set(main_cmakelists "${RunCMake_SOURCE_DIR}/CMakeLists.txt") - sleep(1) # Assume the system as 1 sec timestamp resolution. + sleep(${fs_delay}) touch("${main_cmakelists}") touch("${build_ninja_dep}") run_ninja("${top_build_dir}") diff --git a/Tests/RunCMake/target_link_libraries/CMP0079-iface-NEW-stdout.txt b/Tests/RunCMake/target_link_libraries/CMP0079-iface-NEW-stdout.txt new file mode 100644 index 0000000..89cd806 --- /dev/null +++ b/Tests/RunCMake/target_link_libraries/CMP0079-iface-NEW-stdout.txt @@ -0,0 +1 @@ +-- INTERFACE_LINK_LIBRARIES='foo::@<[Xx0-9A-Fa-f]+>' diff --git a/Tests/RunCMake/target_link_libraries/CMP0079-iface-NEW.cmake b/Tests/RunCMake/target_link_libraries/CMP0079-iface-NEW.cmake new file mode 100644 index 0000000..82486c4 --- /dev/null +++ b/Tests/RunCMake/target_link_libraries/CMP0079-iface-NEW.cmake @@ -0,0 +1,2 @@ +cmake_policy(SET CMP0079 NEW) +include(CMP0079-iface-common.cmake) diff --git a/Tests/RunCMake/target_link_libraries/CMP0079-iface-OLD-stdout.txt b/Tests/RunCMake/target_link_libraries/CMP0079-iface-OLD-stdout.txt new file mode 100644 index 0000000..e575e16 --- /dev/null +++ b/Tests/RunCMake/target_link_libraries/CMP0079-iface-OLD-stdout.txt @@ -0,0 +1 @@ +-- INTERFACE_LINK_LIBRARIES='foo' diff --git a/Tests/RunCMake/target_link_libraries/CMP0079-iface-OLD.cmake b/Tests/RunCMake/target_link_libraries/CMP0079-iface-OLD.cmake new file mode 100644 index 0000000..e04a2bb --- /dev/null +++ b/Tests/RunCMake/target_link_libraries/CMP0079-iface-OLD.cmake @@ -0,0 +1,2 @@ +cmake_policy(SET CMP0079 OLD) +include(CMP0079-iface-common.cmake) diff --git a/Tests/RunCMake/target_link_libraries/CMP0079-iface-WARN-stderr.txt b/Tests/RunCMake/target_link_libraries/CMP0079-iface-WARN-stderr.txt new file mode 100644 index 0000000..6dd7d30 --- /dev/null +++ b/Tests/RunCMake/target_link_libraries/CMP0079-iface-WARN-stderr.txt @@ -0,0 +1,17 @@ +^CMake Warning \(dev\) at CMP0079-iface/CMakeLists.txt:[0-9]+ \(target_link_libraries\): + Policy CMP0079 is not set: target_link_libraries allows use with targets in + other directories. Run "cmake --help-policy CMP0079" for policy details. + Use the cmake_policy command to set the policy and suppress this warning. + + Target + + top + + is not created in this directory. For compatibility with older versions of + CMake, link library + + foo + + will be looked up in the directory in which the target was created rather + than in this calling directory. +This warning is for project developers. Use -Wno-dev to suppress it.$ diff --git a/Tests/RunCMake/target_link_libraries/CMP0079-iface-WARN-stdout.txt b/Tests/RunCMake/target_link_libraries/CMP0079-iface-WARN-stdout.txt new file mode 100644 index 0000000..e575e16 --- /dev/null +++ b/Tests/RunCMake/target_link_libraries/CMP0079-iface-WARN-stdout.txt @@ -0,0 +1 @@ +-- INTERFACE_LINK_LIBRARIES='foo' diff --git a/Tests/RunCMake/target_link_libraries/CMP0079-iface-WARN.cmake b/Tests/RunCMake/target_link_libraries/CMP0079-iface-WARN.cmake new file mode 100644 index 0000000..2041893 --- /dev/null +++ b/Tests/RunCMake/target_link_libraries/CMP0079-iface-WARN.cmake @@ -0,0 +1 @@ +include(CMP0079-iface-common.cmake) diff --git a/Tests/RunCMake/target_link_libraries/CMP0079-iface-common.cmake b/Tests/RunCMake/target_link_libraries/CMP0079-iface-common.cmake new file mode 100644 index 0000000..3982ff2 --- /dev/null +++ b/Tests/RunCMake/target_link_libraries/CMP0079-iface-common.cmake @@ -0,0 +1,6 @@ +enable_language(C) + +add_executable(top empty.c) +add_subdirectory(CMP0079-iface) +get_property(libs TARGET top PROPERTY INTERFACE_LINK_LIBRARIES) +message(STATUS "INTERFACE_LINK_LIBRARIES='${libs}'") diff --git a/Tests/RunCMake/target_link_libraries/CMP0079-iface/CMakeLists.txt b/Tests/RunCMake/target_link_libraries/CMP0079-iface/CMakeLists.txt new file mode 100644 index 0000000..4b15b32 --- /dev/null +++ b/Tests/RunCMake/target_link_libraries/CMP0079-iface/CMakeLists.txt @@ -0,0 +1 @@ +target_link_libraries(top INTERFACE foo) diff --git a/Tests/RunCMake/target_link_libraries/SubDirTarget-result.txt b/Tests/RunCMake/target_link_libraries/CMP0079-link-NEW-bogus-result.txt index d00491f..d00491f 100644 --- a/Tests/RunCMake/target_link_libraries/SubDirTarget-result.txt +++ b/Tests/RunCMake/target_link_libraries/CMP0079-link-NEW-bogus-result.txt diff --git a/Tests/RunCMake/target_link_libraries/CMP0079-link-NEW-bogus-stderr.txt b/Tests/RunCMake/target_link_libraries/CMP0079-link-NEW-bogus-stderr.txt new file mode 100644 index 0000000..b9fe3f6 --- /dev/null +++ b/Tests/RunCMake/target_link_libraries/CMP0079-link-NEW-bogus-stderr.txt @@ -0,0 +1,6 @@ +^CMake Error at CMP0079-link-NEW-bogus.cmake:[0-9]+ \(add_executable\): + Target "top" links to target "foo::@<0xdeadbeef>" but the target was not + found. Perhaps a find_package\(\) call is missing for an IMPORTED target, or + an ALIAS target is missing\? +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/target_link_libraries/CMP0079-link-NEW-bogus.cmake b/Tests/RunCMake/target_link_libraries/CMP0079-link-NEW-bogus.cmake new file mode 100644 index 0000000..8622f14 --- /dev/null +++ b/Tests/RunCMake/target_link_libraries/CMP0079-link-NEW-bogus.cmake @@ -0,0 +1,6 @@ +cmake_policy(SET CMP0028 NEW) +cmake_policy(SET CMP0079 NEW) +enable_language(C) + +add_executable(top empty.c) +set_property(TARGET top APPEND PROPERTY LINK_LIBRARIES "foo::@<0xdeadbeef>") diff --git a/Tests/RunCMake/target_link_libraries/CMP0079-link-NEW-stdout.txt b/Tests/RunCMake/target_link_libraries/CMP0079-link-NEW-stdout.txt new file mode 100644 index 0000000..84b30bd --- /dev/null +++ b/Tests/RunCMake/target_link_libraries/CMP0079-link-NEW-stdout.txt @@ -0,0 +1 @@ +-- LINK_LIBRARIES='foo::@<[Xx0-9A-Fa-f]+>' diff --git a/Tests/RunCMake/target_link_libraries/CMP0079-link-NEW.cmake b/Tests/RunCMake/target_link_libraries/CMP0079-link-NEW.cmake new file mode 100644 index 0000000..72e4574 --- /dev/null +++ b/Tests/RunCMake/target_link_libraries/CMP0079-link-NEW.cmake @@ -0,0 +1,2 @@ +cmake_policy(SET CMP0079 NEW) +include(CMP0079-link-common.cmake) diff --git a/Tests/RunCMake/target_link_libraries/CMP0079-link-OLD-result.txt b/Tests/RunCMake/target_link_libraries/CMP0079-link-OLD-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/target_link_libraries/CMP0079-link-OLD-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/target_link_libraries/CMP0079-link-OLD-stderr.txt b/Tests/RunCMake/target_link_libraries/CMP0079-link-OLD-stderr.txt new file mode 100644 index 0000000..0b4c4c6 --- /dev/null +++ b/Tests/RunCMake/target_link_libraries/CMP0079-link-OLD-stderr.txt @@ -0,0 +1,5 @@ +^CMake Error at CMP0079-link/CMakeLists.txt:[0-9]+ \(target_link_libraries\): + Attempt to add link library "foo" to target "top" which is not built in + this directory. + + This is allowed only when policy CMP0079 is set to NEW.$ diff --git a/Tests/RunCMake/target_link_libraries/CMP0079-link-OLD.cmake b/Tests/RunCMake/target_link_libraries/CMP0079-link-OLD.cmake new file mode 100644 index 0000000..caa7231 --- /dev/null +++ b/Tests/RunCMake/target_link_libraries/CMP0079-link-OLD.cmake @@ -0,0 +1,2 @@ +cmake_policy(SET CMP0079 OLD) +include(CMP0079-link-common.cmake) diff --git a/Tests/RunCMake/target_link_libraries/CMP0079-link-WARN-result.txt b/Tests/RunCMake/target_link_libraries/CMP0079-link-WARN-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/target_link_libraries/CMP0079-link-WARN-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/target_link_libraries/CMP0079-link-WARN-stderr.txt b/Tests/RunCMake/target_link_libraries/CMP0079-link-WARN-stderr.txt new file mode 100644 index 0000000..0b4c4c6 --- /dev/null +++ b/Tests/RunCMake/target_link_libraries/CMP0079-link-WARN-stderr.txt @@ -0,0 +1,5 @@ +^CMake Error at CMP0079-link/CMakeLists.txt:[0-9]+ \(target_link_libraries\): + Attempt to add link library "foo" to target "top" which is not built in + this directory. + + This is allowed only when policy CMP0079 is set to NEW.$ diff --git a/Tests/RunCMake/target_link_libraries/CMP0079-link-WARN.cmake b/Tests/RunCMake/target_link_libraries/CMP0079-link-WARN.cmake new file mode 100644 index 0000000..e83818a --- /dev/null +++ b/Tests/RunCMake/target_link_libraries/CMP0079-link-WARN.cmake @@ -0,0 +1 @@ +include(CMP0079-link-common.cmake) diff --git a/Tests/RunCMake/target_link_libraries/CMP0079-link-common.cmake b/Tests/RunCMake/target_link_libraries/CMP0079-link-common.cmake new file mode 100644 index 0000000..4f9454f --- /dev/null +++ b/Tests/RunCMake/target_link_libraries/CMP0079-link-common.cmake @@ -0,0 +1,6 @@ +enable_language(C) + +add_executable(top empty.c) +add_subdirectory(CMP0079-link) +get_property(libs TARGET top PROPERTY LINK_LIBRARIES) +message(STATUS "LINK_LIBRARIES='${libs}'") diff --git a/Tests/RunCMake/target_link_libraries/CMP0079-link/CMakeLists.txt b/Tests/RunCMake/target_link_libraries/CMP0079-link/CMakeLists.txt new file mode 100644 index 0000000..8b2b3c9 --- /dev/null +++ b/Tests/RunCMake/target_link_libraries/CMP0079-link/CMakeLists.txt @@ -0,0 +1 @@ +target_link_libraries(top PUBLIC foo) diff --git a/Tests/RunCMake/target_link_libraries/CMakeLists.txt b/Tests/RunCMake/target_link_libraries/CMakeLists.txt index 12cd3c7..8f85fbf 100644 --- a/Tests/RunCMake/target_link_libraries/CMakeLists.txt +++ b/Tests/RunCMake/target_link_libraries/CMakeLists.txt @@ -1,3 +1,3 @@ cmake_minimum_required(VERSION 2.8.4) project(${RunCMake_TEST} NONE) -include(${RunCMake_TEST}.cmake) +include(${RunCMake_TEST}.cmake NO_POLICY_SCOPE) diff --git a/Tests/RunCMake/target_link_libraries/RunCMakeTest.cmake b/Tests/RunCMake/target_link_libraries/RunCMakeTest.cmake index 97b0888..a041d6d 100644 --- a/Tests/RunCMake/target_link_libraries/RunCMakeTest.cmake +++ b/Tests/RunCMake/target_link_libraries/RunCMakeTest.cmake @@ -4,11 +4,17 @@ run_cmake(CMP0023-WARN) run_cmake(CMP0023-NEW) run_cmake(CMP0023-WARN-2) run_cmake(CMP0023-NEW-2) +run_cmake(CMP0079-iface-WARN) +run_cmake(CMP0079-iface-OLD) +run_cmake(CMP0079-iface-NEW) +run_cmake(CMP0079-link-WARN) +run_cmake(CMP0079-link-OLD) +run_cmake(CMP0079-link-NEW) +run_cmake(CMP0079-link-NEW-bogus) run_cmake(ImportedTarget) run_cmake(ImportedTargetFailure) run_cmake(MixedSignature) run_cmake(Separate-PRIVATE-LINK_PRIVATE-uses) -run_cmake(SubDirTarget) run_cmake(SharedDepNotTarget) run_cmake(StaticPrivateDepNotExported) run_cmake(StaticPrivateDepNotTarget) diff --git a/Tests/RunCMake/target_link_libraries/SubDirTarget-stderr.txt b/Tests/RunCMake/target_link_libraries/SubDirTarget-stderr.txt deleted file mode 100644 index 5cd1f23..0000000 --- a/Tests/RunCMake/target_link_libraries/SubDirTarget-stderr.txt +++ /dev/null @@ -1,5 +0,0 @@ -^CMake Error at SubDirTarget.cmake:[0-9]+ \(target_link_libraries\): - Attempt to add link library "m" to target "subexe" which is not built in - this directory. -Call Stack \(most recent call first\): - CMakeLists.txt:[0-9]+ \(include\)$ diff --git a/Tests/RunCMake/target_link_libraries/SubDirTarget.cmake b/Tests/RunCMake/target_link_libraries/SubDirTarget.cmake deleted file mode 100644 index 32431ce..0000000 --- a/Tests/RunCMake/target_link_libraries/SubDirTarget.cmake +++ /dev/null @@ -1,3 +0,0 @@ -enable_language(C) -add_subdirectory(SubDirTarget) -target_link_libraries(subexe m) diff --git a/Tests/RunCMake/target_link_libraries/SubDirTarget/CMakeLists.txt b/Tests/RunCMake/target_link_libraries/SubDirTarget/CMakeLists.txt deleted file mode 100644 index b0b2380..0000000 --- a/Tests/RunCMake/target_link_libraries/SubDirTarget/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -add_executable(subexe ../empty.c) |