Getting Started with Swift on Linux

When I wrote my first line of Swift code I immediately had visions of being able to use this beautiful programming language for more than just iOS and OSX apps. Yesterday, Apple officially made Swift open source and my dreams came true. This blog post will help you quickly get started writing your first application using the open source version of Swift on Linux.

Here We Go!
The Linux implementation of Swift currently only runs on Ubuntu 14.04 or Ubuntu 15.10. For our application, I’ll be using Ubuntu 14.04.3. If you don’t have an Ubuntu server sitting around you can always spin one up on your hosting provider of choice (Looking for one? Check out DigitalOcean or Linode). The Swift GitHub page shows you how to build Swift manually but you may want to start writing code without having to wrestle with Linux. Fortunately Apple provides snapshots that you can download and get running with a quickness.

Grab the URL of the Ubuntu 14.04 snapshot and then pull it down to your server using wget:

This may take a couple minutes to download. While you’re waiting, it’s a good time to watch Stephen Malkmus and the Jicks cover Taylor Swift’s “Blank Space”.

Once you have the snapshot, decompress it:

In order to use Swift from the command line you need to update your path. Make sure to update this command to reference the path to where you downloaded the Swift snapshot:

If you’re using a fresh Ubuntu server like I was you may be missing a few packages required for Swift to run correctly. To make sure you have everything in place you can run the following command:

Once that completes install all the required dependencies with this command:

More waiting. Perhaps time for an impromptu dance party?

Test that everything is running correctly by running swift --version. You should see a version number like this: Swift version 2.2-dev.

Let’s Sling some Code
Are you ready to write some code? I sure am! We’ll start by firing up the Swift REPL with the swift command. Once the REPL is running you can start throwing down some Swift. Here are some examples to try:

When you’re ready to exit out of the REPL just type :q. Wow. Wonder where they got that idea?

The time has come to write our first app. First, we’ll create a new folder for our application to live. Within that folder we’ll create another folder called sources where we’ll write the code for our applications:

Within the sources folder create a file called main.swift. The name of this file is important, by naming it main.swift our application will automatically be built into an executable when we run swift build:

Do you ever wish you could play “Rock, Paper, Scissors, Lizard, Spock” but no one is around? We just built a Swift application that will let you play against the computer whenever you want!

You can play your first game with the following command:

One thing I’m very excited about in the open source version of Swift is the Swift Package Manager because it makes it super easy to package and share code like our game with others. We won’t take advantage of some of the advanced features of the package manager in this post but we do need to create a Package.swift file to be able to build our application. The Swift Package Manager is case sensitive so make sure you have the capital P. We can keep this pretty basic for now:

Now that we have everything in place we can build our application by running our build command:

The build command will produce an executable that we can run from the command line:

What Will You Build?
You’ve built your first “Hello, Swift!” application using the open source version Swift on Linux. Looking for some inspiration? I’ve found Apple’s A Swift Tour extremely helpful as I’ve started learning the language. There’s a lot of good stuff to be found on Swift.org as well.

There’s a lot left to be added to the Linux version of Swift but I am looking forward to seeing it grow. Maybe you’ll even want to contribute to the project so we can all benefit from what you’ve learned.

I’d love to see what you build now that you have your environment set up!

  • Joe

    So excited to finally see Swift on Linux! Also did a write up on it http://dev.iachieved.it/iachievedit/swift-on-linux/ and touched upon the topic that without some additional Foundation classes it will be a slow at first getting “server-side Swift” applications up and running.

  • Tunfast dev

    please correct : swift -version and not swift —version

    • rickyrobinett

      Updated! Thanks for catching that!

  • Mick Stevens

    Cheers Ricky, I’ve been looking for an excuse to convert my Chromebook to run Ubuntu, this is it!

    • rickyrobinett

      Oooh! Can’t wait to hear how it goes Mick! I know Rob will be stoked to hear you’re running Linux on your Chromebook :)

  • Punk Rider

    First of all , Ricky,thanks for the introductive blog on Swift under Linux! It was really helpful.I installed swift according to instructions , clang 3.7 , almost everything works OK , swift file.swift , swiftc file.swift. I have only one problem: command swift build is not working(attached error below). Can you help me fix it? Thanks

    ~/swift/helloswift/sources$ swift build
    Compiling Swift Module ‘helloswift’ (1 sources)
    Compiling Swift Module ‘swift22SNAPSHOT20151201bubuntu1510’ (1 sources)
    /home/kornos/swift/swift-2.2-SNAPSHOT-2015-12-01-b-ubuntu15.10/usr/lib/lldb/DumpForDebugger.swift:15:6: error: expected numeric value following ‘$’
    func $__lldb__DumpForDebugger_impl(
    ^
    /home/kornos/swift/swift-2.2-SNAPSHOT-2015-12-01-b-ubuntu15.10/usr/lib/lldb/DumpForDebugger.swift:197:13: error: expected numeric value following ‘$’
    $__lldb__DumpForDebugger_impl(nil,
    ^
    /home/kornos/swift/swift-2.2-SNAPSHOT-2015-12-01-b-ubuntu15.10/usr/lib/lldb/DumpForDebugger.swift:226:13: error: expected numeric value following ‘$’
    $__lldb__DumpForDebugger_impl(child,
    ^
    /home/kornos/swift/swift-2.2-SNAPSHOT-2015-12-01-b-ubuntu15.10/usr/lib/lldb/DumpForDebugger.swift:240:6: error: expected numeric value following ‘$’
    func $__lldb__DumpForDebugger(x: Any) -> String {
    ^
    /home/kornos/swift/swift-2.2-SNAPSHOT-2015-12-01-b-ubuntu15.10/usr/lib/lldb/DumpForDebugger.swift:257:5: error: expected numeric value following ‘$’
    $__lldb__DumpForDebugger_impl(x, Mirror(reflecting: x), nil,
    ^
    :0: error: build had 1 command failures
    swift-build: exit(1): [“/usr/bin/swift-build-tool”, “-f”, “/home/kornos/swift/.build/debug/HelloSwift.o/llbuild.yaml”]

    • Punk Rider

      swift build expects some directory structure or some files with some format to work properly?

    • Punk Rider

      Oh nevermind, i just figured it out, i’m letting this post here , maybe somebody will have the same problem.
      So in my home folder i extracted swift-2.2-SNAPSHOT-2015-12-01-b-ubuntu15.10.tar.gz and copied the file to /usr
      Unfortunately , probably because of some hardcoded paths in swift executables/scripts , when i type command swift build , the error from above appears.

      The solution is to have only one swift instalation :
      1. in /usr and you must delete the swift folder from your $HOME
      2. in your $HOME , with export PATH=$HOME/SWIFT as described in this blog , but do not extract anything in /usr.

      Hope this helps

      • rickyrobinett

        Glad you got it fixed, Punk Rider! How are you liking hacking with Swift on Linux so far?

        • Punk Rider

          It would be wonderful to have some IDE like Visual Studio with Swift support in Linux. :-D (or an IDE with a decent autocompletion for Swift)

          IMO , it seems to have a few rough edges :
          var c = a + b <- valid
          var c = a+b <- valid
          var c = a+ b <- INVALID(i know , unary operator,bla,bal, it sucks)

          when you have a for() loop , it's mandatory to append { …} even of you have only ONE instruction in loop…..

          Sometimes i wonder why somebody does not make a language very similar(almost identical) to C#(without all M$ craft , taking out Pascal-inspired syntactic sugar-where is the case, adding the cool stuff from Python and goroutines) and make it produce native binaries , not JIT ,JVM,CLR kinda crap , with a UI based on OpenGL which would be truly portable across platforms. That would be the perfect language.

          • feloneouscat

            There is a hack for the atom editor that allows you to run and debug (sorta) for swift. It allows you to compile and edit the language, but that is about it. As much an IDE as vi is (well, maybe a little more than vi).

  • 吳亦鈞

    I use docker to run Ubuntu 14.04
    Can i run swift in there?
    Or I need to have a real system
    Due to i am using CentOS7 I have no idea about this
    Can you give me some advise?

    • John

      It should work fine. Try it.

  • Anusorn

    Compiling Swift Module ‘HelloSwift’ (1 sources)

    Linking Executable: .build/debug/HelloSwift

    :0: error: link command failed with exit code 127 (use -v to see invocation)

    :0: error: build had 1 command failures

    • rickyrobinett

      Hi Anusorn – That’s not good. Any more information provided when you run swift build -v?

      • Anusorn

        Hi ricky , currently my problem was solved with the following
        sudo apt-get install 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

        :-)

    • Anonymous Man

      >> :0: error: link command failed with exit code 127 (use -v to see invocation)

      sudo apt-get install clang

  • John

    Just to let you know that you can install it on Linux Mint 17 as well. It’s based on Ubuntu 14.04 so presumably all of the non-Unity buntus and other derivatives will work as well.

  • Punk Rider

    How can I find all swift system modules I can import in Linux? (e.g. Coredata,etc)

  • Garvit Gilhotra

    In order to use Swift from the command line you need to update your path. Make sure to update this command to reference the path to where you downloaded the Swift snapshot: how to update path i extracted it but cant get ahead detain instruyctions?

  • Hi Ricky ~ thanks for posting this. I followed all of your instructions, but I cannot get the command line interactive shell to work nor will the swift command compile any of my programs. It just spits out the same output as if I had types “swift” and hit enter.
    For example:
    $>swift main.swift
    Usage: swift [–version] [–help] [–snet] [–verbose]
    [–debug] [–info] [–quiet] [–auth ]
    [–auth-version ] [–user ]
    [–key ] [–retries ]
    [–os-username ] [–os-password ]
    [–os-tenant-id ]
    [–os-tenant-name ]
    [–os-auth-url ] [–os-auth-token ]
    [–os-storage-url ] [–os-region-name ]
    [–os-service-type ]
    [–os-endpoint-type ]
    [–os-cacert ] [–insecure]
    [–no-ssl-compression]

    Command-line interface to the OpenStack Swift API.

    Positional arguments:

    delete Delete a container or objects within a container
    download Download objects from containers
    list Lists the containers for the account or the objects
    for a container
    post Updates meta information for the account, container,
    or object; creates containers if not present
    stat Displays information for the account, container,
    or object
    upload Uploads files or directories to the given container
    capabilities List cluster capabilities

    Examples:
    swift -A https://auth.api.rackspacecloud.com/v1.0 -U user -K api_key stat -v

    swift –os-auth-url https://api.example.com/v2.0 –os-tenant-name tenant
    –os-username user –os-password password list

    swift –os-auth-token 6ee5eb33efad4e45ab46806eac010566
    –os-storage-url https://10.1.5.2:8080/v1/AUTH_ced809b6a4baea7aeab61a
    list

    swift list –lh

    no such command: main.swift

    swift –version returns 2.0.3
    Any thoughts?

    • rickyrobinett

      Hi Craig – It looks like you have another command name swift already installed on your server. In this case it looks like it’s the “Command-line interface to the OpenStack Swift API.”. If you’re not using that then you could remove it and then see if things are working for you. Hope that helps!

  • gary

    How do we test a Swift IOS GUI app on Linux ?

    • Christopher Hatton

      Sorry, we just don’t. The language is ported, the core libraries are partially ported. UIKit, upon which iOS GUI Apps are based, is unlikely ever to be ported. This is not a priority for Swift on Linux.

  • not-so-swift

    I don’t get this at all: .build/debug/HelloSwift

    How can that ever produce an executable that we can run from the command line?

    I’ve tried running that by itself, running it with ./ in front of it, running it with ./swiftc .build/debug/HelloSwift -o HelloSwift, and too many other ways to mention, and all I ever get is errors.

    Here are a few of them:

    bash: .build/debug/HelloSwift: No such file or directory

    repl.swift:1:8: error: use of unresolved identifier ‘debug’
    .build/debug/HelloSwift

    repl.swift:1:8: error: use of unresolved identifier ‘HelloSwift’
    .build/debug/HelloSwift

    :0: error: no such file or directory: ‘.build/debug/HelloSwift’

    :0: error: no such file or directory: ‘./.build/debug/HelloSwift’

    and many more too numerous to mention.

    I originally had the same error as Craig Boyd, but I got around it not by deleting the other swift, which I thought might be an important Linux program, but by staying within my bin folder and running things like ./swift helloswift/sources/main.swift from there.

    I got the program to run, and I got build-swift to run as ./swift-build in the same fashion, which is where my .build/debug/HelloSwift came from, but no way can I get .build/debug/HelloSwift to run on its own. I’m not even sure what it’s supposed to do or what it is . . .

    • not-so-swift

      OK, I made it work, but it’s very very kludgy.

      I put an empty Package.swift in bin and also a Sources with main.swift and print(“Hello world.”) inside that. I could then run ./swift-build, but my .build/debug/HelloSwift thing became .build/debug/bin. That ran, but in order to change it to .build/debug/Hello, I had to go in and rename bin.o, bin, bin.swiftdoc and bin.swiftmodule. One by one, I had to change them to Hello.o, Hello, Hello.swiftdoc and Hello.swiftmodule.

      Any deviation from the most standard file system, even the slightest deviation, will result in super-kludgy behavior. Yes, it can be made to run, but only at the cost of a lot of manual editing and other fooling around.

      So far, I’m pretty underwhelmed, not impressed at all . . . :^

  • practiko

    On the OS X platform is the Xcode IDE, am I right ? what is the IDE on Linux ???

    • rickyrobinett

      On Linux, you can use your text editor of choice and it will work.

      • feloneouscat

        There is a hack for the Atom Editor that allows you to edit and compile Swift.

        Let me warn you, however, it is a kludge at best.

    • Evan Langlois

      Unlike other systems that tie you to an IDE, Linux is about choices, not being locked into a single choice of IDE. Most of us use a text editor like vim (and I’m kinda liking gEdit as well these days) rather than a full IDE, but there are many choices. Most of the IDEs won’t have specific Swift support (yet).

  • Lorenzo Jiménez

    Swift the next Python? jejeje

  • Robert Madonna

    After following your directions I’m I’m running into this error:

    -bash: ./swift: cannot execute binary file: Exec format error

    I’m running Ubuntu 14.04 on a BBB.

    Any suggestions?

  • Santi Calvo

    Hi, thanks for your explanation:

    I get a “sources/main.swift:1:8: error: no such module ‘Foundation'” when I try to run the example. I guess the Foundation library is no longer on swift for Linux?

  • Lorenzo Jiménez

    Only a Ubuntu release? Until there’s other distros included there’s no point to even begin to learn Swift.

    • Evan Langlois

      You should be able to get it installed easily on most Debian distros (as Ubuntu is just a modified Debian). For distributions that use another package packager, you can convert the archive using a tool like Alien. You may need to manually resolve dependencies and you are on your own at upgrade time, but you can get it done.

      You can also just do a GIT clone of the source and build it from scratch. This may actually be an easier option in some cases.

  • Uriil

    How can I fix this?

    ~/Documentos/swift/sources$ swift build
    error: unable to invoke subcommand: /home/uriel/Escritorio/swift/swift-2.2.1-SNAPSHOT-2016-04-23-a-ubuntu15.10/usr/bin/swift-build (No such file or directory)