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

Brad King brad.king at kitware.com
Fri Jan 15 15:41:31 EST 2016


On 01/15/2016 09:47 AM, Eric Wing wrote:
>> That is the same as for C++.  See CMAKE_PARSE_IMPLICIT_LINK_INFO and
> 
> I looked at this file, but I still havne't groked what I need to do
> with this yet.

Somehow we need to get swift to print verbose output about the command
line it uses to invoke the linker on the small test project CMake uses
while enabling the language.  Then we need to parse that link line to
get the list of libraries and link directories.  This can be a later
step once most other things work though.

> However, I'm heavily debating if 'cc' or 'clang' is the right thing to
> do here.

If the user sets LINKER_LANGUAGE to "C" and does not have main in Swift
then CMake will want to link with the C compiler.  FYI, it is not actually
'cc' but the CMAKE_C_COMPILER selected, which happens to be 'cc' often.
Anyway, we should go with CMAKE_Swift_COMPILER for now.

> - First, CMake seems to be passing the flag -rdynamic to the link
> instructions, and this is causing a "unknown argument" error. I think
> this needs to be removed. I'm not sure where this flag is coming from.
> 
> - Second, -Wl,-rpath,/foo/bar is also causing an "unknown argument"
> error. As shown in the beginning of this thread, swiftc wants each
> argument to lead with -Xlinker (and there is no -Wl,)
> -Xlinker -rpath -Xlinker /foo/bar

You'll need to add proper settings in files of the form

 Modules/Platform/<os>-<id>-<lang>.cmake
 Modules/Compiler/<id>-<lang>.cmake

such as

 Modules/Platform/Linux-Apple-Swift.cmake
 Modules/Platform/Darwin-Apple-Swift.cmake
 Modules/Compiler/Apple-Swift.cmake

See Modules/Platform/Linux-NAG-Fortran.cmake for an example that
changes from -Wl,-rpath to -Xlinker -rpath.  Similarly the
CMAKE_SHARED_LIBRARY_LINK_<LANG>_FLAGS must not have -rdynamic
in it.  You're getting the settings from C right now because
your CMakeSwiftInformation.cmake file is copying them.  Instead
leave all those out and add them as needed, preferably without
copying from C.

> Additionally, I realized I should have some other variable besides
> <CMAKE_Swift_COMPILER>
> Seems like I should have <CMAKE_Swift_LINKER>. I'm not sure what the
> correct way to create this is.

All the languages use CMAKE_<LANG>_COMPILER as the front-end to
invoke for linking.  There should not need to be a separate linker
value unless that is new to Swift semantics.

> However, I currently employ a clever cheat. Since the compiler is
> 'swift', and the linker is 'swiftc', I just do
> '<CMAKE_Swift_COMPILER>c'

So plain 'swift' cannot be used to drive the linker too?

>> Note that for Ninja we actually convert our placeholders to Ninja
>> rule placeholders and then provide the values on the actual build
>> statement line.
> 
> I actually don't' know anything about Ninja. I assume it is just a
> string translation at this point since I did the other? Any guidance
> on the mapping?

Let's start with the Makefile generator.  Porting the results to
the Ninja generator should not be too much work later.

> So I need a new per-target variable in CMake for this and a way to
> inject it into the compiler flags, maybe something like this:
> 
> 	  "<CMAKE_Swift_COMPILER> -frontend -c  <INCLUDES> <FLAGS>
> -import-objc-header <TARGET-Swift-BRIDGING_HEADER> -primary-file
> <SOURCE> <Swift-SOURCES> -emit-module -module-name <TARGET> -o
> <OBJECT>")
> 
> With those two pieces, I think that actually makes add_executable()
> usable in the Makefile generator.

The values for the placeholders are always determined in the context
of a specific target, so just "<Swift-BRIDGING_HEADER>" should be
fine.

Thanks,
-Brad



More information about the cmake-developers mailing list