Golang教程:编译可在苹果iOS设备上运行的Go语言程序 | Konica 的自留地

Golang教程:编译可在苹果iOS设备上运行的Go语言程序

风暴, 天气, 雷暴, 雷声, 云, 权力, 危险, 自然, 闪电, 强大, 引人注目, 飓风, 灾难

前言

写在这里,算是mark一下,给后来的同学少走一些弯路。

本教程仅适用于 macOS, Linux 系统请看我的这篇教程,Golang教程:使用 Ubuntu 系统编译可在 iOS 设备上运行的Go语言程序

Hello-World 是我写的一个example,Github地址

Golang 支持的平台非常多, 运行go tool dist list查看已支持的所有平台

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
appledeimac:Hello-World apple$ go version
go version go1.8.3 darwin/amd64
appledeimac:Hello-World apple$ go tool dist list
android/386
android/amd64
android/arm
android/arm64
darwin/386
darwin/amd64
darwin/arm
darwin/arm64
dragonfly/amd64
freebsd/386
freebsd/amd64
freebsd/arm
linux/386
linux/amd64
linux/arm
linux/arm64
linux/mips
linux/mips64
linux/mips64le
linux/mipsle
linux/ppc64
linux/ppc64le
linux/s390x
nacl/386
nacl/amd64p32
nacl/arm
netbsd/386
netbsd/amd64
netbsd/arm
openbsd/386
openbsd/amd64
openbsd/arm
plan9/386
plan9/amd64
plan9/arm
solaris/amd64
windows/386
windows/amd64

编译可在苹果iOS设备上运行的Go语言程序(需要安装 Xcode)

iOS 系统内核为 darwin,CPU架构为ARM。
ARM处理器,因其功耗低和尺寸小而闻名,几乎所有的手机处理器都基于ARM,苹果当然也不例外。
arm(32位元),arm64(64位元)

arm64设备:iPhone 5s 及以上、iPad Air 及以上
arm设备:iPhone 5s 以下,iPad 4 及以下

可以看到,Golang版本为1.8.3,支持以下两个平台

darwin/arm
darwin/arm64

说明这个版本的Golang是支持iOS

但是不能像编译 windows,linux 程序那样编译iOS程序,否则可能会编译报错,或者编译出的程序不能正常运行.

使用go env查看go的环境变量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
appledeimac:Hello-World apple$ go env
GOARCH="amd64"
GOBIN=""
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOOS="darwin"
GOPATH="/Volumes/KINSTON/Golang"
GORACE=""
GOROOT="/usr/local/go"
GOTOOLDIR="/usr/local/go/pkg/tool/darwin_amd64"
GCCGO="gccgo"
CC="/Users/apple/my/bin/aarch64-linux-android-4.9/bin/aarch64-linux-android-gcc"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fno-common"
CXX="clang++"
CGO_ENABLED="1"
PKG_CONFIG="pkg-config"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"

可以看到 CC的值为 /Users/apple/my/bin/aarch64-linux-android-4.9/bin/aarch64-linux-android-gcc,这里要将CC设为$GOROOT/misc/ios/clangwrap.sh
$GOROOT 为 Golang 默认的安装目录,在 OS X 为 /usr/local/go, 在Windows系统为C:\Go
此外还要将 CGO_ENABLED 设为 1 ,否则可能会编译报错,或者编译出的程序不能正常运行

所以,编译 darwin/arm64 的 example 命令就是:

CC=/usr/local/go/misc/ios/clangwrap.sh GOOS=darwin GOARCH=arm64 CGO_ENABLED=1 go build

不出意外的话,编译成功,可执行二进制程序在该目录生成。使用file命令查看文件类型

appledeimac:Hello-World apple$ file Hello-World
Hello-World: Mach-O 64-bit executable arm64

接下来给程序签名,否则程序在iOS设备运行时可能会返回Killed: 9错误
使用 ldid -S 为程序签名

ldid -S Hello-World

如果没有安装 ldid , 先安装 Homebrew,用 brew 命令安装 ldid

brew install ldid

输入 ldid 验证是否安装成功

1
2
3
4
5
appledeimac:~ apple$ ldid
usage: ldid -S[entitlements.xml] <binary>
ldid -e MobileSafari
ldid -S cat
ldid -Stfp.xml gdb

编译 darwin/arm 的 example 命令是:

CC=/usr/local/go/misc/ios/clangwrap.sh GOOS=darwin GOARCH=arm CGO_ENABLED=1 go build

编译时可能会报错找不到crt1.3.1.o,这是因为高版本的 Xcode 已经去掉了这个文件,有以下解决方案

  1. 访问苹果官网下载低版本的Xcode
    提取低版本Xcode的crt1.3.1.o,路径大致为/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/usr/lib/crt1.3.1.o

  2. 使用现成步骤1提取出的 crt1.3.1.o
    下载地址
    将文件放入/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/usr/lib/目录中

使用file命令查看文件类型

appledeimac:Hello-World apple$ file Hello-World
Hello-World: Mach-O executable arm_v7

亟待完美解决

以上编译出的程序在运行时,会在开头返回一个错误

1
runtime/cgo: no Info.plist URL

实际上, 此错误不会对程序运行造成多大影响,可以忽略,如果想要去除错误,只需在程序所在目录下放置一个名为 Info.plist 的有效文件即可.

随笔

当时我高三,接触Go语言时只有一点点编程基础,gcc、cgo这些“基础”都是后来才懂的

众所周知,Golang在国内不是很火,所以百度出来的东西基本解决不了什么问题

Google搜出的东西就很多了,不过大多都是英文网站,浏览全文后发现这些资料与我遇到的问题关联不大,没有提到解决问题的关键所在,似乎世界上很少有人会关注这个问题。

本教程看上去很简单吧,然而Google却不容易搜到。由于可用资源的缺乏,“基础”不扎实,加上高三空闲时间不可能充足,所以我为了解决编译可在苹果iOS设备上运行的Go语言程序这个问题并不容易。

此后闲着没事干的时候,我偶尔也会关注这问题,浏览各种英文网站,不断寻找对解决问题有用的信息。

期间我也学到了许多东西,包括独立解决问题能力提高、英语词汇扩充、阅读能力提高等。

我英语成绩很一般,成绩总在105分附近波动。

使用Google查英文资料的过程,也小幅提升了我的英语成绩。

高考英语118分,不算高,周围也很多120+的同学,但我已经很满意了。