Skip to content

Commit b54602b

Browse files
authored
Do not report missing dependencies between targets in different domains (swiftlang#344)
Also, update the missing target dependency diagnostics so they no longer rely on sleep calls, increasing reliability and allowing us to run them in CI rdar://146349362
1 parent 325197c commit b54602b

File tree

2 files changed

+99
-4
lines changed

2 files changed

+99
-4
lines changed

Sources/SWBBuildSystem/BuildOperation.swift

+4
Original file line numberDiff line numberDiff line change
@@ -885,6 +885,10 @@ package final class BuildOperation: BuildSystemOperation {
885885
guard targetSettings.platform?.name == antecedentSettings.platform?.name && targetSettings.sdkVariant?.name == antecedentSettings.sdkVariant?.name else {
886886
return
887887
}
888+
// Implicit dependency domains allow projects to build multiple copies of a module in a workspace with implicit dependencies enabled, so never diagnose a cross-domain dependency.
889+
guard targetSettings.globalScope.evaluate(BuiltinMacros.IMPLICIT_DEPENDENCY_DOMAIN) == antecedentSettings.globalScope.evaluate(BuiltinMacros.IMPLICIT_DEPENDENCY_DOMAIN) else {
890+
return
891+
}
888892

889893
let message: DiagnosticData
890894
if self.userPreferences.enableDebugActivityLogs {

Tests/SWBBuildSystemTests/SwiftDriverTests.swift

+95-4
Original file line numberDiff line numberDiff line change
@@ -4518,7 +4518,7 @@ fileprivate struct SwiftDriverTests: CoreBasedTests {
45184518
}
45194519
}
45204520

4521-
@Test(.requireSDKs(.macOS), .disabled(if: getEnvironmentVariable("CI")?.isEmpty == false, "Test relies on timing which would require costly delays in CI"))
4521+
@Test(.requireSDKs(.macOS))
45224522
func diagnosingMissingTargetDependencies() async throws {
45234523
try await withTemporaryDirectory { tmpDir in
45244524
let testWorkspace = try await TestWorkspace(
@@ -4565,8 +4565,6 @@ fileprivate struct SwiftDriverTests: CoreBasedTests {
45654565
"Framework3",
45664566
type: .framework,
45674567
buildPhases: [
4568-
// Ensure that we always happen to build the targets in the right order, even though the dependency is missing.
4569-
TestShellScriptBuildPhase(name: "Sleep", originalObjectID: "A", contents: "sleep 10", alwaysOutOfDate: true),
45704568
TestSourcesBuildPhase(["file_3.swift"]),
45714569
]),
45724570
])])
@@ -4610,7 +4608,7 @@ fileprivate struct SwiftDriverTests: CoreBasedTests {
46104608

46114609
for warningLevel in [BooleanWarningLevel.yes, .yesError] {
46124610
let parameters = BuildParameters(configuration: "Debug", overrides: ["DIAGNOSE_MISSING_TARGET_DEPENDENCIES": warningLevel.rawValue])
4613-
let buildRequest = BuildRequest(parameters: parameters, buildTargets: tester.workspace.projects[0].targets.map({ BuildRequest.BuildTargetInfo(parameters: parameters, target: $0) }), continueBuildingAfterErrors: false, useParallelTargets: true, useImplicitDependencies: false, useDryRun: false)
4611+
let buildRequest = BuildRequest(parameters: parameters, buildTargets: tester.workspace.projects[0].targets.map({ BuildRequest.BuildTargetInfo(parameters: parameters, target: $0) }), continueBuildingAfterErrors: false, useParallelTargets: false, useImplicitDependencies: false, useDryRun: false)
46144612

46154613
try await tester.checkBuild(runDestination: .macOS, buildRequest: buildRequest, persistent: true) { results in
46164614
switch warningLevel {
@@ -4631,6 +4629,99 @@ fileprivate struct SwiftDriverTests: CoreBasedTests {
46314629
}
46324630
}
46334631

4632+
@Test(.requireSDKs(.macOS))
4633+
func diagnosingMissingTargetDependenciesWithDependencyDomains() async throws {
4634+
try await withTemporaryDirectory { tmpDir in
4635+
let testWorkspace = try await TestWorkspace(
4636+
"Test",
4637+
sourceRoot: tmpDir.join("Test"),
4638+
projects: [
4639+
TestProject(
4640+
"aProject",
4641+
groupTree: TestGroup(
4642+
"Sources",
4643+
children: [
4644+
TestFile("Framework1.h"),
4645+
TestFile("file_1.c"),
4646+
TestFile("file_2.swift"),
4647+
]),
4648+
buildConfigurations: [TestBuildConfiguration(
4649+
"Debug",
4650+
buildSettings: [
4651+
"PRODUCT_NAME": "$(TARGET_NAME)",
4652+
"CLANG_ENABLE_MODULES": "YES",
4653+
"_EXPERIMENTAL_CLANG_EXPLICIT_MODULES": "YES",
4654+
"SWIFT_ENABLE_EXPLICIT_MODULES": "YES",
4655+
"SWIFT_VERSION": swiftVersion,
4656+
"DEFINES_MODULE": "YES",
4657+
"VALID_ARCHS": "arm64",
4658+
"DSTROOT": tmpDir.join("dstroot").str,
4659+
"DIAGNOSE_MISSING_TARGET_DEPENDENCIES": "YES",
4660+
])],
4661+
targets: [
4662+
TestStandardTarget(
4663+
"Framework1",
4664+
type: .framework,
4665+
buildConfigurations: [TestBuildConfiguration(
4666+
"Debug",
4667+
buildSettings: [
4668+
"IMPLICIT_DEPENDENCY_DOMAIN": "One"
4669+
])],
4670+
buildPhases: [
4671+
TestHeadersBuildPhase([TestBuildFile("Framework1.h", headerVisibility: .public)]),
4672+
TestSourcesBuildPhase(["file_1.c"]),
4673+
]),
4674+
TestStandardTarget(
4675+
"Framework2",
4676+
type: .framework,
4677+
buildConfigurations: [TestBuildConfiguration(
4678+
"Debug",
4679+
buildSettings: [
4680+
"IMPLICIT_DEPENDENCY_DOMAIN": "Two"
4681+
])],
4682+
buildPhases: [
4683+
TestSourcesBuildPhase(["file_2.swift"]),
4684+
]),
4685+
])])
4686+
4687+
let tester = try await BuildOperationTester(getCore(), testWorkspace, simulated: false)
4688+
4689+
try await tester.fs.writeFileContents(testWorkspace.sourceRoot.join("aProject/Framework1.h")) { stream in
4690+
stream <<<
4691+
"""
4692+
void foo(void);
4693+
"""
4694+
}
4695+
4696+
try await tester.fs.writeFileContents(testWorkspace.sourceRoot.join("aProject/file_1.c")) { stream in
4697+
stream <<<
4698+
"""
4699+
#include <Framework1/Framework1.h>
4700+
void foo(void) {}
4701+
"""
4702+
}
4703+
4704+
try await tester.fs.writeFileContents(testWorkspace.sourceRoot.join("aProject/file_2.swift")) { stream in
4705+
stream <<<
4706+
"""
4707+
import Framework1
4708+
public func baz() {
4709+
foo()
4710+
}
4711+
"""
4712+
}
4713+
4714+
let parameters = BuildParameters(configuration: "Debug")
4715+
let buildRequest = BuildRequest(parameters: parameters, buildTargets: tester.workspace.projects[0].targets.map({ BuildRequest.BuildTargetInfo(parameters: parameters, target: $0) }), continueBuildingAfterErrors: false, useParallelTargets: false, useImplicitDependencies: false, useDryRun: false)
4716+
4717+
try await tester.checkBuild(runDestination: .macOS, buildRequest: buildRequest, persistent: true) { results in
4718+
// Normally, we would report "'Framework2' is missing a dependency on 'Framework1' because dependency scan of Swift module 'Framework2' discovered a dependency on 'Framework1'"
4719+
// However, because the targets are in different domains, we shouldn't report any diagnostics.
4720+
results.checkNoDiagnostics()
4721+
}
4722+
}
4723+
}
4724+
46344725
@Test(.requireSDKs(.macOS))
46354726
func explicitPCMDeduplicationWithBuildVariant() async throws {
46364727
try await withTemporaryDirectory { tmpDirPath async throws -> Void in

0 commit comments

Comments
 (0)