{"id":3021,"date":"2016-06-17T19:27:58","date_gmt":"2016-06-18T01:27:58","guid":{"rendered":"http:\/\/dev.iachieved.it\/iachievedit\/?p=3021"},"modified":"2017-05-02T19:25:49","modified_gmt":"2017-05-03T00:25:49","slug":"swift-3-0-on-raspberry-pi-2-and-3","status":"publish","type":"post","link":"https:\/\/dev.iachieved.it\/iachievedit\/swift-3-0-on-raspberry-pi-2-and-3\/","title":{"rendered":"Swift 3.0 on Raspberry Pi 2 and 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-Ubuntu-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>There are a number of people <a href=\"http:\/\/dev.iachieved.it\/iachievedit\/swift-for-arm-systems\/\">working<\/a> to bring Swift 3.0 to as many ARM-based systems as possible.  This article is specifically about getting Swift 3.0 for your <b>Raspberry Pi<\/b> 2 or Raspberry Pi 3 that is running Ubuntu 16 (<a href=\"https:\/\/wiki.ubuntu.com\/XenialXerus\">Xenial Xerus<\/a>).  It has not been tested for Raspbian variants (and likely doesn&#8217;t work).<\/p>\n<p><b>A fair warning:<\/b>  support for Swift 3.0 on the Raspberry Pi (and all ARM devices) is still beta.  Use it for prototyping and proof-on-concept work rather than building a product with it.  Also, if you&#8217;re interested in joining the community of folks working on getting Swift 3.0 for ARM devices, come join us on <a href=\"https:\/\/slackpass.io\/swift-arm\">Slack<\/a>!<\/p>\n<h2>Xenial on a Raspberry Pi<\/h2>\n<p>You might not have even known Xenial for the Raspberry Pi existed; I didn&#8217;t!  To grab it head over to <a href=\"https:\/\/wiki.ubuntu.com\/ARM\/RaspberryPi\">the Ubuntu Wiki<\/a> and get the distribution for your Pi.  You will want to use at least an 8G SD card.<\/p>\n<h2>Install Swift 3.0<\/h2>\n<p>The team working on Swift for ARM is using <a href=\"https:\/\/jenkins.io\">Jenkins<\/a> to build the Raspberry Pi binaries natively on a <a href=\"https:\/\/www.raspberrypi.org\/products\/raspberry-pi-3-model-b\/\">Raspberry Pi 3<\/a>.  As in, this is the build machine!<\/p>\n<figure id=\"attachment_3032\" aria-describedby=\"caption-attachment-3032\" style=\"width: 355px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/dev.iachieved.it\/iachievedit\/wp-content\/uploads\/2016\/06\/fullsizerender_960-1.jpg\" rel=\"attachment wp-att-3032\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/dev.iachieved.it\/iachievedit\/wp-content\/uploads\/2016\/06\/fullsizerender_960-1.jpg\" alt=\"Swift 3.0 Build Machine\" width=\"355\" height=\"480\" class=\"size-full wp-image-3032\" \/><\/a><figcaption id=\"caption-attachment-3032\" class=\"wp-caption-text\">Swift 3.0 Build Machine<\/figcaption><\/figure>\n<p>For the curious check out the <a href=\"http:\/\/swift-arm.ddns.net\/job\/Swift-3.0-Pi3-ARM-Incremental\/\">Jenkins build project<\/a>.  Quite frankly, I&#8217;m amazed that it only took 6 hours to compile Swift.<\/p>\n<p>Now, on your Raspberry Pi, grab and extract the Swift 3.0 build artifact into a directory and set your <code>PATH<\/code> with something like:<\/p>\n<pre>\ncd $HOME\nwget http:\/\/swift-arm.ddns.net\/job\/Swift-3.0-Pi3-ARM-Incremental\/16\/artifact\/swift-3.0-2016-07-19-RPi23-ubuntu16.04.tar.gz\nmkdir swift-3.0\ncd swift-3.0 && tar -xzf ..\/swift-3.0.tgz\nexport PATH=$HOME\/swift-3.0\/usr\/bin:$PATH\n<\/pre>\n<p><b>Note:<\/b> You aren&#8217;t tied to putting Swift 3.0 in <code>$HOME<\/code>, I typically use <code>\/opt\/swift\/swift-3.0<\/code>.<\/p>\n<p>Now, let&#8217;s give it a spin!<\/p>\n<p>Create a file called <code>helloWorld.swift<\/code>:<\/p>\n<pre>\nprint(\"Hello, world!\")\n<\/pre>\n<p>You can use <code>swift helloWorld.swift<\/code> to execute the file like a script:<\/p>\n<pre class=\"crayon:false\">\n# swift helloWorld.swift\nHello, world!\n<\/pre>\n<p>Or, you can compile the file into an executable with <code>swiftc<\/code> <i>if you have <code>clang<\/code> installed and configured properly<\/i>:<\/p>\n<pre class=\"crayon:false\">\n# swiftc helloWorld.swift\n# .\/helloWorld\nHello world!\n<\/pre>\n<p>If <code>swiftc<\/code> failed with <code>error: link command failed with exit code 127<\/code> there&#8217;s a good chance you don&#8217;t have <code>clang<\/code> installed and configured properly:<\/p>\n<pre class=\"crayon:false\">\nsudo apt-get update\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<p>Let&#8217;s look at a few other tidbits:<\/p>\n<h3>Importing `Glibc` works!<\/h3>\n<p><code>swiftcat.swift<\/code>:<\/p>\n<pre class=\"lang:swift\">\nimport Glibc\n\nguard CommandLine.arguments.count == 2 else {\n  print(\"Usage:  swiftcat FILENAME\")\n  exit(-1)\n}\n\nlet filename = CommandLine.arguments[1]\n\nlet BUFSIZE = 1024\nvar pp      = popen(\"cat \" + filename, \"r\")\nvar buf     = [CChar](repeating:0, count:BUFSIZE)\n\nwhile fgets(&buf, Int32(BUFSIZE), pp) != nil {\n  print(String(cString:buf), terminator:\"\")\n}\n\nexit(0)\n<\/pre>\n<p>Compile (<code>swiftc swiftcat.swift<\/code>) and run (<code>swiftcat<\/code>)!<\/p>\n<h3>Bridging to C routines<\/h3>\n<p>Linking against compiled object files works!<\/p>\n<p><code>escapetext.c<\/code>:<\/p>\n<pre class=\"lang:c\">\n#include <string.h>\n#include <stdlib.h>\n#include <curl\/curl.h>\nint escapeText(const char* text, char** output) {\n  int rc = -1;\n  CURL* curl = curl_easy_init();\n  if (curl) {\n    char* escaped = curl_easy_escape(curl, text, strlen(text));\n    if (escaped) {\n      *output = (char*)malloc(strlen(escaped) + 1);\n      strcpy(*output, escaped);\n      curl_free(escaped);\n      rc = strlen(*output);\n    }\n  }\n  return rc;\n}\n<\/pre>\n<p><code>escapetext.h<\/code>:<\/p>\n<pre class=\"lang:c\">\nint escapeText(const char* text, char** output);\n<\/pre>\n<p><code>escapeswift.swift<\/code>:<\/p>\n<pre class=\"lang:swift\">\nimport Glibc\n\nguard CommandLine.arguments.count == 2 else {\n  print(\"Usage:  escapeswift STRING\")\n  exit(-1)\n}\n\nlet string = CommandLine.arguments[1]\nvar buffer:UnsafeMutablePointer<Int8>? = nil\n\nlet rc = escapeText(string, &buffer)\n\nguard rc > 0 else {\n  print(\"Error escaping text\")\n  exit(-1)\n}\n\nif let escaped = buffer {\n  let escapedString = String(cString:escaped)\n  print(\"Escaped text:  \" + escapedString)\n}\n\nexit(0)\n<\/pre>\n<p>Compile and link everything together:<\/p>\n<pre class=\"crayon:false\">\n# clang -c escapetext.c\n# swiftc -c escapeswift.swift -import-objc-header escapetext.h\n# swiftc escapeswift.o escapetext.o -o escapeswift -lcurl\n<\/pre>\n<p>And run:<\/p>\n<pre class=\"crayon:false\">\n# .\/escapeswift \"foo > bar\"\nEscaped text:  foo%20%3E%20bar\n<\/pre>\n<h3>Swift Package Manager<\/h3>\n<p>Unless you enjoy writing makefiles and build scripts (and trust me, some do), the Swift Package Manager is here to help manage software package dependencies.  We&#8217;ll be writing more about the SwiftPM available in Swift 3.0, but are excited to provide a version that works on armv7 devices.  Try this out:<\/p>\n<pre class=\"crayon:false\">\n# mkdir finalCountdown && cd finalCountdown\n# swift package init --type executable\nCreating executable package: finalCountdown\nCreating Package.swift\nCreating .gitignore\nCreating Sources\/\nCreating Sources\/main.swift\nCreating Tests\/\n<\/pre>\n<p>Replace the contents of <code>Sources\/main.swift<\/code> with<\/p>\n<pre class=\"lang:swift\">\nimport Foundation\nimport Glibc\nlet thread = Thread(){\n  print(\"Entering thread\")\n  for i in (1...10).reversed() {\n    print(\"\\(i)...\", terminator:\"\")\n    fflush(stdout)\n    sleep(1)\n  }\n  print(\"\\nExiting thread\")\n  print(\"Done\")\n  exit(0)\n}\nthread.start()\nselect(0, nil, nil, nil, nil)\n<\/pre>\n<p>Now, run <code>swift build<\/code> to build your <code>finalCountdown<\/code> application:<\/p>\n<pre class=\"crayon:false\">\n# swift build\nCompile Swift Module 'finalCountdown' (1 sources)\nLinking .build\/debug\/finalCountdown\n# .build\/debug\/finalCountdown\nEntering thread\n10...9...8...7...6...5...4...3...2...1...\nExiting thread\nDone\n<\/pre>\n<h3>moreswift<\/h3>\n<p>For a random smattering of Swift 3.0 applications that have been run on both x86 and armv7 systems, check out the <a href=\"https:\/\/github.com\/iachievedit\/moreswift\/tree\/swift-3.0\">moreswift swift-3.0 branch<\/a>.<\/p>\n<h2>What Version Is This?<\/h2>\n<p>The current builds available are not tracking the Swift 3.0 preview builds.  To determine the Git hashes associated with the <code>swift<\/code> binary, type <code>swift --version<\/code>:<\/p>\n<pre class=\"crayon:false\">\n# swift --version\nSwift version 3.0-dev (LLVM eb140647a6, Clang a9f2183da4, Swift bb43874ba1)\n<\/pre>\n<p>You can then, if you so choose go directly to the Swift repository commit with something like <a href=\"https:\/\/github.com\/apple\/swift\/tree\/bb43874ba1\">https:\/\/github.com\/apple\/swift\/tree\/bb43874ba1<\/a> to see the history beginning with the last commit incorporated into the build.<\/p>\n<h2>Acknowledgements<\/h2>\n<p>A lot of people have been apart of the effort to bring Swift to Linux ARM devices.  This list is just a few of those individuals.  Please do visit their blogs; there is a wealth of information and learnings therein.<\/p>\n<ul>\n<li>William Dillon (<a href=\"https:\/\/twitter.com\/hpux735\">@hpux735<\/a>) <a href=\"http:\/\/www.housedillon.com\">http:\/\/www.housedillon.com<\/a>\n<li>Ryan Lovelett (<a href=\"https:\/\/twitter.com\/rlovelett\">@rlovelett) <a href=\"http:\/\/stackoverflow.com\/users\/247730\/ryan\">http:\/\/stackoverflow.com\/users\/247730\/ryan<\/a>\n<li>Brian Gesiak (<a href=\"https:\/\/twitter.com\/modocache\">@modocache<\/a>) <a href=\"http:\/\/modocache.io\">http:\/\/modocache.io<\/a>\n<li><a href=\"https:\/\/github.com\/karwa\">Karl Wagner<\/a> <a href=\"http:\/\/www.springsup.com\/\">http:\/\/www.springsup.com\/<\/a>\n<li><a href=\"https:\/\/twitter.com\/tienex\">@tienex<\/a> <a href=\"https:\/\/github.com\/tienex\">tienex<\/a>\n<li>PJ Gray (<a href=\"https:\/\/twitter.com\/pj4533\">@pj4533<\/a>) <a href=\"http:\/\/saygoodnight.com\">Say Goodnight Software<\/a>\n<li>Cameron Perry (<a href=\"https:\/\/twitter.com\/mistercameron\">@mistercameron<\/a>) <a href=\"http:\/\/mistercameron.com\">http:\/\/mistercameron.com<\/a>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>There are a number of people working to bring Swift 3.0 to as many ARM-based systems as possible. This article is specifically about getting Swift 3.0 for your Raspberry Pi 2 or Raspberry Pi 3 that is running Ubuntu 16 (Xenial Xerus). It has not been tested for Raspbian variants (and likely doesn&#8217;t work). A [&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":[31,32],"class_list":["post-3021","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-raspberry-pi","category-swift","tag-raspberry-pi","tag-swift-3-0"],"_links":{"self":[{"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/posts\/3021"}],"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=3021"}],"version-history":[{"count":28,"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/posts\/3021\/revisions"}],"predecessor-version":[{"id":3256,"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/posts\/3021\/revisions\/3256"}],"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=3021"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/categories?post=3021"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/tags?post=3021"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}