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
3 changes: 2 additions & 1 deletion Fixtures/ModuleAliasing/DirectDeps2/AppPkg/Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ let package = Package(
package: "Bpkg",
moduleAliases: ["Utils": "BUtils"]
)
]),
]
),
]
)

2 changes: 1 addition & 1 deletion Sources/PackageGraph/Resolution/ResolvedProduct.swift
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ public struct ResolvedProduct {

extension ResolvedProduct: CustomStringConvertible {
public var description: String {
"<ResolvedProduct: \(self.name), \(self.type)>"
"<ResolvedProduct: \(self.packageIdentity), \(self.name), \(self.type)>"
}
}

Expand Down
23 changes: 12 additions & 11 deletions Sources/SwiftBuildSupport/PackagePIFBuilder+Helpers.swift
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ extension PackageModel.Product {
var pifTargetGUID: GUID { pifTargetGUID(suffix: nil) }

func pifTargetGUID(suffix: TargetSuffix?) -> GUID {
PackagePIFBuilder.targetGUID(forProductName: self.name, suffix: suffix)
PackagePIFBuilder.targetGUID(forProductName: self.name, withId:self.identity, suffix: suffix)
}
}

Expand Down Expand Up @@ -134,11 +134,11 @@ extension PackagePIFBuilder {
///
/// This format helps make sure that there is no collision with any other PIF targets,
/// and in particular that a PIF target and a PIF product can have the same name (as they often do).
static func targetGUID(forProductName name: String, suffix: TargetSuffix? = nil) -> GUID {
let suffixDescription = suffix.uniqueDescription(forName: name)
return "PACKAGE-PRODUCT:\(name)\(suffixDescription)"
static func targetGUID(forProductName name: String, withId id: String, suffix: TargetSuffix? = nil) -> GUID {
let suffixDescription: String = suffix.uniqueDescription(forName: name)
return "PACKAGE-PRODUCT:\(id).\(name)\(suffixDescription)"
}

/// Helper function to consistently generate a target name string for a product in a package.
///
/// This format helps make sure that modules and products with the same name (as they often have)
Expand Down Expand Up @@ -775,13 +775,13 @@ extension Collection<PackageGraph.ResolvedModule> {
/// Recursively applies a block to each of the *dependencies* of the given module, in topological sort order.
/// Each module or product dependency is visited only once.
func recursivelyTraverseDependencies(with block: (ResolvedModule.Dependency) -> Void) {
var moduleNamesSeen: Set<String> = []
var productNamesSeen: Set<String> = []
var moduleGuidsSeen: Set<ResolvedModule.ID> = []
var productGuidsSeen: Set<ResolvedProduct.ID> = []

func visitDependency(_ dependency: ResolvedModule.Dependency) {
switch dependency {
case .module(let moduleDependency, _):
let (unseenModule, _) = moduleNamesSeen.insert(moduleDependency.name)
let (unseenModule, _) = moduleGuidsSeen.insert(moduleDependency.id)
guard unseenModule else { return }

if moduleDependency.underlying.type != .macro {
Expand All @@ -792,15 +792,15 @@ extension Collection<PackageGraph.ResolvedModule> {
block(dependency)

case .product(let productDependency, let conditions):
let (unseenProduct, _) = productNamesSeen.insert(productDependency.name)
let (unseenProduct, _) = productGuidsSeen.insert(productDependency.id)
guard unseenProduct && !productDependency.isBinaryOnlyExecutableProduct else { return }
block(dependency)

// We need to visit any binary modules to be able to add direct references to them to any client
// targets.
// This is needed so that XCFramework processing always happens *prior* to building any client targets.
for moduleDependency in productDependency.modules where moduleDependency.isBinary {
if moduleNamesSeen.contains(moduleDependency.name) { continue }
if moduleGuidsSeen.contains(moduleDependency.id) { continue }
block(.module(moduleDependency, conditions: conditions))
}
}
Expand Down Expand Up @@ -848,12 +848,13 @@ extension ProjectModel.BuildSettings {
extension ProjectModel.Project {
@discardableResult
public mutating func addTarget(
packageProductId: String,
packageProductName: String,
productType: ProjectModel.Target.ProductType
) throws -> WritableKeyPath<ProjectModel.Project, ProjectModel.Target> {
let targetKeyPath = try self.addTarget { _ in
ProjectModel.Target(
id: PackagePIFBuilder.targetGUID(forProductName: packageProductName),
id: PackagePIFBuilder.targetGUID(forProductName: packageProductName, withId: packageProductId),
productType: productType,
name: packageProductName,
productName: packageProductName
Expand Down
134 changes: 95 additions & 39 deletions Tests/FunctionalTests/ModuleAliasingFixtureTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,32 +30,39 @@ struct ModuleAliasingFixtureTests {
.tags(
Tag.Feature.Command.Build,
),
arguments: SupportedBuildSystemOnAllPlatforms, BuildConfiguration.allCases,
arguments: getBuildData(for: SupportedBuildSystemOnAllPlatforms),
)
func moduleDirectDeps1(
buildSystem: BuildSystemProvider.Kind,
configuration: BuildConfiguration,
data: BuildData,
) async throws {
let buildSystem = data.buildSystem
let configuration = data.config

try await withKnownIssue(isIntermittent: true) {
try await fixture(name: "ModuleAliasing/DirectDeps1") { fixturePath in
let pkgPath = fixturePath.appending(components: "AppPkg")
let buildPath = try pkgPath.appending(components: buildSystem.binPath(for: configuration))
let expectedModules = [
"GameUtils.swiftmodule",
"Utils.swiftmodule",
]
try await executeSwiftBuild(
pkgPath,
configuration: configuration,
extraArgs: ["--vv"],
buildSystem: buildSystem,
)

expectFileExists(at: buildPath.appending(components: executableName("App")))
switch buildSystem {
for file in expectedModules {
switch buildSystem {
case .native:
expectFileExists(at: buildPath.appending(components: "Modules", "GameUtils.swiftmodule"))
expectFileExists(at: buildPath.appending(components: "Modules", "Utils.swiftmodule"))
expectFileExists(at: buildPath.appending(components: "Modules", file))
case .swiftbuild:
expectFileExists(at: buildPath.appending(components: "GameUtils.swiftmodule"))
expectFileExists(at: buildPath.appending(components: "Utils.swiftmodule"))
expectFileExists(at: buildPath.appending(components: file))
case .xcode:
#expect(Bool(false), "expectations are not implemented")
Issue.record("expectations are not implemented")
}
}
_ = try await executeSwiftBuild(
pkgPath,
Expand All @@ -67,93 +74,130 @@ struct ModuleAliasingFixtureTests {
ProcessInfo.hostOperatingSystem == .windows && buildSystem == .swiftbuild
}
}

@Test(
.issue("https://github.com/swiftlang/swift-package-manager/issues/8987", relationship: .defect),
.issue("https://github.com/swiftlang/swift-package-manager/pull/9130", relationship: .fixedBy),
.IssueWindowsLongPath,
.IssueWindowsCannotSaveAttachment,
.tags(
Tag.Feature.Command.Build,
),
arguments: SupportedBuildSystemOnAllPlatforms, BuildConfiguration.allCases,
arguments: getBuildData(for: SupportedBuildSystemOnAllPlatforms),
)
func moduleDirectDeps2(
buildSystem: BuildSystemProvider.Kind,
configuration: BuildConfiguration,
data: BuildData
) async throws {
try await withKnownIssue {
let buildSystem = data.buildSystem
let configuration = data.config
try await withKnownIssue(isIntermittent: true) {
try await fixture(name: "ModuleAliasing/DirectDeps2") { fixturePath in
let pkgPath = fixturePath.appending(components: "AppPkg")
let buildPath = try pkgPath.appending(components: buildSystem.binPath(for: configuration))
let expectedModules = [
"AUtils.swiftmodule",
"BUtils.swiftmodule",
]
try await executeSwiftBuild(
pkgPath,
configuration: configuration,
extraArgs: ["--vv"],
buildSystem: buildSystem,
)
expectFileExists(at: buildPath.appending(components: executableName("App")))
expectFileExists(at: buildPath.appending(components: "Modules", "AUtils.swiftmodule"))
expectFileExists(at: buildPath.appending(components: "Modules", "BUtils.swiftmodule"))
for file in expectedModules {
switch buildSystem {
case .native:
expectFileExists(at: buildPath.appending(components: "Modules", file))
case .swiftbuild:
expectFileExists(at: buildPath.appending(components: file))
case .xcode:
Issue.record("expectations are not implemented")
}
}
_ = try await executeSwiftBuild(
pkgPath,
configuration: configuration,
buildSystem: buildSystem,
)
}
} when: {
buildSystem == .swiftbuild
ProcessInfo.hostOperatingSystem == .windows && buildSystem == .swiftbuild
}
}

@Test(
.issue("https://github.com/swiftlang/swift-package-manager/issues/8987", relationship: .defect),
.issue("https://github.com/swiftlang/swift-package-manager/pull/9130", relationship: .fixedBy),
.IssueWindowsLongPath,
.IssueWindowsCannotSaveAttachment,
.tags(
Tag.Feature.Command.Build,
),
arguments: SupportedBuildSystemOnAllPlatforms, BuildConfiguration.allCases,
arguments: getBuildData(for: SupportedBuildSystemOnAllPlatforms),
)
func moduleNestedDeps1(
buildSystem: BuildSystemProvider.Kind,
configuration: BuildConfiguration,
data: BuildData,
) async throws {
try await withKnownIssue {
let buildSystem = data.buildSystem
let configuration = data.config
try await withKnownIssue(isIntermittent: true) {
try await fixture(name: "ModuleAliasing/NestedDeps1") { fixturePath in
let pkgPath = fixturePath.appending(components: "AppPkg")
let buildPath = try pkgPath.appending(components: buildSystem.binPath(for: configuration))
let expectedModules = [
"A.swiftmodule",
"AFooUtils.swiftmodule",
"CarUtils.swiftmodule",
"X.swiftmodule",
"XFooUtils.swiftmodule",
"XUtils.swiftmodule",
]
try await executeSwiftBuild(
pkgPath,
configuration: configuration,
extraArgs: ["--vv"],
buildSystem: buildSystem,
)
expectFileExists(at: buildPath.appending(components: executableName("App")))
expectFileExists(at: buildPath.appending(components: "Modules", "A.swiftmodule"))
expectFileExists(at: buildPath.appending(components: "Modules", "AFooUtils.swiftmodule"))
expectFileExists(at: buildPath.appending(components: "Modules", "CarUtils.swiftmodule"))
expectFileExists(at: buildPath.appending(components: "Modules", "X.swiftmodule"))
expectFileExists(at: buildPath.appending(components: "Modules", "XFooUtils.swiftmodule"))
expectFileExists(at: buildPath.appending(components: "Modules", "XUtils.swiftmodule"))
for file in expectedModules {
switch buildSystem {
case .native:
expectFileExists(at: buildPath.appending(components: "Modules", file))
case .swiftbuild:
expectFileExists(at: buildPath.appending(components: file))
case .xcode:
Issue.record("expectations are not implemented")
}
}

_ = try await executeSwiftBuild(
pkgPath,
configuration: configuration,
buildSystem: buildSystem,
)
}
} when: {
buildSystem == .swiftbuild
ProcessInfo.hostOperatingSystem == .windows && buildSystem == .swiftbuild
}
}

@Test(
.issue("https://github.com/swiftlang/swift-package-manager/issues/8987", relationship: .defect),
.issue("https://github.com/swiftlang/swift-package-manager/pull/9130", relationship: .fixedBy),
.IssueWindowsLongPath,
.IssueWindowsCannotSaveAttachment,
.tags(
Tag.Feature.Command.Build,
),
arguments: SupportedBuildSystemOnAllPlatforms, BuildConfiguration.allCases,
arguments: getBuildData(for: SupportedBuildSystemOnAllPlatforms),
)
func moduleNestedDeps2(
buildSystem: BuildSystemProvider.Kind,
configuration: BuildConfiguration,
data: BuildData,
) async throws {
try await withKnownIssue {
let buildSystem = data.buildSystem
let configuration = data.config
try await withKnownIssue(isIntermittent: true) {
try await fixture(name: "ModuleAliasing/NestedDeps2") { fixturePath in
let pkgPath = fixturePath.appending(components: "AppPkg")
let buildPath = try pkgPath.appending(components: buildSystem.binPath(for: configuration))
Expand All @@ -163,19 +207,31 @@ struct ModuleAliasingFixtureTests {
extraArgs: ["--vv"],
buildSystem: buildSystem,
)
let expectedModules = [
"A.swiftmodule",
"BUtils.swiftmodule",
"CUtils.swiftmodule",
"XUtils.swiftmodule",
]
expectFileExists(at: buildPath.appending(components: executableName("App")))
expectFileExists(at: buildPath.appending(components: "Modules", "A.swiftmodule"))
expectFileExists(at: buildPath.appending(components: "Modules", "BUtils.swiftmodule"))
expectFileExists(at: buildPath.appending(components: "Modules", "CUtils.swiftmodule"))
expectFileExists(at: buildPath.appending(components: "Modules", "XUtils.swiftmodule"))
for file in expectedModules {
switch buildSystem {
case .native:
expectFileExists(at: buildPath.appending(components: "Modules", file))
case .swiftbuild:
expectFileExists(at: buildPath.appending(components: file))
case .xcode:
Issue.record("expectations are not implemented")
}
}
_ = try await executeSwiftBuild(
pkgPath,
configuration: configuration,
buildSystem: buildSystem,
)
}
} when: {
buildSystem == .swiftbuild
ProcessInfo.hostOperatingSystem == .windows && buildSystem == .swiftbuild
}
}
}