Skip to content

Commit 75b8306

Browse files
authored
Remove arm64e slice; return dyn linking for CocoaPods (#18)
* Automatically enable Apple Silicon support Since Xcode 12.2 (stable) is out, Apple Silicon support can be enabled automatically there. Check the version of the command-line tools and set APPLE_SILICON_SUPPORT value automatically if possible. After a while, once Xcode 12.0.1 and earlier are not longer supported and widely used, this variable can be removed completely. Right now it won't be really necessary to set it explicitly, unless you want something strange. * Revert "Use static frameworks for CocoaPods (#13)" This reverts commit d21e3b7. We can't just migrate CLOpenSSL to static frameworks as that requires all upstream dependencies to migrate to static frameworks too, and that breaks builds left, right, and center. Instead, we have figured out what has been breaking dynamic linkage with CocoaPods, and now we're coming back to using dynamic linkage. If static versions of CLOpenSSL are published, they will be published in a separate podspec. * Drop arm64e to work around CocoaPods issues arm64e builds are included to test the pointer authentication feature of iOS devices. We have to include it in binary CLOpenSSL builds so that upstream users of CLOpenSSL might enable it themselves for testing. However, inclusion of this architecture slice causes issues with CocoaPods handling of vendored binary frameworks. arm64e builds include a certain linker command -- LC_DYLD_CHAINED_FIXUPS (0x80000034) -- which confuses CocoaPods' detector of dynamic binaries, making it believe that the vendored framework in a static one, not dynamic. This in turn causes issues when using CLOpenSSL as CocoaPods refuses to link "static" binary without "static_framework = true". This is a know issue in CocoaPods, stemming from the missing features in Homebrew's Mach-O parser [1][2]. [1]: Homebrew/brew#7857 [2]: Homebrew/ruby-macho#261 There is nothing we can do about it right now, other than disable "arm64e" builds for the time being. This does not affect deployment to App Store, but will break dependencies of CLOpenSSL which expect this architecture to be present. The dependencies will have to disable arm64e in their projects, if they have it explicitly enabled. (Considering that CocoaPods packaging of CLOpenSSL was never in good shape, the actual impact of this change should be minimal.) * Set install name during linkage Instead of using "install_name_tool" to fix the LC_ID_DYLIB value of the dylib, pass the "-install_name" parameter to the linker directly. This doesn't change anything in the resulting binary but looks a bit cleaner. * Use ABI-correct install name on macOS On macOS -- contrary to iOS, watchOS, and tvOS -- it is customary for frameworks to provide additional internal structure which helps with binary compatibility. For example, on iOS/watchOS/tvOS a framework typically has flat structure: openssl.framework ├── Headers ├── Info.plist └── openssl while on macOS it's a bit more involved: frameworks/MacOSX/openssl.framework ├── Headers -> Versions/Current/Headers ├── Resources -> Versions/Current/Resources ├── Versions │ ├── A │ └── Current -> A └── openssl -> Versions/Current/openssl Note that the top-level files are actually symlinks to the "Versions/Current" which in turn is a symlink to the "A" version, which actually contains the framework content: openssl.framework/Versions/A ├── Headers ├── Resources │ └── Info.plist └── openssl Currently, the 'install name' of all "openssl" binaries is set to "@rpath/openssl.framework/openssl", which makes the linked binaries remember and use this path when loading OpenSSL. On macOS this will involve two additional symlink resolutions. Another thing here is that if we will need to introduce a different version of OpenSSL framework on macOS, existing applications will still look up the current one, instead of using the A version that they should. Update the install name computation to use @rpath/openssl.framework/openssl for iOS, watchOS, tvOS while using more explicit @rpath/openssl.framework/Versions/A/openssl for macOS. This is how Apple's system frameworks do it. Though they have a pressing issue of supporting multiple possible ABIs and it's not that important in our case, you never know when this turns out to be necessary or whether some weird tool might choke on the symlinks.
1 parent 6a8e199 commit 75b8306

File tree

5 files changed

+30
-19
lines changed

5 files changed

+30
-19
lines changed

Makefile

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,22 +14,30 @@ endif
1414
VERSION ?= 1.1.1h
1515

1616
## Extra version of the distributed package
17-
PACKAGE_VERSION ?= 1
17+
PACKAGE_VERSION ?= 2
1818
export PACKAGE_VERSION
1919

2020
MIN_IOS_SDK = 10.0
2121
MIN_OSX_SDK = 10.11
2222
export MIN_IOS_SDK MIN_OSX_SDK
2323

24-
BUILD_ARCHS += ios_i386 ios_x86_64 ios_arm64 ios_arm64e ios_armv7s ios_armv7
24+
BUILD_ARCHS += ios_i386 ios_x86_64 ios_arm64 ios_armv7s ios_armv7
2525
BUILD_ARCHS += mac_x86_64
2626
BUILD_TARGETS += ios-sim-cross-i386 ios-sim-cross-x86_64
27-
BUILD_TARGETS += ios64-cross-arm64 ios64-cross-arm64e ios-cross-armv7s ios-cross-armv7
27+
BUILD_TARGETS += ios64-cross-arm64 ios-cross-armv7s ios-cross-armv7
2828
BUILD_TARGETS += macos64-x86_64
2929

30-
# Apple Silicon support is currently experimental. It is available only with
31-
# beta Xcode versions installed. Once iOS 14 and macOS 11 are released and
32-
# stable Xcode supports arm64, these settings are going to become default.
30+
# Automatically enable Apple Silicon support if running with Xcode 12.2+
31+
# unless the user has decided explicitly.
32+
ifeq ($(APPLE_SILICON_SUPPORT),)
33+
xcode_version := $(shell xcodebuild -version | awk '/Xcode/ {print $$2}')
34+
ifeq ($(shell printf '%s\n' "12.2" "$(xcode_version)" | sort -V | head -1),12.2)
35+
APPLE_SILICON_SUPPORT := yes
36+
endif
37+
endif
38+
39+
# Not all currently used Xcode versions support building for Apple Silicon.
40+
# Enable this architecture only when requested.
3341
ifeq ($(APPLE_SILICON_SUPPORT),yes)
3442
BUILD_ARCHS += mac_arm64
3543
BUILD_TARGETS += macos64-arm64

cocoapods/CLOpenSSL.podspec.template

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -204,10 +204,6 @@ EOF
204204
done
205205
EOF
206206

207-
# Tell CocoaPods that the frameworks we publish are "static frameworks".
208-
# This ensures correct resolution of transitive dependencies.
209-
s.static_framework = true
210-
211207
# Set the minimum platform versions. We just know the right ones from the
212208
# prebuilt frameworks we download.
213209
s.ios.deployment_target = min_target_ios

config/20-all-platforms.conf

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,15 @@ my %targets = ();
3838
cflags => add(sub { defined($ENV{'MACOS_MIN_SDK_VERSION'}) ? '-mmacosx-version-min=$(MACOS_MIN_SDK_VERSION)' : '-mmacosx-version-min=10.11'; }),
3939
},
4040

41+
# Apple Silicon support
42+
# https://github.com/openssl/openssl/pull/12369
4143
"darwin64-arm64-cc" => {
42-
inherit_from => [ "darwin-common", asm("") ],
44+
inherit_from => [ "darwin-common", asm("aarch64_asm") ],
4345
CFLAGS => add("-Wall"),
4446
cflags => add("-arch arm64"),
4547
lib_cppflags => add("-DL_ENDIAN"),
4648
bn_ops => "SIXTY_FOUR_BIT_LONG",
47-
perlasm_scheme => "macosx",
49+
perlasm_scheme => "ios64",
4850
},
4951

5052
## Apple WatchOS

create-openssl-framework.sh

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -128,8 +128,6 @@ function get_openssl_version() {
128128

129129
if [ $FWTYPE == "dynamic" ]; then
130130
DEVELOPER=`xcode-select -print-path`
131-
FW_EXEC_NAME="${FWNAME}.framework/${FWNAME}"
132-
INSTALL_NAME="@rpath/${FW_EXEC_NAME}"
133131
COMPAT_VERSION="1.0.0"
134132
CURRENT_VERSION="1.0.0"
135133
NORMALIZE_OPENSSL_VERSION=yes
@@ -178,6 +176,13 @@ if [ $FWTYPE == "dynamic" ]; then
178176
ar -x ../lib/libssl.a
179177
cd ..
180178

179+
# macOS frameworks have a bit different structure inside.
180+
if [[ $PLATFORM == MacOSX* ]]; then
181+
INSTALL_NAME="@rpath/${FWNAME}.framework/Versions/A/${FWNAME}"
182+
else
183+
INSTALL_NAME="@rpath/${FWNAME}.framework/${FWNAME}"
184+
fi
185+
181186
ld obj/*.o \
182187
-dylib \
183188
-bitcode_bundle \
@@ -188,8 +193,8 @@ if [ $FWTYPE == "dynamic" ]; then
188193
-compatibility_version $COMPAT_VERSION \
189194
-current_version $CURRENT_VERSION \
190195
-application_extension \
196+
-install_name $INSTALL_NAME \
191197
-o $FWNAME.dylib
192-
install_name_tool -id $INSTALL_NAME $FWNAME.dylib
193198

194199
cd ..
195200
done

scripts/update-specs.sh

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,10 +71,10 @@ sed -e "s/%%OPENSSL_VERSION%%/$version/g" \
7171
-e "s!%%GITHUB_REPO%%!$GITHUB_REPO!g" \
7272
-e "s/%%MIN_IOS_SDK%%/$MIN_IOS_SDK/g" \
7373
-e "s/%%MIN_OSX_SDK%%/$MIN_OSX_SDK/g" \
74-
-e "s/%%IPHONE_ARCHIVE_NAME%%/$IPHONE_STATIC_NAME/g" \
75-
-e "s/%%IPHONE_ARCHIVE_HASH%%/$(shasum -a 256 "$OUTPUT/$IPHONE_STATIC_NAME" | awk '{print $1}')/g" \
76-
-e "s/%%MACOSX_ARCHIVE_NAME%%/$MACOSX_STATIC_NAME/g" \
77-
-e "s/%%MACOSX_ARCHIVE_HASH%%/$(shasum -a 256 "$OUTPUT/$MACOSX_STATIC_NAME" | awk '{print $1}')/g" \
74+
-e "s/%%IPHONE_ARCHIVE_NAME%%/$IPHONE_DYNAMIC_NAME/g" \
75+
-e "s/%%IPHONE_ARCHIVE_HASH%%/$(shasum -a 256 "$OUTPUT/$IPHONE_DYNAMIC_NAME" | awk '{print $1}')/g" \
76+
-e "s/%%MACOSX_ARCHIVE_NAME%%/$MACOSX_DYNAMIC_NAME/g" \
77+
-e "s/%%MACOSX_ARCHIVE_HASH%%/$(shasum -a 256 "$OUTPUT/$MACOSX_DYNAMIC_NAME" | awk '{print $1}')/g" \
7878
$podspec.template > $podspec
7979
echo "Updated $podspec"
8080
echo

0 commit comments

Comments
 (0)