Hi,
I'm testing out CMake 3.12, and I very much like the new
FindPython.cmake. Being able to use targets for the Python libraries
means I can much easier package my own library without hardcoded paths.
The only thing is that I want to be compatible with older CMakes >=
3.0. Therefore I came up with following approach: write a
FindPythonCompat.cmake that forwards to FindPython.cmake if CMake >=
3.12, and uses FindPythonInterp.cmake and FindPythonLibs.cmake to mimic
the new FindPython.cmake if CMake < 3.12.
You can find that file attached.
Instead of calling this:
find_package(Python 2.7 EXACT REQUIRED COMPONENTS Interpreter
OPTIONAL_COMPONENTS Development)
I now do this:
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/cmake) #
contains FindPythonInterp.cmake
find_package(PythonCompat 2.7 EXACT REQUIRED COMPONENTS Interpreter
OPTIONAL_COMPONENTS Development)
The resulting targets and variables are the same as the ones from
FindPython.cmake.
Another approached I consider is a bit more cunning: add a
PythonConfig.cmake and PythonConfigVersion.cmake to CMAKE_PREFIX_PATH.
PythonConfig.cmake would not contain the forward to FindPython.cmake,
but it would instead rely on the fallback from MODULE to CONFIG mode
when FindPython.cmake cannot be found in CMake < 3.12. I would then
still be calling find_package(Python) but I extend CMAKE_PREFIX_PATH:
list(APPEND CMAKE_PREFIX_PATH ${CMAKE_CURRENT_LIST_DIR}/cmake) #
contains PythonConfig.cmake
find_package(Python 2.7 EXACT REQUIRED COMPONENTS Interpreter
OPTIONAL_COMPONENTS Development)
In both cases it is of course required that I install this
FindPythonCompat.cmake or PythonConfig.cmake next to my own library's
FooConfig.cmake.
Also, in the compatibility mode, it's not my goal to get a 1-on-1 match
with FindPython.cmake. For my needs, I only require what
FindInterp.cmake and FindLibs.cmake can deliver.
Now my questions to you are:
- What do you think of these approaches?
- What's the most CMake-esque approach?
- How can I improve this?
- Any better names for FindPythonCompat.cmake? FindPythonShim.cmake?
FindPythonForward.cmake?
Thanks for your feedback,
Bram
unset(_PythonCompat_ARGS)
if(PythonCompat_FIND_VERSION)
list(APPEND _PythonCompat_ARGS ${PythonCompat_FIND_VERSION})
endif()
if(PythonCompat_FIND_VERSION_EXACT)
list(APPEND _PythonCompat_ARGS EXACT)
endif()
if(PythonCompat_FIND_QUIETLY)
list(APPEND _PythonCompat_ARGS QUIET)
endif()
if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.12)
# Cmake 3.12 has FindPython.cmake, so we can simply forward to it
unset(_PythonCompat_COMPONENTS)
unset(_PythonCompat_OPTIONAL_COMPONENTS)
foreach(_PythonCompat_COMPONENT ${PythonCompat_FIND_COMPONENTS})
if(PythonCompat_FIND_REQUIRED_${_PythonCompat_COMPONENT})
list(APPEND _PythonCompat_COMPONENTS "${_PythonCompat_COMPONENT}")
else()
list(APPEND _PythonCompat_OPTIONAL_COMPONENTS
"${_PythonCompat_COMPONENT}")
endif()
endforeach()
find_package(Python ${_PythonCompat_ARGS}
COMPONENTS ${_PythonCompat_COMPONENTS}
OPTIONAL_COMPONENTS ${_PythonCompat_OPTIONAL_COMPONENTS})
set(PythonCompat_FOUND ${Python_FOUND})
return()
endif()
if(NOT PythonCompat_FIND_COMPONENTS)
set(PythonCompat_FIND_COMPONENTS Interpreter)
set(PythonCompat_FIND_REQUIRED_Interpreter TRUE)
endif()
set(_PythonCompat_REQUIRED_VARS)
if(DEFINED PythonCompat_FIND_REQUIRED_Interpreter)
if(Python_EXECUTABLE AND NOT PYTHON_EXECUTABLE)
set(PYTHON_EXECUTABLE ${Python_EXECUTABLE} CACHE FILEPATH
"Path to a program." FORCE)
endif()
find_package(PythonInterp ${_PythonCompat_ARGS})
set(Python_Interpreter_FOUND ${PYTHONINTERP_FOUND})
set(Python_EXECUTABLE ${PYTHON_EXECUTABLE})
set(Python_VERSION ${PYTHON_VERSION_STRING})
set(Python_VERSION_MAJOR ${PYTHON_VERSION_MAJOR})
set(Python_VERSION_MINOR ${PYTHON_VERSION_MINOR})
set(Python_VERSION_PATCH ${PYTHON_VERSION_PATCH})
if(TARGET Python::Interpreter AND PYTHONINTERP_FOUND)
add_executable (Python::Interpreter IMPORTED)
set_property(TARGET Python::Interpreter PROPERTY
IMPORTED_LOCATION "${PYTHON_EXECUTABLE}")
endif()
if(PythonCompat_FIND_REQUIRED_Interpreter)
list(APPEND _PythonCompat_REQUIRED_VARS PYTHON_EXECUTABLE)
endif()
endif()
if(DEFINED PythonCompat_FIND_REQUIRED_Development)
find_package(PythonLibs ${_PythonCompat_ARGS})
set(Python_Development_FOUND ${PYTHONLIBS_FOUND})
set(Python_INCLUDE_DIRS ${PYTHON_INCLUDE_DIRS})
set(Python_LIBRARIES ${PYTHON_LIBRARIES})
#set(Python_LIBRARY_DIRS ${PYTHON_EXECUTABLE})
#set(Python_RUNTIME_LIBRARY_DIRS ${PYTHON_EXECUTABLE})
set(Python_INCLUDE_DIR ${PYTHON_INCLUDE_DIR})
set(Python_LIBRARY_RELEASE ${PYTHON_LIBRARY_RELEASE})
set(Python_LIBRARY_DEBUG ${PYTHON_DEBUG_LIBRARY})
if(NOT TARGET Python::Python AND PYTHONLIBS_FOUND)
if(PYTHON_LIBRARY MATCHES "${CMAKE_SHARED_LIBRARY_SUFFIX}$" OR
PYTHON_DEBUG_LIBRARY MATCHES "${CMAKE_SHARED_LIBRARY_SUFFIX}$")
set(_PythonCompat_LIBRARY_TYPE SHARED)
else()
set(_PythonCompat_LIBRARY_TYPE UNKNOWN)
endif()
add_library(Python::Python "${_PythonCompat_LIBRARY_TYPE}" IMPORTED)
set_property(TARGET Python::Python PROPERTY
INTERFACE_INCLUDE_DIRECTORIES "${PYTHON_INCLUDE_DIRS}")
if(PYTHON_DEBUG_LIBRARY)
set_property(TARGET Python::Python APPEND PROPERTY
IMPORTED_CONFIGURATIONS RELEASE)
set_target_properties(Python::Python PROPERTIES
IMPORTED_LINK_INTERFACE_LANGUAGES_RELEASE "C"
IMPORTED_LOCATION_RELEASE "${PYTHON_LIBRARY_RELEASE}")
set_property(TARGET Python::Python APPEND PROPERTY
IMPORTED_CONFIGURATIONS DEBUG)
set_target_properties(Python::Python PROPERTIES
IMPORTED_LINK_INTERFACE_LANGUAGES_DEBUG "C"
IMPORTED_LOCATION_DEBUG "${PYTHON_DEBUG_LIBRARY}")
else()
set_target_properties(Python::Python PROPERTIES
IMPORTED_LINK_INTERFACE_LANGUAGES "C"
IMPORTED_LOCATION "${PYTHON_LIBRARY}")
endif()
endif()
if(PythonCompat_FIND_REQUIRED_Development)
list(APPEND _PythonCompat_REQUIRED_VARS PYTHON_LIBRARIES
PYTHON_INCLUDE_DIRS)
endif()
endif()
include(FindPackageHandleStandardArgs)
set(Python_FIND_COMPONENTS ${PythonCompat_FIND_COMPONENTS})
find_package_handle_standard_args(Python
REQUIRED_VARS ${_PythonCompat_REQUIRED_VARS}
VERSION_VAR Python_VERSION
HANDLE_COMPONENTS)
set(PythonCompat_FOUND ${Python_FOUND})
--
Powered by www.kitware.com
Please keep messages on-topic and check the CMake FAQ at:
http://www.cmake.org/Wiki/CMake_FAQ
Kitware offers various services to support the CMake community. For more
information on each offering, please visit:
CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html
Visit other Kitware open-source projects at
http://www.kitware.com/opensource/opensource.html
Follow this link to subscribe/unsubscribe:
https://cmake.org/mailman/listinfo/cmake