From 84f7e19d8b1a49390e3f09e5872d4a728afc2720 Mon Sep 17 00:00:00 2001 From: Marc Prud'hommeaux Date: Sat, 30 Aug 2025 12:53:13 -0400 Subject: [PATCH 01/10] Linux Support --- .github/workflows/ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 091f9d1..0510a60 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -16,6 +16,7 @@ jobs: uses: skiptools/actions/.github/workflows/skip-framework.yml@v1 with: # disable export because there are currently problems with shared PCH module cache files with multi-module native export + runs-on: "['macos-13', 'ubuntu-24.04']" run-export: false #run-local-tests: false From c7281006b0c65a28369c2c120b24fe2ad2691681 Mon Sep 17 00:00:00 2001 From: Marc Prud'hommeaux Date: Sun, 28 Sep 2025 00:12:50 -0400 Subject: [PATCH 02/10] Run tests on Linux --- Tests/SkipAndroidBridgeSamplesTests/XCSkipTests.swift | 2 +- Tests/SkipAndroidBridgeTests/XCSkipTests.swift | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Tests/SkipAndroidBridgeSamplesTests/XCSkipTests.swift b/Tests/SkipAndroidBridgeSamplesTests/XCSkipTests.swift index 45ef89e..1a19069 100644 --- a/Tests/SkipAndroidBridgeSamplesTests/XCSkipTests.swift +++ b/Tests/SkipAndroidBridgeSamplesTests/XCSkipTests.swift @@ -1,7 +1,7 @@ // Copyright 2024–2025 Skip // SPDX-License-Identifier: LGPL-3.0-only WITH LGPL-3.0-linking-exception import Foundation -#if os(macOS) // Skip transpiled tests only run on macOS targets +#if os(macOS) || os(Linux) import SkipTest /// This test case will run the transpiled tests for the Skip module. diff --git a/Tests/SkipAndroidBridgeTests/XCSkipTests.swift b/Tests/SkipAndroidBridgeTests/XCSkipTests.swift index 45ef89e..1a19069 100644 --- a/Tests/SkipAndroidBridgeTests/XCSkipTests.swift +++ b/Tests/SkipAndroidBridgeTests/XCSkipTests.swift @@ -1,7 +1,7 @@ // Copyright 2024–2025 Skip // SPDX-License-Identifier: LGPL-3.0-only WITH LGPL-3.0-linking-exception import Foundation -#if os(macOS) // Skip transpiled tests only run on macOS targets +#if os(macOS) || os(Linux) import SkipTest /// This test case will run the transpiled tests for the Skip module. From caf617116118f2d87efa4d7acf964c0549a6748a Mon Sep 17 00:00:00 2001 From: Marc Prud'hommeaux Date: Sun, 28 Sep 2025 00:26:30 -0400 Subject: [PATCH 03/10] Implement logging stub for Linux --- .../AndroidBridgeBootstrap.swift | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/Sources/SkipAndroidBridge/AndroidBridgeBootstrap.swift b/Sources/SkipAndroidBridge/AndroidBridgeBootstrap.swift index 089dfa6..21a3b95 100644 --- a/Sources/SkipAndroidBridge/AndroidBridgeBootstrap.swift +++ b/Sources/SkipAndroidBridge/AndroidBridgeBootstrap.swift @@ -16,6 +16,25 @@ import Foundation @_exported import AndroidLogging #elseif canImport(OSLog) @_exported import OSLog +#else +// e.g., for Linux define a local logging stub +class Logger { + let subsystem: String + let category: String + + init(subsystem: String, category: String) { + self.subsystem = subsystem + self.category = category + } + + func log(_ string: String) { + print("\(subsystem)/\(category): \(string)") + } + + func debug(_ string: String) { + print("\(subsystem)/\(category): \(string)") + } +} #endif #if canImport(AndroidLooper) @_exported import AndroidLooper From bb094f91a5cead0e1dac9038860763fab1c9376d Mon Sep 17 00:00:00 2001 From: Marc Prud'hommeaux Date: Sun, 28 Sep 2025 00:53:41 -0400 Subject: [PATCH 04/10] Implement logging stub for Linux From 08624f91c7923450579d778c1caf2d481bb9744c Mon Sep 17 00:00:00 2001 From: Marc Prud'hommeaux Date: Sun, 28 Sep 2025 08:17:47 -0400 Subject: [PATCH 05/10] Implement applicationSupportDirectory for non-Darwin --- Sources/SkipAndroidBridge/AndroidBridgeBootstrap.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/SkipAndroidBridge/AndroidBridgeBootstrap.swift b/Sources/SkipAndroidBridge/AndroidBridgeBootstrap.swift index 21a3b95..d097587 100644 --- a/Sources/SkipAndroidBridge/AndroidBridgeBootstrap.swift +++ b/Sources/SkipAndroidBridge/AndroidBridgeBootstrap.swift @@ -146,7 +146,7 @@ private func bootstrapFileManagerProperties(filesDir: String, cacheDir: String) } // URL.applicationSupportDirectory exists in Darwin's Foundation but not in Android's Foundation -#if os(Android) +#if !canImport(Darwin) // SKIP @nobridge extension URL { public static var applicationSupportDirectory: URL { From 6bb53205494cd473ca21b910f4a153aefa2df3ba Mon Sep 17 00:00:00 2001 From: Marc Prud'hommeaux Date: Sun, 28 Sep 2025 08:59:32 -0400 Subject: [PATCH 06/10] Add Package@swift-5.9.swift --- Package.swift | 2 +- Package@swift-5.9.swift | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 Package@swift-5.9.swift diff --git a/Package.swift b/Package.swift index 7347adb..89db7c0 100644 --- a/Package.swift +++ b/Package.swift @@ -1,4 +1,4 @@ -// swift-tools-version: 5.9 +// swift-tools-version: 6.0 import PackageDescription let package = Package( diff --git a/Package@swift-5.9.swift b/Package@swift-5.9.swift new file mode 100644 index 0000000..7347adb --- /dev/null +++ b/Package@swift-5.9.swift @@ -0,0 +1,40 @@ +// swift-tools-version: 5.9 +import PackageDescription + +let package = Package( + name: "skip-android-bridge", + defaultLocalization: "en", + platforms: [.iOS(.v16), .macOS(.v13), .tvOS(.v16), .watchOS(.v9), .macCatalyst(.v16)], + products: [ + .library(name: "SkipAndroidBridge", type: .dynamic, targets: ["SkipAndroidBridge"]), + .library(name: "SkipAndroidBridgeSamples", type: .dynamic, targets: ["SkipAndroidBridgeSamples"]), + ], + dependencies: [ + .package(url: "https://source.skip.tools/skip.git", from: "1.2.34"), + .package(url: "https://source.skip.tools/skip-foundation.git", from: "1.3.1"), + .package(url: "https://source.skip.tools/swift-jni.git", "0.0.0"..<"2.0.0"), + .package(url: "https://source.skip.tools/skip-bridge.git", "0.0.0"..<"2.0.0"), + .package(url: "https://source.skip.tools/swift-android-native.git", from: "1.4.1") + ], + targets: [ + .target(name: "SkipAndroidBridge", dependencies: [ + .product(name: "SkipBridge", package: "skip-bridge"), + .product(name: "SwiftJNI", package: "swift-jni"), + .product(name: "SkipFoundation", package: "skip-foundation"), + .product(name: "AndroidNative", package: "swift-android-native", condition: .when(platforms: [.android])), + ], plugins: [.plugin(name: "skipstone", package: "skip")]), + + .testTarget(name: "SkipAndroidBridgeTests", dependencies: [ + "SkipAndroidBridge", + .product(name: "SkipTest", package: "skip"), + ], plugins: [.plugin(name: "skipstone", package: "skip")]), + + .target(name: "SkipAndroidBridgeSamples", dependencies: [ + "SkipAndroidBridge", + ], resources: [.process("Resources")], plugins: [.plugin(name: "skipstone", package: "skip")]), + .testTarget(name: "SkipAndroidBridgeSamplesTests", dependencies: [ + "SkipAndroidBridgeSamples", + .product(name: "SkipTest", package: "skip"), + ], plugins: [.plugin(name: "skipstone", package: "skip")]), + ] +) From 19de69134bf325c25a03f9a25408fd1a42ec8db8 Mon Sep 17 00:00:00 2001 From: Marc Prud'hommeaux Date: Sun, 28 Sep 2025 09:08:23 -0400 Subject: [PATCH 07/10] Add Package@swift-5.9.swift for compatibility --- Package.swift | 3 ++- Package@swift-5.9.swift | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Package.swift b/Package.swift index 89db7c0..bf9f428 100644 --- a/Package.swift +++ b/Package.swift @@ -36,5 +36,6 @@ let package = Package( "SkipAndroidBridgeSamples", .product(name: "SkipTest", package: "skip"), ], plugins: [.plugin(name: "skipstone", package: "skip")]), - ] + ], + swiftLanguageModes: [.v5] ) diff --git a/Package@swift-5.9.swift b/Package@swift-5.9.swift index 7347adb..2f9b8ee 100644 --- a/Package@swift-5.9.swift +++ b/Package@swift-5.9.swift @@ -36,5 +36,6 @@ let package = Package( "SkipAndroidBridgeSamples", .product(name: "SkipTest", package: "skip"), ], plugins: [.plugin(name: "skipstone", package: "skip")]), - ] + ], + swiftLanguageModes: [.v5] ) From d53842ca1fb48499014d081677a12558ec0dc322 Mon Sep 17 00:00:00 2001 From: Marc Prud'hommeaux Date: Sun, 28 Sep 2025 09:43:16 -0400 Subject: [PATCH 08/10] Workaround for building on Linux --- Package.swift | 3 +- Package@swift-5.9.swift | 41 ------------------- Sources/SkipAndroidBridge/AndroidBundle.swift | 5 +++ .../SkipAndroidBridgeSamples.swift | 5 +++ 4 files changed, 11 insertions(+), 43 deletions(-) delete mode 100644 Package@swift-5.9.swift diff --git a/Package.swift b/Package.swift index bf9f428..89db7c0 100644 --- a/Package.swift +++ b/Package.swift @@ -36,6 +36,5 @@ let package = Package( "SkipAndroidBridgeSamples", .product(name: "SkipTest", package: "skip"), ], plugins: [.plugin(name: "skipstone", package: "skip")]), - ], - swiftLanguageModes: [.v5] + ] ) diff --git a/Package@swift-5.9.swift b/Package@swift-5.9.swift deleted file mode 100644 index 2f9b8ee..0000000 --- a/Package@swift-5.9.swift +++ /dev/null @@ -1,41 +0,0 @@ -// swift-tools-version: 5.9 -import PackageDescription - -let package = Package( - name: "skip-android-bridge", - defaultLocalization: "en", - platforms: [.iOS(.v16), .macOS(.v13), .tvOS(.v16), .watchOS(.v9), .macCatalyst(.v16)], - products: [ - .library(name: "SkipAndroidBridge", type: .dynamic, targets: ["SkipAndroidBridge"]), - .library(name: "SkipAndroidBridgeSamples", type: .dynamic, targets: ["SkipAndroidBridgeSamples"]), - ], - dependencies: [ - .package(url: "https://source.skip.tools/skip.git", from: "1.2.34"), - .package(url: "https://source.skip.tools/skip-foundation.git", from: "1.3.1"), - .package(url: "https://source.skip.tools/swift-jni.git", "0.0.0"..<"2.0.0"), - .package(url: "https://source.skip.tools/skip-bridge.git", "0.0.0"..<"2.0.0"), - .package(url: "https://source.skip.tools/swift-android-native.git", from: "1.4.1") - ], - targets: [ - .target(name: "SkipAndroidBridge", dependencies: [ - .product(name: "SkipBridge", package: "skip-bridge"), - .product(name: "SwiftJNI", package: "swift-jni"), - .product(name: "SkipFoundation", package: "skip-foundation"), - .product(name: "AndroidNative", package: "swift-android-native", condition: .when(platforms: [.android])), - ], plugins: [.plugin(name: "skipstone", package: "skip")]), - - .testTarget(name: "SkipAndroidBridgeTests", dependencies: [ - "SkipAndroidBridge", - .product(name: "SkipTest", package: "skip"), - ], plugins: [.plugin(name: "skipstone", package: "skip")]), - - .target(name: "SkipAndroidBridgeSamples", dependencies: [ - "SkipAndroidBridge", - ], resources: [.process("Resources")], plugins: [.plugin(name: "skipstone", package: "skip")]), - .testTarget(name: "SkipAndroidBridgeSamplesTests", dependencies: [ - "SkipAndroidBridgeSamples", - .product(name: "SkipTest", package: "skip"), - ], plugins: [.plugin(name: "skipstone", package: "skip")]), - ], - swiftLanguageModes: [.v5] -) diff --git a/Sources/SkipAndroidBridge/AndroidBundle.swift b/Sources/SkipAndroidBridge/AndroidBundle.swift index c40ce31..3eda3d7 100644 --- a/Sources/SkipAndroidBridge/AndroidBundle.swift +++ b/Sources/SkipAndroidBridge/AndroidBundle.swift @@ -2,6 +2,10 @@ // SPDX-License-Identifier: LGPL-3.0-only WITH LGPL-3.0-linking-exception import Foundation +#if os(Linux) +// Bundle subclass does not build on Linux due to https://github.com/swiftlang/swift-corelibs-foundation/issues/5108 +public typealias AndroidBundle = Foundation.Bundle +#else /// Override of native `Bundle` for Android that delegates to our `skip.foundation.Bundle` Kotlin object. open class AndroidBundle : Foundation.Bundle, @unchecked Sendable { #if os(Android) || ROBOLECTRIC @@ -304,6 +308,7 @@ open class AndroidBundle : Foundation.Bundle, @unchecked Sendable { } #endif } +#endif #if os(Android) || ROBOLECTRIC diff --git a/Sources/SkipAndroidBridgeSamples/SkipAndroidBridgeSamples.swift b/Sources/SkipAndroidBridgeSamples/SkipAndroidBridgeSamples.swift index c4b313e..045b422 100644 --- a/Sources/SkipAndroidBridgeSamples/SkipAndroidBridgeSamples.swift +++ b/Sources/SkipAndroidBridgeSamples/SkipAndroidBridgeSamples.swift @@ -39,6 +39,11 @@ public func setStringDefault(name: String, value: String?) { UserDefaults.standard.set(value, forKey: name) } +#if os(Linux) +// workaround for missing LocalizedStringResource on Linux +typealias LocalizedStringResource = AndroidLocalizedStringResource +#endif + public func localizedStringResourceLiteralKey() -> String { let literal: LocalizedStringResource = "literal" return literal.key From 3f14aff484ee6b3c006acc47779c573304fef105 Mon Sep 17 00:00:00 2001 From: Marc Prud'hommeaux Date: Sun, 28 Sep 2025 09:46:16 -0400 Subject: [PATCH 09/10] Fix package version --- Package.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Package.swift b/Package.swift index 89db7c0..7347adb 100644 --- a/Package.swift +++ b/Package.swift @@ -1,4 +1,4 @@ -// swift-tools-version: 6.0 +// swift-tools-version: 5.9 import PackageDescription let package = Package( From 1cb7c41f3f2167dc334434df4b1e123d129e85ca Mon Sep 17 00:00:00 2001 From: Marc Prud'hommeaux Date: Mon, 29 Sep 2025 22:07:32 -0400 Subject: [PATCH 10/10] Run CI using new macos-15-intel runner --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0510a60..080c168 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -16,7 +16,7 @@ jobs: uses: skiptools/actions/.github/workflows/skip-framework.yml@v1 with: # disable export because there are currently problems with shared PCH module cache files with multi-module native export - runs-on: "['macos-13', 'ubuntu-24.04']" + runs-on: "['macos-15-intel', 'ubuntu-24.04']" run-export: false #run-local-tests: false