I have a 3rd party static library that hasn't been updated in a long time. As such, it does not include an iPhone simulator build for M1 Macs.
% lipo -info ./Zebra/lib/libZSDK_API.a
Architectures in the fat file: ./Zebra/lib/libZSDK_API.a are: armv7 i386 x86_64 arm64
I tried to set the "Link Binary With Libraries" to be optional for this library so I can still run on the Simulator. (The library is just for printing, and I don't need to print from the Simulator.)
The problem is that even though I have marked the static library as optional, Xcode still gives me a linker error about the missing architecture.
error build: In ../XXXX/External/Zebra/lib/libZSDK_API.a(TcpPrinterConnection.o), building for iOS Simulator, but linking in object file built for iOS, file '../XXXX/External/Zebra/lib/libZSDK_API.a' for architecture arm64
Is there any way to get around this so that Xcode does not fail the build, but just leaves the library unlinked? I thought this was the whole point of the "optional" setting on Link Binary With Libraries?
Related
Is there a way to convert a library that is built for macOS to a library that I can use in my iOS project. I'm getting an error in my app that follows:
/Users/edwardpizzurro/Desktop/LibreriasAlternativas/LibreriasAlternativas.xcodeproj Building for iOS, but the linked library 'libsndfile.a' was built for macOS.
In general, it's not possible and you have to rebuild your library specifying iOS architecture.
To get more info about your library, run
lipo -info libsndfile.a
It'll give you architectures like armv7 armv7s i386 x86_64 arm64. A default architecture for iOS is arm64, while for MacOS it's x86_64 (we are not speaking of new M1 hardware). So most probably for your libsndfile.a you'll get only x86_64.
This will mean you need to build libsndfile by yourself.
Here are releases of this lib, there's no arm64 here: https://github.com/libsndfile/libsndfile/releases
So you have to donwload the repo: https://github.com/libsndfile/libsndfile
And use smth like Autotools to build it for your desired architecture.
A rough example of what you'll have to do it here: Can't cross compile C library for arm (iOS)
While it's quite specific for each library.
When I tried to decrease my flutter app's deployment target (iOS 12 to 9.3), I received this error when running flutter build ios:
=== BUILD TARGET Runner OF PROJECT Runner WITH CONFIGURATION Release ===
fatal error: lipo: -extract armv7 specified but fat file:
/Users/xxx/development/myapp/build/ios/Release-iphoneos/Runner.app/Frameworks/flutter_webview_plugin.framework/flutter_webview_plugin does not contain that architecture
Failed to extract armv7 for /Users/xxx/development/myapp/build/ios/Release-iphoneos/Runner.app/Frameworks/flutter_webview_plugin.framework/flutter_webview_plugin. Running
lipo -info:
Architectures in the fat file: /Users/xxx/development/myapp/build/ios/Release-iphoneos/Runner.app/Frameworks/flutter_webview_plugin.framework/flutter_webview_plugin are:
arm64
I am unable to find any information on how to change the architecture in question - can I even do this? Or is this something the plugin developer has to build in?
I would like to be able to run the app with the lowest possible iOS version for maximum compatibility.
In the project build settings, there is a section called Architectures, there you can set the ones you need. As far as I know, the latest iPhones need to use arm64, but in my picture you can see that I'm also set as valid armv7, that seems to be your problem.
I try to understand the different architectures for iOS, and when I need which.
I have a Hello World example. Is my assumption correct that, if I run it in the Xcode Simulator, I need to compile everything including my dependencies for x64 (because it's running on my computer).
And for my attached iPhone it's getting compiled for only that architecture. And for Generic iPhones my example will be a multiarchitecture app (arm64 arm64 armv7 armv7e) so it can run on a variety of architectures. Is that correct?
Thanks for your insight.
P.S. So if my example links foo.a, but foo.a is just arm64 arm64 armv7 armv7e but not x64, I could compile my app for iPhones but not run it in my simulator
This is essentially correct although you have two arm64 listed above; it should be arm64 and arm64e.
As to what architectures get built, it depends on the setting "Build Active Architecture Only". The typical Debug config has this set to Yes, so it only builds for the architecture of the device that you're targeting.
A Release config has this set to No, so it compiles for all architectures specified in "Architectures", which usually $(ARCHS_STANDARD), i.e., the architectures you listed.
As to your PS, you are correct that a .a file with only ARM archs could not be linked to a Simulator target.
I'm using the LAME MP3 encoder to convert the caf formatted file to MP3 format. I downloaded LAME and compile and build all architecture like arm64, armv7, armv7s, armv6, i386, i686, x86_64 successfully. I followed this link to create the libraries.
But I'm trying to create lipo for armv7, arm64, x86_64 which support to my project. But I'm getting fatal error.
Here is the error that I'm getting.
fatal error: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/lipo: build/libmp3lame-arm64.a and build/libmp3lame-armv7.a have the same architectures (x86_64) and can't be in the same fat output file.
I tried the all combination which two architectures can create fat file, except single only creating. I need it for ios 8.1 and above (please mention which architectures should I put in the fat file for iPhone 4s and above)
It looks like something went wrong with your build: libmp3lame-arm64.a, libmp3lame-armv7.a should have been device builds but they seem to have come out as simulator builds.
You can confirm this by running file on them:
file build/libmp3lame-arm64.a build/libmp3lame-armv7.a
I don't know why it happened, nor which of many answers you used in the question you linked to.
Can you give more information on how you configured and built lame?
I'm trying to build dynamic library for iOS, combined with architectures
armv7
armv7s
arm64
i386
x86_64
Here is my target's Build Settings
As you can see I've added x86_64 and i386 to Architectures and Valid Architectures, also Build Active Architecture Only is set to NO.
So after building my binary, I'm checking supported architectures by running file myDl.dylib in Terminal
myDl.dylib (for architecture armv7): Mach-O dynamically linked shared library arm
myDl.dylib (for architecture arm64): Mach-O 64-bit dynamically linked shared library
So it means it has been compiled for armv7 and arm64, and dlopen() fails on simulator with error "Unsupported architecture".
What am I doing wrong?
PS. When I use custom build script and use there "lipo" tool to create fat library, it works fine, but I don't like that way, and I want to get it normal working on Xcode.
Set armv7,armv7s and arm64 in valid architecture and make sure if you use any thirdparty framework that must be include 64 bit support.