{"id":3052,"date":"2016-06-22T21:01:34","date_gmt":"2016-06-23T03:01:34","guid":{"rendered":"http:\/\/dev.iachieved.it\/iachievedit\/?p=3052"},"modified":"2016-09-24T14:27:01","modified_gmt":"2016-09-24T19:27:01","slug":"building-swift-3-0-on-a-raspberry-pi-3","status":"publish","type":"post","link":"https:\/\/dev.iachieved.it\/iachievedit\/building-swift-3-0-on-a-raspberry-pi-3\/","title":{"rendered":"Building Swift 3.0 on a Raspberry Pi 3"},"content":{"rendered":"<p><img decoding=\"async\" src=\"https:\/\/img.shields.io\/badge\/Swift-3.0-orange.svg?style=flat\" alt=\"Swift 3.0\" \/> <img decoding=\"async\" src=\"https:\/\/img.shields.io\/badge\/OS-Linux-blue.svg?style=flat\" alt=\"Swift 3.0\" \/> <img decoding=\"async\" src=\"https:\/\/img.shields.io\/badge\/Arch-ARM-red.svg?style=flat\" alt=\"Swift 3.0\" \/><\/p>\n<p><b>9\/24\/2016 Update<\/b>:  See our <a href=\"http:\/\/dev.iachieved.it\/iachievedit\/building-swift-3-0-on-an-armv7-system\/\">latest post<\/a> on building Swift 3.0 on ARMv7 systems such as the Pi 3.<\/p>\n<p><b>Editor&#8217;s Note:<\/b>  This post was updated on 9\/4\/2016 to reflect the recent updates for Swift 3.0 (in particular it now includes the build of <code>swift-corelibs-libdispatch<\/code>).<\/p>\n<p>A number of folks have expressed interest in building <a href=\"https:\/\/swift.org\/blog\/swift-3-0-release-process\/\">Swift 3.0<\/a> on their own Raspberry Pi 3.  These instructions are for those brave souls who want to do so!<\/p>\n<p>To get started you&#8217;re going to need:<\/p>\n<ul>\n<li>a <a href=\"https:\/\/www.raspberrypi.org\/products\/raspberry-pi-3-model-b\/\">Raspberry Pi 3<\/a><\/li>\n<li>a UHS-I\/class 10 microSD card with a capacity of <strong>16GB<\/strong> or greater (I like the <a href=\"https:\/\/www.amazon.com\/Patriot-Performance-MicroSDHC-Class-10-Compliant\/dp\/B00KXO0M3I\">Patriot EP Series<\/a> for the price combined with relatively high write speeds)<\/li>\n<li><a href=\"https:\/\/wiki.ubuntu.com\/XenialXerus\/ReleaseNotes\">Ubuntu Xenial 16.04<\/a><\/li>\n<li>Patience<\/li>\n<\/ul>\n<p>Note that this <i>can<\/i> be done; <a href=\"http:\/\/dev.iachieved.it\/iachievedit\/swift-3-0-on-raspberry-pi-2-and-3\/\">we&#8217;ve done it<\/a>, and there are group of folks dedicated to working with Swift on ARM-based devices.  Don&#8217;t give up.  If you <i>do<\/i> decide to give up we aren&#8217;t ones to judge, just head over and download our <a href=\"http:\/\/dev.iachieved.it\/iachievedit\/swift-3-0-on-raspberry-pi-2-and-3\/\">prebuilt Swift 3.0 package for the Raspberry Pi 2 and 3<\/a>.<\/p>\n<h2>Install Xenial<\/h2>\n<p>We will not be using Raspbian here, but rather <a href=\"https:\/\/wiki.ubuntu.com\/ARM\/RaspberryPi\">Ubuntu Xenial<\/a>.  Obtain Xenial with <code>curl<\/code> or <code>wget<\/code> and then write the filesystem out to your microSD card with <code>dd<\/code>.<\/p>\n<p><b>Note:<\/b>  You&#8217;ve read this warning before I&#8217;m sure, but it is critical that you put in the right device name where we reference <code>YOUR_DEVICE<\/code> below.  Failure to do so could destroy your data (they don&#8217;t call <code>dd<\/code> <a href=\"http:\/\/cloudnull.io\/2011\/12\/dd-and-the-mighty-disk-destroyer-or-duplicator\/\">disk destroyer<\/a> for nothing).<\/p>\n<h3>Using Linux<\/h3>\n<pre class=\"crayon:false\">\n# wget http:\/\/www.finnie.org\/software\/raspberrypi\/ubuntu-rpi3\/ubuntu-16.04-preinstalled-server-armhf+raspi3.img.xz\n# xzcat ubuntu-16.04-preinstalled-server-armhf+raspi3.img.xz | sudo dd of=\/dev\/YOUR_DEVICE bs=8M\n<\/pre>\n<p>To find your <code>YOUR_DEVICE<\/code> insert the microSD into your Linux machine and run <code>dmesg|tail<\/code> to see something like<\/p>\n<pre class=\"crayon:false\">\n[1255451.544316] usb-storage 4-2:1.0: USB Mass Storage device detected\n[1255451.544466] scsi host25: usb-storage 4-2:1.0\n[1255452.545332] scsi 25:0:0:0: Direct-Access     Generic  STORAGE DEVICE   0817 PQ: 0 ANSI: 6\n[1255452.545670] sd 25:0:0:0: Attached scsi generic sg8 type 0\n[1255452.828405] sd 25:0:0:0: [sdh] 15523840 512-byte logical blocks: (7.94 GB\/7.40 GiB)\n[1255452.829402] sd 25:0:0:0: [sdh] Write Protect is off\n[1255452.829409] sd 25:0:0:0: [sdh] Mode Sense: 23 00 00 00\n[1255452.830400] sd 25:0:0:0: [sdh] Write cache: disabled, read cache: enabled, doesn't support DPO or FUA\n[1255452.835967]  sdh: sdh1\n[1255452.840401] sd 25:0:0:0: [sdh] Attached SCSI removable disk\n<\/pre>\n<p>In this example your device is <code>\/dev\/sdh<\/code>.<\/p>\n<h3>Using OS X (macOS)<\/h3>\n<p>I personally prefer to use a separate Linux server for these types of operations, but you can use a Mac as well with <a href=\"http:\/\/brew.sh\">homebrew<\/a>:<\/p>\n<pre class=\"crayon:false\">\n# brew install wget xz\n# wget http:\/\/www.finnie.org\/software\/raspberrypi\/ubuntu-rpi3\/ubuntu-16.04-preinstalled-server-armhf+raspi3.img.xz\n# xzcat ubuntu-16.04-preinstalled-server-armhf+raspi3.img.xz|sudo dd of=\/dev\/rdisk3 bs=8m\n<\/pre>\n<p>Note when using <code>dd<\/code> on the Mac its advisable to use <code>\/dev\/rYOUR_DEVICE<\/code>.  Using <code>\/dev\/YOUR_DEVICE<\/code> can be painfully slow, as explained <a href=\"http:\/\/daoyuan.li\/solution-dd-too-slow-on-mac-os-x\/\">here<\/a>.<\/p>\n<p>To find <code>YOUR_DEVICE<\/code> on a Mac, insert the microSD and run <code>diskutil list<\/code> in a terminal.  Look for the disk that that matches your SD card size (if you have other attached drives of the same size look also at its other attributes to ensure you are using the right one).<\/p>\n<pre class=\"crayon:false\">\n# diskutil list\n...\n\/dev\/disk5 (external, physical):\n   #:                       TYPE NAME                    SIZE       IDENTIFIER\n   0:     FDisk_partition_scheme                        *16.0 GB    disk5\n   1:             Windows_FAT_32 system-boot             134.2 MB   disk5s1\n   2:                      Linux                         15.9 GB    disk5s2\n<\/pre>\n<p>If you are nervous about the steps with <code>diskutil<\/code> and <code>dd<\/code>, read <a href=\"http:\/\/www.cyberciti.biz\/faq\/how-to-create-disk-image-on-mac-os-x-with-dd-command\/\">this walkthrough<\/a> to gain some confidence.  As an aside, if you&#8217;re going to make a habit out of working with the Raspberry Pi the <code>wget<\/code>, <code>xzcat<\/code>, and <code>dd<\/code> commands are a critical part of your toolbox.  Get comfortable with them.<\/p>\n<h3>Update Xenial<\/h3>\n<p>Now that you have Xenial written to the microSD card, insert it into the Raspberry Pi 3 and power up! And yes, we&#8217;re assuming you have an Ethernet cable attached or you have network connectivity through the miniUSB.  You can try to <code>ssh<\/code> into the Pi with <code>ssh ubuntu@ubuntu.local<\/code> first, but if that fails use your router LAN page to determine the IP address.  The default password is <code>ubuntu<\/code>.<\/p>\n<pre class=\"crayon:false\">\n# ssh ubuntu@192.168.1.115\nThe authenticity of host '192.168.1.115 (192.168.1.115)' can't be established.\nECDSA key fingerprint is 62:e9:f9:09:d0:30:3c:c9:0e:47:a3:42:f5:2c:e2:ae.\nAre you sure you want to continue connecting (yes\/no)? yes\nWarning: Permanently added '192.168.1.115' (ECDSA) to the list of known hosts.\nubuntu@192.168.1.115's password:\nYou are required to change your password immediately (root enforced)\nWelcome to Ubuntu 16.04 LTS (GNU\/Linux 4.4.0-1009-raspi2 armv7l)\n...\nWARNING: Your password has expired.\nYou must change your password now and login again!\nChanging password for ubuntu.\n(current) UNIX password:\n<\/pre>\n<p>Once you&#8217;ve changed your password log back in with the <code>ubuntu<\/code> user (and your new password) and update the system with <code>sudo apt-get update<\/code>.<\/p>\n<p><b>Warning:<\/b>  Previous versions of this post suggested running <code>sudo apt-get upgrade -y<\/code> as well.  See the comments below for the workarounds if you cannot login via Ethernet afterwards.<\/p>\n<h2>Install Build Prerequisites<\/h2>\n<p>Compiling Swift requires a number of prerequisites.  Get them in one fell swoop with:<\/p>\n<pre class=\"crayon:false\">\n# 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 autoconf libtool systemtap-sdt-dev libcurl4-openssl-dev\n<\/pre>\n<p>Fortunately we didn&#8217;t have to discover the prerequisites iteratively (you know, when you download a repository and try to build it and discover what the prerequisites are, one at a time) because they are outlined in the Open Source Swift <a href=\"https:\/\/github.com\/apple\/swift\">README<\/a>.<\/p>\n<p>I also like to include <code>htop<\/code> (<code>sudo apt-get install -y htop<\/code>) so I can see the Pi compile it&#8217;s little heart out:<\/p>\n<figure id=\"attachment_3061\" aria-describedby=\"caption-attachment-3061\" style=\"width: 507px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/dev.iachieved.it\/iachievedit\/wp-content\/uploads\/2016\/06\/9__ubuntu_ubuntu_____ssh_.png\" rel=\"attachment wp-att-3061\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/dev.iachieved.it\/iachievedit\/wp-content\/uploads\/2016\/06\/9__ubuntu_ubuntu_____ssh_.png\" alt=\"100%\" width=\"507\" height=\"379\" class=\"size-full wp-image-3061\" \/><\/a><figcaption id=\"caption-attachment-3061\" class=\"wp-caption-text\">100%<\/figcaption><\/figure>\n<h2>Add Some Swap<\/h2>\n<p>While the Pi 3 does come with an impressive 1GB of RAM, that is still not enough to build Swift from beginning to end (it&#8217;s the linking steps that usually get us into trouble).  Let&#8217;s add some swap to double that amount:<\/p>\n<pre class=\"crayon:false\">\n# cd \/var\/cache\n# sudo mkdir swap\n# cd swap\n# sudo fallocate -l 1G 1G.swap\n# sudo mkswap 1G.swap\nSetting up swapspace version 1, size = 1024 MiB (1073737728 bytes)\nno label, UUID=184d002a-2f15-4b23-8360-8e792badc6a2\n# sudo chmod 600 1G.swap\n# sudo swapon 1G.swap\n<\/pre>\n<p>Here&#8217;s an example of what happens when you <i>don&#8217;t<\/i> have swap enabled:<\/p>\n<pre class=\"crayon:false\">\ncd \/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\nclang: error: unable to execute command: Killed\nclang: error: linker command failed due to signal (use -v to see invocation)\nninja: build stopped: subcommand failed.\n.\/swift\/utils\/build-script: fatal error: command terminated with a non-zero exit status 1, aborting\n<\/pre>\n<p>Doubling the amount of your Pi&#8217;s RAM with swap space that&#8217;s on a microSD card is not something you would typically do.  Once we do hit the build phases that require us to dip into swap things <i>will<\/i> slow down, but the alternative is to crash with an out-of-memory error.<\/p>\n<p><!--\n\n\n<h3>Making Your Swap Permanent<\/h3>\n\n\nNothing makes you feel silly like building Swift after a reboot only to watch it run out of memory a few hours later.  Let's make the swap space we created above a permanent addition.\n\n\n\n<pre class=\"crayon:false\">\n# sudo sh -c 'echo \"\/var\/cache\/swap\/1G.swap    none    swap    sw    0   0\" >> \/etc\/fstab'\n<\/pre>\n\n\n--><\/p>\n<h2>Use `package-swift`<\/h2>\n<p><code>package-swift<\/code> is our Github repository that has several helper scripts to make life a little easier building Swift.<\/p>\n<pre class=\"crayon:false\">\n# git clone https:\/\/github.com\/iachievedit\/package-swift\n# cd package-swift\n<\/pre>\n<p>By default <code>package-swift<\/code> will check out to the <code>swift-3.0<\/code> branch.  This branch contains important patches needed to properly build Swift for ARM (to see them take a look in <code>patches\/armv7<\/code>, they are organized by the various repos they patch).<\/p>\n<p>The scripts are pretty simple:<\/p>\n<ul>\n<li><code>get.sh<\/code> &#8211; Downloads all of the required repositories for building Swift<\/li>\n<li><code>update.sh<\/code> &#8211; Updates all of your local repositories with the latest on Github.<\/li>\n<li><code>patch.sh<\/code> &#8211; Applies any patches that the <a href=\"http:\/\/dev.iachieved.it\/iachievedit\/swift-for-arm-systems\/\">Swift on ARM<\/a> team has put forward; from time to time we have to apply patches to get things working.  Once a patch is no longer necessary we remove it, so before performing the actual build you will want to <code>git pull<\/code> to get the latest patchset<\/li>\n<li><code>package.sh<\/code> &#8211; Runs the Swift <code>build-script<\/code> with a preset named <code>buildbot_linux_armv7<\/code>.<\/li>\n<\/ul>\n<p>I suggest you look at each shell script and walk through the logic before executing.  They are straightforward but it&#8217;s worth the time understanding what they are doing.  Pay particular attention to the <code>get.sh<\/code> and <code>update.sh<\/code> scripts in that they detect we are building on a ARMv7 processor and thus need <a href=\"http:\/\/www.housedillon.com\">William Dillon&#8217;s<\/a> <a href=\"https:\/\/github.com\/hpux735\/swift-llvm\"><code>swift-llvm<\/code> fork<\/a>.<\/p>\n<h2>Let&#8217;s Do This<\/h2>\n<p>Remember to make sure you have:<\/p>\n<ul>\n<li>installed all of the prerequisite packages\n<li>enabled 1GB of swap space\n<li>cloned `package-swift` from Github\n<\/ul>\n<p>Now, clone all of the required repositories:<\/p>\n<pre class=\"crayon:false\">\n# cd package-swift\n# .\/get.sh\n<\/pre>\n<p>On my SD card this step took about 15 minutes to download and write everything.<\/p>\n<p>Next, apply patches.  It is important to do the step to pick up patches that the Swift on ARM team has developed and tested.  From time to time these patches change so make sure and pick up the latest.<\/p>\n<pre class=\"crayon:false\">\n# .\/patch.sh\n<\/pre>\n<p>Now, compile.  The Swift on ARM team uses <a href=\"https:\/\/jenkins.io\">Jenkins<\/a> to run this in a headless build job, but if you use <code>nohup<\/code> to ensure your compile continues even if the terminal detaches you should be fine:<\/p>\n<pre class=\"crayon:false\">\n# nohup .\/package.sh > swiftbuild.log&\n<\/pre>\n<p>To watch the output of the build use <code>tail -F swiftbuild.log<\/code>.<\/p>\n<p>Now, be prepared to wait!  A clean build of Swift on a Raspberry Pi 3 can take upwards of 6 hours.  The reward is well worth it, however, and that is a <code>swift.tar.gz<\/code> bundle that can be installed on <i>either<\/i> a Raspberry Pi 2 or Pi 3 running Ubuntu Xenial (do not try to install this on a Raspbian machine, you will be sorry).  I like to install Swift in <code>\/opt\/swift\/<\/code> like so:<\/p>\n<pre class=\"crayon:false\">\n# cd \/opt\n# mkdir -p swift\/swift-3.0\n# cd swift\/swift-3.0\n# tar -xzvf \/path\/to\/swift.tar.gz\n<\/pre>\n<p>You can then set your <code>PATH<\/code> with <code>export PATH=\/opt\/swift\/swift-3.0\/usr\/bin:$PATH<\/code>.  To properly use <code>swiftc<\/code> and <code>swift build<\/code> you will also need to run the following commands:<\/p>\n<pre class=\"crayon:false\">\nsudo apt-get install -y libicu-dev\nsudo apt-get install -y clang-3.6\nsudo update-alternatives --install \/usr\/bin\/clang clang \/usr\/bin\/clang-3.6 100\nsudo update-alternatives --install \/usr\/bin\/clang++ clang++ \/usr\/bin\/clang++-3.6 100\n<\/pre>\n<h2>Getting Help<\/h2>\n<p>There is a high likelihood that your build will fail the first time.  In fact, it is possible that builds for ARM devices such as the Raspberry Pi 2 and 3 will be failing for days until someone is available to fix them.  If you are having trouble compiling please feel free to send an e-mail to <code>admin@iachieved.it<\/code> to get invited to the Swift for ARM Slack community.<\/p>\n<h2>Acknowledgements<\/h2>\n<p>I should probably put up a separate page just for this; a number of folks have been instrumental in getting Swift going on ARM devices.  Folks like <a href=\"http:\/\/saygoodnight.com\/2016\/05\/08\/building-swift-for-armv6.html\">PJ<\/a> have blazed the trail building Swift for the Raspberry Pi 1, and no article on Swift on the Pi is complete without mentioning <a href=\"http:\/\/www.housedillon.com\">William Dillon&#8217;s<\/a> work.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>9\/24\/2016 Update: See our latest post on building Swift 3.0 on ARMv7 systems such as the Pi 3. Editor&#8217;s Note: This post was updated on 9\/4\/2016 to reflect the recent updates for Swift 3.0 (in particular it now includes the build of swift-corelibs-libdispatch). A number of folks have expressed interest in building Swift 3.0 on [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":3035,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[13,5],"tags":[37,36,31,34],"class_list":["post-3052","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-raspberry-pi","category-swift","tag-building-swift-on-linux","tag-compile-swift","tag-raspberry-pi","tag-swift-raspberry-pi"],"_links":{"self":[{"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/posts\/3052"}],"collection":[{"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/comments?post=3052"}],"version-history":[{"count":39,"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/posts\/3052\/revisions"}],"predecessor-version":[{"id":3249,"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/posts\/3052\/revisions\/3249"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/media\/3035"}],"wp:attachment":[{"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/media?parent=3052"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/categories?post=3052"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/tags?post=3052"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}