FindPython: `Python_add_library` explicitly links to libpython
The target defined by FindPython, Python::Python
, appears to be intended for embedding Python, since it represents a link against the found libpython library. But, Python_add_library
, which is meant for defining Python extensions, links against it.
This doesn't strictly result in bad linkage, however it does make the binary module difficult to use after redistributing it. I hear this problem plagues macOS users the most -- an extension with explicit linkage against the system Python will segfault when loaded in Homebrew Python and vice versa. So, it's generally considered bad practice to link Python extension modules against libpython on macOS. This is also a problem on certain Linux distributions: Ubuntu tends to statically link its Python binary and export the CPython API with -rdynamic
, and the manylinux1 policy disallows explicit linkage against libpython for this reason.
Recently, though, Python 3.8 has changed the API to make this explicit on Unix, so to support building Python 3.8 extension modules, the FindPython module will need a second target to "link" against, representing the correct build configuration for an extension module. The Python_add_library
macro can then link against this new imported target rather than Python::Python
.
In addition to adding the CPython headers to the include search path, the proper settings seem to be:
-
Win32: Link as normal; can easily be an alias of
Python::Python
-
macOS: Don't link; add
-undefined dynamic_lookup
to the interface linker flags. - Linux/UNIX: Don't link.