https://github.com/python/cpython/commit/daff2a9c3cd6ee9bf64f530055f8acd31e02eec3
commit: daff2a9c3cd6ee9bf64f530055f8acd31e02eec3
branch: 3.14
author: Miss Islington (bot) <[email protected]>
committer: freakboy3742 <[email protected]>
date: 2025-11-19T02:25:34Z
summary:

[3.14] gh-141692: Add a slice-specific lib folder to iOS XCframeworks. 
(GH-141693) (#141733)

Modifies the iOS XCframework to include a lib folder for each slice that
contains a symlinked version of the libPython dynamic library.
(cherry picked from commit 7b0b70867586ef7109de60ccce94d13164dbb776)

Co-authored-by: Russell Keith-Magee <[email protected]>

files:
A Misc/NEWS.d/next/Tools-Demos/2025-11-18-13-55-47.gh-issue-141692.tud9if.rst
M Apple/__main__.py
M Apple/testbed/Python.xcframework/build/utils.sh
M Makefile.pre.in

diff --git a/Apple/__main__.py b/Apple/__main__.py
index 1c588c23d6b5d1..256966e76c2c97 100644
--- a/Apple/__main__.py
+++ b/Apple/__main__.py
@@ -477,6 +477,12 @@ def lib_platform_files(dirname, names):
                 or name == "build-details.json"
             )
         }
+    elif path.parts[-1] == "lib":
+        ignored_names = {
+            name
+            for name in names
+            if name.startswith("libpython") and name.endswith(".dylib")
+        }
     else:
         ignored_names = set()
 
@@ -614,6 +620,12 @@ def create_xcframework(platform: str) -> str:
             slice_framework / "Headers/pyconfig.h",
         )
 
+        print(f" - {slice_name} shared library")
+        # Create a simlink for the fat library
+        shared_lib = slice_path / f"lib/libpython{version_tag}.dylib"
+        shared_lib.parent.mkdir()
+        shared_lib.symlink_to("../Python.framework/Python")
+
         print(f" - {slice_name} architecture-specific files")
         for host_triple, multiarch in slice_parts.items():
             print(f"   - {multiarch} standard library")
@@ -625,6 +637,7 @@ def create_xcframework(platform: str) -> str:
                     framework_path(host_triple, multiarch) / "lib",
                     package_path / "Python.xcframework/lib",
                     ignore=lib_platform_files,
+                    symlinks=True,
                 )
                 has_common_stdlib = True
 
@@ -632,6 +645,7 @@ def create_xcframework(platform: str) -> str:
                 framework_path(host_triple, multiarch) / "lib",
                 slice_path / f"lib-{arch}",
                 ignore=lib_non_platform_files,
+                symlinks=True,
             )
 
             # Copy the host's pyconfig.h to an architecture-specific name.
diff --git a/Apple/testbed/Python.xcframework/build/utils.sh 
b/Apple/testbed/Python.xcframework/build/utils.sh
index 961c46d014b5f5..e7155d8b30e213 100755
--- a/Apple/testbed/Python.xcframework/build/utils.sh
+++ b/Apple/testbed/Python.xcframework/build/utils.sh
@@ -46,7 +46,8 @@ install_stdlib() {
         rsync -au --delete "$PROJECT_DIR/$PYTHON_XCFRAMEWORK_PATH/lib/" 
"$CODESIGNING_FOLDER_PATH/python/lib/"
         rsync -au 
"$PROJECT_DIR/$PYTHON_XCFRAMEWORK_PATH/$SLICE_FOLDER/lib-$ARCHS/" 
"$CODESIGNING_FOLDER_PATH/python/lib/"
     else
-        rsync -au --delete 
"$PROJECT_DIR/$PYTHON_XCFRAMEWORK_PATH/$SLICE_FOLDER/lib/" 
"$CODESIGNING_FOLDER_PATH/python/lib/"
+        # A single-arch framework will have a libpython symlink; that can't be 
included at runtime
+        rsync -au --delete 
"$PROJECT_DIR/$PYTHON_XCFRAMEWORK_PATH/$SLICE_FOLDER/lib/" 
"$CODESIGNING_FOLDER_PATH/python/lib/" --exclude 'libpython*.dylib'
     fi
 }
 
diff --git a/Makefile.pre.in b/Makefile.pre.in
index 711628a4c22242..f29de054aba6ee 100644
--- a/Makefile.pre.in
+++ b/Makefile.pre.in
@@ -3033,6 +3033,9 @@ frameworkinstallunversionedstructure:     $(LDLIBRARY)
        $(INSTALL) -d -m $(DIRMODE) $(DESTDIR)$(PYTHONFRAMEWORKINSTALLDIR)
        sed 's/%VERSION%/'"`$(RUNSHARED) $(PYTHON_FOR_BUILD) -c 'import 
platform; print(platform.python_version())'`"'/g' < $(RESSRCDIR)/Info.plist > 
$(DESTDIR)$(PYTHONFRAMEWORKINSTALLDIR)/Info.plist
        $(INSTALL_SHARED) $(LDLIBRARY) 
$(DESTDIR)$(PYTHONFRAMEWORKPREFIX)/$(LDLIBRARY)
+       $(INSTALL) -d -m $(DIRMODE) $(DESTDIR)$(LIBDIR)
+       $(LN) -fs "../$(LDLIBRARY)" 
"$(DESTDIR)$(prefix)/lib/libpython$(LDVERSION).dylib"
+       $(LN) -fs "../$(LDLIBRARY)" 
"$(DESTDIR)$(prefix)/lib/libpython$(VERSION).dylib"
        $(INSTALL) -d -m $(DIRMODE) $(DESTDIR)$(BINDIR)
        for file in $(srcdir)/$(RESSRCDIR)/bin/* ; do \
                $(INSTALL) -m $(EXEMODE) $$file $(DESTDIR)$(BINDIR); \
diff --git 
a/Misc/NEWS.d/next/Tools-Demos/2025-11-18-13-55-47.gh-issue-141692.tud9if.rst 
b/Misc/NEWS.d/next/Tools-Demos/2025-11-18-13-55-47.gh-issue-141692.tud9if.rst
new file mode 100644
index 00000000000000..d85c54db3646f6
--- /dev/null
+++ 
b/Misc/NEWS.d/next/Tools-Demos/2025-11-18-13-55-47.gh-issue-141692.tud9if.rst
@@ -0,0 +1,3 @@
+Each slice of an iOS XCframework now contains a ``lib`` folder that contains
+a symlink to the libpython dylib. This allows binary modules to be compiled
+for iOS using dynamic libreary linking, rather than Framework linking.

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]

Reply via email to