[cmake-developers] Adding Swift support to CMake

Eric Wing ewmailing at gmail.com
Wed Jun 17 05:52:44 EDT 2015


Hello all,
I wanted to see if I could get the ball rolling on (Apple) Swift
support for CMake.

For more detail, here is the bug I’ve been chatting in:
http://public.kitware.com/Bug/view.php?id=15401

Here is the summary:
- For Apple developers, we need Swift support because it is going to
be increasingly common to have Swift files in the project, often as
backends for the Apple platform specific stuff in cross-platform
projects, just as Objective-C is today.

- Coming this fall, Swift is going to be open sourced, starting with a
Linux port. So we may start seeing more use cases on non-Apple
platforms as well.


To meet these objectives, I see two things we need to do:
- For the first and simplest case, we need to enhance the CMake Xcode
generator so it can handle Swift. Xcode already knows how to handle
Swift files automatically, so we should leverage it by making CMake
generate a correct project for it.

- The next step is to look at the Makefile generator and command line
invocation. With luck, this will work for Mac, Linux, and probably any
other Unix-like platform that gets Swift/LLVM running.


As a first stab to get Xcode support working,
in cmGlobalXCodeGenerator.cxx in the function
GetSourcecodeValueFromFileExtension(), I added swift right after the
Obj-C entries.

  else if (ext == "swift")
    {
    sourcecode += ".swift";
    }

This correctly set the source code type in Xcode for Swift files.
However, every Swift file was lacking any target association (blank
checkboxes for all targets). This means no Swift files were getting
compiled.

After some random guessing, I found in CMakeCCompiler.cmake.in, adding
swift to the CMAKE_C_SOURCE_FILE_EXTENSIONS, would cause the Swift
files to be correctly associated with a target.
set(CMAKE_C_SOURCE_FILE_EXTENSIONS c;m;swift)


This works pretty well for my initial test case which is a mixture of
C/Obj-C/Swift. But I was told we should be looking at building a
separate language generator instead of this latter hack.



So this is where I’m starting to get lost/overwhelmed, and am hoping
to find other people that might be able to help make this happen.

At the moment, I created 4 new files:
	CMakeDetermineSwiftCompiler.cmake
	CMakeSwiftCompiler.cmake.in
	CMakeSwiftInformation.cmake
	CMakeTestSwiftCompiler.cmake

I originally started with C as the template and got lost quickly. I
have since started using Java as the template and have muddled through
a little bit more. In my current Xcode prototype, I’ve been fighting
various flags, e.g. my C flags getting clobbered by Swift, when in
fact I need both. (e.g. lost my @rpath/@loader_path stuff.)

So, I’m still lacking a lot of knowledge on both the CMake side (how
to implement a new language), and also a lot of the reverse
engineering details of how Swift works. Maybe we can layout the
details in this thread.

These are the various details that I’m aware of at the moment:

- The swift compiler is called swiftc

- Swift doesn’t really have a preprocessor or linker in the traditional C sense.

- However, since Swift is designed to operate with C and Obj-C, there
does seem to be a mechanism to create files that can be linked with
C/Obj-C (needed by the Makefile generator; should be automatic by
Xcode)

- I don’t think Swift needs dependency management like in Makefiles
and swift handles everything for you transparently (ignoring
intermixing with C/Obj-C). However, you still need a build system to
handle other things like asset files (images, icons, etc.)

- Swift projects generally need to provide a “bridging header” to be
able to call C/Obj-C code

- Swift projects need a generated Interface Header so C/Obj-C can call
Swift code

- Swift has its own optimization flag settings separate from C/Obj-C

- Swift seems to have its own ‘other flags’

- I think there is a way to build Swift-only modules, but I have not
looked into this. Intermixing C/Obj-C probably means you can fall back
to the clang mechanisms.

- On OSX/iOS, it would be nice to make Swift automatically enabled
since it is kind of a required language now. (Requiring
ENABLE_LANGAUGE(Swift) seems annoying.)

- I’m kind of assuming, but don’t really know, that Obj-C and the
Obj-C runtime will be available with the Linux port of Swift, and that
you will generally want it and might even be required. (Note: I am
being careful to distinguish between Obj-C and libraries like
Foundation.) Being able to call Swift from C requires Obj-C (in my
limited experience). Swift’s easy interoperability with C (in both
directions) I think is a selling point for Swift and expect it to be
used, particularly on Linux where C is prevalent. So I think we need
to make sure this intermixing can be handled by the Makefile
generator.

- Here is the best resource I've found so far on building a Makefile for Swift:
http://owensd.io/2015/01/15/swift-makefiles-take-2.html


So anybody who wants to chime in, please do so!
Let's see if we can make this happen.


Thanks,
Eric


More information about the cmake-developers mailing list