[cmake-developers] Adding Swift support to CMake for Linux/Makefiles

Eric Wing ewmailing at gmail.com
Thu Dec 24 06:13:30 EST 2015


Hi,
This is kind of a continuation of the thread “Adding Swift support to CMake”.

Now that Swift is officially open source and already available for
Linux, I started looking at the build process on Linux which I hope we
can figure out how to incorporate into the CMake Makefile generator.

To start with, there actually seem to be two different approaches.
1) The swiftc command line compiler (similar to gcc, clang with
switches and output that seem to resemble them as well)
2) A formal package/module system for Swift which works with a Swift
command line build tool ‘swift build’

So far, for my usage cases, I’ve found the (2) package/module system
to be annoying and a bunch of indirection and extra steps. I also
don’t feel I have completely wrapped my head around it, so I’m not
going to focus on this for now. However, as more pure Swift libraries
get written, I think interoperating with the module system will become
extremely important, which we’ll ultimately need to deal with.


But in the meantime, back to (1) swiftc, this I found much more
straight-forward, at least for dealing with C code and C libraries and
I think maps pretty well to the current CMake design.

There is a pretty good example/write up found here:
http://dev.iachieved.it/iachievedit/more-swift-on-linux/

For a Swift application that also has C code, and uses C libraries,
this is the basic procedure:

1) Compile the C files into .o
clang -c escapetext.c

2) Compile the Swift files into .o (note: The header seems to be the
‘Bridging Header’ discussed in the prior thread)
swiftc -c escapeswift.swift -import-objc-header escapetext.h

3) Link all the object files together to build the final app executable
swiftc escapeswift.o escapetext.o -o escapeswift -lcurl



Here is another example I did with my own stuff which pushed a few
edges, so I think it is instructive.

- I am using a prebuilt SDL library on my system, but it is not a
system installed component.

- I defined extra C API functions for my SDL library to get around
limitations in the automatic Swift/C binding. This is in
SDLSwiftBinding.c

- I have two swift files instead of one. (Note: ‘main.swift’ seems get
special handling by the swift compiler and is always treated as your
application entry point.)

- I wanted to use -rpath $ORIGIN so I can ship my SDL library
side-by-side with my application executable


clang -I~/BlurrrSDKLinux/include/SDL2/ -c SDLSwiftBinding.c

swiftc -c MyApp.swift main.swift -I~/BlurrrSDKLinux/include/SDL2/
-import-objc-header SwiftSDL-Bridging-Header.h  -module-name MyProj

swiftc main.o MyApp.o SDLSwiftBinding.o -o MyAppExe -Xlinker -rpath
-Xlinker '$ORIGIN' -L~/BlurrrSDKLinux/lib -lSDL2


Note: I had to add -module-name MyProj because the compiler gave me an
error without it. I think it is because I had multiple Swift files. I
think for this case since I’m not making a library, I can use either
the project or executable name.


So I’d like to talk about how to further enhance CMake to do the
above. In my head, for the above examples, I think I would want to do
something like:

find_package(SDL)
include_directories(${SDL_INCLUDE_DIR})

# Forgot if we already had a convention for controlling this in the
Xcode generator
set(SWIFT_BRIDGING_HEADER SwiftSDL-Bridging-Header.h)
add_executable(MyAppExe
	SDLSwiftBinding.c
	main.swift
	MyApp.swift
)
target_link_libraries(MyAppExe ${SDL_LIBRARY})
# Do CMake rpath stuff as normal


Thanks,
Eric


More information about the cmake-developers mailing list