Check and Remove Unsupported Architecture [x86_64, i386] in IPA / Archive

59,555

Solution 1

Apple has started complaining if app contains simulator architectures during distribution.

How can the above error be resolved ?

Solution :

Add below code in run script of Project target, this remove the simulator architecture (x86_64 and i386) from your app on building process:

Shell :

/bin/sh

Code :

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

Solution :

There one more solution, if you wish to do it only once. But be careful though as after doing following steps, you will not be able to run app on simulator. Do it just before deploying the app on Testflight/App-store.

Go inside the your ProjectFramework.framework folder of your project from terminal. Run following commands:

lipo -remove i386 ProjectFramework_SDK -o ProjectFramework_SDK 
lipo -remove x86_64 ProjectFramework_SDK -o ProjectFramework_SDK

Check the architectures from framework?

$ lipo -info PathToProject/ProjectName.framework/ProjectName

Output will be : → Architectures in the fat file: ProjectName are: i386 x86_64 armv7 arm64

Ref. doc: http://ikennd.ac/blog/2015/02/stripping-unwanted-architectures-from-dynamic-libraries-in-xcode/

Solution 2

For custom created Dynamic Framework

  1. Open Terminal

  2. Open your project drag path of respective framework to Terminal

    For example, cd /Users/mahipal/Desktop/masterTest/Alamofire.framework

  3. Set your Framework name in below command and run

    lipo -remove i386 Alamofire -o Alamofire && lipo -remove x86_64 Alamofire -o Alamofire

Solution 3

For Run Script under Build phases, add following steps to the Run Script to remove x86_64 and/or i386:

cd "${ARTIFACTS_FOLDER}"/FrameworkName.framework

lipo -remove x86_64 FrameworkName -o FrameworkName
lipo -remove i386 FrameworkName -o FrameworkName

Can be combined for removing multiple architectures as:

lipo -remove x86_64 FrameworkName -o FrameworkName && lipo -remove i386 FrameworkName -o FrameworkName

Solution 4

When using the script of nikdange_me I got:

error: exportArchive: ipatool failed with an exception: #<CmdSpec::NonZeroExcitException: ... >
error: Framework not found in dylib search path

So I altered it and used lipo -remove instead of lipo -extract and lipo -create which solved my problem:

# This script loops through the frameworks embedded in the application 
# and removes unused architectures.

find "${TARGET_BUILD_DIR}/${WRAPPER_NAME}" -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"
    for arch in $(lipo -archs $FRAMEWORK_EXECUTABLE_PATH); do
        if ! printf '%s\n' ${ARCHS[@]} | egrep -q "^$arch$"; then
            lipo -remove $arch "$FRAMEWORK_EXECUTABLE_PATH" -o "$FRAMEWORK_EXECUTABLE_PATH" 
        fi
    done
done

Solution 5

For an iOS project, you have the following architectures: arm64 armv7 armv7s i386 x86_64

x86_64, i386 are used for the simulator.

What could be your problem is the framework you are using was build for iOS and not a simulator.

To fix this issue you can bypass the build framework and use lipo command lines.

First: lipo -info [The library.framework location]

Example Usage : lipo -info /Users/.../library.framework/LibrarySDK

Example output :

Architectures in the fat file: /Users/.../library.framework/LibrarySDK are: i386 x86_64 armv7 arm64 

You will get the list of architecture used for that framework.

Second: we need to strip the framework from the simulator architecture and make 2 versions of that framework (1 is used for iOS Device and 1 for the simulator)

using: lipo -remove [architecture] [location] -o [output_location]

Example: lipo -remove i386 /Users/.../SDK -o /Users/.../SDK_Output_Directory

Go to your chosen output directory to get the new generated SDK without the removed architecture to verify you can use the lipo -info command same as above

You can use the same lipo remove command on the newly created SDK but with another architecture lipo -remove x86_64 ... and you will get an SDK only for iOS devices

Third: Take that final SDK and rename it "SDK_Name_IOS" and use it.

Happy coding!!

Share:
59,555
user1046037
Author by

user1046037

Updated on July 08, 2022

Comments

  • user1046037
    user1046037 almost 2 years

    Problem:

    While submitting the app to the App Store the following error is reported:

    Unsupported Architecture. Your executable contains unsupported architecture '[x86_64, i386]

    Questions:

    1. How can the above error be resolved ?

    2. How can I check the architectures used by the archive or IPA ?

    3. How can I ensure that the Release archive doesn't include x86_64 and i386 (simulator architectures).

      • Is it only possible through script or is there is a setting in Build Settings or else where ?