On 1/12/16, Brad King <brad.k...@kitware.com> wrote: > On 01/08/2016 06:15 PM, Eric Wing wrote: >> 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-developers