2 Replies
      Latest reply on May 4, 2020 2:18 AM by NickYaw
      craigaps Level 1 Level 1 (0 points)

        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