From 78b32617d1f9dbc23012508cff79fc2daa6ba5b0 Mon Sep 17 00:00:00 2001 From: "Jesse L. Zamora" Date: Fri, 14 Feb 2025 14:08:23 -0500 Subject: [PATCH 1/5] Add String.hasPrefix(in: [String]) method and use where applicable --- .../Extensions/String+hasPrefixIn.swift | 10 ++++++++++ .../SwiftSDKRecipes/LinuxRecipe.swift | 6 ++---- 2 files changed, 12 insertions(+), 4 deletions(-) create mode 100644 Sources/SwiftSDKGenerator/Extensions/String+hasPrefixIn.swift diff --git a/Sources/SwiftSDKGenerator/Extensions/String+hasPrefixIn.swift b/Sources/SwiftSDKGenerator/Extensions/String+hasPrefixIn.swift new file mode 100644 index 0000000..e23339e --- /dev/null +++ b/Sources/SwiftSDKGenerator/Extensions/String+hasPrefixIn.swift @@ -0,0 +1,10 @@ +extension String { + func hasPrefix(in array: [String]) -> Bool { + for item in array { + if self.hasPrefix(item) { + return true + } + } + return false + } +} \ No newline at end of file diff --git a/Sources/SwiftSDKGenerator/SwiftSDKRecipes/LinuxRecipe.swift b/Sources/SwiftSDKGenerator/SwiftSDKRecipes/LinuxRecipe.swift index 6d24169..7a59055 100644 --- a/Sources/SwiftSDKGenerator/SwiftSDKRecipes/LinuxRecipe.swift +++ b/Sources/SwiftSDKGenerator/SwiftSDKRecipes/LinuxRecipe.swift @@ -195,8 +195,7 @@ public struct LinuxRecipe: SwiftSDKRecipe { if self.hostSwiftSource == .preinstalled { // Swift 5.9 and 5.10 require `supportedTriples` to be set in info.json. // FIXME: This can be removed once the SDK generator does not support 5.9/5.10 any more. - if self.versionsConfiguration.swiftVersion.hasPrefix("5.9") - || self.versionsConfiguration.swiftVersion.hasPrefix("5.10") { + if self.versionsConfiguration.swiftVersion.hasPrefix(in: ["5.9", "5.10"]) { return [ Triple("x86_64-unknown-linux-gnu"), Triple("aarch64-unknown-linux-gnu"), @@ -297,8 +296,7 @@ public struct LinuxRecipe: SwiftSDKRecipe { try await generator.prepareLLDLinker(engine, llvmArtifact: downloadableArtifacts.hostLLVM) } - if self.versionsConfiguration.swiftVersion.hasPrefix("5.9") || - self.versionsConfiguration.swiftVersion.hasPrefix("5.10") { + if self.versionsConfiguration.swiftVersion.hasPrefix(in: ["5.9", "5.10"]) { try await generator.symlinkClangHeaders() } From f07b49758f713a015b1ecb228f48f6fc6dc34f1e Mon Sep 17 00:00:00 2001 From: "Jesse L. Zamora" Date: Fri, 14 Feb 2025 14:08:58 -0500 Subject: [PATCH 2/5] Add code to generate an SDKSettings.json file for Swift 5.9, 5.10, and 6.0 - Swift 6.1 and later supress this error automatically. --- .../SwiftSDKGenerator+Metadata.swift | 31 +++++++++++++++++++ .../SwiftSDKRecipes/LinuxRecipe.swift | 6 ++++ 2 files changed, 37 insertions(+) diff --git a/Sources/SwiftSDKGenerator/Generator/SwiftSDKGenerator+Metadata.swift b/Sources/SwiftSDKGenerator/Generator/SwiftSDKGenerator+Metadata.swift index b9985dc..728bf55 100644 --- a/Sources/SwiftSDKGenerator/Generator/SwiftSDKGenerator+Metadata.swift +++ b/Sources/SwiftSDKGenerator/Generator/SwiftSDKGenerator+Metadata.swift @@ -112,4 +112,35 @@ extension SwiftSDKGenerator { ) ) } + + struct SDKSettings: Codable { + var DisplayName: String + var Version: String = "0.0.1" + var VersionMap: [String: String] = [:] + var CanonicalName: String + } + + /// Generates an `SDKSettings.json` file that looks like this: + /// + /// ```json + /// { + /// "CanonicalName" : "-swift-linux-[gnu|gnueabihf]", + /// "DisplayName" : "Swift SDK for ()", + /// "Version" : "0.0.1", + /// "VersionMap" : { + /// + /// } + /// } + /// ``` + func generateSDKSettingsFile(sdkDirPath: FilePath, distribution: LinuxDistribution) throws { + logger.info("Generating SDKSettings.json file to silence cross-compilation warnings...") + + let sdkSettings = SDKSettings( + DisplayName: "Swift SDK for \(distribution) (\(targetTriple.archName))", + CanonicalName: targetTriple.triple.replacingOccurrences(of: "unknown", with: "swift") + ) + + let sdkSettingsFilePath = sdkDirPath.appending("SDKSettings.json") + try writeFile(at: sdkSettingsFilePath, encoder.encode(sdkSettings)) + } } diff --git a/Sources/SwiftSDKGenerator/SwiftSDKRecipes/LinuxRecipe.swift b/Sources/SwiftSDKGenerator/SwiftSDKRecipes/LinuxRecipe.swift index 7a59055..4fcd8c1 100644 --- a/Sources/SwiftSDKGenerator/SwiftSDKRecipes/LinuxRecipe.swift +++ b/Sources/SwiftSDKGenerator/SwiftSDKRecipes/LinuxRecipe.swift @@ -291,6 +291,12 @@ public struct LinuxRecipe: SwiftSDKRecipe { try await generator.fixAbsoluteSymlinks(sdkDirPath: sdkDirPath) + // Swift 6.1 and later do not throw warnings about the SDKSettings.json file missing, + // so they don't need this file. + if self.versionsConfiguration.swiftVersion.hasPrefix(in: ["5.9", "5.10", "6.0"]) { + try await generator.generateSDKSettingsFile(sdkDirPath: sdkDirPath, distribution: linuxDistribution) + } + if self.hostSwiftSource != .preinstalled { if self.mainHostTriple.os != .linux && !self.versionsConfiguration.swiftVersion.hasPrefix("6.0") { try await generator.prepareLLDLinker(engine, llvmArtifact: downloadableArtifacts.hostLLVM) From 97a2063bf501ff62e4276b541d52e6aa0112ebbf Mon Sep 17 00:00:00 2001 From: "Jesse L. Zamora" Date: Fri, 14 Feb 2025 15:26:27 -0500 Subject: [PATCH 3/5] Add missing newline at end of Swift+hasPrefixIn.swift --- Sources/SwiftSDKGenerator/Extensions/String+hasPrefixIn.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/SwiftSDKGenerator/Extensions/String+hasPrefixIn.swift b/Sources/SwiftSDKGenerator/Extensions/String+hasPrefixIn.swift index e23339e..78e2228 100644 --- a/Sources/SwiftSDKGenerator/Extensions/String+hasPrefixIn.swift +++ b/Sources/SwiftSDKGenerator/Extensions/String+hasPrefixIn.swift @@ -7,4 +7,4 @@ extension String { } return false } -} \ No newline at end of file +} From a57242956e27072f51ecda80b8ca33a3d40cdea0 Mon Sep 17 00:00:00 2001 From: "Jesse L. Zamora" Date: Fri, 14 Feb 2025 15:41:10 -0500 Subject: [PATCH 4/5] Add test for SwiftSDKGenerator.generateSDKSettingsFile() - Cover a few different arch names and ensure the correct file output is included. --- .../SwiftSDKGenerator+Metadata.swift | 3 +- .../SwiftSDKGenerator+MetadataTests.swift | 72 +++++++++++++++++++ 2 files changed, 74 insertions(+), 1 deletion(-) create mode 100644 Tests/SwiftSDKGeneratorTests/Generator/SwiftSDKGenerator+MetadataTests.swift diff --git a/Sources/SwiftSDKGenerator/Generator/SwiftSDKGenerator+Metadata.swift b/Sources/SwiftSDKGenerator/Generator/SwiftSDKGenerator+Metadata.swift index 728bf55..8388617 100644 --- a/Sources/SwiftSDKGenerator/Generator/SwiftSDKGenerator+Metadata.swift +++ b/Sources/SwiftSDKGenerator/Generator/SwiftSDKGenerator+Metadata.swift @@ -115,7 +115,7 @@ extension SwiftSDKGenerator { struct SDKSettings: Codable { var DisplayName: String - var Version: String = "0.0.1" + var Version: String var VersionMap: [String: String] = [:] var CanonicalName: String } @@ -137,6 +137,7 @@ extension SwiftSDKGenerator { let sdkSettings = SDKSettings( DisplayName: "Swift SDK for \(distribution) (\(targetTriple.archName))", + Version: bundleVersion, CanonicalName: targetTriple.triple.replacingOccurrences(of: "unknown", with: "swift") ) diff --git a/Tests/SwiftSDKGeneratorTests/Generator/SwiftSDKGenerator+MetadataTests.swift b/Tests/SwiftSDKGeneratorTests/Generator/SwiftSDKGenerator+MetadataTests.swift new file mode 100644 index 0000000..9baf7de --- /dev/null +++ b/Tests/SwiftSDKGeneratorTests/Generator/SwiftSDKGenerator+MetadataTests.swift @@ -0,0 +1,72 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the Swift open source project +// +// Copyright (c) 2022-2025 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See https://swift.org/LICENSE.txt for license information +// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// + +import Logging +import SystemPackage +import XCTest + +@testable import SwiftSDKGenerator + +final class SwiftSDKGeneratorMetadataTests: XCTestCase { + let logger = Logger(label: "SwiftSDKGeneratorMetadataTests") + + func testGenerateSDKSettingsFile() async throws { + let testCases = [ + ( + bundleVersion: "0.0.1", + targetTriple: Triple("x86_64-unknown-linux-gnu"), + expectedCanonicalName: "x86_64-swift-linux-gnu" + ), + ( + bundleVersion: "0.0.2", + targetTriple: Triple("aarch64-unknown-linux-gnu"), + expectedCanonicalName: "aarch64-swift-linux-gnu" + ), + ( + bundleVersion: "0.0.3", + targetTriple: Triple("armv7-unknown-linux-gnueabihf"), + expectedCanonicalName: "armv7-swift-linux-gnueabihf" + ) + ] + + for testCase in testCases { + let sdk = try await SwiftSDKGenerator( + bundleVersion: testCase.bundleVersion, + targetTriple: testCase.targetTriple, + artifactID: "6.0.3-RELEASE_ubuntu_jammy_\(testCase.targetTriple.archName)", + isIncremental: false, + isVerbose: false, + logger: logger + ) + let linuxDistribution = try LinuxDistribution(name: .ubuntu, version: "22.04") + + let sdkDirPath = FilePath(".") + try await sdk.generateSDKSettingsFile(sdkDirPath: sdkDirPath, distribution: linuxDistribution) + + // Make sure the file exists + let sdkSettingsFile = sdkDirPath.appending("SDKSettings.json") + let fileExists = await sdk.doesFileExist(at: sdkSettingsFile) + XCTAssertTrue(fileExists) + + // Read back file, make sure it contains the expected data + let data = String(data: try await sdk.readFile(at: sdkSettingsFile), encoding: .utf8) + XCTAssertNotNil(data) + XCTAssertTrue(data!.contains(testCase.bundleVersion)) + XCTAssertTrue(data!.contains("(\(testCase.targetTriple.archName))")) + XCTAssertTrue(data!.contains(linuxDistribution.description)) + XCTAssertTrue(data!.contains(testCase.expectedCanonicalName)) + + // Cleanup + try await sdk.removeFile(at: sdkSettingsFile) + } + } +} From 0c78b49abe1b14ac2cbd4f4ee33c1370cde425ff Mon Sep 17 00:00:00 2001 From: "Jesse L. Zamora" Date: Sun, 16 Feb 2025 07:49:08 -0500 Subject: [PATCH 5/5] Rename String.hasPrefix(in:) to String.hasAnyPrefix(from:) --- .../{String+hasPrefixIn.swift => String+hasAnyPrefix.swift} | 2 +- Sources/SwiftSDKGenerator/SwiftSDKRecipes/LinuxRecipe.swift | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) rename Sources/SwiftSDKGenerator/Extensions/{String+hasPrefixIn.swift => String+hasAnyPrefix.swift} (75%) diff --git a/Sources/SwiftSDKGenerator/Extensions/String+hasPrefixIn.swift b/Sources/SwiftSDKGenerator/Extensions/String+hasAnyPrefix.swift similarity index 75% rename from Sources/SwiftSDKGenerator/Extensions/String+hasPrefixIn.swift rename to Sources/SwiftSDKGenerator/Extensions/String+hasAnyPrefix.swift index 78e2228..139e371 100644 --- a/Sources/SwiftSDKGenerator/Extensions/String+hasPrefixIn.swift +++ b/Sources/SwiftSDKGenerator/Extensions/String+hasAnyPrefix.swift @@ -1,5 +1,5 @@ extension String { - func hasPrefix(in array: [String]) -> Bool { + func hasAnyPrefix(from array: [String]) -> Bool { for item in array { if self.hasPrefix(item) { return true diff --git a/Sources/SwiftSDKGenerator/SwiftSDKRecipes/LinuxRecipe.swift b/Sources/SwiftSDKGenerator/SwiftSDKRecipes/LinuxRecipe.swift index 4fcd8c1..9af0afc 100644 --- a/Sources/SwiftSDKGenerator/SwiftSDKRecipes/LinuxRecipe.swift +++ b/Sources/SwiftSDKGenerator/SwiftSDKRecipes/LinuxRecipe.swift @@ -195,7 +195,7 @@ public struct LinuxRecipe: SwiftSDKRecipe { if self.hostSwiftSource == .preinstalled { // Swift 5.9 and 5.10 require `supportedTriples` to be set in info.json. // FIXME: This can be removed once the SDK generator does not support 5.9/5.10 any more. - if self.versionsConfiguration.swiftVersion.hasPrefix(in: ["5.9", "5.10"]) { + if self.versionsConfiguration.swiftVersion.hasAnyPrefix(from: ["5.9", "5.10"]) { return [ Triple("x86_64-unknown-linux-gnu"), Triple("aarch64-unknown-linux-gnu"), @@ -293,7 +293,7 @@ public struct LinuxRecipe: SwiftSDKRecipe { // Swift 6.1 and later do not throw warnings about the SDKSettings.json file missing, // so they don't need this file. - if self.versionsConfiguration.swiftVersion.hasPrefix(in: ["5.9", "5.10", "6.0"]) { + if self.versionsConfiguration.swiftVersion.hasAnyPrefix(from: ["5.9", "5.10", "6.0"]) { try await generator.generateSDKSettingsFile(sdkDirPath: sdkDirPath, distribution: linuxDistribution) } @@ -302,7 +302,7 @@ public struct LinuxRecipe: SwiftSDKRecipe { try await generator.prepareLLDLinker(engine, llvmArtifact: downloadableArtifacts.hostLLVM) } - if self.versionsConfiguration.swiftVersion.hasPrefix(in: ["5.9", "5.10"]) { + if self.versionsConfiguration.swiftVersion.hasAnyPrefix(from: ["5.9", "5.10"]) { try await generator.symlinkClangHeaders() }