Hacking up an armv7s library
NOTE: Please take care with this. I obviously cannot test if this will actually work on a new iPhone 5 device! I provide no warranty if you submit having used this and it doesn’t actually work on the new device. Please think twice before submitting an app which you have used this method to create. You don’t have to submit an armv7s binary. Just set your “Architectures” build setting to armv7 only and submit the resulting binary.
UPDATE: It worked! I tested an app that I’d used this method to build an armv7s slice with. It ran fine on my iPhone 5 :-D.
Well the iPhone 5 has been announced and it just so happens that the architecture it uses is what they’re calling armv7s. This brings in yet another architecture to the mix alongside armv6 and armv7. And I bet you are wondering why you’re getting linker errors when building for armv7s when using external libraries. It’s because those external libraries do not have armv7s versions!
If you run file on the library then you’ll see that there is no armv7s version. For example:
|
1 2 3 4 5 |
$ file libUAirship-1.2.1.a libUAirship-1.2.1.a: Mach-O universal binary with 3 architectures libUAirship-1.2.1.a (for architecture armv7): current ar archive random library libUAirship-1.2.1.a (for architecture armv6): current ar archive random library libUAirship-1.2.1.a (for architecture i386): current ar archive random library |
So what can you do? You could wait for the library to be updated, or you could just follow these steps…
So what’s the deal?
Well, the problem is that when the linker does its merry business linking together all your object files, it is told what architecture to link for. Each of your libraries’ .a files will most likely be what are called “fat” meaning they have more than one architecture in them. But the linker won’t be able to find the armv7s version since it doesn’t exist in there.
But, we know that armv7s is a superset of armv7 (it’s just got a new version of the floating point unit so only adds new instructions). So what we can do is to copy the armv7 part of the library and add it again but tell it that it’s for armv7s. That sounds simple, but there’s more to it than that.
Inside each architecture’s portion of the fat library is something called an object file archive. This contains a collection of .o files that were combined together to form the library. Inside each .o is the code for each method. The linker uses these to build the final app binary, picking all the methods it needs to create the app. The problem is that these .o files also have a header to say what architecture they’re for.
Inside this header (called a Mach-O header) is a field for the CPU type and the CPU subtype. ARM is CPU type 12, armv7 is CPU subtype 9 and armv7s is CPU subtype 11. So, all we need to do is toggle all the 9s to 11s, right? Yup! But that’s easier said than done.
My solution is a script that strips out the armv7 portion of the fat library and then unpacks the archive into its constituent .o files. Then I wrote a little C program to do the 9 => 11 toggling which is run on each of the .o files. Then finally the new .o files are packaged up into a new portion which is re-added to the fat library.
Simple!
So, if you’re ready to get going then read on…
Do you need this to submit an app?
No.
Do not use this unless you really understand what you’re doing. You do not need to submit with an armv7s binary. Just set your Architectures build setting to armv7 only and submit the resulting binary.
A program you’ll need
The first thing you’ll need is the following program written in C:
armv7sconvert.c
|
/* * armv7sconvert <infile> <outfile> * Switches CPU subsystem type to armv7s * * By Matt Galloway - http://www.galloway.me.uk * * Based on g3spot.c from http://redbutton.sourceforge.net (c) Simon Kilvington, 2009 */ #include <stdio.h> #include <stdlib.h> #include <stdarg.h> #include <string.h> #include <errno.h> #include <mach-o/loader.h> void fatal(char *msg, ...); void fatal(char *msg, ...) { va_listap; va_start(ap, msg); vfprintf(stderr, msg, ap); fprintf(stderr, "\n"); va_end(ap); exit(EXIT_FAILURE); } int main(int argc, char *argv[]) { if (argc != 3) { fatal("Syntax: %s <in_file> <out_file>", argv[0]); } char *inName = argv[1]; char *outName = argv[2]; FILE *inFile = fopen(inName, "r"); if (inFile == NULL) { fatal("Unable to read %s: %s", inName, strerror(errno)); } /* find out how big it is */ fseek(inFile, 0, SEEK_END); longsize = ftell(inFile); rewind(inFile); printf("%s: %lu bytes\n", inName, size); /* read it all into memory */ unsigned char *buf = malloc(size); if (buf == NULL) { fatal("Out of memory"); } if (fread(buf, 1, size, inFile) != size) { fatal("Error trying to read %s: %s", inName, strerror(errno)); } if (fclose(inFile)) { fatal("Error trying to close %s: %s", inName, strerror(errno)); } structmach_header *mach_hdr = (struct mach_header *) (buf); printf("Mach magic: 0x%08x\n", mach_hdr->magic); if (mach_hdr->magic != MH_MAGIC) { fatal("Wrong magic number (expecting 0x%08x)", MH_MAGIC); } printf("CPU type: %d\n", ntohl(mach_hdr->cputype)); printf("CPU sub-type: %d\n", ntohl(mach_hdr->cpusubtype)); printf("*** Changing to CPU sub-type 11\n"); mach_hdr->cpusubtype = 11; printf("Saving as %s\n", outName); FILE * |
Hacking up an armv7s library的更多相关文章
- Build FFmpeg for iOS
FFmpeg Build Instructions MAC 10.8 or better Copy ffmpeg-2.0.tar.bz2 (https://ffmpeg.org/releases/ff ...
- iOS - Library 库
1.动态库 & 静态库 什么是库: 库是程序代码的集合,是共享程序代码的一种方式.根据源代码的公开情况,库可以分为 2 种类型: 开源库: 公开源代码,能看到具体实现. 比如 SDWebIma ...
- iOS开发之Xcode 6更新默认不支持armv7s架构
最近一次的Xcode 6更新默认不再支持arm7s架构,究竟是要废除不用呢还是仅仅只是一个疏忽? 目前的Xcode 6配置里定义${ARCHS_STANDARD}为armv7, arm64,当然这个定 ...
- 转:Build Your First JavaScript Library
http://net.tutsplus.com/tutorials/javascript-ajax/build-your-first-javascript-library/ Step 1: Creat ...
- xcode5.1 armv7 armv7s arm64 类型, 区分, 概念等
官方: https://developer.apple.com/library/ios/documentation/General/Conceptual/CocoaTouch64BitGuide/In ...
- [转]Hacking the iOS Spotlight
原文:http://theiostream.tumblr.com/post/36905860826/hacking-the-ios-spotlight 原文:http://theiostream.tu ...
- iOS.Library.Architecture
在用file查看library的architechture时有以下输出: $ file WebPWebP: Mach-O universal binary with 3 architecturesWe ...
- Android Mokoid Open Source Project hacking
/***************************************************************************** * Android Mokoid Open ...
- Qt QML referenceexamples attached Demo hacking
/********************************************************************************************* * Qt ...
随机推荐
- 【WPF】TabControl禁用部分选项卡
需求:使用TabControl分页栏控件时,由于部分分页下的内容尚未开发完成,不希望用户能够点击切换到那些分页. 百度搜到的一些做法比较麻烦,或者说是直接把分页移除的,这些都不符合需求.需求要的是能看 ...
- C语言 · 成绩的等级输出
输入一个百分制的成绩t后,按下式输出它的等级.等级为:90~100为A,80~89为B,70~79为C,60~69为D,0~59为E. 样例输入 98 样例输出 A #include<std ...
- 在MAC上查找和设置$JAVA_HOME
最近升级了MAC OS,装了JDK7 for mac,在这里下载JDK7 for mac,装完之后发现在默认的路径下找不到JDK7的HOME,如下所示: $ which java/usr/bin/ja ...
- WF追忆
前一阵子学习了一下工作流,现在写个总结记录一下这个过程.要弄工作流,首先就要有个界面来画图,做web的,没办法,只能选择javascript和silverlight,找来找去,最后用了Shareide ...
- js学习系列之-----apply和call
apply call 从字面意思就看出来,申请请,呼叫. 打个比方就是别人有什么功能,你向别人,申请 呼叫 一下,哥们拿你的功能用一下,而apply 和call就是实现这样的功能 apply 和cal ...
- 用route命令解决多出口的问题
网络已经走进了我们的生活.工作.学习之中,大多数单位.公司都已经连接到了Internet.但是,因为各种原因,有这样一个问题存在.就是:这些单位即有到公网(Internet)的出口连接,也有到专网(单 ...
- qt 窗口控件自动调整大小
/******************************************************************** * qt 窗口控件自动调整大小 * * 在写gui的时候,希 ...
- 用X264编码以后的H264数据
输入的数据准备好了,编码后的数据都在x264_nal_t的数组.我这里设置的参数是Baseline Profile,所以编码后没有B帧,将编码后的数据保存分析后发现,第一次编码的时候会有4个NAl,分 ...
- java web - 为什么要使用spring struts
1.软件里有很多优秀的框架,有一种类型的框架,它的特点是建立在一个现有技术的基础上,提供和现有技术一样业务功能的技术框架,这个新的技术框架比原技术更加易用,更加健壮同时功能更加强大,例如:jQuery ...
- zookper3.4.6集群配置
参考链接: http://blog.csdn.net/shirdrn/article/details/7183503 个人感觉zookeeper 安装在单机上无操作意义,所以直接记录集群配置过程. 连 ...