HOME -> Swift on Linux

Trying to Build Swift on CentOS 7.1 from Source

December 14, 2015

After experimenting with Apple-provided Swift binaries on Ubuntu, I decided to use the instructions at https://github.com/apple/swift/blob/master/README.md to try and build Swift on a Linux distro where pre-build binaries are not available. As of this writing they are only provided for Ubuntu 14.04 and 15.10. I picked CentOS 7.1 in an Azure virtual machine (VM). The VM instance was a standard DS3 (4 cores, 14 GB memory).

My attempts have been only partially successful. Please see the summary.

Caution: A Lot of Memory is Needed

The build process is a memory hog! At first I used the build script as suggested in the instructions: utils/build-script -t and ran out of memory when an executable was buing built. Reading the help dumped by the script when given the -h option, I figured that the memory footprint could be reduced by doing a release build; the default is debug. So, after adding the -R option, I saw the build process complete without starving the box out of memory.

Install Prerequisites

The build instructions at swift.org provide a list of required dependencies for Ubuntu. I had to experiment a little to find the corresponding list for CentOS 7.1: Also please note:

Get the Sources

Then I created the following directory structure. You may, of course, adjust this to your liking. mkdir swift_2.2 cd swift_2.2 Then I obtained the sources from GitHub: git clone --branch swift-2.2-SNAPSHOT-2015-12-01-b https://github.com/apple/swift.git swift git clone --branch swift-2.2-SNAPSHOT-2015-12-01-b https://github.com/apple/swift-llvm.git llvm git clone --branch swift-2.2-SNAPSHOT-2015-12-01-b https://github.com/apple/swift-clang.git clang git clone --branch swift-2.2-SNAPSHOT-2015-12-01-b https://github.com/apple/swift-lldb.git lldb git clone https://github.com/apple/swift-cmark.git cmark git clone --branch swift-2.2-SNAPSHOT-2015-12-01-b https://github.com/apple/swift-llbuild.git llbuild git clone --branch swift-2.2-SNAPSHOT-2015-12-01-b https://github.com/apple/swift-package-manager.git swiftpm git clone --branch swift-2.2-SNAPSHOT-2015-12-01-b https://github.com/apple/swift-corelibs-xctest.git git clone --branch swift-2.2-SNAPSHOT-2015-12-01-b https://github.com/apple/swift-corelibs-foundation.git git clone --branch release https://github.com/ninja-build/ninja.git A few things to note:

The Build Process

The swift.org documentation mentioned earlier suggests using at least Clang 3.6 for building the software. The most recent version available from the repository was 3.4.2, so I did the following:
  1. Built just Swift and LLVM, which includes Clang 3.8, using the repo-provided Clang 3.4.2.
  2. Used the new Clang 3.8, built as part of LLVM, to re-build Swift and LLVM and also build LLDB, llbuild, Swift Package Manager (failed), and Foundation.
Alternatively we can build a more recent Clang from source that can be obtained from http://www.llvm.org, but there may be some surprises there, see http://www.omniprog.info/cpp.html

You can do utils/build-script -h to find out about the various options the build script supports.

Build Clang 3.8

From the swift_2.2 directory, I did: cd swift utils/build-script -t -R This will build LLVM, Clang, and Swift. The -t option will cause tests to be built and run. Unless your box has a lot of memory, make sure you use the -R flag to do a release build. Otherwise debug will be built (the default), and the build may run out of memory. I was unable to do this even on a box with 14 GB. Watching the memory with the -R flag showed that at least 6 GB of RAM is needed for a release build.

At one point the build failed, complaining about the missing /usr/include/x86_64-linux-gnu/sys/ioctl.h header. This was fixed by ln -s /usr/include /usr/include/x86_64-linux-gnu and the build completed successfully.

Build LLDB, LLBUILD, Swift Package Manager, and Foundation

Now that Clang 3.8 is available, LLVM, Clang, and Swift can be re-build using the new Clang. In addition, LLDB, LLBUILD, Swift Package Manager, and Foundation can be built. The build script by default places the build in the "build" sub-directory of (in our case) swift_2.2, so we rename the "build" directory to something else and adjust the path so that Clang, LLVM, and related binaries from that directory are used. Then: # This is from the swift_2.2 directory cd swift utils/build-script -l -b -p --foundation -R Note that tests are not built here. You can add -t to build and run them if desired.

After awhile the build stops with this error: :0: error: unable to attach DB: unable to initialize database (near "WITHOUT": syntax error) bootstrap: error: build failed with exit status 1 utils/build-script: command terminated with a non-zero exit status 1, aborting This happens while swiftpm is being built. So, we'll go straight to building Foundation: utils/build-script --foundation -R The Foundation build completes, but I can't see how to use it yet.

Let's Try It!

swiftc and swift commands can be used with a trivial Swift file to compile it to a native executable or to run it in interpreter mode.

However, swift REPL does not work: [root@centos71 ~]# swift LLVM ERROR: Compiler-internal integrated REPL unimplemented for this platform Trying to use the Swift build system the way it is described in the swift.org instructions mentioned earlier gives: [root@centos71 Hello]# swift build error: unable to invoke subcommand: /root/swift_2.2/build/Ninja-ReleaseAssert/swift-linux-x86_64/bin/swift-build (No such file or directory) Indeed, the file swift-build does not exist in that directory. This works fine on Ubuntu with the Apple-provided binaries.

Now try to use Foundation. Suppose the file junk.swift contains: import Foundation print ("Hey swift on Centos7.1!") Trying to run it: [root@centos71 ~]# swift junk.swift junk.swift:1:8: error: no such module 'Foundation' import Foundation ^ [root@centos71 ~]# swift --help OVERVIEW: Swift compiler USAGE: swift [options] OPTIONS: ... -framework Specifies a framework which should be linked against -F Add directory to framework search path ... -I Add directory to the import search path [root@centos71 ~]# ls /root/swift_2.2/build/Ninja-ReleaseAssert/foundation-linux-x86_64 2ZK9JHZ46ETPO Foundation modules.timestamp [root@centos71 ~]# ls /root/swift_2.2/build/Ninja-ReleaseAssert/foundation-linux-x86_64/Foundation/ closure CoreFoundation Foundation Foundation.swiftdoc Foundation.swiftmodule libFoundation.so usr uuid [root@centos71 ~]# ls /root/swift_2.2/build/Ninja-ReleaseAssert/foundation-linux-x86_64/Foundation/CoreFoundation/ Base.subproj Locale.subproj PlugIn.subproj String.subproj Collections.subproj NumberDate.subproj Preferences.subproj URL.subproj Error.subproj Parsing.subproj StringEncodings.subproj So, let's try a few things: [root@centos71 ~]# swift -I /root/swift_2.2/build/Ninja-ReleaseAssert/foundation-linux-x86_64/Foundation junk.swift junk.swift:1:8: error: missing required module 'CoreFoundation' import Foundation ^ [root@centos71 ~]# swift -I /root/swift_2.2/build/Ninja-ReleaseAssert/foundation-linux-x86_64/Foundation -F /root/swift_2.2/build/Ninja-ReleaseAssert/foundation-linux-x86_64/Foundation -framework CoreFoundation junk.swift junk.swift:1:8: error: missing required module 'CoreFoundation' import Foundation ^ [root@centos71 ~]# swift -I /root/swift_2.2/build/Ninja-ReleaseAssert/foundation-linux-x86_64/Foundation -F /root/swift_2.2/build/Ninja-ReleaseAssert/foundation-linux-x86_64/Foundation/CoreFoundation -framework CoreFoundation junk.swift junk.swift:1:8: error: missing required module 'CoreFoundation' import Foundation ^ As one can see, using the -I flag with the location of the Foundation framework lets swift find Foundation, but I still need to figure out how to make it see CoreFoundation. More documentation reading is needed... If you have any ideas, please let me know.


So, the attempts to build a usable Swift on CentOS 7.1 have been partially successful: the swift command could be run as an interpreter on a trivial source file, swiftc could be used to compile the file into a native binary, but the Swift build system and Swift REPL didn't work.

In addition to building the source tagged with swift-2.2-SNAPSHOT-2015-12-01-b, I also tried the current head of the repository, i.e. cloning without a --branch option, as well as the most recent tag, which is swift-2.2-SNAPSHOT-2015-12-10-a as of this writing. The results were almost the same, except that when the untagged code or the code with the most recent tag was used, things were slightly different:

Building the tag swift-2.2-SNAPSHOT-2015-12-10-a on Ubuntu 14.04 took me a step further: the build system actually worked with trivial code. The binary used for this was built as part of swiftpm, which failed to build on CentOS 7.1. See http://www.swiftprogrammer.info/swift_ubuntu_2.html.

Thus it looks like the newly-open-sourced Swift is in its infancy, and there is a lot of homework to be done, but its a great baby and will hopefully grow into a mature open source language!

Please feel free to contact me with questions or comments.

© 2015 swiftprogrammer.infoAnatoli Peredera