Previously we used separate placeholders for builtin linker flags:
* CMAKE_<LANG>_LINK_FLAGS for EXECUTABLEs
* CMAKE_SHARED_LIBRARY_CREATE_<LANG>_FLAGS for SHARED libraries
* CMAKE_SHARED_MODULE_CREATE_<LANG>_FLAGS for MODULE libraries
These are now always replaced by the empty string, so drop them
from our rule variables.
The `CMAKE_SHARED_LIBRARY_<LANG>_FLAGS` placeholder is meant for flags
used to compile sources meant for a shared library. It is used for
C/CXX to add PIC flags. It is not documented for public use, and we do
not populate it for Swift anyway.
The linker configuration file is now optional: It is loaded only if
variable CMAKE_<LANG>_USE_LINKER_CONFIGURATION is set to TRUE.
The file CMakeAddNewLanguage.txt is updated to take into account the
linker configuration.
Fixes: #26393
Setting `CMAKE_INSTALL_NAME_DIR` or the `INSTALL_NAME_DIR` on Swift
targets had no effect when CMP0157 was set to `NEW`. This was a result
of missing the `<TARGET_INSTALLNAME_DIR>` before the `<TARGET_SONAME>`.
Fix that and add a test to verify that the install name directory is
included in the install name.
Fixes: #26175
A new set of files are dedicated to linker configuration.
This set of files enable a fine-tuned configuration based of the linker
type as identified during compiler detection.
Fixes: #25360
Wire up the flags needed to support module libraries built and used with
Swift. We need to pass `-bundle` to the linker when linking module
libraries on Darwin, and we need to pass `-export-dynamic` to the linker
when emitting an executable that exports symbols on Linux. This patch
wires up `CMAKE_SHARED_MODULE_CREATE_Swift_FLAGS` and
`CMAKE_SHARED_MODULE_LOADER_Swift_FLAG` on Darwin, and hooks up
`CMAKE_EXE_EXPORTS_Swift_FLAG` on Linux in order to support passing
things correctly.
We can't expose `CMAKE_EXE_LINKER_FLAGS` to Swift, as it contains flags
that the Swift compiler doesn't recognize, but the other
language-specific variables are safe to expose.
This was accidentally removed when the command templates were
reorganized to introduce the new policy. Restore the flag in the shared
library creation to ensure that we emit the import libraries to the
correct location.
Splitting the Swift build into an object build and a separate link step,
instead of building and linking in one step. The immediate benefit is
LSP support because we are able to emit compile-commands for Swift files
now. Additionally, it is possible to specify flags to the compile step,
enabling folks to emit C and C++ headers from their Swift builds for
C/C++ interop, without needing custom commands. Eventually, this gives
us a path toward working object libraries.
Object Libraries:
- Object libraries don't work today because CMake doesn't emit targets
for object libraries into the Ninja build file.
- tl;dr: Object libraries work if they aren't WMO. Still need work to
make WMO'd object libraries work.
Object libraries still don't completely work with this patch because,
while we emit the targets, the `TARGET_OBJECTS` generator expression
expansion has a separate mechanism for determining what the names of
the objects are based on the input source files, so targets that
depend on an object library built with a whole-module optimization
will depend on objects based on the name of the source file instead
of the actual emitted object file.
These features require being able to accurately model wholemodule builds
though, because we actually need to track object files and WMO affects
what objects are emitted. For that, we require CMP0157 use the NEW
policy. When it's OLD, we have to fall back on the old behavior and
cannot provide object libraries or the compile-commands for LSP.
Issue: #25308
Add a `CMAKE_Swift_COMPILATION_MODE` variable and corresponding
`Swift_COMPILATION_MODE` target property to control the compilation
mode. Select among `wholemodule`, `singlefile`, and `incremental`.
Add policy CMP0157 to remove the default `-wmo` flags in favor of the
abstract setting.
Issue: #25366
The `-wmo` flag added by commit 6063428de7 (Swift: Update default build
flags, 2022-10-03, v3.26.0-rc1~585^2~1) behaves differently with the old
driver. Detect when the old driver is being used, and avoid adding that
flag.
Fixes: #24641
When building on Windows, pass `-debug` to the linker to emit the PDB
(or `-debug:dwarf` when building with lld and using DWARF). We would
previously not do this which meant that we never emitted the debug
information making debugging more difficult.
Fixes: #24423
This patch adds support for tracking the swiftmodules for executables
exporting symbols.
This fixes a bug in the earlier implementation around emitting the
swiftmodule. Previously, the code would use
`CMAKE_EXE_EXPORTS_Swift_FLAG` to inject the `-emit-module`, and module
path information into the `CMAKE_Swift_LINK_EXECUTABLE` rule. Because
Swift skips the build step and only runs during the link phase, these
flags were injected in `cmNinjaNormalTargetGenerator::ComputeLinkCmd`
instead of `cmLocalGenerator::GetTargetFlags` where it is done normally.
Unfortunately, injecting in `ComputeLinkCmd` didn't do anything because
we have a `linkCmd` so `ComputeLinkCmd` exits early, before the
EXE_EXPORT flags get added to the link command.
Instead of playing with that flag, CMake checks
`CMAKE_Swift_LINK_EXECUTABLE_WITH_EXPORTS` and uses that as the link
rule if it exists and falls back on `CMAKE_Swift_LINK_EXECUTABLE`. I've
defined that variable in terms of `CMAKE_Swift_LINK_EXECUTABLE` with the
necessary additional flags for emitting the swift module instead. This
has the same end effect as the desired behavior, but simplifies things a
bit.
Since we're generating the swiftmodule for executables with exports,
I've also updated the dependency graph to include the swiftmodule as an
output in the build dependency graph if the executable has exports.
Tests updated:
- RunCMake/NoWorkToDo:
Ensure that the build graph does not result in unnecessary rebuilds
with exporting executables.
- SwiftOnly:
Ensure that we can consume functions defined in the executable by a
library getting linked into said executable.
Without this, building a shared Swift library with `CMAKE_SYSTEM_NAME=iOS`
produces the error `ld: unknown option: -soname`. iOS is an Apple platform,
and so should use the `-install_name` option.
Swift is used as the linker for non-swift files because it needs to pull
files like swiftrt.o in when swift symbols are present to ensure that
the swift runtime is linked.
The swift driver uses clang as the underlying linker, which pulls in
crtbegin.o and friends when appropriate, so using Swift as a linker for
C/C++ libraries is fine.
The output-file-map was getting passed to all Swift invocations,
regardless of whether or not we generated one. This patch changes it so
that we only include the output-file-map in the Swift compiler
invocation if we have actually generated the file.
Fully-optimized builds should be using whole-module optimizations(WMO)
to get all the optimizations the compiler can do for a given module.
As such, it makes sense for the release builds to pass
`-whole-module-optimization` or `-wmo` to the compiler by default.
`-whole-module-optimization` and `-wmo` are aliased and have the same
impact on the build.
Removing `-incrementa' from the `CMAKE_Swift_CREATE_*` variable:
WMO is incompatible with incremental builds, so it is removed to avoid
warnings from the Swift compiler.
Pass `-num-threads` to the driver in `CMAKE_Swift_CREATE_*`:
WMO doesn't use the `-j` flag, but instead uses `-num-threads` to get
parallelism. The two flags are applied in mutually exclusive contexts,
so `-j N` is a no-op in WMO, while `-num-threads` is a no-op in other
modes. Passing both at the same time will catch both cases without
negatively impacting the other case.
By default no `-O...` flag is specified for Debug configuration for
Swift so Xcode adds a (wrong) `-O` flag that prevents one from accessing
variables while debugging. Add `-Onone` to the Swift Debug
configuration to avoid this.
Fixes: #23818
Currently, this feature is only supported on ELF platforms. So, the property
LINK_WHAT_YOU_USE will be ignored for other plateforms.
Moreover, flags and commands are now controled by CMake variables.
Fixes: #20174
The configuration previously handled Linux properly but did not function
on macOS as `ld64` does not support `:` delimited paths. Account for
that by setting it to the empty string which will use multiple
invocations of the `-Xlinker -rpath -Xlinker ...` pattern to compute the
correct RPATH.
This adds logic to properly handle Swift executables. Only executables
marked as exporting symbols will now generate module interfaces for the
executable.
This moves the definition of the import library flags for Windows into a
platform specific file (much like the Darwin `-sdk` flag). This is in
preparation for re-use of the flag to make the flags handling for
executables more precise.
Darwin also has the concept of RPATH. Additionally, the flag is
identical to that on other Unixish platforms. Simply avoid the `-rpath`
handling on Windows.
This enables the use of `BUILD_WITH_INSTALL_RPATH` and `INSTALL_RPATH`
with Swift targets on Darwin.
Adjust the shared object rule to ensure that we honour the
`INSTALL_NAME_DIR` property on Swift targets. This enables the use of
`INSTALL_NAME_DIR` and `BUILD_WITH_INSTALL_NAME_DIR` on Darwin with
Ninja.
Define the RPATH separator to `:` so that CMake can reserve room to edit
the ELF RPATH at install time. This enables the use of `BUILD_RPATH` and
`INSTALL_RPATH` with differing values.
`-num-threads` is for the threading, not the job control. Use `-j` to
launch the parallel jobs. This enables parallel builds for Swift again
after driver updates preventing the parallelization through
`-num-threads`.
The rules did not account for the import library location (through
`<TARGET_IMPLB>`) and instead would always write the import library to
the default location (next to the shared library/executable). This
prevented the use of `CMAKE_RUNTIME_OUTPUT_LOCATION` and
`CMAKE_ARCHIVE_OUTPUT_LOCATION`.
This enables the use of MSVC and Swift on Windows in a single project.
MSVC uses no flag to indicate linked libraries while Swift uses `-l`.
Add support for a language specific link library flag which takes
precedence over the global `CMAKE_LINK_LIBRARY_FLAG` which preserves
compatibility with earlier releases.
The Swift driver recently learnt how to generate static libraries using
the `-static` flag. This enables us to generate proper static libraries
with dependency tracking with Swift as well.
This changes the behaviour of the generators to use a per-language
library search path flag. This is needed for multi-language projects
with different compilers (e.g. cl + gfortran). Since the adjusted
variable has been part of the user settings, we control this based on a
policy.
Fixes: #19307