[3.14] gh-132006: Add support for handling XCPrivacy manifests (GH-139163) (#139410)
Some checks are pending
Tests / Change detection (push) Waiting to run
Tests / Docs (push) Blocked by required conditions
Tests / Check if the ABI has changed (push) Blocked by required conditions
Tests / Check if Autoconf files are up to date (push) Blocked by required conditions
Tests / Check if generated files are up to date (push) Blocked by required conditions
Tests / (push) Blocked by required conditions
Tests / Windows MSI (push) Blocked by required conditions
Tests / Ubuntu SSL tests with OpenSSL (push) Blocked by required conditions
Tests / Android (aarch64) (push) Blocked by required conditions
Tests / Android (x86_64) (push) Blocked by required conditions
Tests / WASI (push) Blocked by required conditions
Tests / Hypothesis tests on Ubuntu (push) Blocked by required conditions
Tests / Address sanitizer (push) Blocked by required conditions
Tests / Sanitizers (push) Blocked by required conditions
Tests / Cross build Linux (push) Blocked by required conditions
Tests / CIFuzz (push) Blocked by required conditions
Tests / All required checks pass (push) Blocked by required conditions
Lint / lint (push) Waiting to run

Co-authored-by: Russell Keith-Magee <russell@keith-magee.com>
This commit is contained in:
Miss Islington (bot) 2025-10-01 15:50:33 +02:00 committed by GitHub
parent 20f472b629
commit 86bc87b30d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 55 additions and 2 deletions

View file

@ -316,7 +316,7 @@ def unpack_deps(
for name_ver in [
"BZip2-1.0.8-2",
"libFFI-3.4.7-2",
"OpenSSL-3.0.16-2",
"OpenSSL-3.0.17-1",
"XZ-5.6.4-2",
"mpdecimal-4.0.0-2",
"zstd-1.5.7-1",
@ -577,6 +577,7 @@ def create_xcframework(platform: str) -> str:
# Extract the package version from the merged framework
version = package_version(package_path / "Python.xcframework")
version_tag = ".".join(version.split(".")[:2])
# On non-macOS platforms, each framework in XCframework only contains the
# headers, libPython, plus an Info.plist. Other resources like the standard
@ -647,6 +648,23 @@ def create_xcframework(platform: str) -> str:
slice_framework / f"Headers/pyconfig-{arch}.h",
)
# Apple identifies certain libraries as "security risks"; if you
# statically link those libraries into a Framework, you become
# responsible for providing a privacy manifest for that framework.
xcprivacy_file = {
"OpenSSL": subdir(host_triple) / "prefix/share/OpenSSL.xcprivacy"
}
print(f" - {multiarch} xcprivacy files")
for module, lib in [
("_hashlib", "OpenSSL"),
("_ssl", "OpenSSL"),
]:
shutil.copy(
xcprivacy_file[lib],
slice_path
/ f"lib-{arch}/python{version_tag}/lib-dynload/{module}.xcprivacy",
)
print(" - build tools")
shutil.copytree(
PYTHON_DIR / "Apple/testbed/Python.xcframework/build",

View file

@ -67,6 +67,9 @@ install_dylib () {
# The name of the extension file
EXT=$(basename "$FULL_EXT")
# The name and location of the module
MODULE_PATH=$(dirname "$FULL_EXT")
MODULE_NAME=$(echo $EXT | cut -d "." -f 1)
# The location of the extension file, relative to the bundle
RELATIVE_EXT=${FULL_EXT#$CODESIGNING_FOLDER_PATH/}
# The path to the extension file, relative to the install base
@ -94,6 +97,16 @@ install_dylib () {
# Create a back reference to the .so file location in the framework
echo "${RELATIVE_EXT%.so}.fwork" > "$CODESIGNING_FOLDER_PATH/$FRAMEWORK_FOLDER/$FULL_MODULE_NAME.origin"
# If the framework provides an xcprivacy file, install it.
if [ -e "$MODULE_PATH/$MODULE_NAME.xcprivacy" ]; then
echo "Installing XCPrivacy file for $FRAMEWORK_FOLDER/$FULL_MODULE_NAME"
XCPRIVACY_FILE="$CODESIGNING_FOLDER_PATH/$FRAMEWORK_FOLDER/PrivacyInfo.xcprivacy"
if [ -e "$XCPRIVACY_FILE" ]; then
rm -rf "$XCPRIVACY_FILE"
fi
mv "$MODULE_PATH/$MODULE_NAME.xcprivacy" "$XCPRIVACY_FILE"
fi
echo "Signing framework as $EXPANDED_CODE_SIGN_IDENTITY_NAME ($EXPANDED_CODE_SIGN_IDENTITY)..."
/usr/bin/codesign --force --sign "$EXPANDED_CODE_SIGN_IDENTITY" ${OTHER_CODE_SIGN_FLAGS:-} -o runtime --timestamp=none --preserve-metadata=identifier,entitlements,flags --generate-entitlement-der "$CODESIGNING_FOLDER_PATH/$FRAMEWORK_FOLDER"
}

View file

@ -328,7 +328,12 @@ App Store Compliance
The only mechanism for distributing apps to third-party iOS devices is to
submit the app to the iOS App Store; apps submitted for distribution must pass
Apple's app review process. This process includes a set of automated validation
rules that inspect the submitted application bundle for problematic code.
rules that inspect the submitted application bundle for problematic code. There
are some steps that must be taken to ensure that your app will be able to pass
these validation steps.
Incompatible code in the standard library
-----------------------------------------
The Python standard library contains some code that is known to violate these
automated rules. While these violations appear to be false positives, Apple's
@ -339,3 +344,18 @@ The Python source tree contains
:source:`a patch file <Mac/Resources/app-store-compliance.patch>` that will remove
all code that is known to cause issues with the App Store review process. This
patch is applied automatically when building for iOS.
Privacy manifests
-----------------
In April 2025, Apple introduced a requirement for `certain third-party
libraries to provide a Privacy Manifest
<https://developer.apple.com/support/third-party-SDK-requirements>`__.
As a result, if you have a binary module that uses one of the affected
libraries, you must provide an ``.xcprivacy`` file for that library.
OpenSSL is one library affected by this requirement, but there are others.
If you produce a binary module named ``mymodule.so``, and use you the Xcode
build script described in step 7 above, you can place a ``mymodule.xcprivacy``
file next to ``mymodule.so``, and the privacy manifest will be installed into
the required location when the binary module is converted into a framework.

View file

@ -0,0 +1,2 @@
XCframeworks now include privacy manifests to satisfy Apple App Store
submission requirements.