在树莓派 3 上构建 Swift 3.0
RileyG91
8年前
<p> </p> <p style="text-align:center"><img src="https://simg.open-open.com/show/580e6bac6ed39c125e141fa2a79825df.png"></p> <p> </p> <p>在开始之前你需要准备好以下东西:</p> <ul> <li>一个 <a href="/misc/goto?guid=4959713515265691373" rel="nofollow,noindex">树莓派 3</a></li> <li>一个容量至少 <strong>16GB</strong> 的 UHS-I/class 10 microSD 卡(我喜欢性价比高的 <a href="/misc/goto?guid=4959713515394247878" rel="nofollow,noindex">Patriot EP Series</a> )</li> <li><a href="/misc/goto?guid=4959713515522264886" rel="nofollow,noindex">Ubuntu Xenial 16.04</a></li> <li>耐心</li> </ul> <p>显然这是可以做到的; <a href="/misc/goto?guid=4959713515630445369" rel="nofollow,noindex">而且我们已经做到了</a> ,并且还有其他小伙伴也对基于 ARM 的设备上构建 Swift 程序作出了贡献。所以别放弃。不过就算你放弃了我们也不会说什么,直接下载我们的 <a href="/misc/goto?guid=4959713515630445369" rel="nofollow,noindex">prebuilt Swift 3.0 package for the Raspberry Pi 2 and 3</a> 吧。</p> <h2>安装 Xenial</h2> <p>我们用 <a href="/misc/goto?guid=4959713515748846255" rel="nofollow,noindex">Ubuntu Xenial</a> 代替 Raspbian 。用 curl 或 wget 获取 Xenial,然后用 dd 将文件系统写入 microSD 卡。</p> <p>注意:请确保阅读此警告。你必须替换下文提到的 YOUR_DEVICE 为正确的设备名。如果不替换成正确的名字,你的数据可能会毁坏(它们调用 <a href="/misc/goto?guid=4959713515848258865" rel="nofollow,noindex">dd</a> 清除你的文件)。</p> <h2>使用 Linux</h2> <pre> <code class="language-swift"># 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 </code></pre> <p>想知道你的 YOUR_DEVICE ,你需要将 microSD 卡插入一台装载 Linux 的机器,运行 dmesg|tai 查看类似下面的内容</p> <pre> <code class="language-swift">[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 </code></pre> <p>在这个例子中,你的设备是 /dev/sdh 。</p> <h2>使用 OS X (macOS)</h2> <p>我个人喜欢用一个单独的 Linux 服务器进行这些操作,但你也可以在一台 Mac 上使用 <a href="/misc/goto?guid=4958824006634651729" rel="nofollow,noindex">homebrew</a> 完成这些操作:</p> <pre> <code class="language-swift"># 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 </code></pre> <p>注意到当在 Mac 上操作 dd,使用 /dev/rYOUR_DEVICE 会更明智。使用 /dev/YOUR_DEVICE 的速度很慢,详细解释见 <a href="/misc/goto?guid=4959713515986072389" rel="nofollow,noindex">这里</a> 。</p> <p>要在 Mac 上找到 YOUR_DEVICE ,插入 microSD 卡并且在终端运行 diskutil list 。寻找匹配你 SD 卡大小的磁盘(如果你有其他相同大小可匹配的磁盘,记得查看其他属性保证你找到的磁盘是对的)。</p> <pre> <code class="language-swift"># 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 </code></pre> <p>如果你对使用 diskutil 和 dd 命令感到困惑,建议阅读 <a href="/misc/goto?guid=4959713516081951872" rel="nofollow,noindex">这篇文章</a> 。顺便说一句,如果你经常摆弄 Raspberry Pi 并且形成了习惯, wget 、 xzcat 和 dd 命令都是很重要的工具。要熟练操作它们。</p> <h2>更新 Xenial</h2> <p>好啦,既然你有一个装着 Xenial 的 microSD 卡,就可以直接塞进树莓派 3 启动它!没错就是这样,然后我们假设你有一个以太网接口或者 miniUSB 接口连接网络。你可以先尝试用 ssh ubuntu@ubuntu.local 远程登录你的树莓派,如果失败了,你可以打开路由器的 LAN 页面确认一下 IP 地址。默认密码是 ubuntu 。</p> <pre> <code class="language-swift"># 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: </code></pre> <p>一旦你修改了密码,你需要用 ubuntu 用户重新登录并且更新系统:</p> <pre> <code class="language-swift"># sudo apt-get update && sudo apt-get upgrade -y # reboot </code></pre> <h2>安装构建所需的依赖</h2> <p>编译 Swift 需要很多依赖。可以用如下命令一次性搞定:</p> <pre> <code class="language-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 </code></pre> <p>幸运地是我们不用自己一个个去寻找依赖(你知道的,那些一次又一次下载一个目录尝试构建它后才发现缺少的依赖),因为这些依赖全都列在了 Open Source Swift <a href="/misc/goto?guid=4958973376962661127" rel="nofollow,noindex">README</a> 里。</p> <p>我也喜欢包含 htop 这样我就可以看看树莓派编译出的进程信息:</p> <p><img src="https://simg.open-open.com/show/904273474878f671ad8ba653cc913612.png"></p> <h2>添加一些 Swap 分区</h2> <p>尽管派 3 自带 1GB 的高容量 RAM,依然不够完整的构建 Swift(通常在链接步骤发生问题)。让我们手动添加 1G Swap 分区。</p> <pre> <code class="language-swift"># 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 </code></pre> <p>以下是你在构建过程中出现 Swap 分区不可用的问题。</p> <pre> <code class="language-swift">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 </code></pre> <p>在一个 microSD 卡上利用 Swap 分区双倍扩容 RAM 并不是通用的办法。一旦我们进入到构建阶段需要我们染指 Swap 分区时,构建过程会变慢。但是不使用分区程序,其代价是以内存不足为错误提示崩溃。</p> <h2>使用 package-swift</h2> <p>package-swift 是我们的 Github 目录,内含一些辅助脚本使得构建 Swift 更便捷。</p> <pre> <code class="language-swift"># git clone https://github.com/iachievedit/package-swift # cd package-swift </code></pre> <p>默认情况下 package-swift 会迁出一个 swift-3.0 的分支。脚本都非常简单:</p> <ul> <li>get.sh – 下载所有构建 Swift 需要的目录</li> <li>update.sh – 从 Github 上更新所有的本地目录</li> <li>patch.sh – 应用 Swift on ARM 团队推出的最新补丁;我们必须时不时的更新保证可运行。一旦补丁不再需要我们就移除它,所以在实际的构建之前需要先 git pull 保证所有补丁包最新。</li> <li>package.sh – 运行 Swift 的构建脚本,预设脚本名为 buildbot_linux_armv7</li> </ul> <p>我建议你看看每个 shell 脚本,在执行前弄清它们的逻辑。脚本看上去很简单,但是花时间去弄懂它们还是相当值得的。请注意在 get.sh 和 update.sh 中会检到我们的构建是在 ARMv7 处理器上,所以我们需要 <a href="/misc/goto?guid=4959713516200458549" rel="nofollow,noindex">William Dillon 的 swift-llvm fork</a> 。</p> <h2>开始构建</h2> <p>请确保你有:</p> <ul> <li>安装所有依赖包</li> <li>激活 1 GB Swap 分区</li> <li>已经从 Github 克隆的 package-swift</li> </ul> <p>现在,克隆所有需要的目录:</p> <pre> <code class="language-swift"># cd package-swift # ./get.sh </code></pre> <p>这个步骤我在我的 SD 卡上用了 15 分钟下载和写入所有东西。</p> <p>紧接着,打补丁。获取 Swift on ARM 团队开发测试过的最新的补丁是非常重要的一步。这些补丁时不时就会改变,所以请保证实时更新它们。</p> <pre> <code class="language-swift"># ./patch.sh </code></pre> <p>现在开始编译。Swift on ARM 团队使用 <a href="/misc/goto?guid=4958989363547439185" rel="nofollow,noindex">Jenkins</a> 运行这个脚本,在这之上的构建工作是没有日志的。但是如果你使用 nohup 来确保你的编译正在进行,即使你的终端断线了也能知道。</p> <pre> <code class="language-swift"># nohup ./package.sh > swiftbuild.log& </code></pre> <p>现在,只需要等待!整个构建过程至少 6 个小时。然而等待的成果是值得的,最后奖励是 swift.tar.gz bundle,可以在跑着 Ubuntu Xenial 的树莓派 2 或 3 上安装(不要尝试在装了 Raspbian 的机器上安装,不然你会失望的)。我选择像这样在 /opt/swift/ 安装 Swift:</p> <pre> <code class="language-swift"># cd /opt # mkdir -p swift/swift-3.0 # cd swift/swift-3.0 # tar -xzvf /path/to/swift.tar.gz </code></pre> <p>然后你可以用 export PATH=/opt/swift/swift-3.0/usr/bin:$PATH 设置 PATH。要正确的使用 swiftc 和 swift build 还需要运行以下命令:</p> <pre> <code class="language-swift">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 </code></pre> <h2> </h2> <p> </p> <p>来自:http://swift.gg/2016/08/29/building-swift-3-0-on-a-raspberry-pi-3/</p> <p> </p>