From 5c47c77b9ebbfe1919ebcdd88bbef5db2e13cffc Mon Sep 17 00:00:00 2001 From: John Fairhurst Date: Sat, 21 Sep 2024 11:51:27 +0100 Subject: [PATCH] Updates for Xcode 16 / Linux Swift 6 (#17) --- .github/workflows/test.yml | 13 ++++++----- Makefile | 4 ++-- Package.resolved | 12 +++++----- Package.swift | 8 ++++++- README.md | 16 ++++++++------ Sources/CSteamworks/steam_missing.h | 16 -------------- Sources/CSteamworks/steamapi_headers.h | 1 - Sources/CSteamworks/swift_shims.h | 9 -------- Sources/LibGenerate/IO.swift | 4 ++-- Sources/Steamworks/ManualTypes.swift | 6 ++--- Sources/Steamworks/SteamAPI.swift | 6 ++++- Tests/SteamworksTests/TestGenNames.swift | 4 ++++ Tests/SteamworksTests/TestGenTypes.swift | 4 ++++ Tests/SteamworksTests/TestGenVersion.swift | 6 ++++- Tests/SteamworksTests/TestUtils.swift | 22 +++++++++---------- steamworks-swift.xcodeproj/project.pbxproj | 2 -- .../xcshareddata/swiftpm/Package.resolved | 6 ++--- 17 files changed, 67 insertions(+), 72 deletions(-) delete mode 100644 Sources/CSteamworks/swift_shims.h diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 56a6621f..9de4d10b 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -17,7 +17,7 @@ jobs: persist-credentials: false - uses: maxim-lobanov/setup-xcode@v1 with: - xcode-version: '16.0-beta' + xcode-version: '16.0' - name: Set up SDK run: cd sdk && sudo make install - name: Run tests @@ -33,20 +33,23 @@ jobs: persist-credentials: false - uses: maxim-lobanov/setup-xcode@v1 with: - xcode-version: '16.0-beta' + xcode-version: '16.0' - name: Raw build run: swift build linux: name: Linux SPM unit tests runs-on: ubuntu-latest - + container: + image: swift:6.0 steps: - uses: actions/checkout@v4 with: submodules: true persist-credentials: false + - name: Install tools + run: apt-get update && apt-get install make - name: Set up SDK - run: cd sdk && sudo make install + run: cd sdk && make install - name: Run tests - run: swift test -Xswiftc -cxx-interoperability-mode=default + run: swift test diff --git a/Makefile b/Makefile index 3c8e4a6e..64b9daca 100644 --- a/Makefile +++ b/Makefile @@ -27,7 +27,7 @@ clean: # Random flags here to get around crap Linux C++ support test_linux: - docker run -v `pwd`:`pwd` -w `pwd` --name steamworks --rm swift:5.10 /bin/bash -c "apt-get update; apt-get install make; (cd sdk && make install); swift test -Xswiftc -cxx-interoperability-mode=default" + docker run -v `pwd`:`pwd` -w `pwd` --name steamworks --rm swift:6.0 /bin/bash -c "apt-get update; apt-get install make; (cd sdk && make install); swift test" shell_linux: - docker run -it -v `pwd`:`pwd` -w `pwd` --name steamworks --rm swift:5.10 /bin/bash + docker run -it -v `pwd`:`pwd` -w `pwd` --name steamworks --rm swift:6.0 /bin/bash diff --git a/Package.resolved b/Package.resolved index 15474175..b418973f 100644 --- a/Package.resolved +++ b/Package.resolved @@ -7,7 +7,7 @@ "location" : "https://github.com/apple/swift-atomics.git", "state" : { "branch" : "main", - "revision" : "1f2007ef4165432f59f28615c473eb79a844a2af" + "revision" : "9e6597236356dadea31b681cea6a09e8e065fc85" } }, { @@ -15,14 +15,14 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/apple/swift-docc-plugin", "state" : { - "revision" : "26ac5758409154cc448d7ab82389c520fa8a8247", - "version" : "1.3.0" + "revision" : "85e4bb4e1cd62cec64a4b8e769dcefdf0c5b9d64", + "version" : "1.4.3" } }, { "identity" : "swift-docc-symbolkit", "kind" : "remoteSourceControl", - "location" : "https://github.com/apple/swift-docc-symbolkit", + "location" : "https://github.com/swiftlang/swift-docc-symbolkit", "state" : { "revision" : "b45d1f2ed151d057b54504d653e0da5552844e34", "version" : "1.0.0" @@ -42,8 +42,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/jpsim/Yams.git", "state" : { - "revision" : "9234124cff5e22e178988c18d8b95a8ae8007f76", - "version" : "5.1.2" + "revision" : "3036ba9d69cf1fd04d433527bc339dc0dc75433d", + "version" : "5.1.3" } } ], diff --git a/Package.swift b/Package.swift index 04d72b5d..b01da96c 100644 --- a/Package.swift +++ b/Package.swift @@ -196,7 +196,13 @@ let package = Package( ), .testTarget( name: "SteamworksTests", - dependencies: ["Steamworks", "SteamworksHelpers", "LibGenerate", "SteamworksConcurrency"], + dependencies: [ + .target(name: "Steamworks"), + .target(name: "SteamworksHelpers"), + .target(name: "SteamworksConcurrency"), + .target(name: "LibGenerate", + condition: .when(platforms: [.macOS])), + ], exclude: ["Fixtures"], swiftSettings: [.interoperabilityMode(.Cxx)], // lies lies lies linkerSettings: clientLinkerSettings diff --git a/README.md b/README.md index 9e507120..f20ca572 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ Current state: `SteamworksConcurrency` module * Encrypted app ticket support in separate `SteamworksEncryptedAppTicket` module * Separate demo showing encrypted app-ticket stuff, `make run_ticket` -* Requires Swift 6, Xcode 16 beta -- Linux not building right now, wait for 6 GA +* Requires Swift 6 / Xcode 16 * The Xcode project basically works. * ~Unit tests sometimes crash inside steam on exit~ fixed! @@ -306,7 +306,7 @@ Fully-fledged AppKit/Metal demo [here](https://github.com/johnfairh/spacewar-swi ### Swift C++ Bugs -_to recheck in Swift 6 for Linux - looking good though_ +Mostly fixed in Swift 6. Linux still suffering a bit. Tech limitations, on 6.0 Xcode 16.b3: * Some structures/classes aren't imported -- is the common factor a `protected` @@ -323,15 +323,17 @@ Tech limitations, on 6.0 Xcode 16.b3: * ~sourcekit won't give me a module interface for `CSteamworks` to see what else the importer is doing. Probably Xcode's fault, still not passing the user's flags to sourcekit and still doing insultingly bad error-reporting.~ fixed in Xcode 15?! -* Linux only: random parts of Glibc silently fail to import. SMH. Work around in C++. - See `swift_shims.h`. +* ~Linux only: random parts of Glibc silently fail to import. SMH. Work around in C++. + See `swift_shims.h`.~ Fixed in 6.0 ("for now") * ~Linux only: implicit struct constructors are not created, Swift generates a ref to a non-existent method that fails at link time. Work around with dumb C++ - allocate shim.~ Sort of fixed in 5.9, but instead `swiftc` crashes on some uses -- on + allocate shim.~ ~Sort of fixed in 5.9, but instead `swiftc` crashes on some uses -- on both macOS and Linux. Check by refs to eg. `CSteamNetworkingIPAddr_Allocate()`, see - `steam_missing.h`. + `steam_missing.h`.~ Fixed in 6.0. * Linux only, _again_: SPM test auto-discovery has no clue about C++ interop. Work around by - smashing in the flag everywhere... + smashing in the flag everywhere... Swift 6 - worse now, utterly broken on Linux with + yams 3rd-party dependency. Maybe fixable with swift-testing - for now nobbled those tests + on Linux. Yay? * ~Swift 5.8+ adopts a broken/paranoid model about 'projected pointers' requiring some fairly ugly code to work around. Verify with the `__ unsafe` stuff in `ManualTypes.swift`.~ fixed by Swift 6ish diff --git a/Sources/CSteamworks/steam_missing.h b/Sources/CSteamworks/steam_missing.h index 5f6ae33a..00f94008 100644 --- a/Sources/CSteamworks/steam_missing.h +++ b/Sources/CSteamworks/steam_missing.h @@ -71,19 +71,3 @@ static inline bool CSteamAPI_ISteamNetworkingSockets_SetCertificate( ISteamNetwo auto msgp = reinterpret_cast(errMsg); return SteamAPI_ISteamNetworkingSockets_SetCertificate(self, pCertificate, cbCertificate, *msgp); } - -// On Linux but not Darwin, Swift importer decides not to implement these two -// implicit dumb-struct constructors and instead leaves them as dangling symbols. -// -// OK, that part is fixed in Swift 5.9.... -// ...but the swift compiler crashes in IRGen instead in some of invocations. -// -// So we still need these dumb functions. - -static inline SteamNetworkingIPAddr CSteamNetworkingIPAddr_Allocate() { - return SteamNetworkingIPAddr(); -} - -static inline SteamNetworkingIdentity CSteamNetworkingIdentity_Allocate() { - return SteamNetworkingIdentity(); -} diff --git a/Sources/CSteamworks/steamapi_headers.h b/Sources/CSteamworks/steamapi_headers.h index 0f05f02c..7e86f0fd 100644 --- a/Sources/CSteamworks/steamapi_headers.h +++ b/Sources/CSteamworks/steamapi_headers.h @@ -7,4 +7,3 @@ #include "steam_missing.h" #include "steam_matchmaking_shims.h" #include "steam_networking_shims.h" -#include "swift_shims.h" diff --git a/Sources/CSteamworks/swift_shims.h b/Sources/CSteamworks/swift_shims.h deleted file mode 100644 index 96284da0..00000000 --- a/Sources/CSteamworks/swift_shims.h +++ /dev/null @@ -1,9 +0,0 @@ -#include - -static inline void my_setenv(const char *name, const char *value) { - setenv(name, value, 1); -} - -static inline void my_unsetenv(const char *name) { - unsetenv(name); -} diff --git a/Sources/LibGenerate/IO.swift b/Sources/LibGenerate/IO.swift index 43d7965d..894f6c96 100644 --- a/Sources/LibGenerate/IO.swift +++ b/Sources/LibGenerate/IO.swift @@ -110,7 +110,7 @@ final class IO: Sendable { print("\(Colors.red)\(message)\(Colors.reset)") } guard let url = resources.url(forResource: "EXPECTED_SDK", withExtension: nil), - let expected = try? String(contentsOf: url).trimmingCharacters(in: .newlines) else { + let expected = try? String(contentsOf: url, encoding: .utf8).trimmingCharacters(in: .newlines) else { warn("Can't resolve EXPECTED_SDK") return } @@ -177,7 +177,7 @@ final class IO: Sendable { let url = baseURL.appendingPathComponent(fileName) let fullContents = (header.map { $0 + "\n\n" } ?? "") + contents + "\n" - if let existing = try? String(contentsOf: url) { + if let existing = try? String(contentsOf: url, encoding: .utf8) { if existing == fullContents { print("\(Colors.green)\(fileName): unchanged\(Colors.reset)") return diff --git a/Sources/Steamworks/ManualTypes.swift b/Sources/Steamworks/ManualTypes.swift index a3f44dd0..fd5c894c 100644 --- a/Sources/Steamworks/ManualTypes.swift +++ b/Sources/Steamworks/ManualTypes.swift @@ -268,8 +268,7 @@ public struct SteamNetworkingIPAddr: @unchecked Sendable { /// An invalid address public init() { - // Crashes Swift 5.9 compiler without thunk... - adr = CSteamNetworkingIPAddr_Allocate() // SteamType + adr = SteamType() } /// `INADDR_ANY` with some port @@ -406,8 +405,7 @@ public struct SteamNetworkingIdentity: Sendable { /// Create an invalid identity public init() { - // Crashes Swift 5.9 compiler without thunk... - identity = CSteamNetworkingIdentity_Allocate() //SteamType() + identity = SteamType() } /// Init from a Steam ID diff --git a/Sources/Steamworks/SteamAPI.swift b/Sources/Steamworks/SteamAPI.swift index 5ef64cdf..7cc796ae 100644 --- a/Sources/Steamworks/SteamAPI.swift +++ b/Sources/Steamworks/SteamAPI.swift @@ -16,6 +16,10 @@ internal import CSteamworks import Logging +#if canImport(Glibc) +import Glibc +#endif + /// An instance of the Steamworks user API /// /// Create and retain one of these to access and use the Steamworks APIs. @@ -47,7 +51,7 @@ public final class SteamAPI: SteamBaseAPI, @unchecked Sendable { return nil } if fakeAppIdTxtFile { - my_setenv("SteamAppId", "\(appID.value)") + setenv("SteamAppId", "\(appID.value)", 1) } if let initSteamCEG, !initSteamCEG() { logError("SteamAPI.init() failed: Steamworks_InitCEGLibrary() returned false") diff --git a/Tests/SteamworksTests/TestGenNames.swift b/Tests/SteamworksTests/TestGenNames.swift index 349aaac5..cbf66a08 100644 --- a/Tests/SteamworksTests/TestGenNames.swift +++ b/Tests/SteamworksTests/TestGenNames.swift @@ -5,6 +5,8 @@ // Licensed under MIT (https://github.com/johnfairh/steamworks-swift/blob/main/LICENSE // +#if !os(Linux) + @testable import LibGenerate import XCTest @@ -113,3 +115,5 @@ class TestNames: XCTestCase { XCTAssertEqual("expr.map { T($0) }", SwiftExpr("expr").asCast(to: SwiftType("T?")).expr) } } + +#endif diff --git a/Tests/SteamworksTests/TestGenTypes.swift b/Tests/SteamworksTests/TestGenTypes.swift index 4bcb9424..8444cd6d 100644 --- a/Tests/SteamworksTests/TestGenTypes.swift +++ b/Tests/SteamworksTests/TestGenTypes.swift @@ -5,6 +5,8 @@ // Licensed under MIT (https://github.com/johnfairh/steamworks-swift/blob/main/LICENSE // +#if !os(Linux) + import XCTest @testable import Steamworks @@ -77,3 +79,5 @@ class TestTypes: XCTestCase { XCTAssertEqual(strings, oStrings) } } + +#endif diff --git a/Tests/SteamworksTests/TestGenVersion.swift b/Tests/SteamworksTests/TestGenVersion.swift index 1c724859..44d64066 100644 --- a/Tests/SteamworksTests/TestGenVersion.swift +++ b/Tests/SteamworksTests/TestGenVersion.swift @@ -5,8 +5,10 @@ // Licensed under MIT (https://github.com/johnfairh/steamworks-swift/blob/main/LICENSE // -@testable import LibGenerate +#if !os(Linux) + import XCTest +@testable import LibGenerate /// Readme.txt version parsing ... thought there was going to be more here! /// @@ -34,3 +36,5 @@ class TestVersion: XCTestCase { XCTAssertEqual("1.2", version) } } + +#endif diff --git a/Tests/SteamworksTests/TestUtils.swift b/Tests/SteamworksTests/TestUtils.swift index 40021cec..323abd1c 100644 --- a/Tests/SteamworksTests/TestUtils.swift +++ b/Tests/SteamworksTests/TestUtils.swift @@ -7,16 +7,10 @@ import Foundation import XCTest +#if !os(Linux) @testable import LibGenerate -import Steamworks -import CSteamworks // for weird 'Linux C++ mode erase random stdlib calls' issue - -#if canImport(Darwin) -import Darwin -#endif -#if canImport(GLibc) -import Glibc #endif +import Steamworks /// Wrapper for Steam API initialization /// @@ -225,6 +219,8 @@ extension XCTestCase { fixturesURL.appendingPathComponent("steam_api_extra.json") } + #if !os(Linux) + class Harness { let swiftOutputDirURL: URL let cOutputDirURL: URL @@ -233,8 +229,8 @@ extension XCTestCase { let generator: Generator init() throws { - my_setenv(IO.PATCH_YAML_PATH_VAR, patchYAMLURL.path) - my_setenv(IO.SDK_EXTRA_JSON_PATH_VAR, sdkExtraJSONURL.path) + setenv(IO.PATCH_YAML_PATH_VAR, patchYAMLURL.path, 1) + setenv(IO.SDK_EXTRA_JSON_PATH_VAR, sdkExtraJSONURL.path, 1) swiftOutputDirURL = try! FileManager.default.createTemporaryDirectory() cOutputDirURL = try! FileManager.default.createTemporaryDirectory() docsOutputDirURL = try! FileManager.default.createTemporaryDirectory() @@ -252,8 +248,10 @@ extension XCTestCase { try? FileManager.default.removeItem(at: cOutputDirURL) try? FileManager.default.removeItem(at: docsOutputDirURL) try? FileManager.default.removeItem(at: doccCollectionOutputDirURL) - my_unsetenv(IO.PATCH_YAML_PATH_VAR) - my_unsetenv(IO.SDK_EXTRA_JSON_PATH_VAR) + unsetenv(IO.PATCH_YAML_PATH_VAR) + unsetenv(IO.SDK_EXTRA_JSON_PATH_VAR) } } + + #endif } diff --git a/steamworks-swift.xcodeproj/project.pbxproj b/steamworks-swift.xcodeproj/project.pbxproj index d2615db6..6f238b11 100644 --- a/steamworks-swift.xcodeproj/project.pbxproj +++ b/steamworks-swift.xcodeproj/project.pbxproj @@ -407,7 +407,6 @@ 02B81B202886C82400780A57 /* SteamMatchmaking+Helpers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SteamMatchmaking+Helpers.swift"; sourceTree = ""; }; 02B81B232886D68B00780A57 /* SteamUser+Helpers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SteamUser+Helpers.swift"; sourceTree = ""; }; 02BD4F5A2C3D43B100A50860 /* SteamTimeline.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SteamTimeline.swift; sourceTree = ""; }; - 02BD4F5C2C3D63D700A50860 /* swift_shims.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = swift_shims.h; sourceTree = ""; }; 02D309D62722C49B00DE64F0 /* SteamAPI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SteamAPI.swift; sourceTree = ""; }; 02D309DD2722D81E00DE64F0 /* SteamBaseAPI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SteamBaseAPI.swift; sourceTree = ""; }; 02D309E22728111A00DE64F0 /* Lock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Lock.swift; sourceTree = ""; }; @@ -761,7 +760,6 @@ OBJ_8 /* CSteamworks */ = { isa = PBXGroup; children = ( - 02BD4F5C2C3D63D700A50860 /* swift_shims.h */, OBJ_9 /* steamapi_headers.h */, 02AD45712751565E00BD93ED /* steam_missing.h */, 02AD45EF2758F01100BD93ED /* steam_matchmaking_shims.h */, diff --git a/steamworks-swift.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/steamworks-swift.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index aa861edd..030c38ac 100644 --- a/steamworks-swift.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/steamworks-swift.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -7,7 +7,7 @@ "location" : "https://github.com/apple/swift-atomics.git", "state" : { "branch" : "main", - "revision" : "1f2007ef4165432f59f28615c473eb79a844a2af" + "revision" : "9e6597236356dadea31b681cea6a09e8e065fc85" } }, { @@ -24,8 +24,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/jpsim/Yams.git", "state" : { - "revision" : "9234124cff5e22e178988c18d8b95a8ae8007f76", - "version" : "5.1.2" + "revision" : "3036ba9d69cf1fd04d433527bc339dc0dc75433d", + "version" : "5.1.3" } } ],