Skip to content

Commit ac1ba38

Browse files
committed
Add support for artifact bundles with static libraries
1 parent 1951243 commit ac1ba38

File tree

25 files changed

+710
-75
lines changed

25 files changed

+710
-75
lines changed

Package.swift

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,11 @@ let package = Package(
192192
swiftSettings: swiftSettings(languageMode: .v6)),
193193
.target(
194194
name: "SWBTaskConstruction",
195-
dependencies: ["SWBCore", "SWBUtil"],
195+
dependencies: [
196+
"SWBCore",
197+
"SWBUtil",
198+
.product(name: "SwiftDriver", package: "swift-driver")
199+
],
196200
exclude: ["CMakeLists.txt"],
197201
swiftSettings: swiftSettings(languageMode: .v5)),
198202
.target(
@@ -206,6 +210,7 @@ let package = Package(
206210
"SWBCSupport",
207211
"SWBLibc",
208212
.product(name: "ArgumentParser", package: "swift-argument-parser"),
213+
.product(name: "SwiftDriver", package: "swift-driver"),
209214
.product(name: "SystemPackage", package: "swift-system", condition: .when(platforms: [.linux, .openbsd, .android, .windows, .custom("freebsd")])),
210215
],
211216
exclude: ["CMakeLists.txt"],

Sources/SWBApplePlatform/AppIntentsMetadataCompiler.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ final public class AppIntentsMetadataCompilerSpec: GenericCommandLineToolSpec, S
122122
for variant in buildVariants {
123123
let scope = cbc.scope.subscope(binding: BuiltinMacros.variantCondition, to: variant)
124124
for arch in archs {
125-
let scope = scope.subscope(binding: BuiltinMacros.archCondition, to: arch)
125+
let scope = scope.subscopeBindingArchAndTriple(arch: arch)
126126
let dependencyInfoFile = scope.evaluate(BuiltinMacros.LD_DEPENDENCY_INFO_FILE)
127127
let libtoolDependencyInfo = scope.evaluate(BuiltinMacros.LIBTOOL_DEPENDENCY_INFO_FILE)
128128
if !isStaticLibrary && !dependencyInfoFile.isEmpty {
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift open source project
4+
//
5+
// Copyright (c) 2025 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See http://swift.org/LICENSE.txt for license information
9+
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
package import SWBUtil
14+
import Foundation
15+
16+
package struct ArtifactBundleInfo: Hashable {
17+
package let bundlePath: Path
18+
package let metadata: ArtifactBundleMetadata
19+
20+
package init(bundlePath: Path, metadata: ArtifactBundleMetadata) {
21+
self.bundlePath = bundlePath
22+
self.metadata = metadata
23+
}
24+
}
25+
26+
package struct ArtifactBundleMetadata: Sendable, Hashable, Decodable {
27+
package let schemaVersion: String
28+
package let artifacts: [String: ArtifactMetadata]
29+
30+
package struct ArtifactMetadata: Sendable, Hashable, Decodable {
31+
package let type: ArtifactType
32+
package let version: String
33+
package let variants: [VariantMetadata]
34+
}
35+
36+
package enum ArtifactType: String, Sendable, Decodable {
37+
case executable
38+
case staticLibrary
39+
case swiftSDK
40+
case crossCompilationDestination
41+
}
42+
43+
package struct VariantMetadata: Sendable, Hashable, Decodable {
44+
package let path: Path
45+
package let supportedTriples: [String]?
46+
package let staticLibraryMetadata: StaticLibraryMetadata?
47+
}
48+
49+
package struct StaticLibraryMetadata: Sendable, Hashable, Decodable {
50+
package let headerPaths: [Path]
51+
package let moduleMapPath: Path?
52+
}
53+
54+
package static func parse(
55+
at bundlePath: Path,
56+
fileSystem: any FSProxy
57+
) throws -> ArtifactBundleMetadata {
58+
let infoPath = bundlePath.join("info.json")
59+
60+
guard fileSystem.exists(infoPath) else {
61+
throw StubError.error("artifact bundle info.json not found at '\(infoPath.str)'")
62+
}
63+
64+
do {
65+
let bytes = try fileSystem.read(infoPath)
66+
let data = Data(bytes.bytes)
67+
let decoder = JSONDecoder()
68+
let metadata = try decoder.decode(ArtifactBundleMetadata.self, from: data)
69+
70+
guard let version = try? Version(metadata.schemaVersion) else {
71+
throw StubError.error("invalid schema version '\(metadata.schemaVersion)' in '\(infoPath.str)'")
72+
}
73+
74+
switch version {
75+
case Version(1, 2), Version(1, 1), Version(1, 0):
76+
break
77+
default:
78+
throw StubError.error("invalid `schemaVersion` of bundle manifest at '\(infoPath)': \(version)")
79+
}
80+
81+
return metadata
82+
} catch {
83+
throw StubError.error("failed to parse ArtifactBundle info.json at '\(infoPath.str)': \(error.localizedDescription)")
84+
}
85+
}
86+
}

Sources/SWBCore/BuildRequestContext.swift

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -44,25 +44,25 @@ public final class BuildRequestContext: Sendable {
4444
}
4545

4646
/// Get the cached settings for the given parameters, without considering the context of any project/target.
47-
public func getCachedSettings(_ parameters: BuildParameters) -> Settings {
47+
package func getCachedSettings(_ parameters: BuildParameters) -> Settings {
4848
workspaceContext.workspaceSettingsCache.getCachedSettings(parameters, buildRequestContext: self, purpose: .build, filesSignature: filesSignature(for:))
4949
}
5050

5151
/// Get the cached settings for the given parameters and project.
52-
public func getCachedSettings(_ parameters: BuildParameters, project: Project, purpose: SettingsPurpose = .build, provisioningTaskInputs: ProvisioningTaskInputs? = nil, impartedBuildProperties: [ImpartedBuildProperties]? = nil) -> Settings {
53-
getCachedSettings(parameters, project: project, target: nil, purpose: purpose, provisioningTaskInputs: provisioningTaskInputs, impartedBuildProperties: impartedBuildProperties)
52+
package func getCachedSettings(_ parameters: BuildParameters, project: Project, purpose: SettingsPurpose = .build, provisioningTaskInputs: ProvisioningTaskInputs? = nil) -> Settings {
53+
getCachedSettings(parameters, project: project, target: nil, purpose: purpose, provisioningTaskInputs: provisioningTaskInputs, impartedBuildProperties: nil, artifactBundleInfo: nil)
5454
}
5555

5656
/// Get the cached settings for the given parameters and target.
57-
public func getCachedSettings(_ parameters: BuildParameters, target: Target, purpose: SettingsPurpose = .build, provisioningTaskInputs: ProvisioningTaskInputs? = nil, impartedBuildProperties: [ImpartedBuildProperties]? = nil) -> Settings {
58-
getCachedSettings(parameters, project: workspaceContext.workspace.project(for: target), target: target, purpose: purpose, provisioningTaskInputs: provisioningTaskInputs, impartedBuildProperties: impartedBuildProperties)
57+
package func getCachedSettings(_ parameters: BuildParameters, target: Target, purpose: SettingsPurpose = .build, provisioningTaskInputs: ProvisioningTaskInputs? = nil, impartedBuildProperties: [ImpartedBuildProperties]? = nil, artifactBundleInfo: [ArtifactBundleInfo]? = nil) -> Settings {
58+
getCachedSettings(parameters, project: workspaceContext.workspace.project(for: target), target: target, purpose: purpose, provisioningTaskInputs: provisioningTaskInputs, impartedBuildProperties: impartedBuildProperties, artifactBundleInfo: artifactBundleInfo)
5959
}
6060

6161
/// Private method to get the cached settings for the given parameters, project, and target.
6262
///
6363
/// - remark: This is private so that clients don't somehow call this with a project which doesn't match the target. There are public methods covering this one.
64-
private func getCachedSettings(_ parameters: BuildParameters, project: Project, target: Target?, purpose: SettingsPurpose = .build, provisioningTaskInputs: ProvisioningTaskInputs?, impartedBuildProperties: [ImpartedBuildProperties]?) -> Settings {
65-
workspaceContext.workspaceSettingsCache.getCachedSettings(parameters, project: project, target: target, purpose: purpose, provisioningTaskInputs: provisioningTaskInputs, impartedBuildProperties: impartedBuildProperties, buildRequestContext: self, filesSignature: filesSignature(for:))
64+
private func getCachedSettings(_ parameters: BuildParameters, project: Project, target: Target?, purpose: SettingsPurpose = .build, provisioningTaskInputs: ProvisioningTaskInputs?, impartedBuildProperties: [ImpartedBuildProperties]?, artifactBundleInfo: [ArtifactBundleInfo]?) -> Settings {
65+
workspaceContext.workspaceSettingsCache.getCachedSettings(parameters, project: project, target: target, purpose: purpose, provisioningTaskInputs: provisioningTaskInputs, impartedBuildProperties: impartedBuildProperties, artifactBundleInfo: artifactBundleInfo, buildRequestContext: self, filesSignature: filesSignature(for:))
6666
}
6767

6868
@_spi(Testing) public func getCachedMacroConfigFile(_ path: Path, project: Project? = nil, context: MacroConfigLoadContext) -> MacroConfigInfo {

Sources/SWBCore/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ add_library(SWBCore
1212
ActivityReporting.swift
1313
Apple/DeviceFamily.swift
1414
Apple/InterfaceBuilderShared.swift
15+
ArtifactBundleMetadata.swift
1516
BuildDependencyInfo.swift
1617
BuildFileFilteringContext.swift
1718
BuildFileResolution.swift

Sources/SWBCore/MacroEvaluationExtensions.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,4 +126,10 @@ extension MacroEvaluationScope {
126126
return ($0 == BuiltinMacros.TARGET_BUILD_SUBPATH) ? self.table.namespace.parseLiteralString("") : nil
127127
})
128128
}
129+
130+
public func subscopeBindingArchAndTriple(arch: String) -> MacroEvaluationScope {
131+
let archScope = subscope(binding: BuiltinMacros.archCondition, to: arch)
132+
let swiftTargetTriple = archScope.evaluate(BuiltinMacros.SWIFT_TARGET_TRIPLE)
133+
return archScope.subscope(binding: BuiltinMacros.normalizedUnversionedTripleCondition, to: swiftTargetTriple)
134+
}
129135
}

Sources/SWBCore/Settings/BuiltinMacros.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,9 @@ public final class BuiltinMacros {
2525
public static let platformCondition = BuiltinMacros.declareConditionParameter("__platform_filter")
2626
public static let sdkBuildVersionCondition = BuiltinMacros.declareConditionParameter("_sdk_build_version")
2727
public static let targetNameCondition = BuiltinMacros.declareConditionParameter("target")
28+
public static let normalizedUnversionedTripleCondition = BuiltinMacros.declareConditionParameter("__normalized_unversioned_triple")
2829

29-
private static let allBuiltinConditionParameters = [archCondition, sdkCondition, variantCondition, configurationCondition, platformCondition, sdkBuildVersionCondition, targetNameCondition]
30+
private static let allBuiltinConditionParameters = [archCondition, sdkCondition, variantCondition, configurationCondition, platformCondition, sdkBuildVersionCondition, targetNameCondition, normalizedUnversionedTripleCondition]
3031

3132
// MARK: Built-in Macro Definitions
3233

0 commit comments

Comments
 (0)