Re-examining meaning of global options in cross-compilation contexts
Since the host/target split is new for SwiftPM I think it's a good time to re-visit meaning and structure of affected command options such as --sdk
, --toolchain
, --triple
and various -X
options. This post is also inspired by plugins: Global compiler flags should not be used for plugin dependencies by euanh · Pull Request #7549 · apple/swift-package-manager · GitHub (authored by euanh), which was aimed at fixing a case hit when attempting to cross compile.
First regarding terminology - I use "host" and "target" platforms because that's the terminology that has been agreed upon during the review of the cross-compilation sdk proposal. In particular the following sentence from the acceptance announcement:
We elected to use
host
andtarget
when specifying cross compilation andhost
,build
andtarget
when using Canadian Cross.
Cross compilation complicates the existing options - a module can now be built for both the host and the target depending on the context, completely transparently to the user. For example, a target
could have a macro dependency which would mean that it has to be built for the host. Some other non-macro/plugin module could depend on that target
at the same time, so it would then have to be built for the target platform as well. Note that plugins, macros, and test targets that directly depend on macros, are always built for the host.
Let’s start with -X
options. Currently only Swift language options support host/target separation by means of -Xbuild-tools-swiftc
prefix although how that actually behaves is not well-documented at the moment. Currently -Xswiftc
applies to all builds and -Xbuild-tools-swiftc
applies to manifest, plugins, but not macros. At the same time, such capability doesn't exist at all for cc
, cxx
, and linker
flags.
--sdk/--toolchain
options were originally added as an early form of cross-compilation and were hidden from the help output. When switching to swift-argument-parser, that was no longer the case (no hidden
was added), but they still have no documentation. Both only apply to target.
--triple
applies to the target only and can be useful in cross-compiling scenarios where a separate SDK/toolchain isn’t needed.
I’d like to propose leaving --sdk
/--toolchain
as is for now (and perhaps deprecating for --swift-sdk
in the future), --triple
being renamed to --target-triple
(deprecating --triple
), and renaming the other options through either:
-X{cc, cxx, swiftc, linker}
are applicable to all contexts-Xhost-{cc, cxx, swiftc, linker}
, only applicable to host platform related builds (including macros) and override-X
options.-Xtarget-{cc, cxx, swiftc, linker}
, only applicable to target platform related builds (not macros) and override-X
options.
-X{cc, cxx, swiftc, linker}
are applicable only to target context (not macros)-Xhost-{cc, cxx, swiftc, linker}
could be used to specify host specific values if required (including macros).- Optional: Deprecate
-X
and--triple
in favor of verbose-Xtarget-{cc, cxx, swiftc, linker}
.
With my preference being towards option 1, since it seems like the most intuitive and backward compatible approach.
Please share your thoughts!