Skip to content
Merged
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
71 changes: 31 additions & 40 deletions Sources/SwiftSDKGenerator/PlatformModels/LinuxDistribution.swift
Original file line number Diff line number Diff line change
Expand Up @@ -50,49 +50,41 @@ public enum LinuxDistribution: Hashable, Sendable {
}
}

private var commonPackages: [String] {
[
"libc6",
"libc6-dev",
"libgcc-s1",
"libstdc++6",
"linux-libc-dev",
"zlib1g",
"zlib1g-dev",
"libcurl4-openssl-dev",
]
}

public var requiredPackages: [String] {
switch self {
case .focal:
return [
"libc6",
"libc6-dev",
"libgcc-s1",
return commonPackages + [
"libgcc-10-dev",
"libicu66",
"libicu-dev",
"libstdc++-10-dev",
"libstdc++6",
"linux-libc-dev",
"zlib1g",
"zlib1g-dev",
]
case .jammy:
return [
"libc6",
"libc6-dev",
"libgcc-s1",
return commonPackages + [
"libgcc-12-dev",
"libicu70",
"libicu-dev",
"libstdc++-12-dev",
"libstdc++6",
"linux-libc-dev",
"zlib1g",
"zlib1g-dev",
]
case .noble:
return [
"libc6",
"libc6-dev",
"libgcc-s1",
return commonPackages + [
"libgcc-13-dev",
"libicu74",
"libicu-dev",
"libstdc++-13-dev",
"libstdc++6",
"linux-libc-dev",
"zlib1g",
"zlib1g-dev",
]
}
}
Expand Down Expand Up @@ -121,35 +113,34 @@ public enum LinuxDistribution: Hashable, Sendable {
}
}

private var commonPackages: [String] {
[
"libc6",
"libc6-dev",
"libgcc-s1",
"libstdc++6",
"linux-libc-dev",
"zlib1g",
"zlib1g-dev",
"libcurl4-openssl-dev",
]
}

public var requiredPackages: [String] {
switch self {
case .bullseye:
return [
"libc6",
"libc6-dev",
"libgcc-s1",
return commonPackages + [
"libgcc-10-dev",
"libicu67",
"libicu-dev",
"libstdc++-10-dev",
"libstdc++6",
"linux-libc-dev",
"zlib1g",
"zlib1g-dev",
]
case .bookworm:
return [
"libc6",
"libc6-dev",
"libgcc-s1",
return commonPackages + [
"libgcc-12-dev",
"libicu72",
"libicu-dev",
"libstdc++-12-dev",
"libstdc++6",
"linux-libc-dev",
"zlib1g",
"zlib1g-dev",
]
}
}
Expand Down
76 changes: 46 additions & 30 deletions Tests/SwiftSDKGeneratorTests/EndToEndTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -59,19 +59,21 @@ func buildSDK(_ logger: Logger, scratchPath: String, withArguments runArguments:
async throws -> String
{
var logger = logger
logger[metadataKey: "runArguments"] = "\"\(runArguments)\""
logger[metadataKey: "scratchPath"] = "\(scratchPath)"
logger[metadataKey: "scratchPath"] = .string(scratchPath)

logger.info("Building Swift SDK")
let packageDirectory = FilePath(#filePath)
.removingLastComponent()
.removingLastComponent()

var packageDirectory = FilePath(#filePath)
packageDirectory.removeLastComponent()
packageDirectory.removeLastComponent()
logger.info("Building SDK generator")
_ = try await Shell.readStdout(
"cd \(packageDirectory) && swift build --scratch-path \"\(scratchPath)\" --product swift-sdk-generator"
)

logger.info("Building Swift SDK", metadata: ["runArguments": .string(runArguments)])
let generatorOutput = try await Shell.readStdout(
"cd \(packageDirectory) && swift run --scratch-path \"\(scratchPath)\" swift-sdk-generator make-linux-sdk \(runArguments)"
)
logger.info("Finished building Swift SDK")

let installCommand = try XCTUnwrap(
generatorOutput.split(separator: "\n").first {
Expand All @@ -84,30 +86,28 @@ func buildSDK(_ logger: Logger, scratchPath: String, withArguments runArguments:
).stem
logger[metadataKey: "bundleName"] = "\(bundleName)"

logger.info("Checking installed Swift SDKs")
// Make sure this bundle hasn't been installed already.
let installedSDKs = try await Shell.readStdout("swift experimental-sdk list").components(
separatedBy: "\n"
)

// Make sure this bundle hasn't been installed already.
if installedSDKs.contains(bundleName) {
logger.info("Removing existing Swift SDK")
logger.info("Removing existing Swift SDK", metadata: ["bundleName": .string(bundleName)])
try await Shell.run("swift experimental-sdk remove \(bundleName)")
}

logger.info("Installing new Swift SDK")
logger.info("Installing new Swift SDK", metadata: ["bundleName": .string(bundleName)])
let installOutput = try await Shell.readStdout(String(installCommand))
XCTAssertTrue(installOutput.contains("successfully installed"))

return bundleName
}

private let testcases = [
#"""
"helloWorld": #"""
// Default program generated by swift package init
print("Hello, world!")
"""#,
#"""
"libcNonshared": #"""
// Check that libc_nonshared.a is linked properly
import Foundation

Expand All @@ -117,6 +117,10 @@ private let testcases = [

atexit(fin)
"""#,
"curlDependency": #"""
// Check that FoundationNetworking can be linked with libcurl4.a
import FoundationNetworking
"""#,
]

final class RepeatedBuildTests: XCTestCase {
Expand Down Expand Up @@ -258,7 +262,6 @@ func buildTestcase(_ logger: Logger, testcase: String, bundleName: String, tempD

// This is a workaround for if Swift 6.0 is used as the host toolchain to run the generator.
// We manually set the swift-tools-version to 5.9 to support building our test cases.
logger.info("Updating minimum swift-tools-version in test project...")
let package_swift = testPackageURL.appendingPathComponent("Package.swift")
let text = try String(contentsOf: package_swift, encoding: .utf8)
var lines = text.components(separatedBy: .newlines)
Expand Down Expand Up @@ -325,7 +328,6 @@ func buildTestcase(_ logger: Logger, testcase: String, bundleName: String, tempD

func buildTestcases(config: SDKConfiguration) async throws {
var logger = Logger(label: "EndToEndTests")
logger[metadataKey: "testcase"] = "testPackageInitExecutable"

if ProcessInfo.processInfo.environment.keys.contains("JENKINS_URL")
|| ProcessInfo.processInfo.environment.keys.contains("GITHUB_ACTIONS")
Expand All @@ -350,28 +352,42 @@ func buildTestcases(config: SDKConfiguration) async throws {
withArguments: config.sdkGeneratorArguments
)
}

logger.info("Built Swift SDK")
logger[metadataKey: "bundleName"] = .string(bundleName)

// Cleanup
func cleanupSDK() async {
logger.info("Removing Swift SDK to clean up...")
try? await Shell.run("swift experimental-sdk remove \(bundleName)")
}

for testcase in testcases {
do {
try await FileManager.default.withTemporaryDirectory(logger: logger) { tempDir in
try await buildTestcase(
logger,
testcase: testcase,
bundleName: bundleName,
tempDir: tempDir
)
func testcaseLogger(_ name: String) -> Logger {
var testcaseLogger = logger
testcaseLogger[metadataKey: "testcase"] = .string(name)
return testcaseLogger
}

// Let's run the test cases in parallel to speed things up!
logger.info("Running test cases...")
try await withThrowingTaskGroup(of: Void.self) { group in
for (name, testcase) in testcases {
let testcaseLogger = testcaseLogger(name)
group.addTask {
try await FileManager.default.withTemporaryDirectory(logger: testcaseLogger) { tempDir in
try await buildTestcase(
testcaseLogger,
testcase: testcase,
bundleName: bundleName,
tempDir: tempDir
)
}
}

do {
try await group.next()
} catch {
await cleanupSDK()
throw error
}
} catch {
await cleanupSDK()
throw error
}
}

Expand Down