{"id":2934,"date":"2016-05-05T12:06:38","date_gmt":"2016-05-05T18:06:38","guid":{"rendered":"http:\/\/dev.iachieved.it\/iachievedit\/?p=2934"},"modified":"2016-09-19T05:32:54","modified_gmt":"2016-09-19T11:32:54","slug":"swift-3-0-on-a-beaglebone-black","status":"publish","type":"post","link":"https:\/\/dev.iachieved.it\/iachievedit\/swift-3-0-on-a-beaglebone-black\/","title":{"rendered":"Swift 3.0 on a BeagleBone Black"},"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>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.  I&#8217;m personally interested in the BeagleBoard family of devices and try Swift builds on a BeagleBone Black as soon as they are available.  If you&#8217;re interested in joining the community of folks working on getting Swift 3.0 for ARM devices come join our <script async defer src=\"http:\/\/dev.iachieved.it:9909\/slackin.js\"><\/script> community.<\/p>\n<p>We&#8217;re assuming here you have a BeagleBone Black running Debian Jessie and have <i>at least<\/i> 1G of free space available.  The base <code>.tgz<\/code> distribution is nearly 200M, and around 600M extracted.  If you&#8217;ve booted from a microSD card and taking advantage of its capacity we can <a href=\"http:\/\/dev.iachieved.it\/iachievedit\/expanding-your-beaglebone-microsd-filesystem\/\">show you how to get the most out of it<\/a>.<\/p>\n<p>The team working on Swift for ARM is using <a href=\"https:\/\/jenkins.io\">Jenkins<\/a> to build natively on a <a href=\"http:\/\/dev.iachieved.it\/iachievedit\/a-look-at-the-beagleboard-x15\/\">BeagleBoard X15<\/a>.  You can find the latest build for BeagleBone Black <a href=\"http:\/\/swift-arm.ddns.net\/job\/Swift-3.0-BBB-ARM-Incremental\/lastBuild\/\">here<\/a>.  Grab and extract the contents 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-BBB-ARM-Incremental\/lastBuild\/artifact\/swift-3.0-2016-09-19-BBB-ubuntu14.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>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 libicu-dev\nsudo apt-get install 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> and 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","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. I&#8217;m personally interested in the BeagleBoard family of devices and try Swift builds on a BeagleBone Black as soon as they are available. If you&#8217;re interested in joining the community of folks working on getting Swift 3.0 [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":2944,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[20,5],"tags":[33],"class_list":["post-2934","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-beaglebone","category-swift","tag-swift-beaglebone"],"_links":{"self":[{"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/posts\/2934"}],"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=2934"}],"version-history":[{"count":18,"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/posts\/2934\/revisions"}],"predecessor-version":[{"id":2956,"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/posts\/2934\/revisions\/2956"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/media\/2944"}],"wp:attachment":[{"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/media?parent=2934"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/categories?post=2934"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/tags?post=2934"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}