The second review of SE-0387: Cross-Compilation Destination Bundles begins now and runs through May 5th, 2023.
This proposal has already been accepted in principle . We would like to keep this review focused on Cross-Compilation Triples Nomenclature:
Here is the proposal from @Max_Desiatov:
Cross-Compilation Triples Nomenclature
Alternatives Considered So Far
In the original text of SE-0387 proposal we used “build-time triple” and “run-time triple” nomenclature instead of “host triple” and “target triple”, as was previously established by LLVM/Clang and ad-hoc cross-compilation support in Swift. Main motivation for that was to avoid possible confusion, due to “target” having a different meaning in the context of SwiftPM and build systems in general.
Specifically in SwiftPM, we’d like to keep open a future direction where users can specify a triple they’re building for in each build system target declaration. Suppose one would want to build a compiler with SwiftPM this way:
targets: [
.target(
name: "clang",
triple: .host
),
.target(
name: "compiler-rt",
triple: .target
),
// ...
]
Notice that .target
would have different meaning in each context, either a build system target passed in an array as a targets
argument to Package
initializer, or .target
as a way to specify a triple of the machine this target is built for. We’d like to avoid ambiguity both in the package manifests and in colloquial use of the nomenclature when talking about cross-compilation in SwiftPM.
During SE-0387 review some aslo argued that “build-time triple” and “run-time triple” were unclear and a break from established convention was unexpected. On the other hand, we also received feedback on inconsistency between the convention used CMake/LLVM/Clang (“host”/“target”) and a convention used by GCC, Autotools, and subsequently picked up by the Meson build system (“build”/“host“).
Nomenclature Comparison for Basic Cross-Compilation
To address this feedback we also considered alternative naming that breaks away from these conventions and also avoids possible confusion with the “target” term used by SwiftPM already in Package.swift
manifests. In this alternative nomenclature:
- a builder is a machine that builds code
- an executor is a on which code generated by the builder is executed.
One downside of this approach is that “executor” is ambiguous with previously proposed actor executors in Swift. On the other hand, Swift Concurrency and cross-compilation support in SwiftPM are different enough contexts, so possible ambiguity in “executor” usage is less likely than with the “target” term.
For a basic cross-compilation scenario that SE-0387 is focused on, a comparative nomenclature table looks like this:
GCC/Autotools/Meson | LLVM/Clang/CMake | Original Proposal Text | Alternative |
---|---|---|---|
build | host | build-time triple | builder |
host | target | run-time triple | executor |
Canadian Cross
Another aspect of feedback received during SE-0387 review was related to a so called Canadian Cross scenario. In this case an intermediate platform is used for cross-compilation when the original platform is too slow to build the compiler itself.
For example instead of building on Raspberry Pi a Swift compiler that can cross-compile to x86 Linux, one may prefer to build that compiler on M2 Mac much more quickly than building it on the Raspberry Pi itself.
In this example M2 Mac building the compiler would be called a build platform and Raspberry Pi running the compiler would be called a host platform, by both GCC and LLVM/Clang.
The alternative nomenclature of builder and executor platforms could be extended with a runnerplatform, which is an intermediate platform running the compiler. Here’s the comparative nomenclature table updated for Canadian Cross:
GCC/Autotools/Meson | LLVM/Clang/CMake | Original Proposal Text | Alternative |
---|---|---|---|
build | build | build-time triple | builder |
host | host | N/A | runner |
target | target | run-time triple | executor |
Summary
The original SE-0387 proposal text did not consider more complex scenarios, but we’d like to make sure that the nomenclature we use is consistent. We feel that formalizing cross-compilation in SwiftPM is a good opportunity to make it less ambiguous. From that perspective builder/runner/executor matches that criteria and is proposed to the community for additional review.
We’d also like to gather more feedback on each of these variants, taking into account all the pros and cons:
- GCC/Autotools nomenclature is quite widely established on platforms where these are the default build tools, although they may be less familiar to developers targeting Darwin platforms. In Canadian Cross scenarios the appearance of “target platform” introduces possible confusion with SwiftPM package manifest targets.
- LLVM/Clang/CMake nomenclature is what Swift developers may already be used to, with the downside of “target” term used more frequently, which means that there’s a bigger risk of ambiguity. On the other hand, sticking to this nomenclature means less churn in our documentation and code. Additionally, consistency with LLVM, Clang, and CMake are important factors too.
- “Build-time triple” and “run-time triple” terms introduced in the original proposal text seem a bit more verbose, and they did receive some negative feedback. We also haven’t found a good counterpart term for an intermediate platform in Canadian Cross scenarios.
- “Builder”, “runner”, and “executor” are completely new terms we’re considering here. While this may make them more easily searchable, it also means we’re not following existing conventions. The fact that Swift Concurrency also uses “executors” introduces its own ambiguity, which we think is less harmful than the ambiguity in the use of the term “target”.