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

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

Related

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!

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

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

Using a third party framework into a AppStore app pulls in the iPhoneSimulator bits

I am integrating a third party framework into my AppStore app using Xcode 6.4. The framework from the third party is a universal binary which has the following when I do the file command :
DeviceTester (for architecture i386): Mach-O dynamically linked shared library i386
DeviceTester (for architecture x86_64): Mach-O 64-bit dynamically linked shared library x86_64
DeviceTester (for architecture armv7): Mach-O dynamically linked shared library arm
DeviceTester (for architecture arm64): Mach-O 64-bit dynamically linked shared library
I have tried adding this framework as a Embedded Binary. This works fine it build fine however when I upload the "ipa" to the AppStore, it complains of the ipa having unsupported architecture which are the simulator pieces. when I inspect the ipa file I do see a "Frameworks" folder as is with the universal framework inside it. But I don't see this for any of the other frameworks I including eg. Crashlytics/Fabric etc. So there is something incorrect here.
I also tried adding it as a framework and then made sure it is in the copy phase, but running it gives the following error on the device :
dyld: Library not loaded: #rpath/DeviceTester.framework/DeviceTester
Referenced from: /var/mobil....
Any pointers gladly appreciated, I have spent the whole day today trying to figure out what is happening with no luck.. Cheers.
From Xcode 6.1.1 & 6.2: iOS frameworks containing simulator slices can't be submitted to the App Store. You would need to remove the simulator slices from the fat framework to be able to submit to the AppStore.
Here's a script to do the magic. Add a Run Script step to your build steps, put it after your step to embed frameworks, set it to use /bin/sh and enter the following script:
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
This answer might explain what you are asking.
https://stackoverflow.com/a/31270427/4160199

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

Compiling to get armv7s slice

I am compiling libraries in the terminal with the following command to get an armv7 slice:
./configure CC=/Developer/usr/bin/arm-apple-darwin10-llvm-gcc-4.2 --host=arm
NOTE: I also change the ldflags, sysroot to provide the relevant path, although I don´t show that here to keep this short.
I have successfully generated code slices for: i686, i386 and armv7 and combined them, but I can´t get an armv7s slice.
What settings do I use for armv7s code slice?
You should specify -arch armv7s in CFLAGS. Below is what I use to build ICU:
INSTALL=`pwd`/..
if [ $# -eq 0 ]
then
$0 armv7 iPhoneOS
$0 armv7s iPhoneOS
$0 i386 iPhoneSimulator
mkdir -p $INSTALL/universal/lib
cd $INSTALL/armv7/lib
for f in *.a
do
echo $f
xcrun -sdk iphoneos lipo -output ../../universal/lib/$f -create -arch armv7 $f -arch armv7s ../../armv7s/lib/$f -arch i386 ../../i386/lib/$f
done
#cd ../..
else
echo $1 $2
ARCH=$1
PLATFORM=$2
TOOLCHAIN=/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain
export CC="$TOOLCHAIN/usr/bin/clang"
DEVROOT=/Applications/Xcode.app/Contents/Developer/Platforms/$PLATFORM.platform/Developer
SDK=6.1
SDKROOT=$DEVROOT/SDKs/$PLATFORM$SDK.sdk
export CFLAGS="-arch $ARCH -isysroot $SDKROOT -miphoneos-version-min=5.0 -I/Users/xxx/icu/source/tools/tzcode"
export CXXFLAGS="$CFLAGS"
gnumake distclean
../../icu/source/configure --host=arm-apple-darwin --enable-static --disable-shared --with-cross-build=/Users/xxx/icu-build/mac --prefix=$INSTALL/$ARCH
gnumake
gnumake install
fi
You could do something similar to get what you want.
EDIT: How to call make with clang:
export CFLAGS=-arch armv7s # add more compiler flags as needed here
export CC=/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang
make
I've combined the crt.1.x.x.0, libarclite, and libclang Xcode of the three current device architectures in order to support armv6, armv7, and armv7s for my iOS app.
Original Stack Overflow post that helped me: https://stackoverflow.com/a/12836808/761902.
Since you are trying to compile a ARM (conventional iOS device) and Intel (OS X computer) architectures into one file, you can try getting the crt, libarclite, and libclang files specified in the original post.
As the ARM files were located under
Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/,
I would expect the equivalent i386 files to be located under
Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/
, I'm not sure what Xcode build platform i686 falls under since I don't recall seeing that before, but if it is a iPhoneSimulator.platform, it would be in the same files as the i386 platform.
You might also want to add i686 and i386 to your build settings. The below are my architecture settings for building for armv6, armv7, and armv7s.
If that doesn't work, you can also build i686, i386, and armv7s separately and merge the built binaries with lipo.

Resources