Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,33 @@ jobs:
-destination 'generic/platform=iOS Simulator' \
CODE_SIGNING_ALLOWED=NO
done

# Android gate: cross-compile the package with the official Swift SDK for
# Android and run PatchSDKTests on an Android emulator. Apple-only bridges and
# renderers are #if canImport-gated out there, so this job guards the
# platform-neutral core (WasmKit runtime, loader, Brotli/BSDIFF40, SHA-256,
# update lifecycle) against regressions that only show up off Apple
# platforms. The action copies the test resource bundle (.wasm fixtures) to
# the emulator. Locally: `skip android test`.
android:
name: build + test (android)
runs-on: ubuntu-latest

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Build + test on Android emulator
uses: skiptools/swift-android-action@v2
with:
# Pinned to the toolchain the Android port was verified with. Must be
# the full release name: "6.4" resolves to a non-existent download.
swift-version: "6.4.0"
# Ubuntu runners can run out of disk while installing the emulator.
free-disk-space: true
# Swift 6.4 (swift-build backend) names the test resource bundle
# `PatchSDK_PatchSDKTests.bundle`, but the action only copies
# `*.resources` to the emulator, so Bundle.module fatal-errors. Copy the
# .bundle too. `${BUILD_DIR}` is the action's own build-products
# variable: this value is pasted into its shell script verbatim.
copy-files: ${BUILD_DIR}/*.bundle
56 changes: 55 additions & 1 deletion Package.resolved

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

53 changes: 45 additions & 8 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -74,14 +74,43 @@ let package = Package(
// TODO(remove-cap): once that PR (or an equivalent) ships in a WasmKit
// release we depend on, DROP this `swift-system` constraint and let it
// float again. Tracked in CLAUDE.md §5 / memory `wasmkit-swift-system-170-cap`.
.package(url: "https://github.com/apple/swift-system", "1.5.0" ..< "1.7.0")
.package(url: "https://github.com/apple/swift-system", "1.5.0" ..< "1.7.0"),
// Apple's swift-crypto: the CryptoKit API for platforms without CryptoKit
// (Android). Only linked on non-Apple platforms (see the `.when` conditions
// below); Apple builds keep using the system CryptoKit, so it adds nothing
// to an iOS app. Wide range so it rarely conflicts with a consumer's pin;
// SwiftPM skips releases whose tools-version is newer than the active
// toolchain (swift-crypto 4.4+ needs 6.1, 5.x needs 6.2), so Swift 6.0
// consumers still resolve a compatible version.
.package(url: "https://github.com/apple/swift-crypto.git", "3.0.0" ..< "6.0.0")
],
targets: [
// System-library shim for libbz2 (ships in the macOS + iOS SDKs). Used by
// the client-side bsdiff4 (BSDIFF40) diff applier to inflate the bz2
// control/diff/extra blocks the backend produces. Pure system linkage —
// no third-party code, cross-compiles for iOS device + simulator.
.systemLibrary(name: "CBZ2", path: "Sources/CBZ2"),
// The reference libbzip2 (sourceware.org, 1.0.8, BSD-style license),
// vendored unmodified. Used by the client-side bsdiff4 (BSDIFF40) diff
// applier to inflate the bz2 control/diff/extra blocks the backend
// produces. Same library Apple ships as the SDK's libbz2, compiled from
// source so it also builds where no system libbz2 exists (Android NDK).
// See Sources/CBZ2/README.md for provenance and the update procedure.
.target(
name: "CBZ2",
path: "Sources/CBZ2",
exclude: ["LICENSE", "README.md"],
sources: ["src"],
publicHeadersPath: "include"
),

// Google's reference Brotli decoder (MIT, v1.2.0), vendored unmodified —
// decoder only, no encoder. Inflates the `.wasm.br` modules the backend
// serves. Replaces Apple's `Compression` framework so the same code path
// builds on non-Apple platforms (Android). See Sources/CBrotliDec/README.md
// for provenance and the update procedure.
.target(
name: "CBrotliDec",
path: "Sources/CBrotliDec",
exclude: ["LICENSE", "README.md"],
sources: ["common", "dec"],
publicHeadersPath: "include"
),

// The shared ViewNode IR (Breakthrough #3/#5). Pure Foundation `Codable`
// value types — NO WasmKit, NO SwiftUI — so it compiles unchanged into
Expand Down Expand Up @@ -162,7 +191,12 @@ let package = Package(
// WasmKit PR #349 ships. iOS-safe (pure Swift).
.product(name: "SystemPackage", package: "swift-system"),
// libbz2 shim for diff decompression.
"CBZ2"
"CBZ2",
// Vendored Brotli decoder for module decompression.
"CBrotliDec",
// SHA-256 where CryptoKit is unavailable (SHA256.swift).
.product(name: "Crypto", package: "swift-crypto",
condition: .when(platforms: [.android, .linux]))
],
resources: [
// Apple requires a privacy manifest from third-party SDKs. It is
Expand Down Expand Up @@ -208,7 +242,10 @@ let package = Package(
.product(name: "WasmKit", package: "WasmKit"),
// WASI host shim — the generic-host-bridge tests instantiate the
// real Swift-compiled guest fixture, which imports WASI Preview 1.
.product(name: "WasmKitWASI", package: "WasmKit")
.product(name: "WasmKitWASI", package: "WasmKit"),
// SHA-256 in tests where CryptoKit is unavailable.
.product(name: "Crypto", package: "swift-crypto",
condition: .when(platforms: [.android, .linux]))
],
resources: [
// Real Swift-compiled .wasm fixtures used by the runtime tests.
Expand Down
42 changes: 42 additions & 0 deletions Sources/CBZ2/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@

--------------------------------------------------------------------------

This program, "bzip2", the associated library "libbzip2", and all
documentation, are copyright (C) 1996-2019 Julian R Seward. All
rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.

2. The origin of this software must not be misrepresented; you must
not claim that you wrote the original software. If you use this
software in a product, an acknowledgment in the product
documentation would be appreciated but is not required.

3. Altered source versions must be plainly marked as such, and must
not be misrepresented as being the original software.

4. The name of the author may not be used to endorse or promote
products derived from this software without specific prior written
permission.

THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

Julian Seward, jseward@acm.org
bzip2/libbzip2 version 1.0.8 of 13 July 2019

--------------------------------------------------------------------------
38 changes: 38 additions & 0 deletions Sources/CBZ2/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# CBZ2 — vendored libbzip2

The reference bzip2 library (libbzip2), vendored unmodified so PatchSDK can
inflate the bz2 control/diff/extra blocks of BSDIFF40 patches on every platform.
Apple ships this same library as the SDK's `libbz2`; the Android NDK does not
ship it at all, so it is compiled from source here instead.

| Field | Value |
| --- | --- |
| Upstream | https://sourceware.org/bzip2/ (git: https://sourceware.org/git/bzip2.git) |
| Version | 1.0.8 (tag `bzip2-1.0.8`) |
| Commit | 6a8690fc8d26c815e798c588f796eabe9d684cf0 |
| License | bzip2 license, BSD-style (see `LICENSE`) |

## What was copied

| Upstream path | Here |
| --- | --- |
| `blocksort.c`, `huffman.c`, `crctable.c`, `randtable.c`, `compress.c`, `decompress.c`, `bzlib.c` (the Makefile's `libbz2.a` objects) | `src/` |
| `bzlib_private.h` | `src/` |
| `bzlib.h` | `include/` |
| `LICENSE` | `LICENSE` |

Not copied: the `bzip2` / `bzip2recover` command-line tools, tests, and docs.
The compressor sources are needed because `bzlib.c` references them.

## Updating

```sh
git clone --depth 1 --branch <tag> https://sourceware.org/git/bzip2.git /tmp/bzip2
D=Sources/CBZ2
cp /tmp/bzip2/{blocksort,huffman,crctable,randtable,compress,decompress,bzlib}.c /tmp/bzip2/bzlib_private.h $D/src/
cp /tmp/bzip2/bzlib.h $D/include/
cp /tmp/bzip2/LICENSE $D/LICENSE
```

Then update the version and commit in the table above. Do not edit the
vendored sources by hand.
Loading