Skip to content

Commit e076c45

Browse files
committed
macOS: disable fixup chains when linking extension modules
On macOS, extension library builds usually rely on the flag ``-undefined dynamic_lookup`` to get the linker to temporarily accept missing CPython API symbols. As the name implies, those symbols are then dynamically resolved when Python imports such an extension library. Binaries produced in this way are more portable since they don't contain a hardcoded path to the CPython library. This is critical when distributing binary wheels on PyPI, etc.. When targeting macOS>=12, XCode recently started to generate a somewhat ominous warning: ``-undefined dynamic_lookup may not work with chained fixups`` For further detail on what chained fixups are, see the following informative WWDC https://developer.apple.com/videos/play/wwdc2022/110362/ (the relevant part starts about 20mins into the video) The message that the dynamic resolution functionality became broken. I reported this to Apple via feedback request FB11767124. Apple investigated the request and updated the behavior of ``ld`` starting with XCode 14.3b1+: it now disables the fixup chain linker optimization whenever ``-undefined dynamic_lookup`` is specified. The feedback from Apple also stated that the parameter ``-Wl,-no_fixup_chains`` should be specified on pre-14.3 XCode versions to ensure correct behavior. This commit realizes those changes by passing a flag to *always* disable fixup chains. Related discussion is available in the CPython repository (python/cpython#97524).
1 parent 3cc7e42 commit e076c45

File tree

2 files changed

+8
-6
lines changed

2 files changed

+8
-6
lines changed

docs/compiling.rst

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -582,13 +582,13 @@ using ``pip`` or ``conda``. If it hasn't, you can also manually specify
582582
``-I <path-to-pybind11>/include`` together with the Python includes path
583583
``python3-config --includes``.
584584

585-
On macOS: the build command is almost the same but it also requires passing
586-
the ``-undefined dynamic_lookup`` flag so as to ignore missing symbols when
587-
building the module:
585+
On macOS: the build command is almost the same but it also requires passing the
586+
``-undefined dynamic_lookup -Wl,no_fixup_chains`` flag to ignore missing symbols
587+
when building the module:
588588

589589
.. code-block:: bash
590590
591-
$ c++ -O3 -Wall -shared -std=c++11 -undefined dynamic_lookup $(python3 -m pybind11 --includes) example.cpp -o example$(python3-config --extension-suffix)
591+
$ c++ -O3 -Wall -shared -std=c++11 -undefined dynamic_lookup -Wl,no_fixup_chains $(python3 -m pybind11 --includes) example.cpp -o example$(python3-config --extension-suffix)
592592
593593
In general, it is advisable to include several additional build parameters
594594
that can considerably reduce the size of the created binary. Refer to section

tools/pybind11Common.cmake

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,15 +75,17 @@ if(CMAKE_VERSION VERSION_LESS 3.13)
7575
set_property(
7676
TARGET pybind11::python_link_helper
7777
APPEND
78-
PROPERTY INTERFACE_LINK_LIBRARIES "$<$<PLATFORM_ID:Darwin>:-undefined dynamic_lookup>")
78+
PROPERTY INTERFACE_LINK_LIBRARIES
79+
"$<$<PLATFORM_ID:Darwin>:-undefined dynamic_lookup -no_fixup_chains>")
7980
else()
8081
# link_options was added in 3.13+
8182
# This is safer, because you are ensured the deduplication pass in CMake will not consider
8283
# these separate and remove one but not the other.
8384
set_property(
8485
TARGET pybind11::python_link_helper
8586
APPEND
86-
PROPERTY INTERFACE_LINK_OPTIONS "$<$<PLATFORM_ID:Darwin>:LINKER:-undefined,dynamic_lookup>")
87+
PROPERTY INTERFACE_LINK_OPTIONS
88+
"$<$<PLATFORM_ID:Darwin>:LINKER:-undefined,dynamic_lookup,-no_fixup_chains>")
8789
endif()
8890

8991
# ------------------------ Windows extras -------------------------

0 commit comments

Comments
 (0)