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的更多相关文章

  1. Build FFmpeg for iOS

    FFmpeg Build Instructions MAC 10.8 or better Copy ffmpeg-2.0.tar.bz2 (https://ffmpeg.org/releases/ff ...

  2. iOS - Library 库

    1.动态库 & 静态库 什么是库: 库是程序代码的集合,是共享程序代码的一种方式.根据源代码的公开情况,库可以分为 2 种类型: 开源库: 公开源代码,能看到具体实现. 比如 SDWebIma ...

  3. iOS开发之Xcode 6更新默认不支持armv7s架构

    最近一次的Xcode 6更新默认不再支持arm7s架构,究竟是要废除不用呢还是仅仅只是一个疏忽? 目前的Xcode 6配置里定义${ARCHS_STANDARD}为armv7, arm64,当然这个定 ...

  4. 转:Build Your First JavaScript Library

    http://net.tutsplus.com/tutorials/javascript-ajax/build-your-first-javascript-library/ Step 1: Creat ...

  5. xcode5.1 armv7 armv7s arm64 类型, 区分, 概念等

    官方: https://developer.apple.com/library/ios/documentation/General/Conceptual/CocoaTouch64BitGuide/In ...

  6. [转]Hacking the iOS Spotlight

    原文:http://theiostream.tumblr.com/post/36905860826/hacking-the-ios-spotlight 原文:http://theiostream.tu ...

  7. iOS.Library.Architecture

    在用file查看library的architechture时有以下输出: $ file WebPWebP: Mach-O universal binary with 3 architecturesWe ...

  8. Android Mokoid Open Source Project hacking

    /***************************************************************************** * Android Mokoid Open ...

  9. Qt QML referenceexamples attached Demo hacking

    /********************************************************************************************* * Qt ...

随机推荐

  1. 【Unity笔记】物体朝着鼠标位置移动

    其实思路也很简单,就是先获取到鼠标的坐标,然后赋值给目标物体即可. void Update(){ // 物体跟随鼠标移动 Vector2 mousePos = Input.mousePosition; ...

  2. Java并发(二)多线程的好处

    即使编写多线程程序具有挑战性,但它仍在使用中,是因为它可以带来如下的好处: 更好的资源利用 在某些场景下程序的设计会更简单 提升程序的响应性 更好的资源利用 假设一个应用会从本地文件系统中读取和处理文 ...

  3. MyBatis 网络资料

    http://mybatis.github.io/mybatis-3/zh/index.html 官方文档例子 http://blog.csdn.net/rootsuper/article/detai ...

  4. 开源直播OBS ( Open Broadcaster Software ) 多机位,多场景切换

    项目主页:https://obsproject.com/download 软件是基于MFC的,下载源码后一次性就可以编译通过,使用很简单. 使用了以下开源库: x264                 ...

  5. 修改 ueditor1_4_3-utf8-php 它的图片上传地址

    本来是这样的 至少应该是在,myapp目录下吧,从myapp文件夹,我的网站才刚开始啊...你让我将来怎么设置?麻烦... 找到uploader的文件 $rootPath = $_SERVER['DO ...

  6. mysql -- 模糊查询的四种方法

    摘录自:http://www.jb51.net/article/48315.htm 1 %:表示任意0个或多个字符.可匹配任意类型和长度的字符,有些情况下若是中文,请使用两个百分号(%%)表示. 比如 ...

  7. ZABBIX API简介及使用

    API简介 Zabbix API开始扮演着越来越重要的角色,尤其是在集成第三方软件和自动化日常任务时.很难想象管理数千台服务器而没有自动化是多么的困难.Zabbix API为批量操作.第三方软件集成以 ...

  8. asp.net mvc中加入log4net记录错误日志

    直接上代码示例:https://share.weiyun.com/aff36f2547514cfefe129ebb8ccb28ef 首先添加加log4net的dll,推荐用nuget.... 贴上配置 ...

  9. NET Core 环境搭建和命令行CLI入门[转]

      NET Core 环境搭建和命令行CLI入门 时间:2016-07-06 01:48:19      阅读:258      评论:0      收藏:0      [点我收藏+]   标签: N ...

  10. [转]Git学习笔记与IntelliJ IDEA整合

    Git学习笔记与IntelliJ IDEA整合 一.Git学习笔记(基于Github) 1.安装和配置Git 下载地址:http://git-scm.com/downloads Git简要使用说明:h ...