From 536c24c01b1131f16d3063d601e2feb6cb514c32 Mon Sep 17 00:00:00 2001 From: Shane Loretz Date: Mon, 26 Jul 2021 16:53:30 -0700 Subject: [PATCH 01/11] Use FindPython3 instead of FindPythonInterp Signed-off-by: Shane Loretz --- cmake/Modules/FindPythonExtra.cmake | 240 +++++++--------------------- 1 file changed, 57 insertions(+), 183 deletions(-) diff --git a/cmake/Modules/FindPythonExtra.cmake b/cmake/Modules/FindPythonExtra.cmake index 9e18f83..b9dbc37 100644 --- a/cmake/Modules/FindPythonExtra.cmake +++ b/cmake/Modules/FindPythonExtra.cmake @@ -17,211 +17,85 @@ # # CMake module for providing extra information about the Python interpreter. # -# Output variables: +# Output Targets: +# - PythonExtra::Interpreter - an executable target that will invoke a version of Python +# matching CMAKE_BUILD_TYPE on platforms where that matters # +# Output variables: # - PythonExtra_FOUND: True if a Python executable was found -# - PythonExtra_EXTENSION_SUFFIX: The suffix for a Python extension, according -# to PEP-3149: https://www.python.org/dev/peps/pep-3149/ -# - PythonExtra_EXTENSION_EXTENSION: The extension for a Python extension. On -# Linux and Mac OSX equals to ".so", on Windows to ".pyd" -# - PythonExtra_INCLUDE_DIRS: The paths to the directories where the Python -# headers are installed. -# - PythonExtra_LIBRARIES: The paths to the Python libraries. -# - PYTHON_SOABI: The shared library file name tag according to PEP-3149: -# https://www.python.org/dev/peps/pep-3149/ # -# Conditional output variables -# - PYTHON_EXECUTABLE_DEBUG: If the CMAKE_BUILD_TYPE is Debug and WIN32 is true +# Advanced Output variables +# - PythonExtra_EXECUTABLE: a path to a python interpreter +# - PythonExtra_EXECUTABLE_DEBUG: If the CMAKE_BUILD_TYPE is Debug and WIN32 is true # then this will be a path to a debug build of the Python interpreter. # # Example usage: # # find_package(python_cmake_module REQUIRED) # find_package(PythonExtra MODULE) -# # use PythonExtra_* variables +# # use PythonExtra::Interpreter +# +# Note on Python3 +# This module requires that `find_package(Python3 REQUIRED COMPONENTS Interpreter)` be called, +# and will call it if not present. +# If more components from FindPython3.cmake are needed, then find it manually before finding +# this module. +# Example: +# +# find_package(python_cmake_module REQUIRED) +# find_package(Python3 REQUIRED COMPONENTS Interpreter Development NumPy) +# find_package(PythonExtra MODULE) +# # use PythonExtra::Interpreter # ############################################################################### # lint_cmake: -convention/filename, -package/stdargs -set(PythonExtra_FOUND FALSE) - -# Prevent find_package(PythonLibs) from getting confused. -unset(PYTHON_LIBRARY) - -find_package(PythonInterp 3.6 REQUIRED) - -if(PYTHONINTERP_FOUND) - if(APPLE) - find_program(PYTHON_CONFIG_EXECUTABLE NAMES "python3-config") - if(NOT PYTHON_CONFIG_EXECUTABLE) - message(FATAL_ERROR "Cannot find python3-config executable") - endif() - - if(NOT DEFINED PythonExtra_INCLUDE_DIRS) - execute_process( - COMMAND - "${PYTHON_CONFIG_EXECUTABLE}" - "--includes" - OUTPUT_VARIABLE _output - RESULT_VARIABLE _result - OUTPUT_STRIP_TRAILING_WHITESPACE - ) - if(NOT _result EQUAL 0) - message(FATAL_ERROR - "execute_process(${PYTHON_CONFIG_EXECUTABLE} --includes) returned " - "error code ${_result}") - endif() - - string(REPLACE " " ";" _output_list ${_output}) - - foreach(_includedir ${_output_list}) - string(SUBSTRING "${_includedir}" 2 -1 _includedir) - list(APPEND PythonExtra_INCLUDE_DIRS "${_includedir}") - endforeach() - endif() - set(PythonExtra_INCLUDE_DIRS - ${PythonExtra_INCLUDE_DIRS} - CACHE INTERNAL - "The paths to the Python include directories.") - message(STATUS "Using PythonExtra_INCLUDE_DIRS: ${PythonExtra_INCLUDE_DIRS}") - - if(NOT DEFINED PythonExtra_LIBRARIES) - execute_process( - COMMAND - "${PYTHON_CONFIG_EXECUTABLE}" - "--ldflags" - OUTPUT_VARIABLE _output - RESULT_VARIABLE _result - OUTPUT_STRIP_TRAILING_WHITESPACE - ) - if(NOT _result EQUAL 0) - message(FATAL_ERROR - "execute_process(${PYTHON_CONFIG_EXECUTABLE} --ldflags) returned " - "error code ${_result}") - endif() - - string(REPLACE " " ";" _output_list "${_output}") - set(PythonExtra_LIBRARIES - "" - CACHE INTERNAL - "The libraries that need to be linked against for Python extensions.") - - set(_library_paths "") - foreach(_item ${_output_list}) - string(REGEX MATCH "-L(.*)" _regex_match ${_item}) - if(NOT _regex_match STREQUAL "") - string(SUBSTRING "${_regex_match}" 2 -1 _library_path) - list(APPEND _library_paths "${_library_path}") - endif() - endforeach() - - set(_python_version_no_dots - "${PYTHON_VERSION_MAJOR}${PYTHON_VERSION_MINOR}") - set(_python_version - "${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}") - - find_library(PYTHON_LIBRARY - NAMES - python${_python_version_no_dots} - python${_python_version}mu - python${_python_version}m - python${_python_version}u - python${_python_version} - PATHS - ${_library_paths} - NO_SYSTEM_ENVIRONMENT_PATH - ) - endif() - - set(PythonExtra_LIBRARIES "${PYTHON_LIBRARY}") - message(STATUS "Using PythonExtra_LIBRARIES: ${PythonExtra_LIBRARIES}") - else() - find_package(PythonLibs 3.5 REQUIRED) - if(WIN32 AND CMAKE_BUILD_TYPE STREQUAL "Debug") - get_filename_component(_python_executable_dir "${PYTHON_EXECUTABLE}" DIRECTORY) - get_filename_component(_python_executable_name "${PYTHON_EXECUTABLE}" NAME_WE) - get_filename_component(_python_executable_ext "${PYTHON_EXECUTABLE}" EXT) - set(_python_executable_debug "${_python_executable_dir}/${_python_executable_name}_d${_python_executable_ext}") - if(EXISTS "${_python_executable_debug}") - set(PYTHON_EXECUTABLE_DEBUG "${_python_executable_debug}") - else() - message(FATAL_ERROR "${_python_executable_debug} doesn't exist") - endif() - endif() - message(STATUS "Using PYTHON_EXECUTABLE: ${PYTHON_EXECUTABLE}") - message(STATUS "Using PYTHON_INCLUDE_DIRS: ${PYTHON_INCLUDE_DIRS}") - message(STATUS "Using PYTHON_LIBRARIES: ${PYTHON_LIBRARIES}") - set(PythonExtra_INCLUDE_DIRS "${PYTHON_INCLUDE_DIRS}") - set(PythonExtra_LIBRARIES "${PYTHON_LIBRARIES}") - endif() - - if(NOT DEFINED PYTHON_SOABI) - set(_python_code - "from sysconfig import get_config_var" - "print(get_config_var('SOABI'))" - ) - execute_process( - COMMAND - "${PYTHON_EXECUTABLE}" - "-c" - "${_python_code}" - OUTPUT_VARIABLE _output - RESULT_VARIABLE _result - OUTPUT_STRIP_TRAILING_WHITESPACE - ) - if(NOT _result EQUAL 0) - message(FATAL_ERROR - "execute_process(${PYTHON_EXECUTABLE} -c '${_python_code}') returned " - "error code ${_result}") - endif() - - set(PYTHON_SOABI - "${_output}" - CACHE INTERNAL - "The SOABI suffix for Python native extensions. See PEP-3149: https://www.python.org/dev/peps/pep-3149/.") - endif() +if(PythonExtra_FOUND) + return() +endif() - if(PYTHON_SOABI STREQUAL "" OR PYTHON_SOABI STREQUAL "None") - set(PythonExtra_EXTENSION_SUFFIX - "" - CACHE INTERNAL - "The full suffix for Python native extensions. See PEP-3149: https://www.python.org/dev/peps/pep-3149/." - ) - else() - set(PythonExtra_EXTENSION_SUFFIX - ".${PYTHON_SOABI}" - CACHE INTERNAL - "The full suffix for Python native extensions. See PEP-3149: https://www.python.org/dev/peps/pep-3149/." - ) - endif() +if(Python3_FOUND AND NOT TARGET Python3::Interpreter) + message(FATAL_ERROR "PythonExtra requires Python3 to be found with the Interpreter component") +elseif(NOT Python3_FOUND) + find_package(Python3 REQUIRED COMPONENTS Interpreter) +endif() - if(WIN32) - if(CMAKE_BUILD_TYPE STREQUAL "Debug") - set(PythonExtra_EXTENSION_EXTENSION "_d.pyd") - else() - set(PythonExtra_EXTENSION_EXTENSION ".pyd") - endif() - else() - # Also use .so for OSX, not dylib - set(PythonExtra_EXTENSION_EXTENSION ".so") +get_target_property(PythonExtra_EXECUTABLE Python3::Interpreter IMPORTED_LOCATION) + +add_executable(PythonExtra::Interpreter IMPORTED) +set_property(TARGET PythonExtra::Interpreter + PROPERTY IMPORTED_LOCATION "${PythonExtra_EXECUTABLE}") + +# Set the location to the debug interpretter on Windows if it exists +if(WIN32) + get_target_property(PythonExtra_EXECUTABLE PythonExtra::Interpreter IMPORTED_LOCATION) + get_filename_component(_python_executable_dir "${PythonExtra_EXECUTABLE}" DIRECTORY) + get_filename_component(_python_executable_name "${PythonExtra_EXECUTABLE}" NAME_WE) + get_filename_component(_python_executable_ext "${PythonExtra_EXECUTABLE}" EXT) + set(PythonExtra_EXECUTABLE_DEBUG "${_python_executable_dir}/${_python_executable_name}_d${_python_executable_ext}") + if(EXISTS "${PythonExtra_EXECUTABLE_DEBUG}") + set_target_property(PythonExtra::Interpreter IMPORTED_LOCATION_Debug "${PythonExtra_EXECUTABLE_DEBUG}") + set(PythonExtra_EXECUTABLE_DEBUG "${PythonExtra_EXECUTABLE_DEBUG}") + elseif(CMAKE_BUILD_TYPE STREQUAL "Debug") + message(FATAL_ERROR "${PythonExtra_EXECUTABLE_DEBUG} doesn't exist and Debug build required") endif() - - set(PythonExtra_FOUND TRUE) + unset(_python_executable_dir) + unset(_python_executable_name) + unset(_python_executable_ext) endif() include(FindPackageHandleStandardArgs) set(_required_vars - PythonExtra_EXTENSION_EXTENSION - PythonExtra_INCLUDE_DIRS - PythonExtra_LIBRARIES - PYTHON_SOABI) -if(NOT WIN32) - list(APPEND _required_vars PythonExtra_EXTENSION_SUFFIX) -elseif("${CMAKE_BUILD_TYPE}" STREQUAL "Debug") - list(APPEND _required_vars PYTHON_EXECUTABLE_DEBUG) + PythonExtra_EXECUTABLE) +if(WIN32 AND "${CMAKE_BUILD_TYPE}" STREQUAL "Debug") + list(APPEND _required_vars PythonExra_EXECUTABLE_DEBUG) endif() +# Use PythonExtra::Interpreter instead of these variables +mark_as_advanced( + PythonExtra_EXECUTABLE + PythonExtra_EXECUTABLE_DEBUG) find_package_handle_standard_args(PythonExtra - FOUND_VAR PythonExtra_FOUND REQUIRED_VARS ${_required_vars} ) +unset(_required_vars) From e29e74f3999692512b6e79776cfa656f9ee419fa Mon Sep 17 00:00:00 2001 From: Shane Loretz Date: Wed, 28 Jul 2021 10:37:59 -0700 Subject: [PATCH 02/11] Simplify since FindPython3 can be found multiple times Signed-off-by: Shane Loretz --- cmake/Modules/FindPythonExtra.cmake | 37 +++++++++++------------------ 1 file changed, 14 insertions(+), 23 deletions(-) diff --git a/cmake/Modules/FindPythonExtra.cmake b/cmake/Modules/FindPythonExtra.cmake index b9dbc37..eaaea27 100644 --- a/cmake/Modules/FindPythonExtra.cmake +++ b/cmake/Modules/FindPythonExtra.cmake @@ -35,17 +35,10 @@ # find_package(PythonExtra MODULE) # # use PythonExtra::Interpreter # -# Note on Python3 -# This module requires that `find_package(Python3 REQUIRED COMPONENTS Interpreter)` be called, -# and will call it if not present. -# If more components from FindPython3.cmake are needed, then find it manually before finding -# this module. -# Example: -# -# find_package(python_cmake_module REQUIRED) -# find_package(Python3 REQUIRED COMPONENTS Interpreter Development NumPy) -# find_package(PythonExtra MODULE) -# # use PythonExtra::Interpreter +# Note on FindPython3 +# This module will `find_package(Python3 REQUIRED COMPONENTS Interpreter)` +# If more components from FindPython3.cmake are needed, then find them manually before +# or after finding this module. # ############################################################################### @@ -55,47 +48,45 @@ if(PythonExtra_FOUND) return() endif() -if(Python3_FOUND AND NOT TARGET Python3::Interpreter) - message(FATAL_ERROR "PythonExtra requires Python3 to be found with the Interpreter component") -elseif(NOT Python3_FOUND) - find_package(Python3 REQUIRED COMPONENTS Interpreter) -endif() +find_package(Python3 REQUIRED COMPONENTS Interpreter) -get_target_property(PythonExtra_EXECUTABLE Python3::Interpreter IMPORTED_LOCATION) +get_target_property(PythonExtra_EXECUTABLE Python3::Interpreter LOCATION) add_executable(PythonExtra::Interpreter IMPORTED) set_property(TARGET PythonExtra::Interpreter PROPERTY IMPORTED_LOCATION "${PythonExtra_EXECUTABLE}") -# Set the location to the debug interpretter on Windows if it exists +# Set the location to the debug interpreter on Windows if it exists if(WIN32) - get_target_property(PythonExtra_EXECUTABLE PythonExtra::Interpreter IMPORTED_LOCATION) + get_target_property(PythonExtra_EXECUTABLE PythonExtra::Interpreter LOCATION) get_filename_component(_python_executable_dir "${PythonExtra_EXECUTABLE}" DIRECTORY) get_filename_component(_python_executable_name "${PythonExtra_EXECUTABLE}" NAME_WE) get_filename_component(_python_executable_ext "${PythonExtra_EXECUTABLE}" EXT) set(PythonExtra_EXECUTABLE_DEBUG "${_python_executable_dir}/${_python_executable_name}_d${_python_executable_ext}") if(EXISTS "${PythonExtra_EXECUTABLE_DEBUG}") set_target_property(PythonExtra::Interpreter IMPORTED_LOCATION_Debug "${PythonExtra_EXECUTABLE_DEBUG}") - set(PythonExtra_EXECUTABLE_DEBUG "${PythonExtra_EXECUTABLE_DEBUG}") elseif(CMAKE_BUILD_TYPE STREQUAL "Debug") - message(FATAL_ERROR "${PythonExtra_EXECUTABLE_DEBUG} doesn't exist and Debug build required") + message(WARNING "${PythonExtra_EXECUTABLE_DEBUG} doesn't exist but a Windows Debug build requires it") + unset(PythonExtra_EXECUTABLE_DEBUG) endif() unset(_python_executable_dir) unset(_python_executable_name) unset(_python_executable_ext) endif() -include(FindPackageHandleStandardArgs) set(_required_vars PythonExtra_EXECUTABLE) if(WIN32 AND "${CMAKE_BUILD_TYPE}" STREQUAL "Debug") list(APPEND _required_vars PythonExra_EXECUTABLE_DEBUG) endif() -# Use PythonExtra::Interpreter instead of these variables +# Downstream users should use PythonExtra::Interpreter instead of these variables mark_as_advanced( PythonExtra_EXECUTABLE PythonExtra_EXECUTABLE_DEBUG) + +include(FindPackageHandleStandardArgs) find_package_handle_standard_args(PythonExtra REQUIRED_VARS ${_required_vars} ) + unset(_required_vars) From 4262ed7d02fc0f2e2e7554762454878be3665299 Mon Sep 17 00:00:00 2001 From: Chris Lalancette Date: Fri, 3 Nov 2023 20:59:02 +0000 Subject: [PATCH 03/11] Fix a typo. Signed-off-by: Chris Lalancette --- cmake/Modules/FindPythonExtra.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/Modules/FindPythonExtra.cmake b/cmake/Modules/FindPythonExtra.cmake index eaaea27..9ee327e 100644 --- a/cmake/Modules/FindPythonExtra.cmake +++ b/cmake/Modules/FindPythonExtra.cmake @@ -77,7 +77,7 @@ endif() set(_required_vars PythonExtra_EXECUTABLE) if(WIN32 AND "${CMAKE_BUILD_TYPE}" STREQUAL "Debug") - list(APPEND _required_vars PythonExra_EXECUTABLE_DEBUG) + list(APPEND _required_vars PythonExtra_EXECUTABLE_DEBUG) endif() # Downstream users should use PythonExtra::Interpreter instead of these variables mark_as_advanced( From 06dd86fd5e4740418862fc5af0b34eacdb8c24fd Mon Sep 17 00:00:00 2001 From: Chris Lalancette Date: Thu, 16 Nov 2023 20:16:50 +0000 Subject: [PATCH 04/11] Switch to PYTHON_EXECUTABLE and PYTHON_EXECUTABLE_DEBUG. Signed-off-by: Chris Lalancette --- cmake/Modules/FindPythonExtra.cmake | 31 ++++++++++++++--------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/cmake/Modules/FindPythonExtra.cmake b/cmake/Modules/FindPythonExtra.cmake index 9ee327e..0e5e407 100644 --- a/cmake/Modules/FindPythonExtra.cmake +++ b/cmake/Modules/FindPythonExtra.cmake @@ -25,8 +25,8 @@ # - PythonExtra_FOUND: True if a Python executable was found # # Advanced Output variables -# - PythonExtra_EXECUTABLE: a path to a python interpreter -# - PythonExtra_EXECUTABLE_DEBUG: If the CMAKE_BUILD_TYPE is Debug and WIN32 is true +# - PYTHON_EXECUTABLE: a path to a python interpreter +# - PYTHON_EXECUTABLE_DEBUG: If the CMAKE_BUILD_TYPE is Debug and WIN32 is true # then this will be a path to a debug build of the Python interpreter. # # Example usage: @@ -50,7 +50,7 @@ endif() find_package(Python3 REQUIRED COMPONENTS Interpreter) -get_target_property(PythonExtra_EXECUTABLE Python3::Interpreter LOCATION) +get_target_property(PYTHON_EXECUTABLE Python3::Interpreter LOCATION) add_executable(PythonExtra::Interpreter IMPORTED) set_property(TARGET PythonExtra::Interpreter @@ -58,16 +58,15 @@ set_property(TARGET PythonExtra::Interpreter # Set the location to the debug interpreter on Windows if it exists if(WIN32) - get_target_property(PythonExtra_EXECUTABLE PythonExtra::Interpreter LOCATION) - get_filename_component(_python_executable_dir "${PythonExtra_EXECUTABLE}" DIRECTORY) - get_filename_component(_python_executable_name "${PythonExtra_EXECUTABLE}" NAME_WE) - get_filename_component(_python_executable_ext "${PythonExtra_EXECUTABLE}" EXT) - set(PythonExtra_EXECUTABLE_DEBUG "${_python_executable_dir}/${_python_executable_name}_d${_python_executable_ext}") - if(EXISTS "${PythonExtra_EXECUTABLE_DEBUG}") - set_target_property(PythonExtra::Interpreter IMPORTED_LOCATION_Debug "${PythonExtra_EXECUTABLE_DEBUG}") + get_filename_component(_python_executable_dir "${PYTHON_EXECUTABLE}" DIRECTORY) + get_filename_component(_python_executable_name "${PYTHON_EXECUTABLE}" NAME_WE) + get_filename_component(_python_executable_ext "${PYTHON_EXECUTABLE}" EXT) + set(PYTHON_EXECUTABLE_DEBUG "${_python_executable_dir}/${_python_executable_name}_d${_python_executable_ext}") + if(EXISTS "${PYTHON_EXECUTABLE_DEBUG}") + set_target_property(PythonExtra::Interpreter IMPORTED_LOCATION_Debug "${PYTHON_EXECUTABLE_DEBUG}") elseif(CMAKE_BUILD_TYPE STREQUAL "Debug") - message(WARNING "${PythonExtra_EXECUTABLE_DEBUG} doesn't exist but a Windows Debug build requires it") - unset(PythonExtra_EXECUTABLE_DEBUG) + message(WARNING "${PYTHON_EXECUTABLE_DEBUG} doesn't exist but a Windows Debug build requires it") + unset(PYTHON_EXECUTABLE_DEBUG) endif() unset(_python_executable_dir) unset(_python_executable_name) @@ -75,14 +74,14 @@ if(WIN32) endif() set(_required_vars - PythonExtra_EXECUTABLE) + PYTHON_EXECUTABLE) if(WIN32 AND "${CMAKE_BUILD_TYPE}" STREQUAL "Debug") - list(APPEND _required_vars PythonExtra_EXECUTABLE_DEBUG) + list(APPEND _required_vars PYTHON_EXECUTABLE_DEBUG) endif() # Downstream users should use PythonExtra::Interpreter instead of these variables mark_as_advanced( - PythonExtra_EXECUTABLE - PythonExtra_EXECUTABLE_DEBUG) + PYTHON_EXECUTABLE + PYTHON_EXECUTABLE_DEBUG) include(FindPackageHandleStandardArgs) find_package_handle_standard_args(PythonExtra From 4acdad02f53631b152a08cd8b47fa8010a50cbde Mon Sep 17 00:00:00 2001 From: Chris Lalancette Date: Fri, 17 Nov 2023 13:30:35 +0000 Subject: [PATCH 05/11] Fix for Windows. Signed-off-by: Chris Lalancette --- cmake/Modules/FindPythonExtra.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/Modules/FindPythonExtra.cmake b/cmake/Modules/FindPythonExtra.cmake index 0e5e407..daed667 100644 --- a/cmake/Modules/FindPythonExtra.cmake +++ b/cmake/Modules/FindPythonExtra.cmake @@ -63,7 +63,7 @@ if(WIN32) get_filename_component(_python_executable_ext "${PYTHON_EXECUTABLE}" EXT) set(PYTHON_EXECUTABLE_DEBUG "${_python_executable_dir}/${_python_executable_name}_d${_python_executable_ext}") if(EXISTS "${PYTHON_EXECUTABLE_DEBUG}") - set_target_property(PythonExtra::Interpreter IMPORTED_LOCATION_Debug "${PYTHON_EXECUTABLE_DEBUG}") + set_property(TARGET PythonExtra::Interpreter PROPERTY IMPORTED_LOCATION_Debug "${PYTHON_EXECUTABLE_DEBUG}") elseif(CMAKE_BUILD_TYPE STREQUAL "Debug") message(WARNING "${PYTHON_EXECUTABLE_DEBUG} doesn't exist but a Windows Debug build requires it") unset(PYTHON_EXECUTABLE_DEBUG) From c08b8f75a9f477e96a01c7fd5ee72e13e93b0797 Mon Sep 17 00:00:00 2001 From: Chris Lalancette Date: Mon, 20 Nov 2023 19:32:04 +0000 Subject: [PATCH 06/11] Add in deprecation notice for PYTHON_EXECUTABLE. Signed-off-by: Chris Lalancette --- cmake/Modules/FindPythonExtra.cmake | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmake/Modules/FindPythonExtra.cmake b/cmake/Modules/FindPythonExtra.cmake index daed667..c844078 100644 --- a/cmake/Modules/FindPythonExtra.cmake +++ b/cmake/Modules/FindPythonExtra.cmake @@ -25,9 +25,9 @@ # - PythonExtra_FOUND: True if a Python executable was found # # Advanced Output variables -# - PYTHON_EXECUTABLE: a path to a python interpreter +# - PYTHON_EXECUTABLE: a path to a python interpreter (deprecated; new code should use PythonExtra::Interpreter) # - PYTHON_EXECUTABLE_DEBUG: If the CMAKE_BUILD_TYPE is Debug and WIN32 is true -# then this will be a path to a debug build of the Python interpreter. +# then this will be a path to a debug build of the Python interpreter (deprecated; new code should use PythonExtra::Interpreter) # # Example usage: # From e74ed3b71a85d391dfc79e5e28cdee58f69a08b1 Mon Sep 17 00:00:00 2001 From: Chris Lalancette Date: Mon, 8 Jan 2024 14:46:24 +0000 Subject: [PATCH 07/11] Feedback from review. Signed-off-by: Chris Lalancette --- cmake/Modules/FindPythonExtra.cmake | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmake/Modules/FindPythonExtra.cmake b/cmake/Modules/FindPythonExtra.cmake index c844078..08d27b8 100644 --- a/cmake/Modules/FindPythonExtra.cmake +++ b/cmake/Modules/FindPythonExtra.cmake @@ -54,7 +54,7 @@ get_target_property(PYTHON_EXECUTABLE Python3::Interpreter LOCATION) add_executable(PythonExtra::Interpreter IMPORTED) set_property(TARGET PythonExtra::Interpreter - PROPERTY IMPORTED_LOCATION "${PythonExtra_EXECUTABLE}") + PROPERTY IMPORTED_LOCATION "${PYTHON_EXECUTABLE}") # Set the location to the debug interpreter on Windows if it exists if(WIN32) @@ -63,7 +63,7 @@ if(WIN32) get_filename_component(_python_executable_ext "${PYTHON_EXECUTABLE}" EXT) set(PYTHON_EXECUTABLE_DEBUG "${_python_executable_dir}/${_python_executable_name}_d${_python_executable_ext}") if(EXISTS "${PYTHON_EXECUTABLE_DEBUG}") - set_property(TARGET PythonExtra::Interpreter PROPERTY IMPORTED_LOCATION_Debug "${PYTHON_EXECUTABLE_DEBUG}") + set_property(TARGET PythonExtra::Interpreter PROPERTY IMPORTED_LOCATION "${PYTHON_EXECUTABLE_DEBUG}") elseif(CMAKE_BUILD_TYPE STREQUAL "Debug") message(WARNING "${PYTHON_EXECUTABLE_DEBUG} doesn't exist but a Windows Debug build requires it") unset(PYTHON_EXECUTABLE_DEBUG) From 00027f7573a9fcba8fbce2f3caf922d3fc56f11e Mon Sep 17 00:00:00 2001 From: Chris Lalancette Date: Thu, 25 Jan 2024 12:01:23 -0800 Subject: [PATCH 08/11] Additional fixes. Signed-off-by: Chris Lalancette --- cmake/Modules/FindPythonExtra.cmake | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/cmake/Modules/FindPythonExtra.cmake b/cmake/Modules/FindPythonExtra.cmake index 08d27b8..c987295 100644 --- a/cmake/Modules/FindPythonExtra.cmake +++ b/cmake/Modules/FindPythonExtra.cmake @@ -28,6 +28,7 @@ # - PYTHON_EXECUTABLE: a path to a python interpreter (deprecated; new code should use PythonExtra::Interpreter) # - PYTHON_EXECUTABLE_DEBUG: If the CMAKE_BUILD_TYPE is Debug and WIN32 is true # then this will be a path to a debug build of the Python interpreter (deprecated; new code should use PythonExtra::Interpreter) +# - PythonExtra_POSTFIX: a postfix that downstream consumers can use as the DEBUG_POSTFIX property to a target # # Example usage: # @@ -56,6 +57,8 @@ add_executable(PythonExtra::Interpreter IMPORTED) set_property(TARGET PythonExtra::Interpreter PROPERTY IMPORTED_LOCATION "${PYTHON_EXECUTABLE}") +set(PythonExtra_POSTFIX "") + # Set the location to the debug interpreter on Windows if it exists if(WIN32) get_filename_component(_python_executable_dir "${PYTHON_EXECUTABLE}" DIRECTORY) @@ -63,7 +66,13 @@ if(WIN32) get_filename_component(_python_executable_ext "${PYTHON_EXECUTABLE}" EXT) set(PYTHON_EXECUTABLE_DEBUG "${_python_executable_dir}/${_python_executable_name}_d${_python_executable_ext}") if(EXISTS "${PYTHON_EXECUTABLE_DEBUG}") + # TODO(clalancette): In theory we should be able to set the IMPORTED_LOCATION_Debug property, + # and downstream users would automatically use that with the "Debug" configuration. + # In practice we've found that this doesn't work as advertised in + # https://cmake.org/cmake/help/latest/guide/importing-exporting/index.html#importing-libraries , + # so we are overriding IMPORTED_LOCATION. set_property(TARGET PythonExtra::Interpreter PROPERTY IMPORTED_LOCATION "${PYTHON_EXECUTABLE_DEBUG}") + set(PythonExtra_POSTFIX "_d") elseif(CMAKE_BUILD_TYPE STREQUAL "Debug") message(WARNING "${PYTHON_EXECUTABLE_DEBUG} doesn't exist but a Windows Debug build requires it") unset(PYTHON_EXECUTABLE_DEBUG) @@ -81,7 +90,8 @@ endif() # Downstream users should use PythonExtra::Interpreter instead of these variables mark_as_advanced( PYTHON_EXECUTABLE - PYTHON_EXECUTABLE_DEBUG) + PYTHON_EXECUTABLE_DEBUG + PythonExtra_POSTFIX) include(FindPackageHandleStandardArgs) find_package_handle_standard_args(PythonExtra From 5d948c0f194d4f55310e813d6f1e44b6e6291f08 Mon Sep 17 00:00:00 2001 From: Chris Lalancette Date: Sun, 28 Jan 2024 13:57:38 +0000 Subject: [PATCH 09/11] More fixes for Windows Debug. Signed-off-by: Chris Lalancette --- cmake/Modules/FindPythonExtra.cmake | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/cmake/Modules/FindPythonExtra.cmake b/cmake/Modules/FindPythonExtra.cmake index c987295..554828f 100644 --- a/cmake/Modules/FindPythonExtra.cmake +++ b/cmake/Modules/FindPythonExtra.cmake @@ -57,14 +57,18 @@ add_executable(PythonExtra::Interpreter IMPORTED) set_property(TARGET PythonExtra::Interpreter PROPERTY IMPORTED_LOCATION "${PYTHON_EXECUTABLE}") +set(_required_vars + PYTHON_EXECUTABLE) + set(PythonExtra_POSTFIX "") # Set the location to the debug interpreter on Windows if it exists -if(WIN32) +if(WIN32 AND CMAKE_BUILD_TYPE STREQUAL "Debug") get_filename_component(_python_executable_dir "${PYTHON_EXECUTABLE}" DIRECTORY) get_filename_component(_python_executable_name "${PYTHON_EXECUTABLE}" NAME_WE) get_filename_component(_python_executable_ext "${PYTHON_EXECUTABLE}" EXT) set(PYTHON_EXECUTABLE_DEBUG "${_python_executable_dir}/${_python_executable_name}_d${_python_executable_ext}") + list(APPEND _required_vars PYTHON_EXECUTABLE_DEBUG) if(EXISTS "${PYTHON_EXECUTABLE_DEBUG}") # TODO(clalancette): In theory we should be able to set the IMPORTED_LOCATION_Debug property, # and downstream users would automatically use that with the "Debug" configuration. @@ -73,7 +77,7 @@ if(WIN32) # so we are overriding IMPORTED_LOCATION. set_property(TARGET PythonExtra::Interpreter PROPERTY IMPORTED_LOCATION "${PYTHON_EXECUTABLE_DEBUG}") set(PythonExtra_POSTFIX "_d") - elseif(CMAKE_BUILD_TYPE STREQUAL "Debug") + else() message(WARNING "${PYTHON_EXECUTABLE_DEBUG} doesn't exist but a Windows Debug build requires it") unset(PYTHON_EXECUTABLE_DEBUG) endif() @@ -82,11 +86,6 @@ if(WIN32) unset(_python_executable_ext) endif() -set(_required_vars - PYTHON_EXECUTABLE) -if(WIN32 AND "${CMAKE_BUILD_TYPE}" STREQUAL "Debug") - list(APPEND _required_vars PYTHON_EXECUTABLE_DEBUG) -endif() # Downstream users should use PythonExtra::Interpreter instead of these variables mark_as_advanced( PYTHON_EXECUTABLE From 72a7ec2a722385c432c9a96eeb14c8ca386f0cda Mon Sep 17 00:00:00 2001 From: Chris Lalancette Date: Thu, 8 Feb 2024 12:29:44 -0800 Subject: [PATCH 10/11] Switch to Python3::Interpreter. This simplifies things so we no longer need a PythonExtra::Interpreter. Signed-off-by: Chris Lalancette --- cmake/Modules/FindPythonExtra.cmake | 45 +++++++++++++++-------------- 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/cmake/Modules/FindPythonExtra.cmake b/cmake/Modules/FindPythonExtra.cmake index 554828f..1a88b7c 100644 --- a/cmake/Modules/FindPythonExtra.cmake +++ b/cmake/Modules/FindPythonExtra.cmake @@ -18,7 +18,7 @@ # CMake module for providing extra information about the Python interpreter. # # Output Targets: -# - PythonExtra::Interpreter - an executable target that will invoke a version of Python +# - Python3::Interpreter - an executable target that will invoke a version of Python # matching CMAKE_BUILD_TYPE on platforms where that matters # # Output variables: @@ -38,8 +38,8 @@ # # Note on FindPython3 # This module will `find_package(Python3 REQUIRED COMPONENTS Interpreter)` -# If more components from FindPython3.cmake are needed, then find them manually before -# or after finding this module. +# If more components from FindPython3.cmake are needed, then find them manually +# after finding this module. # ############################################################################### @@ -53,40 +53,41 @@ find_package(Python3 REQUIRED COMPONENTS Interpreter) get_target_property(PYTHON_EXECUTABLE Python3::Interpreter LOCATION) -add_executable(PythonExtra::Interpreter IMPORTED) -set_property(TARGET PythonExtra::Interpreter - PROPERTY IMPORTED_LOCATION "${PYTHON_EXECUTABLE}") - -set(_required_vars - PYTHON_EXECUTABLE) +set(PYTHON_EXECUTABLE_DEBUG "${PYTHON_EXECUTABLE}") set(PythonExtra_POSTFIX "") +set(_required_vars + PYTHON_EXECUTABLE + PYTHON_EXECUTABLE_DEBUG) + # Set the location to the debug interpreter on Windows if it exists if(WIN32 AND CMAKE_BUILD_TYPE STREQUAL "Debug") get_filename_component(_python_executable_dir "${PYTHON_EXECUTABLE}" DIRECTORY) get_filename_component(_python_executable_name "${PYTHON_EXECUTABLE}" NAME_WE) get_filename_component(_python_executable_ext "${PYTHON_EXECUTABLE}" EXT) - set(PYTHON_EXECUTABLE_DEBUG "${_python_executable_dir}/${_python_executable_name}_d${_python_executable_ext}") - list(APPEND _required_vars PYTHON_EXECUTABLE_DEBUG) - if(EXISTS "${PYTHON_EXECUTABLE_DEBUG}") - # TODO(clalancette): In theory we should be able to set the IMPORTED_LOCATION_Debug property, - # and downstream users would automatically use that with the "Debug" configuration. - # In practice we've found that this doesn't work as advertised in - # https://cmake.org/cmake/help/latest/guide/importing-exporting/index.html#importing-libraries , - # so we are overriding IMPORTED_LOCATION. - set_property(TARGET PythonExtra::Interpreter PROPERTY IMPORTED_LOCATION "${PYTHON_EXECUTABLE_DEBUG}") - set(PythonExtra_POSTFIX "_d") + if (_python_executable_name MATCHES ".*_d") + # The interpreter name we found already includes _d. We don't need to do any additional work. + set(PYTHON_EXECUTABLE_DEBUG "${PYTHON_EXECUTABLE}") else() - message(WARNING "${PYTHON_EXECUTABLE_DEBUG} doesn't exist but a Windows Debug build requires it") - unset(PYTHON_EXECUTABLE_DEBUG) + set(PYTHON_EXECUTABLE_DEBUG "${_python_executable_dir}/${_python_executable_name}_d${_python_executable_ext}") + if(NOT EXISTS "${PYTHON_EXECUTABLE_DEBUG}") + message(WARNING "${PYTHON_EXECUTABLE_DEBUG} doesn't exist but a Windows Debug build requires it") + unset(PYTHON_EXECUTABLE_DEBUG) + endif() endif() + + set(Python3_EXECUTABLE "${PYTHON_EXECUTABLE_DEBUG}") + set_property(TARGET Python3::Interpreter PROPERTY IMPORTED_LOCATION "${PYTHON_EXECUTABLE_DEBUG}") + + set(PythonExtra_POSTFIX "_d") + unset(_python_executable_dir) unset(_python_executable_name) unset(_python_executable_ext) endif() -# Downstream users should use PythonExtra::Interpreter instead of these variables +# Downstream users should use Python3::Interpreter instead of these variables mark_as_advanced( PYTHON_EXECUTABLE PYTHON_EXECUTABLE_DEBUG From 51b769c6ed5a669ad15b5f98934597542d9f613d Mon Sep 17 00:00:00 2001 From: Chris Lalancette Date: Fri, 9 Feb 2024 14:43:55 -0500 Subject: [PATCH 11/11] Fixes from review. Signed-off-by: Chris Lalancette --- cmake/Modules/FindPythonExtra.cmake | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/cmake/Modules/FindPythonExtra.cmake b/cmake/Modules/FindPythonExtra.cmake index 1a88b7c..f4c1169 100644 --- a/cmake/Modules/FindPythonExtra.cmake +++ b/cmake/Modules/FindPythonExtra.cmake @@ -25,16 +25,16 @@ # - PythonExtra_FOUND: True if a Python executable was found # # Advanced Output variables -# - PYTHON_EXECUTABLE: a path to a python interpreter (deprecated; new code should use PythonExtra::Interpreter) +# - PYTHON_EXECUTABLE: a path to a python interpreter (deprecated; new code should use Python3::Interpreter) # - PYTHON_EXECUTABLE_DEBUG: If the CMAKE_BUILD_TYPE is Debug and WIN32 is true -# then this will be a path to a debug build of the Python interpreter (deprecated; new code should use PythonExtra::Interpreter) +# then this will be a path to a debug build of the Python interpreter (deprecated; new code should use Python3::Interpreter) # - PythonExtra_POSTFIX: a postfix that downstream consumers can use as the DEBUG_POSTFIX property to a target # # Example usage: # # find_package(python_cmake_module REQUIRED) # find_package(PythonExtra MODULE) -# # use PythonExtra::Interpreter +# # use Python3::Interpreter # # Note on FindPython3 # This module will `find_package(Python3 REQUIRED COMPONENTS Interpreter)` @@ -66,8 +66,8 @@ if(WIN32 AND CMAKE_BUILD_TYPE STREQUAL "Debug") get_filename_component(_python_executable_dir "${PYTHON_EXECUTABLE}" DIRECTORY) get_filename_component(_python_executable_name "${PYTHON_EXECUTABLE}" NAME_WE) get_filename_component(_python_executable_ext "${PYTHON_EXECUTABLE}" EXT) - if (_python_executable_name MATCHES ".*_d") - # The interpreter name we found already includes _d. We don't need to do any additional work. + if(_python_executable_name MATCHES ".*_d") + # The interpreter name we found already includes _d. We don't need to reconstruct it. set(PYTHON_EXECUTABLE_DEBUG "${PYTHON_EXECUTABLE}") else() set(PYTHON_EXECUTABLE_DEBUG "${_python_executable_dir}/${_python_executable_name}_d${_python_executable_ext}")