summaryrefslogtreecommitdiff
path: root/Modules
diff options
context:
space:
mode:
authorMarc Chevrier <marc.chevrier@gmail.com>2019-05-04 17:09:31 +0200
committerMarc Chevrier <marc.chevrier@gmail.com>2019-05-07 16:37:24 +0200
commit30b873c05d6281b865ba08524bb1b90e0afd1ece (patch)
tree235ff9a85d3a4e83de7f2b7ad94037d1edcb07eb /Modules
parent37bf503db268c41d5a337265300357c76bda34ea (diff)
downloadcmake-30b873c05d6281b865ba08524bb1b90e0afd1ece.tar.gz
FindPython*: Manage weak link for Python modules
Add new target Python::Module which take care of platform requirements for Python module development. Fixes: #18100
Diffstat (limited to 'Modules')
-rw-r--r--Modules/FindPython.cmake12
-rw-r--r--Modules/FindPython/Support.cmake161
-rw-r--r--Modules/FindPython2.cmake14
-rw-r--r--Modules/FindPython3.cmake14
4 files changed, 124 insertions, 77 deletions
diff --git a/Modules/FindPython.cmake b/Modules/FindPython.cmake
index c5074e8b3d..36c0611218 100644
--- a/Modules/FindPython.cmake
+++ b/Modules/FindPython.cmake
@@ -46,7 +46,11 @@ This module defines the following :ref:`Imported Targets <Imported Targets>`
``Python::Compiler``
Python compiler. Target defined if component ``Compiler`` is found.
``Python::Python``
- Python library. Target defined if component ``Development`` is found.
+ Python library for Python embedding. Target defined if component
+ ``Development`` is found.
+``Python::Module``
+ Python library for Python module. Target defined if component ``Development``
+ is found.
``Python::NumPy``
NumPy Python library. Target defined if component ``NumPy`` is found.
@@ -175,9 +179,9 @@ Commands
This module defines the command ``Python_add_library`` (when
:prop_gbl:`CMAKE_ROLE` is ``PROJECT``), which has the same semantics as
-:command:`add_library`, but takes care of Python module naming rules
-(only applied if library is of type ``MODULE``), and adds a dependency to target
-``Python::Python``::
+:command:`add_library` and adds a dependency to target ``Python::Python`` or,
+when library type is ``MODULE``, to target ``Python::Module`` and takes care of
+Python module naming rules::
Python_add_library (my_module MODULE src1.cpp)
diff --git a/Modules/FindPython/Support.cmake b/Modules/FindPython/Support.cmake
index 6572fb8bd6..6d709e10cb 100644
--- a/Modules/FindPython/Support.cmake
+++ b/Modules/FindPython/Support.cmake
@@ -1253,72 +1253,104 @@ if(_${_PYTHON_PREFIX}_CMAKE_ROLE STREQUAL "PROJECT")
endif()
if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS
- AND ${_PYTHON_PREFIX}_Development_FOUND AND NOT TARGET ${_PYTHON_PREFIX}::Python)
+ AND ${_PYTHON_PREFIX}_Development_FOUND)
- if (${_PYTHON_PREFIX}_LIBRARY_RELEASE MATCHES "${CMAKE_SHARED_LIBRARY_SUFFIX}$"
- OR ${_PYTHON_PREFIX}_LIBRARY_DEBUG MATCHES "${CMAKE_SHARED_LIBRARY_SUFFIX}$"
- OR ${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE OR ${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG)
- set (_${_PYTHON_PREFIX}_LIBRARY_TYPE SHARED)
- else()
- set (_${_PYTHON_PREFIX}_LIBRARY_TYPE STATIC)
- endif()
-
- add_library (${_PYTHON_PREFIX}::Python ${_${_PYTHON_PREFIX}_LIBRARY_TYPE} IMPORTED)
-
- set_property (TARGET ${_PYTHON_PREFIX}::Python
- PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${${_PYTHON_PREFIX}_INCLUDE_DIR}")
-
- if ((${_PYTHON_PREFIX}_LIBRARY_RELEASE AND ${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE)
- OR (${_PYTHON_PREFIX}_LIBRARY_DEBUG AND ${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG))
- # System manage shared libraries in two parts: import and runtime
- if (${_PYTHON_PREFIX}_LIBRARY_RELEASE AND ${_PYTHON_PREFIX}_LIBRARY_DEBUG)
- set_property (TARGET ${_PYTHON_PREFIX}::Python PROPERTY IMPORTED_CONFIGURATIONS RELEASE DEBUG)
- set_target_properties (${_PYTHON_PREFIX}::Python
- PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES_RELEASE "C"
- IMPORTED_IMPLIB_RELEASE "${${_PYTHON_PREFIX}_LIBRARY_RELEASE}"
- IMPORTED_LOCATION_RELEASE "${${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE}")
- set_target_properties (${_PYTHON_PREFIX}::Python
- PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES_DEBUG "C"
- IMPORTED_IMPLIB_DEBUG "${${_PYTHON_PREFIX}_LIBRARY_DEBUG}"
- IMPORTED_LOCATION_DEBUG "${${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG}")
+ macro (__PYTHON_IMPORT_LIBRARY __name)
+ if (${_PYTHON_PREFIX}_LIBRARY_RELEASE MATCHES "${CMAKE_SHARED_LIBRARY_SUFFIX}$"
+ OR ${_PYTHON_PREFIX}_LIBRARY_DEBUG MATCHES "${CMAKE_SHARED_LIBRARY_SUFFIX}$"
+ OR ${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE OR ${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG)
+ set (_${_PYTHON_PREFIX}_LIBRARY_TYPE SHARED)
else()
- set_target_properties (${_PYTHON_PREFIX}::Python
- PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES "C"
- IMPORTED_IMPLIB "${${_PYTHON_PREFIX}_LIBRARY}"
- IMPORTED_LOCATION "${${_PYTHON_PREFIX}_RUNTIME_LIBRARY}")
+ set (_${_PYTHON_PREFIX}_LIBRARY_TYPE STATIC)
endif()
- else()
- if (${_PYTHON_PREFIX}_LIBRARY_RELEASE AND ${_PYTHON_PREFIX}_LIBRARY_DEBUG)
- set_property (TARGET ${_PYTHON_PREFIX}::Python PROPERTY IMPORTED_CONFIGURATIONS RELEASE DEBUG)
- set_target_properties (${_PYTHON_PREFIX}::Python
- PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES_RELEASE "C"
- IMPORTED_LOCATION_RELEASE "${${_PYTHON_PREFIX}_LIBRARY_RELEASE}")
- set_target_properties (${_PYTHON_PREFIX}::Python
- PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES_DEBUG "C"
- IMPORTED_LOCATION_DEBUG "${${_PYTHON_PREFIX}_LIBRARY_DEBUG}")
+
+ add_library (${__name} ${_${_PYTHON_PREFIX}_LIBRARY_TYPE} IMPORTED)
+
+ set_property (TARGET ${__name}
+ PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${${_PYTHON_PREFIX}_INCLUDE_DIR}")
+
+ if ((${_PYTHON_PREFIX}_LIBRARY_RELEASE AND ${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE)
+ OR (${_PYTHON_PREFIX}_LIBRARY_DEBUG AND ${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG))
+ # System manage shared libraries in two parts: import and runtime
+ if (${_PYTHON_PREFIX}_LIBRARY_RELEASE AND ${_PYTHON_PREFIX}_LIBRARY_DEBUG)
+ set_property (TARGET ${__name} PROPERTY IMPORTED_CONFIGURATIONS RELEASE DEBUG)
+ set_target_properties (${__name}
+ PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES_RELEASE "C"
+ IMPORTED_IMPLIB_RELEASE "${${_PYTHON_PREFIX}_LIBRARY_RELEASE}"
+ IMPORTED_LOCATION_RELEASE "${${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE}")
+ set_target_properties (${__name}
+ PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES_DEBUG "C"
+ IMPORTED_IMPLIB_DEBUG "${${_PYTHON_PREFIX}_LIBRARY_DEBUG}"
+ IMPORTED_LOCATION_DEBUG "${${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG}")
+ else()
+ set_target_properties (${__name}
+ PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES "C"
+ IMPORTED_IMPLIB "${${_PYTHON_PREFIX}_LIBRARY}"
+ IMPORTED_LOCATION "${${_PYTHON_PREFIX}_RUNTIME_LIBRARY}")
+ endif()
else()
- set_target_properties (${_PYTHON_PREFIX}::Python
- PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES "C"
- IMPORTED_LOCATION "${${_PYTHON_PREFIX}_LIBRARY}")
+ if (${_PYTHON_PREFIX}_LIBRARY_RELEASE AND ${_PYTHON_PREFIX}_LIBRARY_DEBUG)
+ set_property (TARGET ${_PYTHON_PREFIX}::Python PROPERTY IMPORTED_CONFIGURATIONS RELEASE DEBUG)
+ set_target_properties (${__name}
+ PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES_RELEASE "C"
+ IMPORTED_LOCATION_RELEASE "${${_PYTHON_PREFIX}_LIBRARY_RELEASE}")
+ set_target_properties (${__name}
+ PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES_DEBUG "C"
+ IMPORTED_LOCATION_DEBUG "${${_PYTHON_PREFIX}_LIBRARY_DEBUG}")
+ else()
+ set_target_properties (${__name}
+ PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES "C"
+ IMPORTED_LOCATION "${${_PYTHON_PREFIX}_LIBRARY}")
+ endif()
endif()
+
+ if (_${_PYTHON_PREFIX}_CONFIG AND _${_PYTHON_PREFIX}_LIBRARY_TYPE STREQUAL "STATIC")
+ # extend link information with dependent libraries
+ execute_process (COMMAND "${_${_PYTHON_PREFIX}_CONFIG}" --ldflags
+ RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT
+ OUTPUT_VARIABLE _${_PYTHON_PREFIX}_FLAGS
+ ERROR_QUIET
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+ if (NOT _${_PYTHON_PREFIX}_RESULT)
+ string (REGEX MATCHALL "-[Ll][^ ]+" _${_PYTHON_PREFIX}_LINK_LIBRARIES "${_${_PYTHON_PREFIX}_FLAGS}")
+ # remove elements relative to python library itself
+ list (FILTER _${_PYTHON_PREFIX}_LINK_LIBRARIES EXCLUDE REGEX "-lpython")
+ foreach (_${_PYTHON_PREFIX}_DIR IN LISTS ${_PYTHON_PREFIX}_LIBRARY_DIRS)
+ list (FILTER _${_PYTHON_PREFIX}_LINK_LIBRARIES EXCLUDE REGEX "-L${${_PYTHON_PREFIX}_DIR}")
+ endforeach()
+ set_property (TARGET ${__name}
+ PROPERTY INTERFACE_LINK_LIBRARIES ${_${_PYTHON_PREFIX}_LINK_LIBRARIES})
+ endif()
+ endif()
+ endmacro()
+
+ if (NOT TARGET ${_PYTHON_PREFIX}::Python)
+ __python_import_library (${_PYTHON_PREFIX}::Python)
endif()
- if (_${_PYTHON_PREFIX}_CONFIG AND _${_PYTHON_PREFIX}_LIBRARY_TYPE STREQUAL "STATIC")
- # extend link information with dependent libraries
- execute_process (COMMAND "${_${_PYTHON_PREFIX}_CONFIG}" --ldflags
- RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT
- OUTPUT_VARIABLE _${_PYTHON_PREFIX}_FLAGS
- ERROR_QUIET
- OUTPUT_STRIP_TRAILING_WHITESPACE)
- if (NOT _${_PYTHON_PREFIX}_RESULT)
- string (REGEX MATCHALL "-[Ll][^ ]+" _${_PYTHON_PREFIX}_LINK_LIBRARIES "${_${_PYTHON_PREFIX}_FLAGS}")
- # remove elements relative to python library itself
- list (FILTER _${_PYTHON_PREFIX}_LINK_LIBRARIES EXCLUDE REGEX "-lpython")
- foreach (_${_PYTHON_PREFIX}_DIR IN LISTS ${_PYTHON_PREFIX}_LIBRARY_DIRS)
- list (FILTER _${_PYTHON_PREFIX}_LINK_LIBRARIES EXCLUDE REGEX "-L${${_PYTHON_PREFIX}_DIR}")
- endforeach()
- set_property (TARGET ${_PYTHON_PREFIX}::Python
- PROPERTY INTERFACE_LINK_LIBRARIES ${_${_PYTHON_PREFIX}_LINK_LIBRARIES})
+ if (NOT TARGET ${_PYTHON_PREFIX}::Module)
+ if (CMAKE_SYSTEM_NAME MATCHES "^(Windows.*|CYGWIN|MSYS)$")
+ # On Windows/CYGWIN/MSYS, Python::Module is the same as Python::Python
+ # but ALIAS cannot be used because the imported library is not GLOBAL.
+ __python_import_library (${_PYTHON_PREFIX}::Module)
+ else()
+ add_library (${_PYTHON_PREFIX}::Module INTERFACE IMPORTED)
+ set_property (TARGET ${_PYTHON_PREFIX}::Module
+ PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${${_PYTHON_PREFIX}_INCLUDE_DIR}")
+
+ # When available, enforce shared library generation with undefined symbols
+ if (APPLE)
+ set_property (TARGET ${_PYTHON_PREFIX}::Module
+ PROPERTY INTERFACE_LINK_OPTIONS "LINKER:-undefined,dynamic_lookup")
+ endif()
+ if (CMAKE_SYSTEM_NAME STREQUAL "SunOS")
+ set_property (TARGET ${_PYTHON_PREFIX}::Module
+ PROPERTY INTERFACE_LINK_OPTIONS "LINKER:-z,nodefs")
+ endif()
+ if (CMAKE_SYSTEM_NAME STREQUAL "AIX")
+ set_property (TARGET ${_PYTHON_PREFIX}::Module
+ PROPERTY INTERFACE_LINK_OPTIONS "LINKER:-b,erok")
+ endif()
endif()
endif()
@@ -1328,7 +1360,7 @@ if(_${_PYTHON_PREFIX}_CMAKE_ROLE STREQUAL "PROJECT")
#
function (__${_PYTHON_PREFIX}_ADD_LIBRARY prefix name)
cmake_parse_arguments (PARSE_ARGV 2 PYTHON_ADD_LIBRARY
- "STATIC;SHARED;MODULE" "" "")
+ "STATIC;SHARED;MODULE" "" "")
unset (type)
if (NOT (PYTHON_ADD_LIBRARY_STATIC
@@ -1337,15 +1369,18 @@ if(_${_PYTHON_PREFIX}_CMAKE_ROLE STREQUAL "PROJECT")
set (type MODULE)
endif()
add_library (${name} ${type} ${ARGN})
- target_link_libraries (${name} PRIVATE ${prefix}::Python)
- # customize library name to follow module name rules
get_property (type TARGET ${name} PROPERTY TYPE)
+
if (type STREQUAL "MODULE_LIBRARY")
+ target_link_libraries (${name} PRIVATE ${prefix}::Module)
+ # customize library name to follow module name rules
set_property (TARGET ${name} PROPERTY PREFIX "")
if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
set_property (TARGET ${name} PROPERTY SUFFIX ".pyd")
endif()
+ else()
+ target_link_libraries (${name} PRIVATE ${prefix}::Python)
endif()
endfunction()
endif()
@@ -1355,7 +1390,7 @@ if(_${_PYTHON_PREFIX}_CMAKE_ROLE STREQUAL "PROJECT")
add_library (${_PYTHON_PREFIX}::NumPy INTERFACE IMPORTED)
set_property (TARGET ${_PYTHON_PREFIX}::NumPy
PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR}")
- target_link_libraries (${_PYTHON_PREFIX}::NumPy INTERFACE ${_PYTHON_PREFIX}::Python)
+ target_link_libraries (${_PYTHON_PREFIX}::NumPy INTERFACE ${_PYTHON_PREFIX}::Module)
endif()
endif()
diff --git a/Modules/FindPython2.cmake b/Modules/FindPython2.cmake
index a2be84fee5..67499d827f 100644
--- a/Modules/FindPython2.cmake
+++ b/Modules/FindPython2.cmake
@@ -47,7 +47,11 @@ This module defines the following :ref:`Imported Targets <Imported Targets>`
``Python2::Compiler``
Python 2 compiler. Target defined if component ``Compiler`` is found.
``Python2::Python``
- Python 2 library. Target defined if component ``Development`` is found.
+ Python 2 library for Python embedding. Target defined if component
+ ``Development`` is found.
+``Python2::Module``
+ Python 2 library for Python module. Target defined if component
+ ``Development`` is found.
``Python2::NumPy``
NumPy library for Python 2. Target defined if component ``NumPy`` is found.
@@ -174,11 +178,11 @@ Hints
Commands
^^^^^^^^
-This module defines the command ``Python2_add_library`` (when
+This module defines the command ``Python_add_library`` (when
:prop_gbl:`CMAKE_ROLE` is ``PROJECT``), which has the same semantics as
-:command:`add_library`, but takes care of Python module naming rules
-(only applied if library is of type ``MODULE``), and adds a dependency to target
-``Python2::Python``::
+:command:`add_library` and adds a dependency to target ``Python2::Python`` or,
+when library type is ``MODULE``, to target ``Python2::Module`` and takes care
+of Python module naming rules::
Python2_add_library (my_module MODULE src1.cpp)
diff --git a/Modules/FindPython3.cmake b/Modules/FindPython3.cmake
index 3409554580..fdb99a69a7 100644
--- a/Modules/FindPython3.cmake
+++ b/Modules/FindPython3.cmake
@@ -47,7 +47,11 @@ This module defines the following :ref:`Imported Targets <Imported Targets>`
``Python3::Compiler``
Python 3 compiler. Target defined if component ``Compiler`` is found.
``Python3::Python``
- Python 3 library. Target defined if component ``Development`` is found.
+ Python 3 library for Python embedding. Target defined if component
+ ``Development`` is found.
+``Python3::Module``
+ Python 3 library for Python module. Target defined if component
+ ``Development`` is found.
``Python3::NumPy``
NumPy library for Python 3. Target defined if component ``NumPy`` is found.
@@ -174,11 +178,11 @@ Hints
Commands
^^^^^^^^
-This module defines the command ``Python3_add_library`` (when
+This module defines the command ``Python_add_library`` (when
:prop_gbl:`CMAKE_ROLE` is ``PROJECT``), which has the same semantics as
-:command:`add_library`, but takes care of Python module naming rules
-(only applied if library is of type ``MODULE``), and adds a dependency to target
-``Python3::Python``::
+:command:`add_library` and adds a dependency to target ``Python3::Python`` or,
+when library type is ``MODULE``, to target ``Python3::Module`` and takes care
+of Python module naming rules::
Python3_add_library (my_module MODULE src1.cpp)