I’m trying to use CMake to build a Swift program, because SwiftPM using C++ libraries with SwiftPM on Windows seems more difficult, but I’m running into trouble.
$ swiftc --help
...
-static-executable Statically link the executable
-static-stdlib Statically link the Swift standard library
-static Make this module statically linkable and make the output of -emit-library a static library.
...
Are you compiling on Windows? I copied your example exactly on Linux and did not experience any problems. Maybe @compnerd could speak to this if you’re on Windows…
The log indicates that the build is for Linux. It appears as though CoreFoundation is missing. This is odd because we have at least two ways to indicate the dependency: either the extension we use in swift (swift-autolink-extract) or the response file we inject for static linking. I would be recommend investigating that linker invocation and why neither of those are triggering the link dependency.
Did you do so with CMake/ninja or just by manually passing in the source file yourself?
@needlesslygrim, as Saleem says, something is going wrong when linking. I tried running basically the same command in one line, swiftc -v Main.swift -static-stdlib, and didn't have an issue. However, if you examine the output there, you will see a bunch of Swift runtime libraries automatically added:
My guess is that CMake's Swift support either doesn't properly work with the Swift compiler's support for linking against the static stdlib, so CMake sets up ninja to separately compile your code then link it and loses that linker info, or the way you are configuring it is unexpected. Maybe @etcwilde, who added some Swift support to CMake, can chime in.
When I originally added the support for Swift in CMake there wasn't anything specific for the static standard library. The reason for that is that the support for it is pretty much entirely on the driver side, the user simply passes in -static-stdlib. This mirrors how C++ is handled: -static-stdlibc++. Neither of these are explicitly added into CMake, it is a user controllable behaviour with the standard CMAKE_Swift_FLAGS or CMAKE_CXX_FLAGS property.
I do wonder if we accidentally broke this configuration with recent refactorings. It would be interesting to know if CMAKE_Swift_FLAGS vs CMAKE_EXE_LINKER_FLAGS makes a difference. But, really, this is difficult to judge without the actual linker invocation.
If it worked before, that may be the case. It is easy to reproduce his linker error, as CMake is configuring Swift to build that object file first, then link it separately, so I'm able to reproduce his error manually by doing something similar, ie swiftc -c Main.swift && swiftc Main.o -static-stdlib. I notice now that if I change it to add -static-stdlib to the first command too, it works, so maybe the target_compile_options doesn't work for Swift with certain versions of CMake?
@needlesslygrim, please check if that compile flag is passed in with ninja -v and if not, let us know which version of CMake isn't doing that, as Jesse said your config worked for him.
Sorry for the slow reply. Unfortunately, the behaviour is extremely odd. I just ran ninja -v again to test, and it failed running this command: /home/needlesslygrim/.local/share/swiftly/bin/swiftc -j 16 -num-threads 16 -emit-executable -o broken CMakeFiles/broken.dir/Main.swift.o -static-stdlib
However, I then ran ninja clean and ninja -v, and it works???
Additionally, it seems to be working on my Desktop as well now (although I was using the Fedora repo version of Swft there and update in between so that could be the reason). I guess this is solved then?
I do wonder if the Fedora repo version was the issue then. I have tried to use it before and run into some strange behaviors myself, before just switching to Swiftly and using the rhel-ubi9 tool chain.