Discussion:
[cmake-developers] Adding Swift support to CMake for Linux/Makefiles
Eric Wing
2015-12-24 11:13:30 UTC
Permalink
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
--
Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
ht
Eric Wing
2015-12-24 12:46:15 UTC
Permalink
Post by Eric Wing
set(SWIFT_BRIDGING_HEADER SwiftSDL-Bridging-Header.h)
Quick addendum: Just realized the bridging header should probably be per-target.
--
Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
http://public.kitware.com/mailman/listinfo/cmake-developers
Eric Wing
2016-01-08 01:18:53 UTC
Permalink
Post by Eric Wing
Post by Eric Wing
set(SWIFT_BRIDGING_HEADER SwiftSDL-Bridging-Header.h)
Quick addendum: Just realized the bridging header should probably be per-target.
For reference, we have an Xcode specific, per-target variable for the
bridging header: XCODE_ATTRIBUTE_SWIFT_OBJC_BRIDGING_HEADER.

set_property(TARGET ${BLURRR_USER_EXECUTABLE_NAME} PROPERTY
XCODE_ATTRIBUTE_SWIFT_OBJC_BRIDGING_HEADER
"${PROJECT_SOURCE_DIR}/source/MySwiftBridgingHeader.h")
--
Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
http://public.kitware.com/mailman/listinfo/cmake-developers
Brad King
2016-01-08 16:30:44 UTC
Permalink
Post by Eric Wing
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.
Thanks for digging in to this!
Post by Eric Wing
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.
Yes. A few months ago I spent a few hours looking at the commands Xcode
uses to build Swift code. For reference, here are some notes I took
(not well organized):

----------------------------------------------------------------------------
MergeSwiftModule produces .swiftmodule files, which seem to be serialized
copies of swift modules, like binary headers, each covering an entire module
over multiple source files. MergeSwiftModule merges partial modules from
individual sources into one for the whole module.

The .swiftmodule for a shared library can be consumed while compiling
other projects whose "import" statements search the -I path for the
.swiftmodule files. The .swiftmodule file is a binary header for the
whole shared library.

The compiler leaves in .o files a decl that tells the linker what libraries
to link. The linker hopefully tolerates seeing those libraries explicitly
on the command line too, since CMake will generate those.

Swift does have conditional compilation that affects imports.

See the -emit-dependencies and output file map options to control where .d
files are generated.

swift -help
swift -help-hidden
swift -frontend -help
swift -frontend -help-hidden

If one imports a library written in C/objc then something generates a
module map pointing to the headers. It seems to lazily generate from
the headers a module that can be loaded. To use a C library from Swift
one must write a module map explicitly. Some lib providers may support
modules directly and provide the module map next to the library file.

----------------------------------------------------------------------------
Post by Eric Wing
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.
Great.
Post by Eric Wing
http://dev.iachieved.it/iachievedit/more-swift-on-linux/
Good link.
Post by Eric Wing
For a Swift application that also has C code, and uses C libraries,
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
Okay.
Post by Eric Wing
(Note: ‘main.swift’ seems get
special handling by the swift compiler and is always treated as your
application entry point.)
Yes, that seems to be the case. Furthermore the file can just have
code directly in the top level because the whole thing is the "main"
function.
Post by Eric Wing
So I’d like to talk about how to further enhance CMake to do the above.
Okay. Ideally I'd like a solution designed with understanding of the
module system as mentioned in my notes above.
Post by Eric Wing
In my head, for the above examples, I think I would want to do
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)
As you noted in another response, we have a per-target property
XCODE_ATTRIBUTE_SWIFT_OBJC_BRIDGING_HEADER. The bridging header
does need to be per-target, yes.
Post by Eric Wing
add_executable(MyAppExe
SDLSwiftBinding.c
main.swift
MyApp.swift
)
target_link_libraries(MyAppExe ${SDL_LIBRARY})
Yes, that looks like what we want to achieve.

Thanks,
-Brad
--
Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
htt
Eric Wing
2016-01-08 23:15:03 UTC
Permalink
Post by Brad King
Yes. A few months ago I spent a few hours looking at the commands Xcode
uses to build Swift code. For reference, here are some notes I took
----------------------------------------------------------------------------
MergeSwiftModule produces .swiftmodule files, which seem to be serialized
copies of swift modules, like binary headers, each covering an entire module
over multiple source files. MergeSwiftModule merges partial modules from
individual sources into one for the whole module.
The .swiftmodule for a shared library can be consumed while compiling
other projects whose "import" statements search the -I path for the
.swiftmodule files. The .swiftmodule file is a binary header for the
whole shared library.
The compiler leaves in .o files a decl that tells the linker what libraries
to link. The linker hopefully tolerates seeing those libraries explicitly
on the command line too, since CMake will generate those.
That article I linked to also mentions the .swiftmodule system via swiftc.

=========
swiftc -emit-library translator.swift -module-name translator
-import-objc-header bridgingHeader.h
clang -shared -o libtranslator.so translator.o

# Now, create the module:
swiftc -emit-module -module-name translator translator.swift
-import-objc-header bridgingHeader.h

# This leaves us with three files: libtranslator.so,
translator.swiftmodule, and translator.swiftdoc.


# You must have a translator.swiftmodule in your module search path,
which we add with -I.:
swiftc -I. -c main.swift -import-objc-header bridgingHeader.h

# Let’s link everything together:
swiftc -o translate.exe jsonparse.o main.o -L. -ltranslator -lcurl
-ljson-c -lswiftGlibc -lFoundation
=========

I haven't given deep thought to libraries yet (still just trying to
get applications going), I'm thinking ADD_LIBRARY most needs to just
invoke the -emit-library flag on swiftc, and automatically add the -I
(include path) to the output directory for the linking. Maybe
-module-name can be inferred from the TARGET name?
Post by Brad King
See the -emit-dependencies and output file map options to control where .d
files are generated.
swift -help
swift -help-hidden
swift -frontend -help
swift -frontend -help-hidden
If one imports a library written in C/objc then something generates a
module map pointing to the headers. It seems to lazily generate from
the headers a module that can be loaded. To use a C library from Swift
one must write a module map explicitly. Some lib providers may support
modules directly and provide the module map next to the library file.
It looks like the 'swift' front-end build and packaging system is
still a work in progress and doesn't seem to fully work on Linux yet.
Post by Brad King
Swift does have conditional compilation that affects imports.
Yes. I'm wondering at least with a swiftc backend, this is up to the
user to manually specify (mirror) in the CMake description to say what
files are compiled/linked, like they do now with C/C++/Obj-C.

Maybe when the 'swift' front-end gets farther, we can try to make this
more automatic. But since the 'swift' front-end is entangled with git,
and introduces its own package file conventions, it's not something
I've given much thought to.



Anyway, I have a couple of hours on a train this weekend. I was
wondering if you could give me guidance on what I need to do to get a
simple 'swiftc' integration going for ADD_EXECUTABLE, as described in
the original post.

Thanks,
Eric
--
Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
http://p
Brad King
2016-01-12 19:41:12 UTC
Permalink
Post by Eric Wing
simple 'swiftc' integration going for ADD_EXECUTABLE, as described in
the original post.
Take the generator check out of Modules/CMakeDetermineSwiftCompiler.cmake
to get rid of the up-front error. See "Modules/CMakeAddNewLanguage.txt"
(many of the steps are already done).

Edit Modules/CMakeSwiftInformation.cmake and add settings for variables
like CMAKE_Swift_COMPILE_OBJECT and CMAKE_Swift_LINK_EXECUTABLE. See
the CMake{C,CXX,Fortran}Information.cmake modules for examples. The
available placeholders are in cmLocalGenerator::ExpandRuleVariable.

If all the compile/link steps used for C and C++ map well to switfc
then it should be fairly straightforward. If other steps are needed
or the steps have wildly different semantics then more in-depth changes
to the actual generators may be needed.

-Brad
--
Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
http://public.kitware.com/mailman/listinfo/cmake-developers
Eric Wing
2016-01-13 12:00:39 UTC
Permalink
Post by Brad King
Post by Eric Wing
simple 'swiftc' integration going for ADD_EXECUTABLE, as described in
the original post.
Take the generator check out of Modules/CMakeDetermineSwiftCompiler.cmake
to get rid of the up-front error. See "Modules/CMakeAddNewLanguage.txt"
(many of the steps are already done).
Edit Modules/CMakeSwiftInformation.cmake and add settings for variables
like CMAKE_Swift_COMPILE_OBJECT and CMAKE_Swift_LINK_EXECUTABLE. See
the CMake{C,CXX,Fortran}Information.cmake modules for examples. The
available placeholders are in cmLocalGenerator::ExpandRuleVariable.
If all the compile/link steps used for C and C++ map well to switfc
then it should be fairly straightforward. If other steps are needed
or the steps have wildly different semantics then more in-depth changes
to the actual generators may be needed.
-Brad
So I got the trivial base case working with swiftc (no library
dependencies, Mac for now but will shift to Linux eventually):
add_exectuable(MyTarget main.swift)

Yay.

So next I wanted to add more files to the mix. And now I have some problems.


Problem 1: Intermixing C and Swift
add_exectuable(MyTarget main.swift some_c.c)
Note: I presume C++ (and Obj-C) could also be in the mix:
add_exectuable(MyTarget main.swift some_c.c some_cpp.cpp some_objc.m)

It looks like the link phase is invoking cc on my system (the C linker
rules?) instead of the Swift linker commands.

If my hunch is correct, how do I tell CMake to ‘promote’ Swift as the
correct tool?
(Perhaps there is a similar existing mechanism already is handling
intermixing C/C++ or C/Obj-C?)

Additional note: I am a little surprised to see cc instead of ld (or
swiftc). Now I may be able to use cc or ld, but I need to figure out
how to adapt and add some additional flags. So it could be that I
could work around this problem. (Kind of working solution at the
bottom.)



Problem 2: Multiple Swift files in the target
add_exectuable(MyTarget main.swift OtherSwift.swift)

With two or more files, I was hoping to do a single one-shot call:
swiftc -c OtherSwift.swift main.swift -module-name MyTarget

But it looks like CMake invokes each file separately. The problem that
creates in the above case is that if main.swift uses stuff from the
other file, it can no longer compile because it is unable to find the
code in OtherSwift because they are treated as separate unconnected
modules. I haven’t figured a way yet around this using swiftc.

However, I can switch to the tool ‘swift’, but it looks like Swift has
a similar constraint which I will discuss shortly.

But before I move on to that, is there a way to get CMake to invoke
all the Swift files in the target together? (It would need to exclude
any non-Swift files in the list.)

I think there may be trade-offs here. On one hand, file-by-file might
get us incremental compilation. But there is a flag called
-whole-module-optimization which suggests treating them as a batch
could allow better code generation.


Now for the 'swift' tool:

So the swift tool can go file-by-file, but the additional constraint
is that all the other Swift files in the target must be listed too. To
distinguish which file is actually being processed, you must use the
-primary-file <active_file.swift> <other_files>. I think this is so
Swift can figure out all the cross-file dependencies since there are
no header files in Swift.

Here is an example of compiling my two files:

# Compile main.swift to main.o
swift -frontend -c -primary-file
/Volumes/DataPartition/Users/ewing/Source/CodeTest/CMakeSwiftBasic/main.swift
/Volumes/DataPartition/Users/ewing/Source/CodeTest/CMakeSwiftBasic/OtherSwift.swift
-emit-module -module-name MyTarget -o CMakeFiles/MyApp.dir/main.o
-emit-module-path CMakeFiles/MyApp.dir/main~partial.swiftmodule

# Compile OtherSwift.swift to OtherSwift.o
swift -frontend -c -primary-file
/Volumes/DataPartition/Users/ewing/Source/CodeTest/CMakeSwiftBasic/OtherSwift.swift
/Volumes/DataPartition/Users/ewing/Source/CodeTest/CMakeSwiftBasic/main.swift
-emit-module -module-name MyTarget -o
CMakeFiles/MyApp.dir/OtherSwift.o -emit-module-path
CMakeFiles/MyApp.dir/OtherSwift~partial.swiftmodule

Other things to notice:
- I am using the CMake Target Name for the -module-name
- There is a basename~partial.swiftmodule being generated. I'm not
completely sure why this is needed, but I see it in the Xcode build
lines and other examples on the web.


Finally, the link line can look like this: (Xcode invokes clang
instead of cc, but they map to the same thing on Mac)

/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/cc
-arch x86_64 -isysroot
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk
-L/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift_static/macosx
-Xlinker -force_load_swift_libs -lswiftRuntime -lc++ -framework
Foundation CMakeFiles/MyApp.dir/OtherSwift.o
CMakeFiles/MyApp.dir/main.o -o MyApp



So in the CMake rules, for CMAKE_Swift_COMPILE_OBJECT, I think I need
something kind of like:

set(CMAKE_Swift_COMPILE_OBJECT

"<CMAKE_Swift_COMPILER> -frontend -c <INCLUDES> <FLAGS>
-primary-file <SOURCE> <SOURCES> -emit-module -module-name <TARGET> -o
<OBJECT> -emit-module-path -c <SOURCE>~partial.swiftmodule"
)

Additional notes:
- SOURCES doesn't actually exist in CMake, but I saw something called
OBJECTS which makes me think they are a similar concept.

- Also, for the second <SOURCES>, I need to remove the one I'm using
from my -primary-file. And there shouldn't be any non-Swift files in
the list (no C/C++/Obj-C).

- I actually need the basename of <SOURCE> for the ~partial.swiftmodule stuff.

- I'm not sure if I'm responsible for the intermediate products
directories. Do I need to explicitly concat the paths to any of these
things.

- I haven't added the bridging header flag/value yet. I need some
expected variable that holds it.




Can you give me some suggestions on what to look at next?

Thanks,
Eric
--
Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
http://public.kitware.com/mailman/listinfo/cmake-de
Brad King
2016-01-13 15:07:39 UTC
Permalink
Post by Eric Wing
So I got the trivial base case working with swiftc (no library
add_exectuable(MyTarget main.swift)
Great!
Post by Eric Wing
Problem 1: Intermixing C and Swift
add_exectuable(MyTarget main.swift some_c.c)
add_exectuable(MyTarget main.swift some_c.c some_cpp.cpp some_objc.m)
It looks like the link phase is invoking cc on my system (the C linker
rules?) instead of the Swift linker commands.
If my hunch is correct, how do I tell CMake to ‘promote’ Swift as the
correct tool?
See the CMAKE_<LANG>_LINKER_PREFERENCE platform information variable.
There is also the LINKER_LANGUAGE target property. For C, C++, and
Fortran one generally chooses between C++ and Fortran to drive the
linker based on which language has the entry point (main) in its
sources. If we see a "main.swift" then we know Swift should be used.
If not then I don't know enough about Swift linking requirements to say.
Post by Eric Wing
Problem 2: Multiple Swift files in the target
add_exectuable(MyTarget main.swift OtherSwift.swift)
swiftc -c OtherSwift.swift main.swift -module-name MyTarget
[snip]
Post by Eric Wing
But before I move on to that, is there a way to get CMake to invoke
all the Swift files in the target together? (It would need to exclude
any non-Swift files in the list.)
I think there may be trade-offs here. On one hand, file-by-file might
get us incremental compilation. But there is a flag called
-whole-module-optimization which suggests treating them as a batch
could allow better code generation.
This looks like a semantic difference between how the switfc and cc
compilers work that as I feared in my previous response may require
C++ changes to CMake to make work. Before diving into that we need
to understand the preferred way to compile multiple Swift sources.
Last time I looked at this the only reference was "what Xcode does".
Hopefully there is more information out there now.
Post by Eric Wing
So the swift tool can go file-by-file, but the additional constraint
is that all the other Swift files in the target must be listed too. To
distinguish which file is actually being processed, you must use the
-primary-file <active_file.swift> <other_files>. I think this is so
Swift can figure out all the cross-file dependencies since there are
no header files in Swift.
Interesting. My previous comment above applies here too.

It may be that we're supposed to invoke Swift with all sources at once
and let it take responsibility for generating the results and doing any
kind of incremental stuff internally.
Post by Eric Wing
- SOURCES doesn't actually exist in CMake, but I saw something called
OBJECTS which makes me think they are a similar concept.
It shouldn't be too hard to add a <SOURCES> placeholder if needed. We
may need it either way because we either list all the sources on one
call to swift or on every call to swift.
Post by Eric Wing
- Also, for the second <SOURCES>, I need to remove the one I'm using
from my -primary-file. And there shouldn't be any non-Swift files in
the list (no C/C++/Obj-C).
That kind of filtering may be harder to define and require custom logic
in CMake's generators for Swift instead of trying to do it with generic
placeholders.
Post by Eric Wing
- I'm not sure if I'm responsible for the intermediate products
directories. Do I need to explicitly concat the paths to any of these
things.
The <OBJECT> placeholder will contain the intermediate directories when
replaced. We may need new placeholders for other things that go in these
directories for Swift though.
Post by Eric Wing
- I haven't added the bridging header flag/value yet. I need some
expected variable that holds it.
A target property will likely have to be introduced to hold this.
Post by Eric Wing
Can you give me some suggestions on what to look at next?
Before proceeding with CMake changes I think we need a better
understanding of the tools involved in Swift development. What
does individual compilation achieve over monolithic compilation?
How does Swift linking interact with other languages? Etc.

Side note: When we first added Java support to CMake we tried to
make it a builtin language just like C and C++, and even have
rules to tell the generators how to compile each .java -> .class
source separately. Later we learned that due to nested classes
there can be circular dependencies among .java sources and the
only safe way to compile it is to list all sources at once and
let the compiler handle them internally. Now Java is used in
CMake through the FindJava and UseJava modules that use custom
commands to do the monolithic compilation. All the builtin
Java support is pretty much unused because it has never been
ported to the monolithic compilation approach. I'd prefer not
to repeat such mistakes with Swift.

Given Swift's relationship to ObjC/C++ this may also be time to
revive earlier work posted here (but never finished) on making
OBJC and OBJCXX languages separate from C and CXX in CMake. This
would be useful if we need to distinguish the languages in order
to properly mix with Swift.

-Brad
--
Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
http://public.kitware.com/mailman/listinfo
Eric Wing
2016-01-13 23:17:45 UTC
Permalink
Post by Brad King
Post by Eric Wing
If my hunch is correct, how do I tell CMake to ‘promote’ Swift as the
correct tool?
See the CMAKE_<LANG>_LINKER_PREFERENCE platform information variable.
There is also the LINKER_LANGUAGE target property. For C, C++, and
Fortran one generally chooses between C++ and Fortran to drive the
linker based on which language has the entry point (main) in its
sources. If we see a "main.swift" then we know Swift should be used.
If not then I don't know enough about Swift linking requirements to say.
I suspect it is like C++ and C. If there is both, you promote up to C++ linking.
So if there is any .swift file or library in the mix, you need to
promote up to use Swift.

Under the hood, I think the LLVM linker can handle all of these
through ld. But I think the thing that is tripping me up is that Swift
seems to need to link against some additional libraries which are not
needed in the pure C case. The swiftc command seems to know how to
automatically link in those extra dependencies (and I don't need to
add all the search paths to where the Swift core libraries are
located).

Anyway, I tried bumping up CMAKE_Swift_LINKER_PREFERENCE to 40. (Same
as Java). But it didn't seem to do anything for me.

I then added to my test CMakeLists.txt:
set_property(TARGET MyApp PROPERTY LINKER_LANGUAGE Swift)

That then worked, but I'm confused how to get CMake to automatically
do this for me because I expected CMAKE_Swift_LINKER_PREFERENCE to do
this.
Post by Brad King
This looks like a semantic difference between how the switfc and cc
compilers work that as I feared in my previous response may require
C++ changes to CMake to make work. Before diving into that we need
to understand the preferred way to compile multiple Swift sources.
Last time I looked at this the only reference was "what Xcode does".
Hopefully there is more information out there now.
Unfortunately, there isn't a whole lot more information. The majority
of the examples are hello world programs with one file.

The best write up I've seen is this series:
http://owensd.io/blog/compiling-swift-without-xcode/
http://owensd.io/blog/compiling-individual-files/
http://owensd.io/blog/swift-vs-swiftc/
http://owensd.io/blog/swift-makefiles---take-2/

One interesting note, swiftc is just an alias for swift.


The exception is the Swift Package manager. But this is a convention
based system. Right now it is far from finished and its conventions
are actually incompatible with Xcode. It has its own file format and
also requires all dependency packages be in a Git repo and follow a
certain tagging convention. I also haven't seen any way to directly
mix C+Swift code in a module and they expect you to create a separate
module for C stuff which you then import in. I'm under the impression
they plan to relax a lot of these things, but I find it currently too
incomplete and with too much impedance to be useful right now.

(By the way, I think I'm a little incorrect about main.swift being
special. I'm seeing examples where they name the file anything.swift.
It looks like Swift will automatically create a main entry point for
you when building an executable, especially in the one-shot case. With
swiftc it must be a one-shot otherwise you get duplicate symbols. With
swift -frontend, it some how manages to create one. But with the Swift
Package system, I think main.swift is a convention-requirement.)
Post by Brad King
It may be that we're supposed to invoke Swift with all sources at once
and let it take responsibility for generating the results and doing any
kind of incremental stuff internally.
So Xcode is using the swift -frontend technique and it looks like it
doing it incrementally. I think the requirement for the list of other
files is so it can resolve the dependencies.
Post by Brad King
It shouldn't be too hard to add a <SOURCES> placeholder if needed. We
may need it either way because we either list all the sources on one
call to swift or on every call to swift.
Right.
Post by Brad King
Post by Eric Wing
- Also, for the second <SOURCES>, I need to remove the one I'm using
from my -primary-file. And there shouldn't be any non-Swift files in
the list (no C/C++/Obj-C).
That kind of filtering may be harder to define and require custom logic
in CMake's generators for Swift instead of trying to do it with generic
placeholders.
I just tried not filtering the current primary file from the list. It
still worked. So maybe we can get away with not filtering that.
However, we do need to filter any C files. That didn't work. (It tried
to compile those .c files as Swift which obviously won't work.)
Post by Brad King
Post by Eric Wing
Can you give me some suggestions on what to look at next?
Before proceeding with CMake changes I think we need a better
understanding of the tools involved in Swift development. What
does individual compilation achieve over monolithic compilation?
I'm actually not sure. The monolithic one-shot should avoid any
potential incorrectness problems if a dependent file was changed but a
calling file wasn't recompiled. I don't know if Swift has these types
of problems like C or if it is immune.

It feels like Xcode is doing some incremental building or caching for
me by doing individual compilation. However, it seems to recompile
both files in the log. But Xcode is using a bunch of other switches
and temporary files that may be assisting this.
Post by Brad King
How does Swift linking interact with other languages? Etc.
So as I mentioned, ld seems to be able to handle all the .o files
regardless of language and link them. The constraint seems to be that
Swift adds some additional dependencies.

I think I read a claim that somebody linked to .o files created by gcc
instead of clang. I probably wouldn't recommend this, but it suggests
there isn't anything that special by the time we reach this stage.
Post by Brad King
Side note: When we first added Java support to CMake we tried to
make it a builtin language just like C and C++, and even have
rules to tell the generators how to compile each .java -> .class
source separately. Later we learned that due to nested classes
there can be circular dependencies among .java sources and the
only safe way to compile it is to list all sources at once and
let the compiler handle them internally. Now Java is used in
CMake through the FindJava and UseJava modules that use custom
commands to do the monolithic compilation. All the builtin
Java support is pretty much unused because it has never been
ported to the monolithic compilation approach. I'd prefer not
to repeat such mistakes with Swift.
So I think we will need that list of all sources for Swift because
like Java, there are no header files so the compiler needs to resolve
dependencies.

For the moment, I like swiftc over swift because it seems a lot
simpler. I hope this means the least changes for CMake right now.

I won't lie to you. In maybe two years, the Swift Package Manager will
probably be closer to finished/stable and we may need to re-evaluate
things. I suspect there will be a temptation to invoke it because it
will have the ability to download dependencies from the internet on
the fly. However, it's still too early for me to guess how this is
going to interoperate with C code, local libraries, bundling
resources, packaging and codesigning for distribution. One story is
that this will completely sub-plant the need for something like CMake.
Another story is that the Linux/Swift effort initially seems to be
focused on server/headless backends which doesn't need a lot of the
same things as front-end applications. So Xcode and CMake still may be
needed and people may find the Package Manager isn't useful outside
server apps. (It currently reminds me a little of Go's system which is
also heavily server focused.)
Post by Brad King
Given Swift's relationship to ObjC/C++ this may also be time to
revive earlier work posted here (but never finished) on making
OBJC and OBJCXX languages separate from C and CXX in CMake. This
would be useful if we need to distinguish the languages in order
to properly mix with Swift.
Maybe, but I think we can punt on that for two reasons.
1) As I said, the LLVM linker seems to handle all these already more
or less transparently. For Swift, we just need to separate Swift files
from everything else.

2) The open source Swift release does not include Obj-C. They are
pushing a pure Swift solution for everybody else.

Since the Xcode generator for Swift more or less works*, I think that
is the proper way using Swift on Mac/iOS. That already handles a lot
of esoteric platform stuff better and also handles the Obj-C/Obj-C++
more correctly.

*By the way, I found two minor issues... (1) Swift has additional
separate flags for some things like optimization settings: we need to
duplicate the CMake Debug/Release/MinSizeRel/RelWithDebug flags for
the Swift section, (2) Everytime I create a new Xcode/Swift project, a
prompt comes up telling me my Swift version is 1.x and the wizard will
help me migrate my code to the latest. I suspect there is some version
flag in the generated Xcode project that needs to be bumped up.


Anyway, it seems like adding SOURCES is the next step. Any hints on
how to do that?

Thanks,
Eric
--
Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
http://public.kitware.com/mailman/l
Eric Wing
2016-01-13 23:39:07 UTC
Permalink
Post by Eric Wing
For the moment, I like swiftc over swift because it seems a lot
simpler. I hope this means the least changes for CMake right now.
I need to correct myself on this. While I like swiftc for looking
simpler, I'm actually thinking swift might be fewer changes since the
file-by-file thing is what CMake does today.
It may turn out swift is easier to figure out in the end too when we
eventually look at add_library and linking them (since we can reverse
engineer from the Xcode logs).

But either way, both of them seem to need SOURCES.

Thanks,
Eric
--
Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
http://public.kitware.com/mailman/listinfo/cmake-developers
Brad King
2016-01-14 18:56:04 UTC
Permalink
Post by Eric Wing
Under the hood, I think the LLVM linker can handle all of these
through ld. But I think the thing that is tripping me up is that Swift
seems to need to link against some additional libraries which are not
needed in the pure C case. The swiftc command seems to know how to
automatically link in those extra dependencies (and I don't need to
add all the search paths to where the Swift core libraries are
located).
That is the same as for C++. See CMAKE_PARSE_IMPLICIT_LINK_INFO and
the call to it in "Modules/CMakeDetermineCompilerABI.cmake". That is
responsible for extracting the implicit link information passed by a
given language compiler's front-end. We'll need to extract that for
Swift.
Post by Eric Wing
Anyway, I tried bumping up CMAKE_Swift_LINKER_PREFERENCE to 40. (Same
as Java). But it didn't seem to do anything for me.
Where did you add the code to set it?
Post by Eric Wing
I just tried not filtering the current primary file from the list. It
still worked. So maybe we can get away with not filtering that.
Great. It will be simplest to list all the sources in every call and then
repeat the one that is current.
Post by Eric Wing
Anyway, it seems like adding SOURCES is the next step. Any hints on
how to do that?
The cmLocalGenerator::ExpandRuleVariable method does the placeholder
substitution. It relies on values in the RuleVariables structure
to be populated by the calling generator. The Makefile generator
populates that for the compile line here:

cmMakefileTargetGenerator::WriteObjectBuildFile

and the Ninja generator here:

cmNinjaTargetGenerator::WriteCompileRule
cmNinjaTargetGenerator::WriteObjectBuildStatement

Note that for Ninja we actually convert our placeholders to Ninja
rule placeholders and then provide the values on the actual build
statement line.

You should be able to call

this->GeneratorTarget->GetObjectSources(objectSources, config);

to get the list of source files and then filter it based on
sf->GetLanguage().

The name "<SOURCES>" is not very good because it does not specify
how any filtering is done. Perhaps a special case name such as
"<Swift-SOURCES>" would be better.

Do we know that there is a one-to-one mapping between libraries
and Swift modules?

-Brad
--
Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
http://public.kitware.com/mailman/listinfo/cmake-developers
Eric Wing
2016-01-15 14:11:42 UTC
Permalink
Okay, I think I'm making some good progress. I got a trivial program
built on Mac. I've now switched to Linux. I'm mostly there, but there
are still some things that need to be done. More inline...


https://github.com/ewmailing/CMake/tree/SwiftMakefile
Post by Brad King
Post by Eric Wing
Anyway, I tried bumping up CMAKE_Swift_LINKER_PREFERENCE to 40. (Same
as Java). But it didn't seem to do anything for me.
Where did you add the code to set it?
I got it working. I put it in.
CMakeSwiftCompiler.cmake.in
I figured out I also needed to add:
set(CMAKE_Swift_LINKER_PREFERENCE_PROPAGATES 1)
Post by Brad King
Post by Eric Wing
Under the hood, I think the LLVM linker can handle all of these
through ld. But I think the thing that is tripping me up is that Swift
seems to need to link against some additional libraries which are not
needed in the pure C case. The swiftc command seems to know how to
automatically link in those extra dependencies (and I don't need to
add all the search paths to where the Swift core libraries are
located).
That is the same as for C++. See CMAKE_PARSE_IMPLICIT_LINK_INFO and
the call to it in "Modules/CMakeDetermineCompilerABI.cmake". That is
responsible for extracting the implicit link information passed by a
given language compiler's front-end. We'll need to extract that for
Swift.
I looked at this file, but I still havne't groked what I need to do
with this yet.

However, I'm heavily debating if 'cc' or 'clang' is the right thing to
do here. I'm starting to think 'swiftc' might be the most robust and
correct thing for the linking command. There are several reasons for
this:

- swiftc seems to already do the right thing
- Not using swiftc requires me to set a lot of things, including the
Apple SDK when on Mac. This feels really messy.
- On Linux, I think there is a danger in calling 'cc'.




realized I may need to take a step back.
Post by Brad King
Post by Eric Wing
I just tried not filtering the current primary file from the list. It
still worked. So maybe we can get away with not filtering that.
Great. It will be simplest to list all the sources in every call and then
repeat the one that is current.
Post by Eric Wing
Anyway, it seems like adding SOURCES is the next step. Any hints on
how to do that?
The cmLocalGenerator::ExpandRuleVariable method does the placeholder
substitution. It relies on values in the RuleVariables structure
to be populated by the calling generator. The Makefile generator
cmMakefileTargetGenerator::WriteObjectBuildFile
cmNinjaTargetGenerator::WriteCompileRule
cmNinjaTargetGenerator::WriteObjectBuildStatement
Note that for Ninja we actually convert our placeholders to Ninja
rule placeholders and then provide the values on the actual build
statement line.
You should be able to call
this->GeneratorTarget->GetObjectSources(objectSources, config);
to get the list of source files and then filter it based on
sf->GetLanguage().
The name "<SOURCES>" is not very good because it does not specify
how any filtering is done. Perhaps a special case name such as
"<Swift-SOURCES>" would be better.
Do we know that there is a one-to-one mapping between libraries
and Swift modules?
-Brad
--
Beginning iPhone Games Development
http://playcontrol.net/iphonegamebook/
--
Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
http://public.kitware.com/mailman/listinfo/cmake-developers
Eric Wing
2016-01-15 14:47:42 UTC
Permalink
(Ignore the last post. The last message sent accidentally before I was
even close to done. Not sure why it sent. I must have accidentally
discovered a hot key in Gmail. Everything is rewritten here.)


Okay, I think I'm making some good progress. I got a trivial program
built on Mac. I've now switched to Linux. I'm mostly there, but there
are still some things that need to be done. More inline...
Post by Brad King
Post by Eric Wing
Anyway, I tried bumping up CMAKE_Swift_LINKER_PREFERENCE to 40. (Same
as Java). But it didn't seem to do anything for me.
Where did you add the code to set it?
I got it working. I put it in.
CMakeSwiftCompiler.cmake.in
I figured out I also needed to add:
set(CMAKE_Swift_LINKER_PREFERENCE_PROPAGATES 1)
Post by Brad King
Post by Eric Wing
Under the hood, I think the LLVM linker can handle all of these
through ld. But I think the thing that is tripping me up is that Swift
seems to need to link against some additional libraries which are not
needed in the pure C case. The swiftc command seems to know how to
automatically link in those extra dependencies (and I don't need to
add all the search paths to where the Swift core libraries are
located).
That is the same as for C++. See CMAKE_PARSE_IMPLICIT_LINK_INFO and
the call to it in "Modules/CMakeDetermineCompilerABI.cmake". That is
responsible for extracting the implicit link information passed by a
given language compiler's front-end. We'll need to extract that for
Swift.
I looked at this file, but I still havne't groked what I need to do
with this yet.

However, I'm heavily debating if 'cc' or 'clang' is the right thing to
do here. I'm starting to think 'swiftc' might be the most robust and
correct thing for the linking command. There are several reasons for
this:

- swiftc seems to already do the right thing

- Not using swiftc requires me to set a lot of things, including the
Apple SDK when on Mac. This feels really messy.

- On Linux, I think there is a danger in calling 'cc' because it could
be gcc or it could be an older version of clang. (Officially, clang
3.5 is needed, but the default one on the particular Linux I'm using
is less than that.) Invoking swiftc theoretically side-steps this
problem.


But if I use swiftc, I create a few new complications:

- 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

Again, I'm not sure where the old stuff is, and what is involved to
inject the -Xlinker stuff.


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.

However, I currently employ a clever cheat. Since the compiler is
'swift', and the linker is 'swiftc', I just do
'<CMAKE_Swift_COMPILER>c'
Post by Brad King
cmMakefileTargetGenerator::WriteObjectBuildFile
You should be able to call
this->GeneratorTarget->GetObjectSources(objectSources, config);
Okay, I added this code. It seems to be working. Though I'm not
completely sure I fetched config correctly.

My current changes can be found here in the SwiftMakefile branch
https://github.com/ewmailing/CMake/tree/SwiftMakefile
Post by Brad King
cmNinjaTargetGenerator::WriteCompileRule
cmNinjaTargetGenerator::WriteObjectBuildStatement
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?
Post by Brad King
Do we know that there is a one-to-one mapping between libraries
and Swift modules?
Sorry, I'm still not completely up to speed on Swift modules. My
impression is there are 3 parts: .swiftmodule (which contains the
public interface/definitions), .swiftdoc (for documentation), and a
library (.a, .so). I suspect the .swiftmodule will need to be part of
the compile parameters and the library will be part of the link, but
I'm not sure if there will be additional requirements.


But anyway, I would like to get something building on Linux first, so
I need to fix the swiftc/linker stuff first. Any suggestions?

Then, I would like to enhance the trivial test to support actually
using something from the intermixed C files. This means I need to add
the bridging header parameter.
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.

Thanks,
Eric
--
Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
http://public.kitware.com/mailman/listinfo/cmake-developers
Brad King
2016-01-15 20:41:31 UTC
Permalink
Post by Eric Wing
Post by Brad King
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.
Post by Eric Wing
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.
Post by Eric Wing
- 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.
Post by Eric Wing
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.
Post by Eric Wing
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?
Post by Eric Wing
Post by Brad King
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.
Post by Eric Wing
So I need a new per-target variable in CMake for this and a way to
"<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
--
Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
http://public.kitware.com/mailman/listinfo/cmake-developers
Eric Wing
2016-01-18 18:51:40 UTC
Permalink
Post by Brad King
Post by Eric Wing
Post by Brad King
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.
Post by Eric Wing
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.
Post by Eric Wing
- 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.
Post by Eric Wing
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.
Post by Eric Wing
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?
Post by Eric Wing
Post by Brad King
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.
Post by Eric Wing
So I need a new per-target variable in CMake for this and a way to
"<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
This email is intended to be positive news, though there will be a lot
of details about what still needs to be done or is not quite right
yet.

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.

I took one of my small, but non-trivial programs which does a lot with
CMake to package up resources (images, audio, etc) and set rpaths and
has lots of (C) dynamic libraries it links to which also get shipped
with the bundle to make a self-contained app (rpath), and ported the
core parts to Swift. CMake handled this pretty much transparently (had
to enable_language(Swift), set the bridging header, and there are
Swift Standard Library things to sort out later). So overall, I’m
really happy with this.



So now the details.

- 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.

- TODO: I need to look at Swift's DEFINE system.

- Link flags for -rpath are now rewritten (and -rdynamic is removed)

- Added set_target_property(my_exe SWIFT_BRIDGING_HEADER
“/foo/bar/mybridge.h”). There is a token in the .cmake description for
<Swift-BRIDGING_HEADER>, but the full flag for -import-objc-header
/foo/bar/mybridge.h is generated in the C++ side. This is because I
need to dynamically decide whether this flag gets submitted or not
based on whether a header was provided. (I can’t have a
-import-objc-header without an argument.)

- TODO: Unify SWIFT_BRIDGING_HEADER with the Xcode generator. Right
now, we rely on the user setting the Xcode property directly which has
a different name. Seems like if they set SWIFT_BRIDGING_HEADER, it
should set the Xcode one for them.

- TODO: Need to do Platform/Darwin-Apple-Swift.cmake.

- 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).


- Quirks/Bugs/Limitations about add_executable and the main symbol:

I learned a few details and there are some quirks.
Swift treats main.swift specially and will generate a main symbol.
If you have a C main function, there is an edge case bug...
If you have only 1 Swift file (and your C main), Swift will
autogenerate a main symbol for Swift. This will cause a duplicate
symbol problem and fail to link.
If you have multiple Swift files (and your C main), this will link
correctly, with the exception that you must not have a main.swift
file.

I still need to look deeper into how Xcode deals with this, but a
quick glance, and I noticed an extra build stage between the object
files and the linking. I think this extra stage in Xcode takes all the
Swift object files and makes a .swiftmodule (library?) out of them and
then may submit this to the linker. This could be the mechanism Xcode
to avoid duplicate symbol problems, though as I said, I haven’t
dissected this for real yet. But I’m thinking this may automatically
come into more focus as we work on the library/module support for
Swift.


- 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. I usually get a link
failure and a bunch of console spew which contains non-ASCII
characters and my terminal starts beeping and going crazy. It’s
unpleasant to debug. And I can’t find one real world example of using
swift for just linking. It’s either clang, ld, or swiftc. I’m also
worried about how to determine the SDK paths when I’m not using
swiftc, since I don’t provide that information explicitly when on Mac.
Interesting Trivia: The swiftc linker calls clang++ under the hood for
linking.


- Swift Standard (or Core) Libraries: Swift comes with multiple
standard libraries. There is swiftCore which I think contains a lot of
the fundamental types like Int and Double and containers like Array
and Dictionary. (It’s still fuzzy to me where the line between
language and library begins.)
https://developer.apple.com/library/ios/documentation/Swift/Reference/Swift_Int_Structure/index.html#//apple_ref/swift/struct/s:Si

Then there is Foundation which is a Swift rewrite of Apple’s Cocoa
(Obj-C) Foundation, which contains a large set of classes and
convenience methods for non-GUI stuff, like NSString, NSURL,
NSURLSession, etc. It is mostly incompletely right now on Linux.

Then they also plan to include libdispatch and XCTest.
https://swift.org/core-libraries/


Additionally, they provide a wrapper interface to the C standard
library on the platform. This library has either the darwin or glibc
name in it depending on situation. So I think something as simple as
M_PI from C’s math.h will bring in the C library dependency.


As far as I can tell, the swiftc linker knows how to automatically
link to these libraries as needed depending if your code uses them or
not. So the nice thing is that the CMake user scripts don’t currently
need you to specify anything explicitly for these libraries. However,
the one complication for me is that I am trying to ship stand-alone,
redistributable application binaries, which means I need to copy these
libraries with my application on non-Apple platforms. (I’ve already
been setting path $ORIGIN on Linux). So I think CMake should provide
some variables to the full paths to these libraries since users like
me will want to refer to them. The question is whether these are set
as part of the language bootstrap scripts, or a separate
FindSwiftCoreLibraries.cmake module the user needs to manually
include. (And unfortunately, for me, I don’t see a good way to know
which libraries I actually need to copy without running ldd on the
binary unless I know a priori. I know for now, I’m avoiding Foundation
since it is unfinished and probably going to be huge binary and I
don’t need it for my stuff.)


Thanks,
Eric
--
Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
http://public.k
Brad King
2016-01-19 16:28:59 UTC
Permalink
Post by Eric Wing
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!
Post by Eric Wing
- 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)
Post by Eric Wing
- 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.
Post by Eric Wing
- 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?
Post by Eric Wing
- 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.
Post by Eric Wing
- Swift Standard (or Core) Libraries: Swift comes with multiple
standard libraries.
[snip]
Post by Eric Wing
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
--
Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
http:/
Eric Wing
2016-01-20 13:48:59 UTC
Permalink
Post by Brad King
Post by Eric Wing
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!
Post by Eric Wing
- 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.
set(CMAKE_INCLUDE_FLAG_Swift -I)
Post by Eric Wing
- 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.
Post by Eric Wing
- 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?
Post by Eric Wing
- 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.
Post by Eric Wing
- Swift Standard (or Core) Libraries: Swift comes with multiple
standard libraries.
[snip]
Post by Eric Wing
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
--
Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
http://public.kitwar
Brad King
2016-01-20 15:15:39 UTC
Permalink
Post by Eric Wing
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.
Those are internal details of the CMAKE_DETERMINE_COMPILER_ID
function and are not meant to be set anywhere else. I think you
may be looking for something like this:

https://cmake.org/gitweb?p=cmake.git;a=blob;f=Modules/CMakeDetermineFortranCompiler.cmake;hb=v3.4.2#l122

It is used by the CMAKE_DETERMINE_COMPILER_ID_VENDOR fallback when
the compiler id cannot be extracted from the basic compiler output.
More work may be needed to also extract a version number through
the CMAKE_DETERMINE_COMPILER_ID_VENDOR infrastructure.
Post by Eric Wing
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.)
It looks like it came from your port from CMakeCInformation. The

set(CMAKE_Swift_FLAGS_INIT "$ENV{SWIFTFLAGS} ${CMAKE_Swift_FLAGS_INIT}")

line looks correct.
Post by Eric Wing
export SWIFTFLAGS='-target armv7-unknown-linux-gnueabihf'
And CMake picks it up. Is this the correct expected behavior for CMake?
Yes. One remaining question is if there is an established convention
already out there for the name of the SWIFTFLAGS environment variable.

-Brad
--
Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
http://public.kitware.com/mailman/listinfo/cmake-developers
Eric Wing
2016-01-29 20:16:26 UTC
Permalink
Post by Brad King
Post by Eric Wing
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.
Those are internal details of the CMAKE_DETERMINE_COMPILER_ID
function and are not meant to be set anywhere else. I think you
https://cmake.org/gitweb?p=cmake.git;a=blob;f=Modules/CMakeDetermineFortranCompiler.cmake;hb=v3.4.2#l122
It is used by the CMAKE_DETERMINE_COMPILER_ID_VENDOR fallback when
the compiler id cannot be extracted from the basic compiler output.
More work may be needed to also extract a version number through
the CMAKE_DETERMINE_COMPILER_ID_VENDOR infrastructure.
I need more guidance here. I'm not connecting the dots.
My problem seems to be that the execute_process() in
CMakeDetermineCompilerId.cmake is trying to invoke the command:
'swift CompilerId/main.swift'

This will cause swift to run in REPL mode which won't return.
It is not passing any of the flags I taught CMake to use when trying
to compile a Swift program.

Looking at the execute_process() that gets invoked (final one in the
big if/elseif block of CMAKE_DETERMINE_COMPILER_ID_BUILD), the only
way to get the flags I need are via CMAKE_${lang}_COMPILER_ID_FLAGS.
But there is a block at the top of the file which overwrites the
variables. I was suggesting list(APPEND) instead of set() would fix
that problem, and in fact look suspicious to me since there is no way
to access those values passed to execute_process().

if(CMAKE_${lang}_FLAGS)
#set(CMAKE_${lang}_COMPILER_ID_FLAGS ${CMAKE_${lang}_FLAGS})
list(APPEND CMAKE_${lang}_COMPILER_ID_FLAGS ${CMAKE_${lang}_FLAGS})
else()
# set(CMAKE_${lang}_COMPILER_ID_FLAGS $ENV{${flagvar}})
list(APPEND CMAKE_${lang}_COMPILER_ID_FLAGS $ENV{${flagvar}})
endif()
Post by Brad King
Yes. One remaining question is if there is an established convention
already out there for the name of the SWIFTFLAGS environment variable.
I haven't spotted anything so far. Remember that Xcode and anything
GUI based on Mac doesn't use environmental variables. So this isn't a
feature that the existing Apple community would be using.


Thanks,
Eric
--
Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
http://public.kitware.com/mailman/listinfo/cmake-developers
Brad King
2016-02-04 18:08:06 UTC
Permalink
Post by Eric Wing
I need more guidance here. I'm not connecting the dots.
My problem seems to be that the execute_process() in
'swift CompilerId/main.swift'
[snip]
Post by Eric Wing
Looking at the execute_process() that gets invoked (final one in the
big if/elseif block of CMAKE_DETERMINE_COMPILER_ID_BUILD), the only
way to get the flags I need are via CMAKE_${lang}_COMPILER_ID_FLAGS.
Some refactoring may be needed to allow language-specific behavior
to add flags that must be there for the check. Add an explicit
internal variable or other code path to support it (that is just
not set for other languages). The semantics of selecting flags
from the environment in CMAKE_${lang}_COMPILER_ID_FLAGS must not
change.

Thanks,
-Brad
--
Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
http://public.kitware.com/mailman/listinfo/cmake-developers
Eric Wing
2016-02-05 22:14:27 UTC
Permalink
Post by Brad King
Post by Eric Wing
I need more guidance here. I'm not connecting the dots.
My problem seems to be that the execute_process() in
'swift CompilerId/main.swift'
[snip]
Post by Eric Wing
Looking at the execute_process() that gets invoked (final one in the
big if/elseif block of CMAKE_DETERMINE_COMPILER_ID_BUILD), the only
way to get the flags I need are via CMAKE_${lang}_COMPILER_ID_FLAGS.
Some refactoring may be needed to allow language-specific behavior
to add flags that must be there for the check. Add an explicit
internal variable or other code path to support it (that is just
not set for other languages). The semantics of selecting flags
from the environment in CMAKE_${lang}_COMPILER_ID_FLAGS must not
change.
Thanks,
-Brad
Okay, thanks, will do.

A quick update on my progress.

- I started looking at the DEFINE system for Swift. It has a very
simplified form of what we would do in C. You can doo -DFOO for
#if FOO
// do something
#endif

But it doesn't allow for anything more complicated like values. So
this is not supported: -DFOO=1

So currently there doesn't seem to be any compiler failure, it just
doesn't do anything useful.

Currently I'm using ADD_DEFINITIONS. And that works. However, since
this blends C/C++/Obj-C/Swift into the same pool, it doesn't feel
right. (I think Xcode has separate definitions for Swift.) Right now
if I'm clever and don't pick any definitions that conflict, I can use
the system. And the more complex ones are simply ignored by Swift. But
longer term, I'm thinking these may need to be split up.


- Second, I got word from a Swift engineer that the 'swift' frontend
compiler is not a supported tool and can break the interface. I should
be using swiftc. Furthermore, I was told that the file-by-file
compilation which 'swift' allows is not really supported and the
output I'm seeing from Xcode is more debug information than what's
really going on. They seemed adamant that the all files in one-shot
via swiftc was the correct path and what I was doing was unreliable
and also loses information for the debugger and libraries.

Anyway, I'm still reflecting on this about what to do next. The
reality is that what I have right now works (for me), and solves a
bunch of problems that their current tools do not solve (Xcode is more
proof of that). The current path has pretty minimal changes to CMake
as well. I'm still reflecting and will probably need to press them for
more specifics, but based on all the realities of the situation, I'm
thinking I should press on with this initial implementation to get
something useable if not perfect. But longer term, we probably need to
look at swiftc and one-shot.
--
Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
http://public.kitware.com/mailman/listinfo/cmake-developers
Eric Wing
2016-02-29 11:59:40 UTC
Permalink
I'm finding that I'm going to need to completely separate the C FLAGS
from the Swift FLAGS. I hit some complicated situations where the C
FLAGS (both compile and linker) are confusing the process and
shouldn't be passed to Swift.

I see in the CMakeSwiftInformation.cmake, there is a
<CMAKE_Swift_LINK_FLAGS>. However, I do not see a <CMAKE_Swift_FLAGS>,
just <FLAGS>.

Additionally, in regular CMake script, I was trying to set/use
${CMAKE_Swift_FLAGS} hoping it would just work, but it doesn't seem to
have any effect. Is this something I'm going to have to implement in
the C++ core?

Thanks,
Eric
--
Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
http://public.kitware.com/mailman/listinfo/cmake-developers
Brad King
2016-02-29 15:23:27 UTC
Permalink
Post by Eric Wing
I see in the CMakeSwiftInformation.cmake, there is a
<CMAKE_Swift_LINK_FLAGS>. However, I do not see a <CMAKE_Swift_FLAGS>,
just <FLAGS>.
That <FLAGS> is implicitly the flags for the corresponding language
since it appears in the compilation rule specific to the language.
Post by Eric Wing
Additionally, in regular CMake script, I was trying to set/use
${CMAKE_Swift_FLAGS} hoping it would just work, but it doesn't seem to
have any effect. Is this something I'm going to have to implement in
the C++ core?
For the Makefile generator take a look at

cmMakefileTargetGenerator::WriteTargetLanguageFlags
cmMakefileTargetGenerator::WriteObjectBuildFile

methods. They generate a <LANG>_FLAGS variable in the makefile and
reference it. Make sure those code paths are executed for Swift.
There should be similar code for the Ninja generator too.

-Brad
--
Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
http://public.kitware.com/mailman/listinfo/cmake-developers
Loading...