diff --git a/.github/workflows/xcodebuild.yml b/.github/workflows/xcodebuild.yml index 957ca84..b548274 100644 --- a/.github/workflows/xcodebuild.yml +++ b/.github/workflows/xcodebuild.yml @@ -8,7 +8,9 @@ on: - 'InterposeKit.xcodeproj/**' - 'Sources/**/*.[ch]' - 'Sources/**/*.swift' + - 'Example/**' - 'Tests/**/*.swift' + - 'Tests/verify_release_linking.sh' - '!Tests/LinuxMain.swift' pull_request: paths: @@ -16,7 +18,9 @@ on: - 'InterposeKit.xcodeproj/**' - 'Sources/**/*.[ch]' - 'Sources/**/*.swift' + - 'Example/**' - 'Tests/**/*.swift' + - 'Tests/verify_release_linking.sh' - '!Tests/LinuxMain.swift' workflow_dispatch: @@ -32,6 +36,8 @@ jobs: steps: - uses: actions/checkout@v2 - run: xcodebuild -version + - name: Release device app preserves object-hook helper + run: bash Tests/verify_release_linking.sh - name: macOS with UTF16 if: always() run: YAMS_DEFAULT_ENCODING=UTF16 xcodebuild ${{ matrix.xcode_flags }} ${{ matrix.flags_for_test }} -destination "platform=macOS,arch=$(uname -m)" test | xcpretty diff --git a/CHANGELOG.md b/CHANGELOG.md index b46c821..4d4d683 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ ##### Bug Fixes * Preserve trampoline argument registers in code-coverage builds. +* Preserve object-hook super trampolines in optimized Release builds, fixing https://github.com/steipete/InterposeKit/issues/29. Thanks to [@Thomvis](https://github.com/Thomvis). ## 0.01 diff --git a/Sources/SuperBuilder/src/ITKSuperBuilder.m b/Sources/SuperBuilder/src/ITKSuperBuilder.m index f698c07..a80e44f 100644 --- a/Sources/SuperBuilder/src/ITKSuperBuilder.m +++ b/Sources/SuperBuilder/src/ITKSuperBuilder.m @@ -36,7 +36,8 @@ static IMP ITKGetTrampolineForTypeEncoding(__unused const char *typeEncoding) { return requiresStructDispatch ? (IMP)msgSendSuperStretTrampoline : (IMP)msgSendSuperTrampoline; } -// Helper for binding with Swift +// Keep the helper available for Swift's runtime lookup in optimized application binaries. +__attribute__((__used__)) BOOL IKTAddSuperImplementationToClass(Class originalClass, SEL selector, NSError **error); BOOL IKTAddSuperImplementationToClass(Class originalClass, SEL selector, NSError **error) { return [SuperBuilder addSuperInstanceMethodToClass:originalClass selector:selector error:error]; diff --git a/Tests/verify_release_linking.sh b/Tests/verify_release_linking.sh new file mode 100644 index 0000000..5549430 --- /dev/null +++ b/Tests/verify_release_linking.sh @@ -0,0 +1,25 @@ +#!/bin/bash + +set -euo pipefail + +derived_data="$(mktemp -d "${TMPDIR:-/tmp}/InterposeKitReleaseLinking.XXXXXX")" + +xcodebuild \ + -project Example/InterposeExample.xcodeproj \ + -scheme InterposeExample \ + -configuration Release \ + -sdk iphoneos \ + -destination "generic/platform=iOS" \ + -derivedDataPath "$derived_data" \ + CODE_SIGNING_ALLOWED=NO \ + build \ + -quiet + +binary="$derived_data/Build/Products/Release-iphoneos/InterposeExample.app/InterposeExample" + +if ! xcrun nm -a "$binary" | grep -E '[[:space:]]T[[:space:]]_IKTAddSuperImplementationToClass$' >/dev/null; then + echo "IKTAddSuperImplementationToClass was stripped from the optimized app binary." >&2 + exit 1 +fi + +echo "Verified IKTAddSuperImplementationToClass in the optimized app binary."