How to get rid of the warning “file was built for

2019-01-21 15:07发布

问题:

I've an application which includes an external library I developed, and I'm getting the following warning message every time I compile using the device as target:

mylib-release-iphonesimulator.a, file was built for unsupported file format which is not the architecture being linked (armv7).

I've 2 versions of the library, both added into the project. One built for the iphonesimulator and the other for iphoneos.

Even though it works well on any target (seems the compiler takes the correct version of the library depending of the target) that sort of warning becomes anoying.

Is any way to get rid of the warning, or even better compile both platforms on a single library avoiding to have 2 binaries of the same library?

Thanks!

回答1:

You don't want to get rid of this error, you want to fix it.

The problem here is that you're linking a simulator version of your library into the device build of your app. The simulator wants libraries in the i386 architecture, and the device wants things in the armv6 or armv7 architecture.

So the solution here is to link the correct version of your library.

What I usually do is combine them into a single library and let the linker pick the right version for me. Here's what you do in Terminal:

$ cd /path/to/my/libraries
$ ls 
  libMyLibrary-Device.a
  libMyLibrary-Simulator.a
$ file libMyLibrary-Device.a
  libMyLibrary-Device.a: Mach-O universal binary with 2 architectures
  libMyLibrary-Device.a (for architecture armv6):   current ar archive random library
  libMyLibrary-Device.a (for architecture armv7):   current ar archive random library
$ file libMyLibrary-Simulator.a
  libMyLibrary-Simulator.a: Mach-O universal binary with 1 architecture
  libMyLibrary-Simulator.a (for architecture i386): current ar archive random library
$ lipo -create -output libMyLibrary.a libMyLibrary-Device.a libMyLibrary-Simulator.a
$ ls
  libMyLibrary-Device.a
  libMyLibrary-Simulator.a
  libMyLibrary.a
$ file libMyLibrary.a
  libMyLibrary.a: Mach-O universal binary with 3 architectures
  libMyLibrary.a (for architecture armv6):  current ar archive random library
  libMyLibrary.a (for architecture armv7):  current ar archive random library
  libMyLibrary.a (for architecture i386):   current ar archive random library

Then you just link libMyLibrary instead of the device or simulator version, and the linker will do the right thing.



回答2:

I was having this same problem with the SQLite 3 library (libsqlite3.dylib). I opened up an older project and the same library compiled. I compared the Target Info > Build Settings > Search Paths on each project, and while the older (working) project was empty, there were multiple search paths in "Framework Search Paths" in the newer project. Deleting all of them solved the issue. Hope this helps someone, this took me many, many hours to figure out.



回答3:

If you don't want to combine the libraries for some reason (like having a debug lib and a release lib) there is a way that you can include different libraries depending on your build target.

If you open up your project info (right-click on the project->Get Info or highlight it and click the info button) and go down to the Linking section, highlight Other Linker Flags and then click on the cog on the bottom-left of the screen one of the options is Add Build Setting Condition. Clicking on that will give you a child option under Other Linker Flags that has, by default, Any SDK and Any Architecture drop-downs with a blank line following. From there you can set specific linker flags (-lmylib-release-iphonesimulator etc.) depending on various build settings.