Skip to content

Merge upstream main and provide Skip-prefixed compatibility modules#1

Merged
colemancda merged 260 commits into
feature/pureswiftfrom
feature/merge-upstream-main
Jul 20, 2026
Merged

Merge upstream main and provide Skip-prefixed compatibility modules#1
colemancda merged 260 commits into
feature/pureswiftfrom
feature/merge-upstream-main

Conversation

@colemancda

Copy link
Copy Markdown
Member

Brings feature/pureswift up to current upstream main and replaces the target renames with
compatibility shims, so one source can serve every dependent again.

The problem

feature/pureswift was 87 commits behind upstream, and the "Add Skip prefix to conflicting
packages" commit renamed targetsAndroidLoggingSkipAndroidLogging,
AndroidLooperSkipAndroidLooper, AndroidNDKSkipAndroidNDK.

A target's name is its module name, so that rename split the ecosystem in two:

  • skip-android-bridge imports SkipAndroidLogging
  • PureSwift/Android imports the upstream names, and needs AndroidManifest,
    AndroidFileManager, AndroidInput and AndroidHardware — none of which this branch exported

Since SwiftPM resolves by package identity, a graph containing both dependents could not be
satisfied by any single revision of this package. Downstream that surfaced as an unresolvable
graph, and then as:

error: product 'AndroidManifest' required by package 'androidbluetooth'
target 'AndroidBluetooth' not found in package 'swift-android-native'

What this does

  1. Merge upstream main (-X theirs for the two conflicts, both files upstream had
    reorganized: AndroidAssetManager.swift folded into AndroidFileManager, and
    AndroidLooper.swift split into several files). The branch now has the full upstream product
    set: AndroidSystem, AndroidNative, AndroidContext, AndroidFileManager, AndroidLogging,
    AndroidLooper, AndroidChoreographer, AndroidManifest, AndroidInput, AndroidHardware.

  2. Re-add the Skip-prefixed names as thin re-export shims rather than renames:

    // Sources/SkipAndroidLogging/SkipAndroidLogging.swift
    @_exported import AndroidLogging

    with matching SkipAndroidLogging / SkipAndroidLooper products. Both
    import AndroidLogging and import SkipAndroidLogging now resolve to the same code, so
    skip-android-bridge keeps working unchanged while PureSwift/Android gets the upstream names
    it expects.

AndroidNDK is left with its upstream name, as no dependent imports the Skip-prefixed variant.

Note on the diff size

The commit count is large because merging upstream brings its history onto the branch. The
branch-specific change is small: the merge resolution plus two shim files and their manifest
entries.

Downstream

This is a prerequisite for PureSwift/Android#43 and PureSwift/AndroidBluetooth#4, which both point
at this branch. Merge this first.

Verified by resolving and building the BluetoothExplorer app graph against it.

marcprux and others added 29 commits March 24, 2026 18:16
* Work around documentation validation errors

* Fix starting space in YAML

* Exclude AndroidLooper due to doc build errors

* Fix doc errors
* Update to Swift 6.3 and swift-java-jni-core 0.5.0

* Disable docs check
…#33)

* Update CI matrix to test Swift 6.3.2, nightly-6.4, and nightly-main

* Add OSLog dependency to AndroidContextTests and AndroidHardwareTests on Android

* Remove nightly-6.4 from CI Swift matrix

* Fix YAML syntax
Add a SWIFT_BUILD_DYNAMIC_LIBRARY environment variable, following the
same pattern used by PureSwift/Bluetooth, that switches every library
product's type to .dynamic instead of the default automatic (static)
linking. This lets downstream consumers cross-compiling for Android
opt into dynamic libraries for these packages without needing a fork.
AndroidLooper's main-queue drain used CoreFoundation's CFRunLoopRunInMode,
which requires linking all of Foundation (and, on this Android SDK,
FoundationInternationalization + ICU with it) even though nothing else
needs it. Add a "CoreFoundation" trait (off by default) that switches the
drain to call _dispatch_main_queue_callback_4CF() directly instead - the
same primitive CFRunLoop calls internally when its main-queue port fires.
Consumers that want the original CoreFoundation-backed behavior can opt
back in via traits: ["CoreFoundation"].

Also excludes Thread.swift's withLooper convenience wrapper on Android,
since Thread requires the full Foundation module (not available via
FoundationEssentials alone) and the wrapper isn't used by the Looper
bridge itself.
Per review feedback: the trait should be the single toggle for this
module's Foundation/CoreFoundation usage rather than mixing it with a
platform check.
Add the trailing comma swift-format expects on the last element of the
traits array.
Avoid linking Foundation on Android for the dispatch main queue drain
Support building library products as dynamic libraries
# Conflicts:
#	Sources/AndroidAssetManager/AndroidAssetManager.swift
#	Sources/AndroidLooper/AndroidLooper.swift
@colemancda
colemancda merged commit ebf3fef into feature/pureswift Jul 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants