mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Create CrossCompilationModel.md
Add some documentation to describe the proposed model for cross-compilation, associated flags, and the reasoning for the structure. This should allow us to have a reference for the design allowing us to evolve the model. Co-authored-by: Evan Wilde <ewilde@apple.com> Co-authored-by: Alexander Smarus <bender@readdle.com> Co-authored-by: Danielle <dani@builds.terrible.systems>
This commit is contained in:
104
docs/CrossCompilationModel.md
Normal file
104
docs/CrossCompilationModel.md
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
|
||||||
|
# Cross-Compilation Model
|
||||||
|
|
||||||
|
## Components
|
||||||
|
|
||||||
|
When compiling Swift code, the compiler will consult three different sources of
|
||||||
|
inputs outside of the user provided code.
|
||||||
|
|
||||||
|
1. Compiler Resources
|
||||||
|
2. System (C/C++) Headers (Platform SDK)
|
||||||
|
3. Platform Swift Modules (Swift SDK)
|
||||||
|
|
||||||
|
These pieces compose in a particular manner to build a system image to build
|
||||||
|
code against.
|
||||||
|
|
||||||
|
The compiler resources are content shipped with the toolchain and are tied to
|
||||||
|
that specific version and build of the compiler. In the case of the Swift
|
||||||
|
compiler, this includes the Swift shims. Whilst this is a compiler resource, the
|
||||||
|
packaging may not necessarily be part of the toolchain due to interdependencies.
|
||||||
|
Some of this content is required to process the system headers themselves (e.g.
|
||||||
|
clang's builtin resource headers).
|
||||||
|
|
||||||
|
The C/C++ system headers (and libraries) are what is traditionally called the
|
||||||
|
Unix "sysroot". On most Unix systems, this is the set of headers that are
|
||||||
|
associated with the system library set which normally may be found in
|
||||||
|
`/usr/include`. On Darwin, this is included in the unified SDK which is shipped
|
||||||
|
to the user, while on Windows, this is called the Windows SDK, which is a
|
||||||
|
separate installable component. For simplicity, we will refer to this as the
|
||||||
|
Platform SDK universally.
|
||||||
|
|
||||||
|
The Swift SDK contains the libraries and overlays that provide the core
|
||||||
|
language runtime and expose system libraries to Swift code in an ergonomic
|
||||||
|
manner. This may be in the form of API Notes, module maps, wrapper types, or
|
||||||
|
Swift `extension`s, or entire libraries. This code may or may not be fully
|
||||||
|
inlined into the client code and thus be part of the platform ABI. In some
|
||||||
|
distributions, the Swift SDK and Platform SDK are combined where the system C,
|
||||||
|
C++, and Swift libraries are shipped together, such as the SDKs for the Apple
|
||||||
|
platforms.
|
||||||
|
|
||||||
|
## Flags
|
||||||
|
|
||||||
|
The compiler resources are controlled via the driver flag `-resource-dir`. This
|
||||||
|
allows the driver to select the correct location in most cases while allowing
|
||||||
|
the developer control to override the value if required. Normally, you should
|
||||||
|
not need to set this flag as the location of these files is intrinsic to the
|
||||||
|
compiler.
|
||||||
|
|
||||||
|
The Platform SDK contains C/C++ content which is actually consumed through the
|
||||||
|
clang importer rather than the Swift compiler. The Swift toolchain uses clang as
|
||||||
|
the C/C++ compiler on all platforms as it is embedded to generate inline foreign
|
||||||
|
function interface (FFI) to enable seamless C/C++ bridging to Swift. The flag
|
||||||
|
used by clang is derived from the GCC toolchain, and is spelt `--sysroot`. The
|
||||||
|
compiler driver is responsible for identifying the structure of the sysroot.
|
||||||
|
When cross-compiling, there isn't a consistent location for these files, so the
|
||||||
|
driver must expose an argument to specify where to find these files.
|
||||||
|
|
||||||
|
On Darwin platforms, the Platform SDK and Swift SDK are shipped combined into a
|
||||||
|
single SDK. As a result the singular `-sdk` flag allows control over the
|
||||||
|
Platform SDK and Swift SDK. Windows uses a split model as the Windows SDK is
|
||||||
|
split into multiple components and can be controlled individually (i.e. UCRT
|
||||||
|
version, SDK version, VCRuntime version). The `-sdk` flag is used to specify the
|
||||||
|
location of the Swift SDK which is merged with the Platform SDK. By default, the
|
||||||
|
environment variable `SDKROOT` is used to seed the value of `-sdk`, though the
|
||||||
|
user may specify the value explicitly. Other platforms do not currently have a
|
||||||
|
flag to control this location and the toolchain defaults to a set of relative
|
||||||
|
paths to locate the content. This prevents cross-compilation as the included
|
||||||
|
content would be for a single platform.
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> `-resource-dir` historically influenced the driver's search for the SDK content, locating the standard library relative to the resource directory. This behaviour is considered deprecated but remains for compatibility. The `-sdk` parameter is given precedence and is the preferred mechanism for controlling the behaviour of the driver to locate the SDK content.
|
||||||
|
|
||||||
|
## Solution
|
||||||
|
|
||||||
|
Generalising the above structure and sharing the common sharing gives way to the
|
||||||
|
following set of flags for cross-compilation:
|
||||||
|
|
||||||
|
1. `-target`: specifies the triple for the host
|
||||||
|
2. `-sysroot`: specifies the Platform SDK for the host platform content
|
||||||
|
3. `-sdk`: specifies the Swift SDK for the host
|
||||||
|
|
||||||
|
The values for these may be defaulted by the driver on a per-platform basis.
|
||||||
|
|
||||||
|
The `-sysroot` flag identifies the location for the C/C++ headers and libraries
|
||||||
|
required for compilation. This is primarily used by non-Darwin, non-Windows
|
||||||
|
hosts as Darwin has its own SDK concept that allows for co-installation and
|
||||||
|
Windows uses a different model which merges multiple locations in memory.
|
||||||
|
|
||||||
|
The `-sdk` flag identifies the location of the Swift SDK, which provides the
|
||||||
|
necessary content for Swift compilation (including binary swiftmodules). This
|
||||||
|
includes the standard library and the core libraries (dispatch, Foundation, and
|
||||||
|
possibly XCTest - Windows isolates XCTest from the rest of the SDK). The Swift
|
||||||
|
shims are also provided by this location as they are a dependency for properly
|
||||||
|
processing the Swift core library.
|
||||||
|
|
||||||
|
## Compatibility
|
||||||
|
|
||||||
|
In order to retain compatibility with older toolchain releases which did not
|
||||||
|
include support for the `-sysroot` flag, the driver shall default the value to
|
||||||
|
the value provided to `-sdk`. This allows us to transition between the existing
|
||||||
|
toolchains which expected a single root containing all the necessary components.
|
||||||
|
This allows the driver to make the most appropriate choice for the host that is
|
||||||
|
being compiled for without loss of generality. A platform may opt to ignore one
|
||||||
|
or more of these flags (e.g. Windows does not use `-sysroot` as the system
|
||||||
|
headers are not organised like the traditional unix layout).
|
||||||
Reference in New Issue
Block a user