Skip to content

Commit

Permalink
[Explicit Module Builds] Fix topological sort of inter-module depende…
Browse files Browse the repository at this point in the history
…ncy graph

to account for Swift overlay dependencies
  • Loading branch information
artemcm committed Sep 8, 2023
1 parent ac85d40 commit f5df590
Show file tree
Hide file tree
Showing 3 changed files with 128 additions and 2 deletions.
Expand Up @@ -57,7 +57,15 @@ extension InterModuleDependencyGraph {
var topologicalSorting: [ModuleDependencyId] {
get throws {
try topologicalSort(Array(modules.keys),
successors: { try moduleInfo(of: $0).directDependencies! })
successors: {
var dependencies: [ModuleDependencyId] = []
let moduleInfo = try moduleInfo(of: $0)
dependencies.append(contentsOf: moduleInfo.directDependencies ?? [])
if case .swift(let swiftModuleDetails) = moduleInfo.details {
dependencies.append(contentsOf: swiftModuleDetails.swiftOverlayDependencies ?? [])
}
return dependencies
})
}
}

Expand All @@ -71,7 +79,7 @@ extension InterModuleDependencyGraph {
/// T(v) = T(v) ∪ T(w)
/// }
/// }
func computeTransitiveClosure() throws -> [ModuleDependencyId : Set<ModuleDependencyId>] {
@_spi(Testing) public func computeTransitiveClosure() throws -> [ModuleDependencyId : Set<ModuleDependencyId>] {
let topologicalIdList = try self.topologicalSorting
// This structure will contain the final result
var transitiveClosureMap =
Expand Down
12 changes: 12 additions & 0 deletions Tests/SwiftDriverTests/ExplicitModuleBuildTests.swift
Expand Up @@ -1791,6 +1791,18 @@ final class ExplicitModuleBuildTests: XCTestCase {
XCTAssertTrue(scanJobCommand.contains(swiftInputWithoutSpace))
}

func testDependencyGraphTransitiveClosure() throws {
let moduleDependencyGraph =
try JSONDecoder().decode(
InterModuleDependencyGraph.self,
from: ModuleDependenciesInputs.simpleDependencyGraphInputWithSwiftOverlayDep.data(using: .utf8)!)
let reachabilityMap = try moduleDependencyGraph.computeTransitiveClosure()
let mainModuleDependencies = try XCTUnwrap(reachabilityMap[.swift("simpleTestModule")])
let aModuleDependencies = try XCTUnwrap(reachabilityMap[.swift("A")])
XCTAssertTrue(mainModuleDependencies.contains(.swift("B")))
XCTAssertTrue(aModuleDependencies.contains(.swift("B")))
}

func testExplicitSwiftModuleMap() throws {
let jsonExample : String = """
[
Expand Down
Expand Up @@ -515,6 +515,112 @@ enum ModuleDependenciesInputs {
"""
}

static var simpleDependencyGraphInputWithSwiftOverlayDep: String {
"""
{
"mainModuleName": "simpleTestModule",
"modules": [
{
"swift": "A"
},
{
"modulePath": "A.swiftmodule",
"sourceFiles": [
],
"directDependencies": [
{
"clang": "B"
}
],
"details": {
"swift": {
"moduleInterfacePath": "A.swiftmodule/A.swiftinterface",
"isFramework": false,
"extraPcmArgs": [
"-Xcc",
"-fapinotes-swift-version=5"
],
"swiftOverlayDependencies": [
{
"swift": "B"
}
]
}
}
},
{
"swift": "simpleTestModule"
},
{
"modulePath": "simpleTestModule.swiftmodule",
"sourceFiles": [
"/main/simpleTestModule.swift"
],
"directDependencies": [
{
"swift": "A"
},
],
"details": {
"swift": {
"isFramework": false,
"extraPcmArgs": [
"-Xcc",
"-fapinotes-swift-version=5"
]
}
}
},
{
"swift" : "B"
},
{
"modulePath" : "B.swiftmodule",
"sourceFiles": [
],
"directDependencies" : [
],
"details" : {
"swift" : {
"moduleInterfacePath": "B.swiftmodule/B.swiftinterface",
"isFramework": false,
"extraPcmArgs": [
"-Xcc",
"-fapinotes-swift-version=5"
],
}
}
},
{
"clang": "B"
},
{
"modulePath": "B.pcm",
"sourceFiles": [
"/B/module.map",
"/B/include/b.h"
],
"directDependencies": [
],
"details": {
"clang": {
"moduleMapPath": "/B/module.map",
"contextHash": "2QEMRLNY63H2N",
"commandLine": [
"-remove-preceeding-explicit-module-build-incompatible-options",
"-fno-implicit-modules",
"-emit-module",
"-fmodule-name=c_simd"
]
}
}
}
]
}
"""
}

static var mergeGraphInput2: String {
"""
{
Expand Down

0 comments on commit f5df590

Please sign in to comment.