Hi
I have an Xcode 8.3.3 Swift 3 project that builds a Universal framework (MyMobileKit). The project builds to simulator and device just fine. I reference the framework in another project i.e a UI project (MyApp), that project also builds to simulator, device and archive fine. When I export MyApp with bitcode enabled the problems occur as follows:
IDEDistribution.standard.log
(truncated the output, displaying the last sections where the export fails)
{
code = 284;
description = "Failed to resolve linkage dependency libswiftUIKit.dylib x86_64 -> @rpath/libswiftObjectiveC.dylib: Unknown arch x86_64";
info = {
};
level = WARN;
},
{
code = 630;
description = "ipatool failed with an exception: #<NoMethodError: undefined method `platform' for nil:NilClass>\n /Applications/Xcode.app/Contents/Developer/usr/bin/ipatool:922:in `platform'\n /Applications/Xcode.app/Contents/Developer/usr/bin/ipatool:2074:in `block in CompileOrStripBitcodeInBundle'\n /Applications/Xcode.app/Contents/Developer/usr/bin/ipatool:2056:in `each'\n /Applications/Xcode.app/Contents/Developer/usr/bin/ipatool:2056:in `CompileOrStripBitcodeInBundle'\n /Applications/Xcode.app/Contents/Developer/usr/bin/ipatool:2125:in `ProcessIPA'\n /Applications/Xcode.app/Contents/Developer/usr/bin/ipatool:2693:in `<main>'";
info = {
};
level = ERROR;
type = exception;
}
);
thinnableAssetCatalogs = (
"/var/folders/qj/vct1ccc13_s2g65vdpxsyqr80000gn/T/XcodeDistPipeline.oVB/Root/Payload/MyApp.app/Assets.car"
);
}
2017-08-31 00:55:49 +0000 [MT] Exporting using IDEDistributionPackageExportStep
2017-08-31 00:55:53 +0000 [MT] Canceled distribution assistant
The MyMobileKit framework project uses the following :
Linked Framework and Libraries
LocalAuthentication.framework
UIKit.framework
AVFoundation.framework
Build Settings
BITCODE_GENERATION_MODE = bitcode
Always Embed Swift Standard Libraries = Yes
The in the Build Phases of MyMobileKit.framework project it ends with a Run Script to create a Universal framework as follows:
#!/bin/sh
UNIVERSAL_OUTPUTFOLDER=${BUILD_DIR}/${CONFIGURATION}-universal
# make sure the output directory exists
mkdir -p "${UNIVERSAL_OUTPUTFOLDER}"
# Next, work out if we're in SIM or DEVICE
if [ "false" == ${ALREADYINVOKED:-false} ]; then
export ALREADYINVOKED="true"
if [ ${PLATFORM_NAME} = "iphonesimulator" ]; then
xcodebuild -target "MyMobileKit" ONLY_ACTIVE_ARCH=NO -configuration ${CONFIGURATION} -sdk iphoneos BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" clean build
else
xcodebuild -target "MyMobileKit" -configuration ${CONFIGURATION} -sdk iphonesimulator ONLY_ACTIVE_ARCH=NO BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" clean build
fi
# Step 2. Copy the framework structure (from iphoneos build) to the universal folder
cp -LR "${BUILD_DIR}/${CONFIGURATION}-iphoneos/MyMobileKit.framework" "${UNIVERSAL_OUTPUTFOLDER}/"
# Step 3. Copy Swift modules and frameworks from iphonesimulator build (if it exists) to the copied framework directory
SIMULATOR_SWIFT_MODULES_DIR="${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/MyMobileKit.framework/Modules/MyMobileKit.swiftmodule/."
if [ -d "${SIMULATOR_SWIFT_MODULES_DIR}" ]; then
cp -LR "${SIMULATOR_SWIFT_MODULES_DIR}" "${UNIVERSAL_OUTPUTFOLDER}/MyMobileKit.framework/Modules/MyMobileKit.swiftmodule"
fi
SIMULATOR_SWIFT_FRAMEWORKS_DIR="${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/MyMobileKit.framework/Frameworks/."
if [ -d "${SIMULATOR_SWIFT_FRAMEWORKS_DIR}" ]; then
cp -LR "${SIMULATOR_SWIFT_FRAMEWORKS_DIR}" "${UNIVERSAL_OUTPUTFOLDER}/MyMobileKit.framework/Frameworks"
fi
# Step 4. Create universal binary file using lipo and place the combined executable in the copied framework directory
lipo -create -output "${UNIVERSAL_OUTPUTFOLDER}/MyMobileKit.framework/MyMobileKit" "${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/MyMobileKit.framework/MyMobileKit" "${BUILD_DIR}/${CONFIGURATION}-iphoneos/MyMobileKit.framework/MyMobileKit"
# Step 5. Convenience step to copy the framework to the project's directory
mkdir -p "${PROJECT_DIR}/Universal"
if [ -d "${PROJECT_DIR}/Universal/MyMobileKit.framework" ]; then
rm -rf "${PROJECT_DIR}/Universal/MyMobileKit.framework"
fi
cp -LR "${UNIVERSAL_OUTPUTFOLDER}/MyMobileKit.framework" "${PROJECT_DIR}/Universal"
fi
In the MyApp project, the Targets settings appears as follows:
Embedded Binaries
MyMobileKit.framework
Linked Frameworks and Libraries
MyMobileKit.framework
Build Settings
Enable Bitcode = Yes
Always Embed Swift Standard Libraries = No
I also have a Run Script in the Build Phases to merge architectires, this occurs as the last step of the build:
APP_PATH="${TARGET_BUILD_DIR}/${WRAPPER_NAME}"
# This script loops through the frameworks embedded in the application and removes unused architectures.
find "$APP_PATH" -name '*.framework' -type d | while read -r FRAMEWORK
do
FRAMEWORK_EXECUTABLE_NAME=$(defaults read "$FRAMEWORK/Info.plist" CFBundleExecutable)
FRAMEWORK_EXECUTABLE_PATH="$FRAMEWORK/$FRAMEWORK_EXECUTABLE_NAME"
echo "Executable is $FRAMEWORK_EXECUTABLE_PATH"
EXTRACTED_ARCHS=()
for ARCH in $ARCHS
do
echo "Extracting $ARCH from $FRAMEWORK_EXECUTABLE_NAME"
lipo -extract "$ARCH" "$FRAMEWORK_EXECUTABLE_PATH" -o "$FRAMEWORK_EXECUTABLE_PATH-$ARCH"
EXTRACTED_ARCHS+=("$FRAMEWORK_EXECUTABLE_PATH-$ARCH")
done
echo "Merging extracted architectures: ${ARCHS}"
lipo -o "$FRAMEWORK_EXECUTABLE_PATH-merged" -create "${EXTRACTED_ARCHS[@]}"
rm "${EXTRACTED_ARCHS[@]}"
echo "Replacing original executable with thinned version"
rm "$FRAMEWORK_EXECUTABLE_PATH"
mv "$FRAMEWORK_EXECUTABLE_PATH-merged" "$FRAMEWORK_EXECUTABLE_PATH"
done
I am completely blocked on release the app, the errors seem to have appeared after updating to Xcode 8.3.3
Any help, greatly appreicated.
Craig