Ad

Our DNA is written in Swift
Jump

Xcode 6 drops armv7s

The latest Xcode update no longer builds for the armv7s architecture by default. Is it planned obsolesce or an oversight?

The current Xcode 6 defines ${ARCHS_STANDARD} as armv7, arm64. Also whenever you update Xcode it keeps pestering you to remove your own definition of what architectures to build so that it can decide this for you. If you give in to this insisting then you find that you’ll no longer build your things for armv7s.

The armv7s instruction set is found in Apple’s A6 (iPhone 5) and A6X (iPad 4) CPUs. The following Apple A7 (found in iPhone 5S, iPad Air, iPad Mini Retina) already had moved to 64-bit architecture arm64.

When Apple added support for building armv7s to Xcode they confused quite a few developers who were using binary builds of third party libraries, like Google Analytics. In order to build an app’s architecture slice the linker requires the same architecture also to be present in all linked static libraries. Developers had to remove armv7s support from their apps while the third parties where struggling to update their binary builds to add the new architecture.

That was not a real issue, because A6 would run armv7 code just fine, albeit with a few less optimizations. Nevertheless it is a bit unsettling if suddenly your app does not build any more with Xcode outputting a linker error about a missing architecture, just because you updated your Xcode.

Missing armv7s architecture

The fix is quite simple. As an app maker you can simply go with Xcode’s recommendation and remove your override on the Architectures build setting. If this setting is shown in bold then you can revert it to the project-wide setting with CMD+backspace.

As a component vender you should probably go a different route. You want to leave the decision to support or drop armv7s to the developer. And therefore you should add the armv7s architecture to all your static library and framework targets for it to be included.

Adding armv7s

The developer’s linker will then pick out the architecture slices it needs for the app. You can see that certain architectures are included if you build with “Build Active Architecture Only” set to now. The default for Debug builds is to have this on Yes on only build for the current device or simulator architecture. Release builds have this set to No and thus all architectures mentioned are going to be built.

In the build log for the static library target you will have one line for the library for each architecture, followed by one line combining the individual libraries into one “fat” universal library.

Screen Shot 2014-10-10 at 10.53.48

Another method to verifying what architecture slices are present in a file is to use the file command:

file libBarCodeKit.a 
libBarCodeKit.a: Mach-O universal binary with 3 architectures
libBarCodeKit.a (for architecture armv7):	current ar archive random library
libBarCodeKit.a (for architecture arm64):	current ar archive random library
libBarCodeKit.a (for architecture armv7s):	current ar archive random library

This library contains the slices for all relevant mobile architectures. If you are building a static framework or universal static library for binary distribution you would even include the simulator architectures. This looks like so:

file DTRichTextEditor 
DTRichTextEditor: Mach-O universal binary with 5 architectures
DTRichTextEditor (for architecture armv7):	current ar archive random library
DTRichTextEditor (for architecture armv7s):	current ar archive random library
DTRichTextEditor (for architecture arm64):	current ar archive random library
DTRichTextEditor (for architecture i386):	current ar archive random library
DTRichTextEditor (for architecture x86_64):	current ar archive random library

To conclude, Apple is again nudging us in a certain direction: to stop supporting armv7s. This architecture has been superseded by powerful 64-bit CPUs in two product generations by now. Yet, as a component vendor I believe that we should still include the armv7s slice to leave the choice up to the app developers.


Categories: Apple

5 Comments »

  1. I suppose that at some point in the future it makes sense for library vendors to drop the armv7s slice, but when would that be? I’d probably wait until the next major release of Xcode…

  2. Could you please tell me how you include the simulator architectures. Do you use a special script? I set all five architectures in project settings, but in my result file I get only device architectures or only simulator architectures.

  3. Hello,

    I am using xcode 6.2 to upload my app on app store but my app having the Google’s libGDataTouchStaticLib.aa
    which is used for video upload on youtube from the app but xcode giving the error “Undefined symbols for architecture arm64” for libGDataTouchStaticLib.a becouse its not compiled for arm64 architecture.

    How can I solve this issue.
    Apple says at the time of validation app if I add the arm64 in Valid architecture:

    Missing 64-bit support – Beginning on February 1, 2015 new iOS apps submitted to the App Store must include 64-bit support and be built with the iOS 8 SDK. Beginning June 1, 2015 app updates will also need to follow the same requirements. To enable 64-bit in your project, we recommend using the default Xcode build setting of “Standard architectures” to build a single binary with both 32-bit and 64-bit code.

    if I Change valid architecture setting the it gives:

    Undefined symbols for architecture arm64:
    “_OBJC_METACLASS_$_GTMHTTPFetcher”, referenced from:
    _OBJC_METACLASS_$_GTMHTTPUploadFetcher1 in GTMHTTPUploadFetcher1.o
    “_OBJC_CLASS_$_GTMHTTPFetcher”, referenced from:
    _OBJC_CLASS_$_GTMHTTPUploadFetcher1 in GTMHTTPUploadFetcher1.o
    objc-class-ref in GTMHTTPUploadFetcher1.o
    objc-class-ref in GTMOAuth2Authentication1.o
    objc-class-ref in GTMOAuth2SignIn1.o
    “_OBJC_IVAR_$_GTMHTTPFetcher.retryBlock_”, referenced from:
    -[GTMHTTPUploadFetcher1 chunkFetcher:willRetry:forError:] in GTMHTTPUploadFetcher1.o
    “_kGTMHTTPFetcherStatusDomain”, referenced from:
    -[GTMHTTPUploadFetcher1 connectionDidFinishLoading:] in GTMHTTPUploadFetcher1.o
    -[GTMHTTPUploadFetcher1 chunkFetcher:finishedWithData:error:] in GTMHTTPUploadFetcher1.o
    -[GTMHTTPUploadFetcher1 chunkFetcher:willRetry:forError:] in GTMHTTPUploadFetcher1.o
    -[GTMOAuth2Authentication1 beginTokenFetchWithDelegate:didFinishSelector:] in GTMOAuth2Authentication1.o
    -[GTMOAuth2SignIn1 authCodeObtained] in GTMOAuth2SignIn1.o
    “_kGTMHTTPFetcherErrorDomain”, referenced from:
    -[GTMHTTPUploadFetcher1 uploadNextChunkWithOffset:fetcherProperties:] in GTMHTTPUploadFetcher1.o
    “_OBJC_IVAR_$_GTMHTTPFetcher.delegate_”, referenced from:
    -[GTMHTTPUploadFetcher1 invokeFinalCallbacksWithData:error:] in GTMHTTPUploadFetcher1.o
    -[GTMHTTPUploadFetcher1 chunkFetcher:willRetry:forError:] in GTMHTTPUploadFetcher1.o
    -[GTMHTTPUploadFetcher1 uploadFetcher:didSendBytes:totalBytesSent:totalBytesExpectedToSend:] in GTMHTTPUploadFetcher1.o
    “_GTMAssertSelectorNilOrImplementedWithArgs”, referenced from:
    -[GTMHTTPUploadFetcher1 beginFetchWithDelegate:didFinishSelector:] in GTMHTTPUploadFetcher1.o
    -[GTMOAuth2Authentication1 authorizeRequest:delegate:didFinishSelector:] in GTMOAuth2Authentication1.o
    -[GTMOAuth2SignIn1 initWithAuthentication:authorizationURL:delegate:webRequestSelector:finishedSelector:] in GTMOAuth2SignIn1.o
    “_OBJC_CLASS_$_GDataEntryYouTubeUpload”, referenced from:
    objc-class-ref in YouTubeUploader.o
    “_OBJC_IVAR_$_GTMHTTPFetcher.retrySel_”, referenced from:
    -[GTMHTTPUploadFetcher1 chunkFetcher:willRetry:forError:] in GTMHTTPUploadFetcher1.o
    “_OBJC_CLASS_$_GDataMediaDescription”, referenced from:
    objc-class-ref in YouTubeUploader.o
    “_OBJC_CLASS_$_GDataUtilities”, referenced from:
    objc-class-ref in YouTubeUploader.o
    “_OBJC_IVAR_$_GTMHTTPFetcher.completionBlock_”, referenced from:
    ___57-[GTMHTTPUploadFetcher1 beginFetchWithCompletionHandler:]_block_invoke in GTMHTTPUploadFetcher1.o
    -[GTMHTTPUploadFetcher1 invokeFinalCallbacksWithData:error:] in GTMHTTPUploadFetcher1.o
    “_OBJC_IVAR_$_GTMHTTPFetcher.sentDataBlock_”, referenced from:
    -[GTMHTTPUploadFetcher1 uploadFetcher:didSendBytes:totalBytesSent:totalBytesExpectedToSend:] in GTMHTTPUploadFetcher1.o
    -[GTMHTTPUploadFetcher1 sentDataSelector] in GTMHTTPUploadFetcher1.o
    “_OBJC_IVAR_$_GTMHTTPFetcher.downloadedData_”, referenced from:
    -[GTMHTTPUploadFetcher1 chunkFetcher:finishedWithData:error:] in GTMHTTPUploadFetcher1.o
    “_OBJC_CLASS_$_GDataYouTubeMediaGroup”, referenced from:
    objc-class-ref in YouTubeUploader.o
    “_OBJC_CLASS_$_GDataMediaTitle”, referenced from:
    objc-class-ref in YouTubeUploader.o
    “_OBJC_CLASS_$_GDataMediaCategory”, referenced from:
    objc-class-ref in YouTubeUploader.o
    “_OBJC_CLASS_$_GDataServiceGoogleYouTube”, referenced from:
    objc-class-ref in YouTubeUploader.o
    “_kGDataServiceDefaultUser”, referenced from:
    -[YouTubeUploader uploadVideoFile:] in YouTubeUploader.o
    “_kGDataSchemeYouTubeCategory”, referenced from:
    -[YouTubeUploader uploadVideoFile:] in YouTubeUploader.o
    ld: symbol(s) not found for architecture arm64
    clang: error: linker command failed with exit code 1 (use -v to see invocation)