You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
**⚠️ Embedded Swift is experimental. This document might be out of date with latest development.**
4
+
5
+
**‼️ Use the latest downloadable 'Trunk Development' snapshot from swift.org to use Embedded Swift. Public releases of Swift do not yet support Embedded Swift.**
6
+
7
+
For an introduction and motivation into Embedded Swift, please see "[A Vision for Embedded Swift](https://github.com/apple/swift-evolution/blob/main/visions/embedded-swift.md)", a Swift Evolution document highlighting the main goals and approaches.
8
+
9
+
## Embedded Standard Library Breakdown
10
+
11
+
This status table describes which of the following standard library features can be used in Embedded Swift:
12
+
13
+
|**Swift Standard Library Feature**|**Currently Supported In Embedded Swift**|
# Embedded Swift -- Integrating with embedded SDKs
2
+
3
+
**⚠️ Embedded Swift is experimental. This document might be out of date with latest development.**
4
+
5
+
**‼️ Use the latest downloadable 'Trunk Development' snapshot from swift.org to use Embedded Swift. Public releases of Swift do not yet support Embedded Swift.**
6
+
7
+
For an introduction and motivation into Embedded Swift, please see "[A Vision for Embedded Swift](https://github.com/apple/swift-evolution/blob/main/visions/embedded-swift.md)", a Swift Evolution document highlighting the main goals and approaches.
8
+
9
+
The following document sketches how to integrate Swift code into some popular embedded platforms' SDKs and build systems.
10
+
11
+
## Integrating with Raspberry Pi Pico (W) build system:
Copy file name to clipboardExpand all lines: docs/EmbeddedSwift/UserManual.md
+71-29Lines changed: 71 additions & 29 deletions
Original file line number
Diff line number
Diff line change
@@ -33,42 +33,42 @@ Most of these steps are out of scope for this document, instead refer to the ven
33
33
A basic way to build a set of Swift source files in Embedded Swift mode, is to simply give the compiler (1) a target triple, (2) the `-enable-experimental-feature Embedded` flag, (3) the set of source files that form the input module:
The target triple also decides whether whether the output object file will be an ELF file, or a Mach-O. For example:
40
+
## Examples
41
+
42
+
### Building Swift firmware for an embedded target
43
+
44
+
To build Swift firmware (for now ingnoring integration with SDKs, libraries and other pre-existing C code), we can use the `-target` argument to specify the CPU architecture. The target triple also decides whether the output object file will be an ELF file, or a Mach-O. For example:
Additionally, you probably want to specify additional Clang and/or LLVM flags to get the compiler to produce code for the exact ISA and ABI you need for your target. For example, a Raspberry Pi Pico / Pico W expects the `-mfloat-abi=soft` Clang option, and if you want to match ABI with libraries built with the GNU toolchain, you might also need `-fshort-enums`. To pass those to Swift, use the `-Xcc` prefix:
56
+
Additionally, you probably want to specify additional Clang and/or LLVM flags to get the compiler to produce code for the exact ISA and ABI you need for your target.
57
+
58
+
For example, a Raspberry Pi Pico / Pico W should target the ARMv6-M architecture via the `armv6m-*` target triple, but the `-mfloat-abi=soft` Clang option should also be used, and if you want to match ABI with libraries built with the GNU toolchain, you might also need `-fshort-enums`. To pass those to Swift, use the `-Xcc` prefix:
53
59
54
60
```bash
55
61
# To build an ELF object file for ARMv6-M with soft float ABI (floating-point arguments passed in integer registers) and "short enums":
This might not be obvious: `-Xcc` flags are typically only used to alter behavior of the Clang importer, but passing flags to Clang this way also works to specify LLVM target options like selecting a specific CPU architecture (`-march`, `-mcpu`, `-mmcu`), FPU unit availability (`-mfpu`), which registers are used to pass floating-point values (`-mfloat-abi`), and others.
62
68
63
-
## Examples
64
-
65
-
### Building a pure Swift firmware for an embedded target
66
-
67
-
TODO
68
-
69
69
### Integrating with embedded SDKs and build systems
70
70
71
-
TODO
71
+
For details and concrete examples of how to integrate with existing SDKs, see [Embedded Swift -- Integrating with embedded SDKs](IntegratingWithSDKs.md).
72
72
73
73
### Building a macOS Embedded Swift program:
74
74
@@ -109,30 +109,72 @@ Features that are not available:
109
109
-**Not available**: Metatypes, e.g. `let t = SomeClass.Type` or `type(of: value)` are not allowed.
110
110
-**Not available yet (under development)**: The print() function for types other than StaticString and integers.
111
111
-**Not available yet (under development)**: String. (StaticString **is** available).
112
-
-**Not available yet (under development)**: Set.
113
-
-**Not available yet (under development)**: Dictionary.
112
+
-**Not available yet (under development)**: Swift Concurrency.
113
+
114
+
For a more complete list of supported features in Embedded Swift, see [Embedded Swift -- Status](EmbeddedSwiftStatus.md).
114
115
115
116
## Libraries and modules in Embedded Swift
116
117
117
-
TODO
118
+
Traditional library build and use model of Swift is that library code is compiled into a .swiftmodule, containing the interfaces, and a compiled library with binary code, either a .a static library or a .dylib/.so dynamic library. A client's build then uses the .swiftmodule at compile-time, and the static/dynamic library at link-time.
118
119
119
-
## Allocating and non-allocating Embedded Swift mode
120
+
The library model in Embedded Swift works slightly differently: All Swift source code of a library is promoted into being inlineable and visible to client builds (this is necessary for generic code, and beneficial for optimizations for non-generic code), and ends up serialized into the .swiftmodule, the interface of the library. Therefore, the compiled code of a library is never needed, and doesn't even need to be produced. For example:
120
121
121
-
TODO
122
+
```
123
+
# Build the library, only as a .swiftmomodule. Notice that we never build the .o or .a for the library.
The Embedded Swift standard library is distributed in the toolchain the same way: It's strictly a .swiftmodule without any compiled code present anywhere. All the compiling into machine code is performed as part of the client's build. This has the major benefit that the client's build can provide additional ABI and ISA defining flags, such as the above-mentioned `-mfloat-abi`, `-fshort-enums`, `-mcpu`, `-march` flags, and these flags in the client's build will apply to all the library code (including standard library code) as well.
126
133
127
-
## External dependencies
134
+
## Allocating and non-allocating Embedded Swift mode
135
+
136
+
Embedded Swift does allow instantiating and using reference types (classes) which are refcounted objects allocated on the heap. A common case of needing those is for dynamic containers like arrays and sets (they use dynamically-sized heap-allocated class instances as their storage). Outside of creating class instances and explicitly calling allocation APIs (e.g. `UnsafeMutablePointer.allocate()`), Embedded Swift does not perform allocations or cause heap usage.
128
137
129
-
Embedded Swift minimizes external dependencies, but they still exist. In Embedded Swift compilation mode, the compiler only triggers external dependencies based on actual usage of the program under compilation. The following table lists which situations cause which external dependencies:
138
+
Some embedded platforms don't have and/or don't want *any heap allocations whatsoever* and don't provide a heap at all. The `-no-allocations`compiler flag can be used to match that, which will cause the compiler to produce an error at compile time when creating class instances or calling allocation APIs.
test.swift:1:37: error: cannot use allocating operation in -no-allocations mode
145
+
```
146
+
147
+
## External dependencies
137
148
138
-
The user and/or the platform is expected to provide these well-known APIs.
149
+
Embedded Swift minimizes external dependencies (i.e. functions that need to be available at link-time), but they still exist. There are generally two categories of dependencies: (1) functions that the Swift standard library or Embedded Swift runtime need to call, and (2) functions/symbols that are implicitly added by LLVM and the compiler pipeline.
150
+
151
+
For (1), external dependencies are only used based on actual usage of the program under compilation:
152
+
153
+
- instantiating a class, or using UnsafeMutablePointer.allocate()
For (2), external dependencies are also triggered by specific code needing them, but they are somewhat lower-level patterns where it might not be obvious that such patterns should cause external dependencies:
162
+
163
+
-**basic memory copying and zeroing functions**
164
+
- usage added for a variety of reasons (e.g. using structs on the stack)
0 commit comments