"no matching architecture in universal wrapper", but file has it - ios

Note: There are a lot of SO questions with a similar problem, but almost all of them have an issue running in the Simulator because they failed to build universal libraries. In this case, I have a universal library, I just can't figure out why the device loader doesn't like the architecture in the wrapper.
We build some C++ code that uses Tensorflow Lite on multiple platforms. I'm trying to link it into our iOS build. I created a universal shared library with a couple of shared libraries built by that team. They build them as individual shared libraries with one architecture per file (one for macOS, one for iOS arm64, and one for iOS x86). I put the two iOS files together using lipo, and I was able to link and run in the Simulator. Unfortunately, I can't exercise that code path in the Simulator (for other reasons), so I built and ran on a device.
But when I try to run on a device, I get
dyld: Library not loaded: #rpath/libtensorflowlite.so
Referenced from: /private/var/containers/Bundle/Application/E3E3B0E9-B36E-4ADB-9FFC-CA2D6D2A8AC8/MyApp.app/MyApp
Reason: no suitable image found. Did find:
/private/var/containers/Bundle/Application/E3E3B0E9-B36E-4ADB-9FFC-CA2D6D2A8AC8/MyApp.app/Frameworks/libtensorflowlite.so: no matching architecture in universal wrapper
I know the App Store doesn't like x86 bits in universal shared libraries, so I used lipo in an Xcode build phase to remove the x86 part, and now my file looks like:
$ file /Users/rmann/Library/Developer/Xcode/DerivedData/MyApp-fdskkibuvbsubudkmqtgsjxmyqme/Build/Products/Debug-iphoneos/MyApp.app/Frameworks/libtensorflowlite.so
/Users/rmann/Library/Developer/Xcode/DerivedData/MyApp-fdskkibuvbsubudkmqtgsjxmyqme/Build/Products/Debug-iphoneos/MyApp.app/Frameworks/libtensorflowlite.so: Mach-O universal binary with 1 architecture: [arm64:Mach-O 64-bit dynamically linked shared library arm64]
/Users/rmann/Library/Developer/Xcode/DerivedData/MyApp-fdskkibuvbsubudkmqtgsjxmyqme/Build/Products/Debug-iphoneos/MyApp.app/Frameworks/libtensorflowlite.so (for architecture arm64): Mach-O 64-bit dynamically linked shared library arm64
But it still doesn't see it.
I do something similar with another library we get from a third party, and everything works fine. How can I inspect this further to determine what the issue is? Thanks.

Related

What's the difference between `*.framework`, `*.dylib` and `*.a` libs

I have a project, in the Framework, there have *.framework, *.dylib, *.a libs.
I want to know what's them? and the difference between them.
Dynamic and static libraries
First of all, a library is a collection of resources and the code itself, compiled for one or more architectures.
Static libraries (*.a):
In the case of static libraries (*.a), the code that the app uses is
copied to the generated executable file by a static linker during
compilation time.
Dynamic libraries (*.dylib):
Dynamic libraries (*.dylib) are different from static libraries in the
sense that they are linked with the app’s executable at runtime, but
not copied into it. As a result, the executable is smaller and,
because the code is loaded only when it is needed, the startup time is
typically faster.
Dynamic and static frameworks:
For frameworks, we first need to understand the bundle concept (as a
framework is a specific kind of a bundle). A bundle is a file
directory with subdirectories inside. On iOS, bundles serve to
conveniently ship related files together in one package – for
instance, images, nibs, or compiled code. The system treats it as one
file and you can access bundle resources without knowing its internal
structure.
The library may also have additional resources: headers, localization
files, images, documentation, and examples of usage. We can bundle all
of this together in one bundle – and the name of this is the framework.
Static frameworks contain a static library packaged with its
resources. Dynamic frameworks contain the dynamic library with its
resources. In addition to that, dynamic frameworks may conveniently
include different versions of the same dynamic library in the same
framework!
Other useful references:
Hackernoon
Runtastic
Static library
Software framework
Update:
Thanks for accepting my answer!
Compiled for one or more architectures?
Every architecture requires a different binary, and when you build an
app Xcode will build the correct architecture for whatever you’re
currently working with. For instance, if you’ve asked it to run in the
simulator, then it’ll only build the i386 version (or x86_64 for
64-bit).
This means that builds are as fast as they can be. When you archive an
app or build in release mode, then Xcode will build for all three ARM
architectures, thus allowing the app to run on most devices. What
about the other builds though?
Naturally, when you build your framework, you’ll want developers to be
able to use it for all possible architectures, right? Of course you do
since that’ll mean you can earn the respect and admiration of your
peers.
Therefore you need to make Xcode build for all five architectures.
This process creates a so-called fat binary, which contains a slice
for each of the architectures.
arm7: Used in the oldest iOS 7-supporting devices
arm7s: As used in iPhone 5 and 5C
arm64: For the 64-bit ARM processor in iPhone 5S
i386: For the 32-bit simulator
x86_64: Used in 64-bit simulator
Raywenderlich: Multi-Architecture

Undefined symbols for architecture x86_64: xcode 9 Swift 4

I create app that uses Huawei SDK written in Objc with updated docs in Oct 2017. But when I add framework to project, this shows me stange error. I have stack on this problem couple days, I have tried everything from similar problems, but nothing helped for me.
Framework added correctly(header file, link binary with libraries) autocomplition works well and shows the methods when trying to use SDK.
Already tried: change/edit/update
Valid architecture: arm, armv, armv7, armv7s, i386, x64_86
Clean Derived date and achieves
Restart OS
Change swift version: Shows another error
Checked ObjC bridging header
Pod update/install
Framework search path
SOLUTION:
Launch on real device=)
Looks like your HWMobileSDK.framework is not a fat framework. You'll either need to find a fat framework, or a second build of the framework that's compiled for the simulator (x86_64). I couldn't find any reference to that framework online, so it looks like it's not publicly available. If you got this from Huawei directly, you should ask the person you're in contact with there. Either they don't provide a version of the library for the simulator and you'll need to develop using a device only, or you need another version of the library.

Using pre compiled dylib in iOS8+ or building dynamic framework out of dylibs?

I'm trying to use a fat dylib I've made that contains the latest version of tbb with code for all architectures I may be targetting (armv7, arm64, i386 and x86_x64)
Since iOS8 using dylib(s) is meant to be possible, in fact one of the error messages I found googling was the following one:
ld: embedded dylibs/frameworks are only supported on iOS 8.0 and later
Which seems to suggest that embedding dylibs is actually possible and we aren't only restricted to the new so called dynamic frameworks, yet, when I try to run my project I get the following:
dyld: Library not loaded: #rpath/libtbb.dylib
Referenced from: /Users/user/Library/Developer/CoreSimulator/Devices/B4DCFF3E-10B2-4C01-953F-BD26D14300E7/data/Containers/Bundle/Application/8C84A844-97FC-4993-A37E-A456C4E2240F/TestTBB.app/TestTBB
Reason: image not found
I thought it would be due to the dylib not being automagically copied into the app being built so I added it to the "Copy Bundle Resources" section in the projects "Build Phases" and I've since made sure that the libtbb.dylib is in fact being copied into the app and yet I keep getting the message saying that it can't be loaded.
I've tried using the "Embedded Binaries" section under "General" but it seems to be restricted to using only the new framework types.
Is there anything I might be missing?
As you may have noticed I'm trying to use TBB which comes with its own build makefiles that generates dylibs, I'm assuming that if it does it's because dylibs can be used, legally since the iOS8+ update.
I have seen ways of getting dylibs to load, but these aren't the ones that Apple would accept in their AppStore, I'm trying to do this for an app that is currently on the AppStore and I have no plans of getting it removed or not accepted after an update so I'd like to go with whatever the new "legal" way is to get dylibs loaded. My app is targetting iOS9.2+ since the latest update so this shouldn't be an issue.
All I can find are ways to get dynamic frameworks loaded but no info about actual dylibs even though the error message clearly states that they could be used.
Alternatively, is there a way to build a dynamic framework out of existing dylib files?
Thanks in advance.

Xcode Warning: Ignoring file libxml2.2.dylib, built for unsupported file format which is not the architecture being linked

I have been given the task of adding a few features to an iOS app. I checked out the source on SVN to be greeted with over 100 warnings (argh), thankfully I'm down to the last one, which is:
(The blocked out bits are the client name...).
I believe this warning is saying something along the lines of: 'this XML library is not compatible with the OS architecture that is being linked on the build'.
With the next release, we are supporting only iOS5 and iPhone 4 and above (rather than lower versions of iOS and older iPhones).
So do I change the link architecture? What is the link architecture? How do I change the architecture? Or am I completely on the wrong track?
May be worth mentioning that I am running the latest Xcode, I've added the framework from the Xcode list (link binary with libraries).
EDIT
I only get the message when building from the simulator. It doesn't cause any harm, just winds me up!
Thanks in advance.
Do not link against libxml2.2.dylib, instead link against libxml2.dylib. Linking against that should ensure you are always linked against the correct implementation for your architecture.
As a general rule, in your applications link to the generic version of a library rather than a specific version. In this case this means libxml2 rather than libxml2.2 .
You are linking to a (symlink to a) dynamic library which at runtime will automatically point to the correct implementation for the current OS version and architecture. Linking to the specific version of a library does not guarantee this, and you can end up linking to a something that only has a single architecture. Thus, during development if you link to libxml2.2.dylib when targetting the simulator you may be linking against something that is i386, then when you target a device it can't find the correct architecture (because it's trying to use i386 for armvWhatever, which is exactly what you are telling it do).
If you're trying to use libxml2.2, it's already available in Xcode. Instead of getting it from an outside source (Apple wouldn't let you use a dynamic library anyway), add it in Xcode to your frameworks, and then link it by adding /usr/lib/libxml2/ in Header Search Paths. Don't link your project with a dylib that's not Apple provided or else your app will get rejected. Also, the architecture i386 isn't the architecture for iOS, as iOS uses the armv7 and armv7s architectures for the newer versions of their devices, which is why you are getting the architecture warning.
Basically the difference between libxml2.2 and libxml2 is that libxml2.2 points to a specific version/implementation of libxml whereas libxml2 is a shortcut/symlink that points to the latest version AND correct architecture of libxml2 that XCode can find. Therefore when adding a framework like this, you should always add the 'general version' (the symlink) of it (libxml2) rather than the 'specific version' of it (libxml2.2) because of the exact issue you're seeing.
Hope this helps!
That says you're linking to something built for 386 not arm.
You will either need a different dylib to link to or go into project settings and change the arch. ( if you are building the dylib)
Probably to include arm7 or similar.

In Xcode project target build settings, What is Mach-O Type?

After getting tired of numerous Match-O linker error, I want to know that this thing means. Instead of trial and error solution, I would like to know the concept behind these things. Specifically I want to know the difference between :
Executable
Dynamic Library
Bundle
Static Library
Relocatable Object File
These are the options presented when I click on Mach-O Type settings on Linking section. Some small definition or some link to appropriate content is ok too.
Mach-O, short for Mach object file format, is a file format for executables, object code, shared libraries, dynamically-loaded code, and core dumps. For unix users this is like a.out but with improvements. This is the format used in Mac OS X and iPhone OS libraries for executable files.
As you know iOS devices (iPhone, iPad etc.) have different architectures ARMv6 (iPhone 2G + 3G, iPod Touch) and ARMv7 (iPhone 3GS, iPod Touch 2G + 3G) but the simulators used in Xcode runs mostly on i386 platform. This means the that the library clients have to setup separate targets for the simulator and device. The separate targets duplicate most information, and only differ in the static libraries included. So if you are getting a Mach-O linker error what it means is that xcode is having trouble linking to one of the libraries for that target device; as a result of which compilation fails.
Now your definitions -
Executable - compiled machine targeted program ready to be run in binary format.
Dynamic Library - are linked during runtime -- a program with references to a dynamic library will load and link with the library when it starts up (or on demand).
Bundles - and bundle identifier let iOS and OSX recognise any updates to your app. It gives it a unique presence in the app.
Static Library - files are linked at build time. code is copied into the executable. Code in the library that isn't referenced by your program is removed. A program with only static libraries doesn't have any dependencies during runtime.
Relocatable Object File - is another word for a dynamic library. When you link with a dynamic library, the addresses of the functions contained within are computed, based on where the library is loaded in memory. They are "relocatable" because the addresses of the contained functions are not determined at link time. (In a static library, the addresses are computed during link time.)
As per apple documentation,
Check this for more details Building Mach-O Files and Xcode Build Setting Reference

Resources