Skip to content

Merge main 1d48e0a into release/6.2 #8488

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

Closed
wants to merge 12 commits into from
Closed
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
26 changes: 17 additions & 9 deletions Documentation/Usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -497,7 +497,7 @@ This feature is intended for use in the following scenarios:

It is *not* expected that the packages would ever use this feature unless absolutely
necessary to support existing clients. Specifically, packages *should not*
adopt this syntax for tagging versions supporting the _latest GM_ Swift
adopt this syntax for tagging versions supporting the _latest released_ Swift
version.

The package manager supports looking for any of the following marked tags, in
Expand All @@ -511,7 +511,7 @@ order of preference:

The package manager will additionally look for a version-specific marked
manifest version when loading the particular version of a package, by searching
for a manifest in the form of `Package@swift-3.swift`. The set of markers
for a manifest in the form of `Package@swift-6.swift`. The set of markers
looked for is the same as for version-specific tag selection.

This feature is intended for use in cases where a package wishes to maintain
Expand All @@ -521,20 +521,28 @@ changes in the manifest API).

It is *not* expected the packages would ever use this feature unless absolutely
necessary to support existing clients. Specifically, packages *should not*
adopt this syntax for tagging versions supporting the _latest GM_ Swift
adopt this syntax for tagging versions supporting the _latest released_ Swift
version.

In case the current Swift version doesn't match any version-specific manifest,
the package manager will pick the manifest with the most compatible tools
version. For example, if there are three manifests:

`Package.swift` (tools version 3.0)
`Package@swift-4.swift` (tools version 4.0)
`Package@swift-4.2.swift` (tools version 4.2)
- `Package.swift` (tools version 6.0)
- `Package@swift-5.10.swift` (tools version 5.10)
- `Package@swift-5.9.swift` (tools version 5.9)

The package manager will pick `Package.swift` on Swift 3, `[email protected]` on
Swift 4, and `[email protected]` on Swift 4.2 and above because its tools
version will be most compatible with future version of the package manager.
The package manager will pick `Package.swift` on Swift 6 and above, because its
tools version will be most compatible with future version of the package manager.
When using Swift 5.10, it will pick `[email protected]`. Otherwise, when
using Swift 5.9 it will pick `[email protected]`, and this is the minimum
tools version this package may be used with.

A package may have versioned manifest files which specify newer tools versions
than its unversioned `Package.swift` file[^1]. In this scenario, the manifest
corresponding to the newest-compatible tools version will be used.

[^1]: Support for having a versioned manifest file with a _newer_ tools version was required when the feature was first introduced, because prior versions of the package manager were not aware of the concept and only knew to look for the unversioned `Package.swift`. This is still supported, but there have been many Swift releases since the feature was introduced and it is now considered best practice to have `Package.swift` declare the newest-supported tools version and for versioned manifest files to only specifer older versions.

## Editing a Package

Expand Down
6 changes: 4 additions & 2 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -725,7 +725,7 @@ let package = Package(

// MARK: Additional Test Dependencies

.target(
.testTarget(
/** SwiftPM internal build test suite support library */
name: "_InternalBuildTestSupport",
dependencies: [
Expand All @@ -734,12 +734,13 @@ let package = Package(
"SwiftBuildSupport",
"_InternalTestSupport"
],
path: "Sources/_InternalBuildTestSupport",
swiftSettings: [
.unsafeFlags(["-static"]),
]
),

.target(
.testTarget(
/** SwiftPM internal test suite support library */
name: "_InternalTestSupport",
dependencies: [
Expand All @@ -754,6 +755,7 @@ let package = Package(
.product(name: "OrderedCollections", package: "swift-collections"),
"Workspace",
],
path: "./Sources/_InternalTestSupport",
swiftSettings: [
.unsafeFlags(["-static"]),
]
Expand Down
47 changes: 47 additions & 0 deletions Sources/Basics/Graph/GraphAlgorithms.swift
Original file line number Diff line number Diff line change
Expand Up @@ -131,3 +131,50 @@ public func depthFirstSearch<T: Hashable>(
}
}
}

/// Implements a pre-order depth-first search that traverses the whole graph and
/// doesn't distinguish between unique and duplicate nodes. The visitor can abort
/// a path as needed to prune the tree.
/// The method expects the graph to be acyclic but doesn't check that.
///
/// - Parameters:
/// - nodes: The list of input nodes to sort.
/// - successors: A closure for fetching the successors of a particular node.
/// - onNext: A callback to indicate the node currently being processed
/// including its parent (if any) and its depth. Returns whether to
/// continue down the current path.
///
/// - Complexity: O(v + e) where (v, e) are the number of vertices and edges
/// reachable from the input nodes via the relation.
public enum DepthFirstContinue {
case `continue`
case abort
}

public func depthFirstSearch<T: Hashable>(
_ nodes: [T],
successors: (T) throws -> [T],
visitNext: (T, _ parent: T?) throws -> DepthFirstContinue
) rethrows {
var stack = OrderedSet<TraversalNode<T>>()

for node in nodes {
precondition(stack.isEmpty)
stack.append(TraversalNode(parent: nil, curr: node))

while !stack.isEmpty {
let node = stack.removeLast()

if try visitNext(node.curr, node.parent) == .continue {
for succ in try successors(node.curr) {
stack.append(
TraversalNode(
parent: node.curr,
curr: succ
)
)
}
}
}
}
}
22 changes: 22 additions & 0 deletions Sources/Build/BuildDescription/ModuleBuildDescription.swift
Original file line number Diff line number Diff line change
Expand Up @@ -187,8 +187,30 @@ extension ModuleBuildDescription {
var dependencies: [Dependency] = []
plan.traverseDependencies(of: self) { product, _, description in
dependencies.append(.product(product, description))
return .continue
} onModule: { module, _, description in
dependencies.append(.module(module, description))
return .continue
}
return dependencies
}

package func recursiveLinkDependencies(using plan: BuildPlan) -> [Dependency] {
var dependencies: [Dependency] = []
plan.traverseDependencies(of: self) { product, _, description in
guard product.type != .macro && product.type != .plugin else {
return .abort
}

dependencies.append(.product(product, description))
return .continue
} onModule: { module, _, description in
guard module.type != .macro && module.type != .plugin else {
return .abort
}

dependencies.append(.module(module, description))
return .continue
}
return dependencies
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1042,6 +1042,12 @@ extension SwiftModuleBuildDescription {
ModuleBuildDescription.swift(self).dependencies(using: plan)
}

package func recursiveLinkDependencies(
using plan: BuildPlan
) -> [ModuleBuildDescription.Dependency] {
ModuleBuildDescription.swift(self).recursiveLinkDependencies(using: plan)
}

package func recursiveDependencies(
using plan: BuildPlan
) -> [ModuleBuildDescription.Dependency] {
Expand Down
3 changes: 1 addition & 2 deletions Sources/Build/BuildPlan/BuildPlan+Swift.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import class PackageModel.SystemLibraryModule
extension BuildPlan {
func plan(swiftTarget: SwiftModuleBuildDescription) throws {
// We need to iterate recursive dependencies because Swift compiler needs to see all the targets a target
// depends on.
// builds against
for case .module(let dependency, let description) in swiftTarget.recursiveDependencies(using: self) {
switch dependency.underlying {
case let underlyingTarget as ClangModule where underlyingTarget.type == .library:
Expand Down Expand Up @@ -53,5 +53,4 @@ extension BuildPlan {
}
}
}

}
12 changes: 6 additions & 6 deletions Sources/Build/BuildPlan/BuildPlan.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1154,8 +1154,8 @@ extension BuildPlan {

package func traverseDependencies(
of description: ModuleBuildDescription,
onProduct: (ResolvedProduct, BuildParameters.Destination, ProductBuildDescription?) -> Void,
onModule: (ResolvedModule, BuildParameters.Destination, ModuleBuildDescription?) -> Void
onProduct: (ResolvedProduct, BuildParameters.Destination, ProductBuildDescription?) -> DepthFirstContinue,
onModule: (ResolvedModule, BuildParameters.Destination, ModuleBuildDescription?) -> DepthFirstContinue
) {
var visited = Set<TraversalNode>()
func successors(
Expand Down Expand Up @@ -1196,16 +1196,16 @@ extension BuildPlan {
case .package:
[]
}
} onNext: { module, _ in
} visitNext: { module, _ in
switch module {
case .package:
break
return .continue

case .product(let product, let destination):
onProduct(product, destination, self.description(for: product, context: destination))
return onProduct(product, destination, self.description(for: product, context: destination))

case .module(let module, let destination):
onModule(module, destination, self.description(for: module, context: destination))
return onModule(module, destination, self.description(for: module, context: destination))
}
}
}
Expand Down
11 changes: 0 additions & 11 deletions Sources/PackageModel/SwiftSDKs/SwiftSDK.swift
Original file line number Diff line number Diff line change
Expand Up @@ -691,17 +691,6 @@ public struct SwiftSDK: Equatable {
hostSDK: SwiftSDK,
environment: Environment = .current
) -> SwiftSDK? {
if targetTriple.isWASI() {
let wasiSysroot = hostSDK.toolset.rootPaths.first?
.parentDirectory // usr
.appending(components: "share", "wasi-sysroot")
return SwiftSDK(
targetTriple: targetTriple,
toolset: hostSDK.toolset,
pathsConfiguration: .init(sdkRootPath: wasiSysroot)
)
}

#if os(macOS)
if let darwinPlatform = targetTriple.darwinPlatform {
// the Darwin SDKs are trivially available on macOS
Expand Down
Loading