在樹莓派 3 上構建 Swift 3.0
在開始之前你需要準備好以下東西:
- 一個 樹莓派 3
- 一個容量至少 16GB 的 UHS-I/class 10 microSD 卡(我喜歡性價比高的 Patriot EP Series )
- Ubuntu Xenial 16.04
- 耐心
顯然這是可以做到的; 而且我們已經做到了 ,并且還有其他小伙伴也對基于 ARM 的設備上構建 Swift 程序作出了貢獻。所以別放棄。不過就算你放棄了我們也不會說什么,直接下載我們的 prebuilt Swift 3.0 package for the Raspberry Pi 2 and 3 吧。
安裝 Xenial
我們用 Ubuntu Xenial 代替 Raspbian 。用 curl 或 wget 獲取 Xenial,然后用 dd 將文件系統寫入 microSD 卡。
注意:請確保閱讀此警告。你必須替換下文提到的 YOUR_DEVICE 為正確的設備名。如果不替換成正確的名字,你的數據可能會毀壞(它們調用 dd 清除你的文件)。
使用 Linux
# wget http://www.finnie.org/software/raspberrypi/ubuntu-rpi3/ubuntu-16.04-preinstalled-server-armhf+raspi3.img.xz
# xzcat ubuntu-16.04-preinstalled-server-armhf+raspi3.img.xz | sudo dd of=/dev/YOUR_DEVICE bs=8M
想知道你的 YOUR_DEVICE ,你需要將 microSD 卡插入一臺裝載 Linux 的機器,運行 dmesg|tai 查看類似下面的內容
[1255451.544316] usb-storage 4-2:1.0: USB Mass Storage device detected
[1255451.544466] scsi host25: usb-storage 4-2:1.0
[1255452.545332] scsi 25:0:0:0: Direct-Access Generic STORAGE DEVICE 0817 PQ: 0 ANSI: 6
[1255452.545670] sd 25:0:0:0: Attached scsi generic sg8 type 0
[1255452.828405] sd 25:0:0:0: [sdh] 15523840 512-byte logical blocks: (7.94 GB/7.40 GiB)
[1255452.829402] sd 25:0:0:0: [sdh] Write Protect is off
[1255452.829409] sd 25:0:0:0: [sdh] Mode Sense: 23 00 00 00
[1255452.830400] sd 25:0:0:0: [sdh] Write cache: disabled, read cache: enabled, doesn't support DPO or FUA
[1255452.835967] sdh: sdh1
[1255452.840401] sd 25:0:0:0: [sdh] Attached SCSI removable disk
在這個例子中,你的設備是 /dev/sdh 。
使用 OS X (macOS)
我個人喜歡用一個單獨的 Linux 服務器進行這些操作,但你也可以在一臺 Mac 上使用 homebrew 完成這些操作:
# brew install wget xz
# wget http://www.finnie.org/software/raspberrypi/ubuntu-rpi3/ubuntu-16.04-preinstalled-server-armhf+raspi3.img.xz
# xzcat ubuntu-16.04-preinstalled-server-armhf+raspi3.img.xz|sudo dd of=/dev/rdisk3 bs=8m
注意到當在 Mac 上操作 dd,使用 /dev/rYOUR_DEVICE 會更明智。使用 /dev/YOUR_DEVICE 的速度很慢,詳細解釋見 這里 。
要在 Mac 上找到 YOUR_DEVICE ,插入 microSD 卡并且在終端運行 diskutil list 。尋找匹配你 SD 卡大小的磁盤(如果你有其他相同大小可匹配的磁盤,記得查看其他屬性保證你找到的磁盤是對的)。
# diskutil list
...
/dev/disk5 (external, physical):
#: TYPE NAME SIZE IDENTIFIER
0: FDisk_partition_scheme *16.0 GB disk5
1: Windows_FAT_32 system-boot 134.2 MB disk5s1
2: Linux 15.9 GB disk5s2
如果你對使用 diskutil 和 dd 命令感到困惑,建議閱讀 這篇文章 。順便說一句,如果你經常擺弄 Raspberry Pi 并且形成了習慣, wget 、 xzcat 和 dd 命令都是很重要的工具。要熟練操作它們。
更新 Xenial
好啦,既然你有一個裝著 Xenial 的 microSD 卡,就可以直接塞進樹莓派 3 啟動它!沒錯就是這樣,然后我們假設你有一個以太網接口或者 miniUSB 接口連接網絡。你可以先嘗試用 ssh ubuntu@ubuntu.local 遠程登錄你的樹莓派,如果失敗了,你可以打開路由器的 LAN 頁面確認一下 IP 地址。默認密碼是 ubuntu 。
# ssh ubuntu@192.168.1.115
The authenticity of host '192.168.1.115 (192.168.1.115)' can't be established.
ECDSA key fingerprint is 62:e9:f9:09:d0:30:3c:c9:0e:47:a3:42:f5:2c:e2:ae.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.1.115' (ECDSA) to the list of known hosts.
ubuntu@192.168.1.115's password:
You are required to change your password immediately (root enforced)
Welcome to Ubuntu 16.04 LTS (GNU/Linux 4.4.0-1009-raspi2 armv7l)
...
WARNING: Your password has expired.
You must change your password now and login again!
Changing password for ubuntu.
(current) UNIX password:
一旦你修改了密碼,你需要用 ubuntu 用戶重新登錄并且更新系統:
# sudo apt-get update && sudo apt-get upgrade -y
# reboot
安裝構建所需的依賴
編譯 Swift 需要很多依賴。可以用如下命令一次性搞定:
# sudo apt-get install -y git cmake ninja-build clang uuid-dev libicu-dev icu-devtools libbsd-dev libedit-dev libxml2-dev libsqlite3-dev swig libpython-dev libncurses5-dev pkg-config
幸運地是我們不用自己一個個去尋找依賴(你知道的,那些一次又一次下載一個目錄嘗試構建它后才發現缺少的依賴),因為這些依賴全都列在了 Open Source Swift README 里。
我也喜歡包含 htop 這樣我就可以看看樹莓派編譯出的進程信息:
添加一些 Swap 分區
盡管派 3 自帶 1GB 的高容量 RAM,依然不夠完整的構建 Swift(通常在鏈接步驟發生問題)。讓我們手動添加 1G Swap 分區。
# fallocate -l 1G 1G.swap
# sudo mkswap 1G.swap
Setting up swapspace version 1, size = 1024 MiB (1073737728 bytes)
no label, UUID=184d002a-2f15-4b23-8360-8e792badc6a2
# sudo swapon 1G.swap
以下是你在構建過程中出現 Swap 分區不可用的問題。
cd /root/workspace/Swift-3.0-Pi3-ARM-Incremental/build/buildbot_linux/swift-linux-armv7/bin && /usr/bin/cmake -E create_symlink swift swiftc && cd /root/workspace/Swift-3.0-Pi3-ARM-Incremental/build/buildbot_linux/swift-linux-armv7/bin && /usr/bin/cmake -E create_symlink swift swift-autolink-extract
clang: error: unable to execute command: Killed
clang: error: linker command failed due to signal (use -v to see invocation)
ninja: build stopped: subcommand failed.
./swift/utils/build-script: fatal error: command terminated with a non-zero exit status 1, aborting
在一個 microSD 卡上利用 Swap 分區雙倍擴容 RAM 并不是通用的辦法。一旦我們進入到構建階段需要我們染指 Swap 分區時,構建過程會變慢。但是不使用分區程序,其代價是以內存不足為錯誤提示崩潰。
使用 package-swift
package-swift 是我們的 Github 目錄,內含一些輔助腳本使得構建 Swift 更便捷。
# git clone https://github.com/iachievedit/package-swift
# cd package-swift
默認情況下 package-swift 會遷出一個 swift-3.0 的分支。腳本都非常簡單:
- get.sh – 下載所有構建 Swift 需要的目錄
- update.sh – 從 Github 上更新所有的本地目錄
- patch.sh – 應用 Swift on ARM 團隊推出的最新補丁;我們必須時不時的更新保證可運行。一旦補丁不再需要我們就移除它,所以在實際的構建之前需要先 git pull 保證所有補丁包最新。
- package.sh – 運行 Swift 的構建腳本,預設腳本名為 buildbot_linux_armv7
我建議你看看每個 shell 腳本,在執行前弄清它們的邏輯。腳本看上去很簡單,但是花時間去弄懂它們還是相當值得的。請注意在 get.sh 和 update.sh 中會檢到我們的構建是在 ARMv7 處理器上,所以我們需要 William Dillon 的 swift-llvm fork 。
開始構建
請確保你有:
- 安裝所有依賴包
- 激活 1 GB Swap 分區
- 已經從 Github 克隆的 package-swift
現在,克隆所有需要的目錄:
# cd package-swift
# ./get.sh
這個步驟我在我的 SD 卡上用了 15 分鐘下載和寫入所有東西。
緊接著,打補丁。獲取 Swift on ARM 團隊開發測試過的最新的補丁是非常重要的一步。這些補丁時不時就會改變,所以請保證實時更新它們。
# ./patch.sh
現在開始編譯。Swift on ARM 團隊使用 Jenkins 運行這個腳本,在這之上的構建工作是沒有日志的。但是如果你使用 nohup 來確保你的編譯正在進行,即使你的終端斷線了也能知道。
# nohup ./package.sh > swiftbuild.log&
現在,只需要等待!整個構建過程至少 6 個小時。然而等待的成果是值得的,最后獎勵是 swift.tar.gz bundle,可以在跑著 Ubuntu Xenial 的樹莓派 2 或 3 上安裝(不要嘗試在裝了 Raspbian 的機器上安裝,不然你會失望的)。我選擇像這樣在 /opt/swift/ 安裝 Swift:
# cd /opt
# mkdir -p swift/swift-3.0
# cd swift/swift-3.0
# tar -xzvf /path/to/swift.tar.gz
然后你可以用 export PATH=/opt/swift/swift-3.0/usr/bin:$PATH 設置 PATH。要正確的使用 swiftc 和 swift build 還需要運行以下命令:
sudo apt-get install -y libicu-dev
sudo apt-get install -y clang-3.6
sudo update-alternatives --install /usr/bin/clang clang /usr/bin/clang-3.6 100
sudo update-alternatives --install /usr/bin/clang++ clang++ /usr/bin/clang++-3.6 100
來自:http://swift.gg/2016/08/29/building-swift-3-0-on-a-raspberry-pi-3/