Skip to content

Commit 3eef2a6

Browse files
incertumal45tair
andcommitted
[static-linux-sdk] Update "Getting Started with the Static Linux SDK"
Enhance clarity and transparency by adding more details about dependency management when using the Static Linux SDK, especially regarding the dependencies bundled with it. Co-authored-by: Alastair Houghton <[email protected]> Signed-off-by: Melissa Kilby <[email protected]>
1 parent 8d03373 commit 3eef2a6

File tree

1 file changed

+78
-2
lines changed

1 file changed

+78
-2
lines changed

documentation/articles/static-linux-getting-started.md

Lines changed: 78 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
layout: page
33
date: 2024-06-04 12:00:00
44
title: Getting Started with the Static Linux SDK
5-
author: [al45tair]
5+
author: [al45tair, incertum]
66
---
77

88
It's well known that Swift can be used to build software for Apple
@@ -24,6 +24,16 @@ with no external dependencies at all (not even the C library), which
2424
means that it will run on _any_ Linux distribution as the only thing
2525
it depends on is the Linux system call interface.
2626

27+
This portability comes at a cost, namely that everything your program
28+
depends on must be statically linked. There is no support for dynamic
29+
linking whatsoever — even the `dlopen()` function will not work.
30+
31+
A result of this design choice is that the Static Linux SDK uses a
32+
“bring your own dependencies” model, similar to that you might be used
33+
to with the Swift Package Manager. You cannot use system libraries,
34+
but must either rely on the handful of common libraries supplied with
35+
the Static SDK (see below), or build any extras yourself.
36+
2737
Additionally, the Static Linux SDK can be used from any platform
2838
supported by the Swift compiler and package manager; this means that
2939
you can develop and test your program on macOS before building and
@@ -255,7 +265,7 @@ in another, or a pointer type will be imported as `OpaquePointer`
255265
rather than `UnsafePointer<FOO>`.
256266

257267
If you do find yourself needing to make these kinds of adjustments,
258-
you can make your local copy of the package dependency editable by
268+
you can make your [local copy](https://developer.apple.com/documentation/xcode/editing-a-package-dependency-as-a-local-package) of the package dependency editable by
259269
doing
260270

261271
```console
@@ -265,3 +275,69 @@ $ swift package edit SomePackage
265275
and then editing the files in the `Packages` directory that appears in
266276
your program's source directory. You may wish to consider raising PRs
267277
upstream with any fixes you may have.
278+
279+
If your project makes use of C or C++ language libraries, you may need
280+
to take additional steps. The Static SDK for Linux includes a small
281+
handful of very common dependencies (e.g.
282+
[libxml2](https://gitlab.gnome.org/GNOME/libxml2/-/wikis/home),
283+
[zlib](https://www.zlib.net/) and [curl](https://curl.se/)). There is
284+
a high bar for adding dependencies to the SDK itself, because it makes
285+
the SDK image larger, and means the SDK must be updated to track the
286+
versions of those dependencies.
287+
288+
The Static SDK includes an SBOM, in [SPDX format](https://spdx.dev/),
289+
that you can use to determine exactly what is present in any given
290+
release of the Static SDK for Linux. For instance, using the `bom`
291+
tool, you can display the SBOM using a command like:
292+
293+
```console
294+
$ bom document outline ~/.swiftpm/swift-sdks/swift-6.1.2-RELEASE-static-linux-0.0.1.artifactbundle/sbom.spdx.json
295+
_
296+
___ _ __ __| |_ __
297+
/ __| '_ \ / _` \ \/ /
298+
\__ \ |_) | (_| |> <
299+
|___/ .__/ \__,_/_/\_\
300+
|_|
301+
302+
📂 SPDX Document SBOM-SPDX-648fa59a-9d9d-476f-9183-78d57d847c31
303+
304+
│ 📦 DESCRIBES 1 Packages
305+
306+
├ Swift statically linked SDK for [email protected]
307+
│ │ 🔗 7 Relationships
308+
│ ├ GENERATED_FROM PACKAGE [email protected]
309+
│ ├ GENERATED_FROM PACKAGE [email protected]
310+
│ ├ GENERATED_FROM PACKAGE [email protected]
311+
│ ├ GENERATED_FROM PACKAGE [email protected]
312+
│ ├ GENERATED_FROM PACKAGE [email protected]
313+
│ ├ GENERATED_FROM PACKAGE boringssl@fips-20220613
314+
│ └ GENERATED_FROM PACKAGE [email protected]
315+
316+
└ 📄 DESCRIBES 0 Files
317+
```
318+
319+
If your project has additional C/C++ dependencies, the process is the
320+
same as using any static library you’ve built yourself in any other
321+
context. You must ensure the static library (`.a` file) is in the
322+
linker’s search path. Additionally, if you intend to call the
323+
library's functions directly from your Swift code, you must also add
324+
its header files to the compiler's include path. The only
325+
Swift-specific part is that you will need a module map for the
326+
library, but this is also true outside of the Static SDK for Linux
327+
(see [Mixing Swift and
328+
C++](https://www.swift.org/documentation/cxx-interop/)).
329+
330+
Some of the dependencies bundled in the Static SDK may be pulled in by
331+
Swift’s runtime libraries, if you use the functionality that requires
332+
them — for instance, Foundation Networking uses `libcurl` and
333+
`libcurl` uses `libz` — but because of the way static linking works,
334+
you will generally only “pay for what you use”.
335+
336+
You may be able to override the versions of libraries that ship with
337+
the Static SDK by placing a newer build of the library earlier in the
338+
linker’s search path. Note however that where other libraries that
339+
ship with the Static SDK have been built against the library in
340+
question, your new build will need to be ABI compatible with the
341+
version that shipped in the Static SDK, since the other libraries in
342+
the Static SDK will have been built against the headers from the
343+
version that they ship with.

0 commit comments

Comments
 (0)