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

Eric Wing ewmailing at gmail.com
Wed Jan 20 08:48:59 EST 2016


On 1/19/16, Brad King <brad.king at kitware.com> wrote:
> On 01/18/2016 01:51 PM, Eric Wing wrote:
>> So the good news is I have a basic add_executable working with Swift
>> on Linux via the Makefile generator.
>>
>> It works with all Swift files, or intermixed C+Swift files. Bridging
>> header is also supported.
>
> Great!
>
>> - I’m still copying over some CFLAGS to Swift_FLAGS. For example, I
>> couldn’t figure out what was providing the ‘-I’ flag for include
>> paths. Rules like this still need to be rewritten for Swift.
>
> Try adding to CMakeSwiftInformation:
>
>  set(CMAKE_INCLUDE_FLAG_Swift -I)
>
>> - TODO: I need to look at Swift's DEFINE system.
>
> Yes.  After we get things building correctly the first time then we'll
> also need to see about adding needed dependencies to the build system.
>
>> - Note: The new file is Linux-unknown-Swift.cmake. When I compile
>> Swift myself, there is no company or organization identifier (swift
>> --version) unlike the one Apple ships with Xcode, and CMake refers to
>> the identifier as ‘unknown’. I made the file reflect this, but maybe
>> we should rename this later (maybe Swift_org).
>
> In an earlier Swift thread there was discussion about the name of the
> compiler id and ``Apple`` was chosen because that is the vendor of
> their version.  We definitely need to choose an id besides "unknown"
> for this.  Perhaps ``SwiftOrg``?  Also, we need a good way to check
> the id.  We could use `--version` if necessary but do we know whether
> the language provides any kind of identifier for code to use for
> conditional compilation?
>
>> - To answer your question about whether ‘swift’ instead of ’swiftc’
>> can be used for linking, I think the answer is yes, but I have been
>> unable to figure out the correct incantation.
>
> Okay.  Let's go with the ``<CMAKE_Swift_COMPILER>c`` hack until we
> know more.  I'd prefer not to have to expose a separate setting for
> the link driver only to remove it later.
>
>> - Swift Standard (or Core) Libraries: Swift comes with multiple
>> standard libraries.
> [snip]
>> I think CMake should provide some variables to the full paths to
>> these libraries since users like me will want to refer to them.
>
> Perhaps, but we currently don't do that for any other languages.
> We do provide CMAKE_{C,CXX,Fortran}_IMPLICIT_LINK_DIRECTORIES
> listing directories that may contain the standard libraries.
> This is the same as the information needed to use the C linker
> to mix languages that we previously discussed trying to extract
> for Swift.
>
> -Brad


Thanks for the response. I looking at version related stuff.
I've been trying to get things running on the Raspberry Pi (Raspbian).
I uncovered a few issues.

First, the CMake Swift compiler version check being run was actually
wrong all this time, but somehow got through on my desktop Linux. It
was calling swift without proper flags, so interactive (REPL) mode
should have run and blocked the process. Not sure how that got
through. But on the Pi, the REPL segfaults which made the problem
obvious.

To answer your other question about getting the version from within
Swift, I haven't figured out a way to do this yet. All the examples
are about getting the iOS version number or availability of APIs,
nothing about the language or compiler.

So via command line on Pi:
swift -version
Swift version 2.2-dev (LLVM cb23059150, Clang f66c5bb67b, Swift 7187741628)
Target: armv7-unknown-linux-gnueabihf


So to correct this crash (which is a blocking issue on Pi for CMake),
I want to pass the -version flag during that CMake check. But this
leads to another question.
I thought maybe setting the internal
CMAKE_${lang}_COMPILER_ID_FLAGS_LIST or
CMAKE_${lang}_COMPILER_ID_FLAGS
to "-version" would fix this.

But this did nothing. I tracked the code to the function definition of
CMAKE_DETERMINE_COMPILER_ID. I think there may be a bug:


function(CMAKE_DETERMINE_COMPILER_ID lang flagvar src)
<snip>

  # Make sure user-specified compiler flags are used.
  if(CMAKE_${lang}_FLAGS)
    set(CMAKE_${lang}_COMPILER_ID_FLAGS ${CMAKE_${lang}_FLAGS})
  else()
    set(CMAKE_${lang}_COMPILER_ID_FLAGS $ENV{${flagvar}})
  endif()
  string(REPLACE " " ";" CMAKE_${lang}_COMPILER_ID_FLAGS_LIST
"${CMAKE_${lang}_COMPILER_ID_FLAGS}")


The CMAKE_${lang}_COMPILER_ID_FLAGS gets overwritten with generic
flags, not the compiler_id_flags and I don't think the
compiler_id_flags can ever be used.

I think set() in those cases should be list(APPEND ...)
Can you confirm?


Additionally, there seems to be another Swift/ARM bug where the
default target architecture name is slightly wrong. This causes the
compile object files phases to always fail. This isn't a CMake
problem, but to work around it, I want something like environmental
variable CFLAGS or CXXFLAGS to be picked up by CMake. Coincidentally,
it looks like somehow I already have $ENV{SWIFTFLAGS} set to
CMAKE_Swift_FLAGS_INIT in CMakeSwiftInformation.cmake. (Either you did
it, or it was copy/paste/substitute from C.)

So I can do this in my shell:
export SWIFTFLAGS='-target armv7-unknown-linux-gnueabihf'

And CMake picks it up. Is this the correct expected behavior for CMake?


Thanks.
Eric


More information about the cmake-developers mailing list