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

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:
How can the above error be resolved ?
How can I check the architectures used by the archive or IPA ?
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 ?

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/

For custom created Dynamic Framework
Open Terminal
Open your project drag path of respective framework to Terminal
For example, cd /Users/mahipal/Desktop/masterTest/Alamofire.framework
Set your Framework name in below command and run
lipo -remove i386 Alamofire -o Alamofire && lipo -remove x86_64 Alamofire -o Alamofire

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

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

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!!

Related

Undefined symbols for architecture arm64 with "_cblas_sgemm", referenced from:

I encounter a problem that i try my best to resolve it, but i spend so much time it not working for me.
I don't have any idea to fix it. My project build on Xcode 9.1, libnama.a library is in a thirdParty for my project,called Faceunity, .a library added my project, Other Linker Flags i have added $(inherited)
Architectures set armv7 armv7s arm64 x86_64, used some other people's methods it always not ok!!!! I hope that if anyone have any idea maybe to fix please tell me, thanks!
Error:
Undefined symbols for architecture arm64: "_cblas_sgemm", referenced
from:
_cnn_run in libnama.a(cnn-arm64.o) ld: symbol(s) not found for architecture arm64 clang: error: linker command failed with exit code
1 (use -v to see invocation)
Other info:
This is a typical error when we integrate third-party libraries in our applications. It is saying that the required library has not built for arm64 architecture.
The linker couldn't able to find the symbols for arm64 in the specified static library. To check the supported architectures for static library use lipo or file
lipo -info libGoogleAnalytics.a .
Architectures in the fat file:libGoogleAnalytics.a are: armv7 i386 x86_64 arm64
It is because some third party library includes support simulators. But while building the application you have to exclude the support to the architecture support for simulators
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

input file XXXX must be a fat file when the -remove option is specified

I am trying to publish our app to testflight/appstore by fastlane and i get these two errors:
fatal error: lipo: input file (==FILEPATH==/CommonCrypto.framework/CommonCrypto) must be a fat file when the -remove option is specified
fatal error: lipo: can't open input file: ==FILEPATH==/Frameworks/CommonCrypto.framework/CommonCrypto (No such file or directory)
Before i got these errors i got lot of "Unsupported Architectures" errors.
ERROR ITMS-90087: "Unsupported Architectures. The executable for ==APPNAME==.app/Frameworks/==FRAMEWORK_NAME==.framework contains unsupported
architectures '[x86_64, i386]'."
ERROR ITMS-90087: "Unsupported Architectures. The executable for ==APPNAME==.app/Frameworks/CommonCrypto.framework contains unsupported
architectures '[x86_64]'."
So i added this script to the build phase:(From another stack overflow post)
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
Build settings:
Architectures: Standard Architectures
Base SDK: iOS 11.0
Build Active Architectures Only: YES (tried with NO)
Supported Platforms: iOS
Valid Architectures: arm64, arm7, arm7s
NOTE
The commoncrypto framework is added manualy in embedded Binaries since its only avalible through Carthage. But the project uses mainly cocoapods.
I guess removing the script would solve it. But then its back to the old problem.
But all help is appreciated!

Creating iOS universal framework with Xcode 9

I am creating universal framework for iOS. I am trying to create one through lipo and it does create a universal one
I check the architecture with lipo after creation it returns me correct:
Architectures in the fat file: i386 x86_64 armv7 arm64
I run the application on phone and simulator that works fine as well.. But when I try to export the .ipa from xcarchive I get the following error:
Failed to verify bitcode in Myframework.framework/Myframework:\nerror: Platform iPhoneSimulator is not supported\n\n
Also I can the bitcode symbols in my universal framework running
otool -l /Path/To/Framework | grep __LLVM
segname __LLVM
segname __LLVM
If I choose only iphoneos framework that works fine
You need to strip i386 and x86_64 from the framework before exporting the archive.
e.g.
$ lipo -remove i386 ./path/to/binary_name -o ./path/to/binary_name
$ lipo -remove x86_64 ./path/to/binary_name -o ./path/to/binary_name
You need to do this, since i386 and x86_64 are not supported for export -- "Platform iPhoneSimulator is not supported"

Submit to App Store issues: Unsupported Architecture x86

So I am trying to use the Shopify API. When I archive the app and validate it then there are no issues but when I submit it to the app store then it gives me the following issues.
ERROR ITMS-90087: "Unsupported Architecture. Your executable contains unsupported architecture '[x86_64, i386]'."
ERROR ITMS-90209: "Invalid segment Alignment. The App Binary at SJAPP.app/Frameworks/Buy.framework/Buy does not have proper segment alignment. Try rebuilding the app with the latest Xcode version." (I am already using the latest version.)
ERROR ITMS-90125: "The Binary is invalid. The encryption info in the LC_ENCRYPTION_INFO load command is either missing or invalid, or the binary is already encrypted. This binary does not seem to have been built with Apple's Linker."
WARNING ITMS-90080: "The Executable Payload/..../Buy.framework is not a Position Independent Executable. Please ensure that ur build settings are configured to create PIE executables."
The problem is that the Buy framework contains a build for both the simulator (x86_64) and the actual devices (ARM).
Of course, you aren't allowed to submit to the App Store a binary for an unsupported architecture, so the solution is to "manually" remove the unneeded architectures from the final binary, before submitting it.
Daniel Kennett came up with a nice solution and provides this script to add to the build phase:
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 used it and it worked perfectly.
EDIT: make sure you look at the modified script posted by Varrry, as this one has some minor issues.
Answer given by pAkY88 works, but I faced the same problem as Mario A Guzman in https://stackoverflow.com/a/35240555/5272316: once we cut off unused architectures we can't run script any more since it tries to remove not existing slices, because xcode doesn't re-embed binary every time.
Idea was - just remove i386 and x86_64 slices when building for archive, so I modified script:
echo "Target architectures: $ARCHS"
APP_PATH="${TARGET_BUILD_DIR}/${WRAPPER_NAME}"
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"
echo $(lipo -info "$FRAMEWORK_EXECUTABLE_PATH")
FRAMEWORK_TMP_PATH="$FRAMEWORK_EXECUTABLE_PATH-tmp"
# remove simulator's archs if location is not simulator's directory
case "${TARGET_BUILD_DIR}" in
*"iphonesimulator")
echo "No need to remove archs"
;;
*)
if $(lipo "$FRAMEWORK_EXECUTABLE_PATH" -verify_arch "i386") ; then
lipo -output "$FRAMEWORK_TMP_PATH" -remove "i386" "$FRAMEWORK_EXECUTABLE_PATH"
echo "i386 architecture removed"
rm "$FRAMEWORK_EXECUTABLE_PATH"
mv "$FRAMEWORK_TMP_PATH" "$FRAMEWORK_EXECUTABLE_PATH"
fi
if $(lipo "$FRAMEWORK_EXECUTABLE_PATH" -verify_arch "x86_64") ; then
lipo -output "$FRAMEWORK_TMP_PATH" -remove "x86_64" "$FRAMEWORK_EXECUTABLE_PATH"
echo "x86_64 architecture removed"
rm "$FRAMEWORK_EXECUTABLE_PATH"
mv "$FRAMEWORK_TMP_PATH" "$FRAMEWORK_EXECUTABLE_PATH"
fi
;;
esac
echo "Completed for executable $FRAMEWORK_EXECUTABLE_PATH"
echo $(lipo -info "$FRAMEWORK_EXECUTABLE_PATH")
done
This script simply removes i386 and x86_64 slices from fat binary (if they exist) if running not for simulator (that means destination folder isn't like "Debug-iphonesimulator").
Sorry, I'm not familiar with shell scripts, so may be someone could write it more elegant way. But it works)
If you're using Carthage then you may experience this issue because the project is:
Missing the carthage copy-frameworks build phase.
Or the build phase doesn't include all the frameworks (incomplete list).
This action filters frameworks to a list of valid architectures (code).
Setting up the copy-frameworks build phase
From the Carthage building for iOS steps:
On your application targets’ “Build Phases” settings tab, click the
“+” icon and choose “New Run Script Phase”. Create a Run Script in
which you specify your shell (ex: bin/sh), add the following contents
to the script area below the shell:
/usr/local/bin/carthage copy-frameworks
and add the paths to the frameworks you want to use under “Input Files”, e.g.:
$(SRCROOT)/Carthage/Build/iOS/Box.framework
$(SRCROOT)/Carthage/Build/iOS/Result.framework
$(SRCROOT)/Carthage/Build/iOS/ReactiveCocoa.framework
This script works around an App Store submission bug triggered by universal
binaries and ensures that necessary bitcode-related files and dSYMs
are copied when archiving.
I resolved the error ITMS-90080 by removing a framework (the excellent SVProgressHUD) from the Embedded Binaries section (Xcode target -> General tab).
If you are using Carthage make sure your Embed Frameworks Build Step is before the Carthage copy-frameworks
In some unusual cases (example: Lottie-iOS framework):
you will have it simply in "Link Library" as usual.
However you have to also explicitly add it in "Embed Frameworks" (even though that seems pointless, since it works perfectly when you have it only in "Embed Frameworks"),
and put it in copy-frameworks
and ensure copy-frameworks is after "Embed Frameworks"
Remove [x86_64, i386] from the framework using below step. [x86_64, i386] is used for simulator.
Open Terminal
open your project drag path of respective framework to Terminal
example : cd /Users/MAC/Desktop/MyProject/Alamofire.framework
set your Framework name in below command and run
lipo -remove i386 Alamofire -o Alamofire && lipo -remove x86_64 Alamofire -o Alamofire
Now open your project again, Clean, Build & Run and Create Archive...
I will add my 2 cents here (in a less scary way :-). I have encountered quite a number of fat libraries from Vendors that (for some reason) do not work the normal way by adding them to the Frameworks directory as documented by Apple. The only way we have been able to make them work is by pulling the .framekwork right into the project directory and linking the Embedded Frameworks and Link Binary with Libraries manually in Build Settings. This seem to have worked without any issues, however, as with any fat library they come with the extraneous Simulator Architectures i386 and x86_64 along with the arm architectures.
A quick way to check the architectures on the fat library is
$ cd 'Project_dir/Project'
$ lipo -info 'YourLibrary.framework/YourLibExec`
Which should spit an output something like this
Architectures in the fat file: YourLibrary.framework/YourLibExec are: i386 x86_64 armv7 arm64
This confirms that you will need to "trim the fat" (namely i386 & x86_64) from your framework prior to iTunesConnect Archival upload, which doesn't allow these architectures (since they are unsupported for iOS).
Now, all the answers (or atleast some of the answers) here provide these wonderful Run Scripts that I am sure works really well, but only if your Framework resides in the Frameworks directory. Now unless you are a shell script junkie, those scripts without modifications, won't work for the scenario I explain above. However, there is a very simple way to get rid of the i386 & x86_64 architectures from the framework.
Open terminal in your project's directory.
Change directory directly into the .framekwork, like
cd YourProjectDir/YourProject/YourLibrary.framework
Run the series of commands as shown below-
$ mv YourLibrary YourLibrary_all_archs
$ lipo -remove x86_64 YourLibrary_all_archs -o YourLibrary_some_archs
$ lipo -remove i386 YourLibrary_some_archs -o YourLibrary
$ rm YourLibrary_all_archs YourLibrary_some_archs
A few things to note here - lipo -remove has to be done once for each architecture to remove. lipo does not modify the input file, it only produces a file so you have to run lipo -remove once for x86_64 and i386. The commands above is simply doing that by first renaming the executable and then eventually removing the desired archs, and then cleaning up the left over files. And that's it, you should now see a green check mark in Application Loader Archival upload to iTunesConnect.
Things to keep in mind : The above steps should only be done while production build, since the .framework will be stripped off the simulator architectures, builds on simulators will stop working (which is expected). In development environment, there should be no need to strip the architectures off of the .framework file since you want to be able to test on both Simulator and a physical device. If your fat library resides in the Frameworks folder in the project then please look at the accepted answer.
Thanks to all the above answers. Here is a script working with swift 4.2 and 5. Replace Your_Framework_Name string with your Framework's original name.
APP_PATH="${TARGET_BUILD_DIR}/${WRAPPER_NAME}"
FRAMEWORK_NAME="Your_Framework_Name.framework"
# Check if Framework is present.
FRAMEWORK_LOCATION=$(find "$APP_PATH" -name "$FRAMEWORK_NAME" -type d)
if [ -z $FRAMEWORK_LOCATION ]; then
echo "Couldn't find Your_Framework_Name.framework in $APP_PATH. Make sure 'Embed Frameworks' build phase is listed before the 'Strip Unused Architectures' build phase."
exit 1
fi
# This script strips unused architectures
find "$APP_PATH" -name "$FRAMEWORK_NAME" -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 had same issue even after adding the script and updating the framework a few times.
Make sure in xCode the script is added at the end, after the embed. I think I accidentally moved the script before the embedded framework.
Note: I have xCode 9.1
Updated for Xcode 10.1, Below solution worked for me :
Just you have to remove the framework from Embedded Binaries and just add it to the Linked Frameworks and Libraries.
Refer below screenshot;
This issue was resolved for me by slightly modifying the run script from pAky88's answer and executing after embedding frameworks. Also be sure to uncheck the box for "Run Script only when installing".
/usr/local/bin/carthage copy-frameworks
#!/usr/bin/env bash
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"
if [ ! -f "${FRAMEWORK_EXECUTABLE_PATH}" ]; then
continue
fi
if xcrun lipo -info "${FRAMEWORK_EXECUTABLE_PATH}" | grep --silent "Non-fat"; then
echo "Framework non-fat, skipping: $FRAMEWORK_EXECUTABLE_NAME"
continue
fi
echo "Thinning framework $FRAMEWORK_EXECUTABLE_NAME"
EXTRACTED_ARCHS=()
for ARCH in $ARCHS
do
echo "Extracting $ARCH from $FRAMEWORK_EXECUTABLE_NAME"
xcrun lipo -extract "$ARCH" "$FRAMEWORK_EXECUTABLE_PATH" -o "$FRAMEWORK_EXECUTABLE_PATH-$ARCH"
EXTRACTED_ARCHS+=("$FRAMEWORK_EXECUTABLE_PATH-$ARCH")
done
echo "Merging extracted architectures: ${ARCHS}"
xcrun 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 removed architectures i386 & x64_86 from Build Settings - Valid Architectures - Release, and everything worked just fine.
Now the only issue would be that you can't run a RELEASE build for testing purposes on a SIMULATOR. But as easily as you removed the archs, you can add them back if you want to.
the simple solution that worked for me was
1- remove the framework from embedded frameworks.
2- add the framework as a linked framework
done!
This error (ITMS-90240) can also be caused by a static (.a) library. heres a script to strip the excess architectures. In Xcode add this to Target > BuildPhases > Click the + and select Run Script. Then paste this into the script box.
The script searches for .a files, checks to see if it contains an offending architecture, then if it does makes a new .a file without that architecture.
For macOS:
APP_PATH="${TARGET_BUILD_DIR}/${WRAPPER_NAME}"
STRIPARCHS="armv7 armv7s arm64"
for t in $STRIPARCHS
do
if find "$APP_PATH" -name '*.a' -exec lipo -info {} \; | grep $t ; then
find "$APP_PATH" -name '*.a' -exec lipo -remove $t {} -output {}2 \; -exec rm {} \; -exec mv {}2 {} \; ;
fi
done
exit 0
For iOS :
APP_PATH="${TARGET_BUILD_DIR}/${WRAPPER_NAME}"
STRIPARCHS="x86_64 i386"
for t in $STRIPARCHS
do
if find "$APP_PATH" -name '*.a' -exec lipo -info {} \; | grep $t ; then
find "$APP_PATH" -name '*.a' -exec lipo -remove $t {} -output {}2 \; -exec rm {} \; -exec mv {}2 {} \; ;
fi
done
exit 0
I had same issue.
Even it was not working after adding the given Run Script.
It was Xcode related issue.
I was using the Xcode version 9.0 but latest version was 9.2.
So i installed latest Xcode (9.2) and it worked.
Your framework contains both ARM and x86 code, which allows you to use it on a device or in the simulator. If you intend to submit your app to the App Store, run the following script to strip the inactive code from the binary.
1.Select your target in the Project Navigator, and click Build Phases at the top of the project editor.
2.From the Editor menu, select Add Build Phase, then Add Run Script Build Phase (or click the + button in the upper-left corner of the Build Phases editor).
3.Expand the disclosure triangle next to the new Run Script build phase that was just added. In the script editor box, paste the following:
bash
${BUILT_PRODUCTS_DIR}/${FRAMEWORKS_FOLDER_PATH}/"YourframeworkName.framework"/strip-frameworks.sh
Here is a script I used to specifically remove just one framework's architecture from the executable file.
# Remove unused Framework architecture from "YourApp" framework.
FRAMEWORK_EXECUTABLE_PATH="${TARGET_BUILD_DIR}/${WRAPPER_NAME}/Frameworks/YourApp.framework/YourApp"
echo "$FRAMEWORK_EXECUTABLE_PATH"
cp "$FRAMEWORK_EXECUTABLE_PATH" "${FRAMEWORK_EXECUTABLE_PATH}_X86_64"
echo "Executing following command to remove x86_64 arch from YourApp framework executable"
echo "lipo -remove x86_64 \"$FRAMEWORK_EXECUTABLE_PATH\" -o \"${FRAMEWORK_EXECUTABLE_PATH}_X86_64\""
lipo -remove x86_64 "${FRAMEWORK_EXECUTABLE_PATH}_X86_64" -o "$FRAMEWORK_EXECUTABLE_PATH"
rm "${FRAMEWORK_EXECUTABLE_PATH}_X86_64"
Add this script to your projects "Build Phases" of your project target. Be sure to check the box: "Run script only when installing"

ERROR ITMS-9000: "Unsupported architectures. Your executable contains unsupported architectures '[x86_64, i386]'"

It is impossible to send in itunesconnect new version of the application. Although last week, the same version send happened. In the code, I just changed the name of a button, no more changes are not made ​​where.
But always get error:
ERROR ITMS-9000: "Unsupported architectures. Your executable contains unsupported architectures '[x86_64, i386]'"
In my project -> Build Settings:
ARCHS = $(ARCHS_STANDARD_32_BIT)
//:configuration = Debug
ONLY_ACTIVE_ARCH = YES
//:configuration = Release
ONLY_ACTIVE_ARCH = NO
VALID_ARCHS = armv7 armv7s
Check out this slick solution on Daniel Kennett's blog - it worked perfectly for me with the SpritzSDK, which I had similar issues with.
He supplies a script you can drop-in to your build phases to strip out the unwanted architectures as a last step - doesn't break the simulator, and iTunesConnect approved my upload as well on the first try.
http://ikennd.ac/blog/2015/02/stripping-unwanted-architectures-from-dynamic-libraries-in-xcode/
You can remove unwanted ARCHS from IPA by putting below peace of Shell Script in Build Phase -- > RUN Script
This Script removes all simulator ARCHS from IPA and ARCH issues from Embedded framework.
Source :
http://ikennd.ac/blog/2015/02/stripping-unwanted-architectures-from-dynamic-libraries-in-xcode/
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
The script in the above two answers needs to be edited if you have an watch app in your project. Add /Frameworks to the $APP_PATH to avoid errors when building the project.
If you are using LiveSDK directly or via ShareKit, you will run into this problem. In my case I was using LiveSDK directly.
Check this answer on Apple Developer Forum
https://devforums.apple.com/message/1037603#1037603

Resources