Skip to content

Commit 00085b0

Browse files
Stamp Xcode build-provenance keys into generated framework Info.plists (#36)
create_plist() emitted ten hand-written keys and not a single DT* key, so the frameworks built from lib-dynload .so's did not look to Apple's tooling like anything Xcode had produced. Now emits the same key set Xcode stamps into a real framework: BuildMachineOSBuild, DTCompiler, DTPlatformBuild, DTPlatformName, DTPlatformVersion, DTSDKBuild, DTSDKName, DTXcode, DTXcodeBuild, UIDeviceFamily and (device slice only) UIRequiredDeviceCapabilities. Values are resolved once per run from the SDK actually in use — sw_vers, xcrun --show-sdk-version/--show-sdk-build-version, and xcodebuild -version. Also fixes the simulator slice, which previously claimed CFBundleSupportedPlatforms=iPhoneOS. create_plist() now takes the platform as its fourth argument and labels each slice correctly. Context: flet-dev/flet#6724 (ITMS-91065 on _ssl/_hashlib). The missing DT* keys are the most substantive difference we could find between these frameworks and third-party OpenSSL xcframeworks the App Store accepts. Whether that is what Apple's scan reads is unverified — a source signature was ruled out experimentally (codesign -f at export destroys everything but the identifier) and the privacy manifest was ruled out (the accepted third-party package ships an empty stub).
1 parent 8749e94 commit 00085b0

1 file changed

Lines changed: 81 additions & 6 deletions

File tree

darwin/xcframework_utils.sh

Lines changed: 81 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,56 @@ archs=("iphoneos.arm64" "iphonesimulator.arm64" "iphonesimulator.x86_64")
22

33
dylib_ext=so
44

5+
# Build-provenance values that Xcode stamps into every framework Info.plist it
6+
# produces (DT* / BuildMachineOSBuild). The frameworks here are assembled by hand
7+
# from lib-dynload .so's, so without this they carry none of them and the bundle
8+
# doesn't look like it was built by Xcode at all -- which is the most substantive
9+
# difference we could find between our _ssl/_hashlib frameworks and third-party
10+
# OpenSSL xcframeworks that Apple's App Store scan accepts. See flet-dev/flet#6724.
11+
#
12+
# Resolved once per run: identical for every framework built from the same SDK.
13+
sdk_metadata_init() {
14+
[ -n "${sdk_metadata_ready:-}" ] && return
15+
16+
build_machine_os_build=$(sw_vers -buildVersion)
17+
sdk_version=$(xcrun --sdk iphoneos --show-sdk-version)
18+
sdk_build=$(xcrun --sdk iphoneos --show-sdk-build-version)
19+
xcode_build=$(xcodebuild -version | sed -n 's/^Build version //p')
20+
21+
# DTXcode is the Xcode version with the separators dropped, as major(2) +
22+
# minor(1) + patch(1): 26.5 -> "2650", 16.2 -> "1620", 9.4.1 -> "0941".
23+
local xcode_version major minor patch
24+
xcode_version=$(xcodebuild -version | sed -n '1s/^Xcode //p')
25+
IFS=. read -r major minor patch <<< "$xcode_version"
26+
dt_xcode=$(printf '%02d%d%d' "$major" "${minor:-0}" "${patch:-0}")
27+
28+
sdk_metadata_ready=1
29+
}
30+
531
create_plist() {
632
name=$1
733
identifier=$2
834
plist_file=$3
35+
# "iphoneos" (default) or "iphonesimulator". The previous version hardcoded
36+
# iPhoneOS for both slices, which mislabelled the simulator framework.
37+
platform=${4:-iphoneos}
38+
39+
sdk_metadata_init
40+
41+
local supported_platform
42+
if [ "$platform" = "iphonesimulator" ]; then
43+
supported_platform=iPhoneSimulator
44+
else
45+
supported_platform=iPhoneOS
46+
fi
947

1048
cat > $plist_file << PLIST_TEMPLATE
1149
<?xml version="1.0" encoding="UTF-8"?>
1250
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
1351
<plist version="1.0">
1452
<dict>
53+
<key>BuildMachineOSBuild</key>
54+
<string>$build_machine_os_build</string>
1555
<key>CFBundleDevelopmentRegion</key>
1656
<string>en</string>
1757
<key>CFBundleName</key>
@@ -28,15 +68,50 @@ create_plist() {
2868
<string>1.0</string>
2969
<key>CFBundleSupportedPlatforms</key>
3070
<array>
31-
<string>iPhoneOS</string>
71+
<string>$supported_platform</string>
3272
</array>
33-
<key>MinimumOSVersion</key>
34-
<string>13.0</string>
3573
<key>CFBundleVersion</key>
3674
<string>1</string>
75+
<key>DTCompiler</key>
76+
<string>com.apple.compilers.llvm.clang.1_0</string>
77+
<key>DTPlatformBuild</key>
78+
<string>$sdk_build</string>
79+
<key>DTPlatformName</key>
80+
<string>$platform</string>
81+
<key>DTPlatformVersion</key>
82+
<string>$sdk_version</string>
83+
<key>DTSDKBuild</key>
84+
<string>$sdk_build</string>
85+
<key>DTSDKName</key>
86+
<string>$platform$sdk_version</string>
87+
<key>DTXcode</key>
88+
<string>$dt_xcode</string>
89+
<key>DTXcodeBuild</key>
90+
<string>$xcode_build</string>
91+
<key>MinimumOSVersion</key>
92+
<string>13.0</string>
93+
<key>UIDeviceFamily</key>
94+
<array>
95+
<integer>1</integer>
96+
<integer>2</integer>
97+
</array>
98+
PLIST_TEMPLATE
99+
100+
# Device slice only: the simulator framework is a fat arm64/x86_64 binary, so
101+
# it can't claim an arm64 device capability.
102+
if [ "$platform" != "iphonesimulator" ]; then
103+
cat >> $plist_file << PLIST_CAPABILITIES
104+
<key>UIRequiredDeviceCapabilities</key>
105+
<array>
106+
<string>arm64</string>
107+
</array>
108+
PLIST_CAPABILITIES
109+
fi
110+
111+
cat >> $plist_file << PLIST_TAIL
37112
</dict>
38113
</plist>
39-
PLIST_TEMPLATE
114+
PLIST_TAIL
40115
}
41116

42117
# convert lib-dynloads to xcframeworks
@@ -66,7 +141,7 @@ create_xcframework_from_dylibs() {
66141
mv "$iphone_dir/$dylib_relative_path" $fd/$framework
67142
echo "Frameworks/$framework.framework/$framework" > "$iphone_dir/$dylib_without_ext.fwork"
68143
install_name_tool -id @rpath/$framework.framework/$framework $fd/$framework
69-
create_plist $framework "org.python.$framework_identifier" $fd/Info.plist
144+
create_plist $framework "org.python.$framework_identifier" $fd/Info.plist iphoneos
70145
echo "$origin_prefix/$dylib_without_ext.fwork" > $fd/$framework.origin
71146

72147
# copy privacy manifest if any
@@ -84,7 +159,7 @@ create_xcframework_from_dylibs() {
84159
rm "$simulator_arm64_dir/$dylib_without_ext".*.$dylib_ext
85160
rm "$simulator_x86_64_dir/$dylib_without_ext".*.$dylib_ext
86161
install_name_tool -id @rpath/$framework.framework/$framework $fd/$framework
87-
create_plist $framework "org.python.$framework_identifier" $fd/Info.plist
162+
create_plist $framework "org.python.$framework_identifier" $fd/Info.plist iphonesimulator
88163
echo "$origin_prefix/$dylib_without_ext.fwork" > $fd/$framework.origin
89164

90165
# copy privacy manifest if any

0 commit comments

Comments
 (0)