1.原因:
Xcode 7's New Linker Rules
The other day I received a new error from Xcode 7. I was building an iOS project for simulator, linking in a fat static library with i386 and x86_64. The error looked like this:
ld: in /Users/tk/Code/.../libtest.a(TestLib.o), building for iOS simulator,
but linking in object file built for OSX, for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
This is a pretty strange thing for a linker to say. The iOS simulator and OSX use exactly the same architectures. How is it supposed to know the difference, and why does it matter?
I followed this up with some testing. If I compiled a simple C library like this:
$ clang -c -arch i386 -arch x86_64 TestLib.c
$ libtool -static -o libtest.a TestLib.o
$ lipo -info libtest.a
Architectures in the fat file: libtest.a are: i386 x86_64
…then that would fail to link inside an iOS simulator project.
But if I took exactly the same files and built a static library using Xcode, then thatlibtest.a
would link fine, even though both files contained the same function for the same architectures.
So Xcode was doing something magic and I figured it must be a bug in Xcode 7’s linker. At this point I filed a bug report with Apple, who quickly got back to me with this explanation:
"In Xcode 7, the linker enforces that all files linked together were built for the same platform. You control the platform via -mmacosx-version-min=XX or -miphoneos-version-min=XX."
As far as I can tell Xcode 7 makes sure that every single object file is marked with extra flags for both the platform (OSX, iOS, tvOS, watchOS) and the minimum version of the platform that it’s designed for. I’m not sure why. Perhaps there are technical reasons, but I can certainly imagine that with so many platforms flying about this could be a source of errors.
I tried recompiling my static library using clang -miphoneos-version-min=7.0
and sure it enough it worked. Makes sense. (Though confusingly, this particular option doesn’t appear in clang --help
.)
They went on to explain that you can see these flags in .o
or .a
files by using theotool
command. I tried it out and it came out like this:
# A static library marked as iOS
$ otool -lv libtest.a | grep LC_VERSION
cmd LC_VERSION_MIN_IPHONEOS
# A static library marked as OSX
$ otool -lv libtest.a | grep LC_VERSION
cmd LC_VERSION_MIN_MACOSX
Bafflingly, I haven’t been able to find any Apple documentation about these clang flags and their new significance. I decided I’d better write this up as it might save some people some time.
亲测:
# 设置编译ios最小版本为6.0(xcode7支持6.0及以上) $ clang -c -arch i386 -arch x86_64 TestLib.c -miphoneos-version-min=6.0 $ libtool -static -o libtest.a TestLib.o $ lipo -info libtest.a Architectures in the fat file: libtest.a are: i386 x86_64 $ otool -lv libtest.a | grep LC_VERSION cmd LC_VERSION_MIN_IPHONEOS2.解决方案:
(参考https://discuss.newrelic.com/t/build-failure-in-ios-9/25963/63
Hi all! Posting here to ensure you have seen this announcement:
EDIT 9/17/15 3:30PM: Our newest release, iOS Agent v5.3.0, is fully compatible with Xcode 7. Please use this rather than the dev build linked below in my original post. Hi everyone, As Xcode 7 and iOS 9 near GA we want to clarify on New Relic's current compatibility and our strategy for supporting older versions of Xcode moving forward. 1) Apps built with Xcode 6 with our existing iOS agents have worked fine on iOS 9 in our own internal testing. 2) We have an alternate version of …
This should be ready to use. Thank you for all of your feedback on this important issue!
Hey there! Looks like you're enjoying the discussion, but you're not signed up for an account.
When you create an account, we remember exactly what you've read, so you always come right back where you left off. You also get notifications, here and via email, whenever new posts are made. And you can like posts to share the love.
下载iOS模拟器代理
iOS Agent v5.3.0(https://docs.newrelic.com/docs/release-notes/mobile-release-notes/ios-release-notes/ios-530)