Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generate SDKSettings.json file for Swift SDKs for Swift 5.9-6.0 #185

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
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
10 changes: 10 additions & 0 deletions Sources/SwiftSDKGenerator/Extensions/String+hasAnyPrefix.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
extension String {
func hasAnyPrefix(from array: [String]) -> Bool {
for item in array {
if self.hasPrefix(item) {
return true
}
}
return false
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -112,4 +112,36 @@ extension SwiftSDKGenerator {
)
)
}

struct SDKSettings: Codable {
var DisplayName: String
var Version: String
var VersionMap: [String: String] = [:]
var CanonicalName: String
}

/// Generates an `SDKSettings.json` file that looks like this:
///
/// ```json
/// {
/// "CanonicalName" : "<arch>-swift-linux-[gnu|gnueabihf]",
/// "DisplayName" : "Swift SDK for <distribution> (<arch>)",
/// "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))",
Version: bundleVersion,
CanonicalName: targetTriple.triple.replacingOccurrences(of: "unknown", with: "swift")
)

let sdkSettingsFilePath = sdkDirPath.appending("SDKSettings.json")
try writeFile(at: sdkSettingsFilePath, encoder.encode(sdkSettings))
}
}
12 changes: 8 additions & 4 deletions Sources/SwiftSDKGenerator/SwiftSDKRecipes/LinuxRecipe.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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.hasAnyPrefix(from: ["5.9", "5.10"]) {
return [
Triple("x86_64-unknown-linux-gnu"),
Triple("aarch64-unknown-linux-gnu"),
Expand Down Expand Up @@ -292,13 +291,18 @@ 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.hasAnyPrefix(from: ["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)
}

if self.versionsConfiguration.swiftVersion.hasPrefix("5.9") ||
self.versionsConfiguration.swiftVersion.hasPrefix("5.10") {
if self.versionsConfiguration.swiftVersion.hasAnyPrefix(from: ["5.9", "5.10"]) {
try await generator.symlinkClangHeaders()
}

Expand Down
Original file line number Diff line number Diff line change
@@ -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)
}
}
}