Skip to content

Commit 01eb92d

Browse files
committed
Add an opt-out from explicit target dependency import checking.
`--disable-explicit-target-dependency-import-checking` prevents the verification code from being run as a just-in-case option to opt-out from this warning
1 parent 08725a9 commit 01eb92d

File tree

6 files changed

+34
-2
lines changed

6 files changed

+34
-2
lines changed

Sources/Build/BuildOperation.swift

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -161,8 +161,11 @@ public final class BuildOperation: PackageStructureDelegate, SPMBuildCore.BuildS
161161
// Emit a warning if a target imports another target in this build
162162
// without specifying it as a dependency in the manifest
163163
private func verifyTargetImports(in description: BuildDescription) throws {
164+
guard !description.disableExplicitTargetDependencyImportChecking else {
165+
return
166+
}
164167
// Ensure the compiler supports the import-scan operation
165-
guard SwiftTargetBuildDescription.checkSupportedFrontendFlags(flags: ["import-prescan"], fs: localFileSystem) else {
168+
guard SwiftTargetBuildDescription.checkSupportedFrontendFlags(flags: ["import-prescan"], fileSystem: localFileSystem) else {
166169
return
167170
}
168171

@@ -199,7 +202,7 @@ public final class BuildOperation: PackageStructureDelegate, SPMBuildCore.BuildS
199202
Set(description.targetDependencyMap.keys.filter { !targetDependenciesSet.contains($0) })
200203
let importedTargetsMissingDependency = Set(imports).intersection(nonDependencyTargetsSet)
201204
if let missedDependency = importedTargetsMissingDependency.first {
202-
diagnostics.emit(warning: "Target \(target) imports another target (\(missedDependency)) in the package without declaring it a dependency.", location: nil)
205+
self.observabilityScope.emit(warning: "Target \(target) imports another target (\(missedDependency)) in the package without declaring it a dependency.")
203206
}
204207
} catch {
205208
// The above verification is a best-effort attempt to warn the user about a potential manifest

Sources/Build/BuildOperationBuildSystemDelegateHandler.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,10 @@ public struct BuildDescription: Codable {
226226
/// The map of copy commands.
227227
let copyCommands: [BuildManifest.CmdName: LLBuildManifest.CopyTool]
228228

229+
/// A flag that inidcates this build should skip checking whether targets only import
230+
/// their explicitly-declared dependencies
231+
let disableExplicitTargetDependencyImportChecking: Bool
232+
229233
/// Every target's set of dependencies.
230234
let targetDependencyMap: [TargetName: [TargetName]]
231235

@@ -253,6 +257,7 @@ public struct BuildDescription: Codable {
253257
self.swiftFrontendCommands = swiftFrontendCommands
254258
self.testDiscoveryCommands = testDiscoveryCommands
255259
self.copyCommands = copyCommands
260+
self.disableExplicitTargetDependencyImportChecking = plan.buildParameters.disableExplicitTargetDependencyImportChecking
256261
self.targetDependencyMap = try plan.targets.reduce(into: [TargetName: [TargetName]]()) {
257262
let deps = try $1.target.recursiveTargetDependencies().map { $0.c99name }
258263
$0[$1.target.c99name] = deps

Sources/Commands/Options.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,11 @@ struct BuildOptions: ParsableArguments {
335335
@Flag()
336336
var useIntegratedSwiftDriver: Bool = false
337337

338+
/// A flag that inidcates this build should check whether targets only import
339+
/// their explicitly-declared dependencies
340+
@Flag()
341+
var enableExplicitTargetDependencyImportChecking: Bool = false
342+
338343
/// Whether to use the explicit module build flow (with the integrated driver)
339344
@Flag(name: .customLong("experimental-explicit-module-build"))
340345
var useExplicitModuleBuild: Bool = false

Sources/Commands/SwiftTool.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -792,6 +792,7 @@ public class SwiftTool {
792792
enableParseableModuleInterfaces: options.build.shouldEnableParseableModuleInterfaces,
793793
emitSwiftModuleSeparately: options.build.emitSwiftModuleSeparately,
794794
useIntegratedSwiftDriver: options.build.useIntegratedSwiftDriver,
795+
disableExplicitTargetDependencyImportChecking: build.disableExplicitTargetDependencyImportChecking,
795796
useExplicitModuleBuild: options.build.useExplicitModuleBuild,
796797
isXcodeBuildSystemEnabled: options.build.buildSystem == .xcode,
797798
forceTestDiscovery: options.build.enableTestDiscovery, // backwards compatibility, remove with --enable-test-discovery

Sources/SPMBuildCore/BuildParameters.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,10 @@ public struct BuildParameters: Encodable {
128128
/// Whether to use the explicit module build flow (with the integrated driver)
129129
public var useExplicitModuleBuild: Bool
130130

131+
/// A flag that inidcates this build should skip checking whether targets only import
132+
/// their explicitly-declared dependencies
133+
public var disableExplicitTargetDependencyImportChecking: Bool
134+
131135
/// Whether to create dylibs for dynamic library products.
132136
public var shouldCreateDylibForDynamicProducts: Bool
133137

@@ -199,6 +203,7 @@ public struct BuildParameters: Encodable {
199203
isXcodeBuildSystemEnabled: Bool = false,
200204
enableTestability: Bool? = nil,
201205
forceTestDiscovery: Bool = false,
206+
disableExplicitTargetDependencyImportChecking: Bool = false
202207
linkerDeadStrip: Bool = true,
203208
colorizedOutput: Bool = false,
204209
verboseOutput: Bool = false
@@ -236,6 +241,7 @@ public struct BuildParameters: Encodable {
236241
self.enableTestability = enableTestability ?? (.debug == configuration)
237242
// decide if to enable the use of test manifests based on platform. this is likely to change in the future
238243
self.testDiscoveryStrategy = triple.isDarwin() ? .objectiveC : .manifest(generate: forceTestDiscovery)
244+
self.disableExplicitTargetDependencyImportChecking = disableExplicitTargetDependencyImportChecking
239245
self.linkerDeadStrip = linkerDeadStrip
240246
self.colorizedOutput = colorizedOutput
241247
self.verboseOutput = verboseOutput

Tests/CommandsTests/BuildToolTests.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,18 @@ final class BuildToolTests: CommandsTestCase {
8989
XCTAssertTrue(stderr.contains("warning: Target A imports another target (B) in the package without declaring it a dependency."))
9090
}
9191
}
92+
93+
// Verify that the disable toggle works as expected
94+
fixture(name: "Miscellaneous/ImportOfMissingDependency") { path in
95+
let fullPath = resolveSymlinks(path)
96+
XCTAssertThrowsError(try build(["--disable-explicit-target-dependency-import-checking"], packagePath: fullPath)) { error in
97+
guard case SwiftPMProductError.executionFailure(_, _, let stderr) = error else {
98+
XCTFail()
99+
return
100+
}
101+
XCTAssertFalse(stderr.contains("warning: Target A imports another target (B) in the package without declaring it a dependency."))
102+
}
103+
}
92104
}
93105

94106
func testBinPathAndSymlink() throws {

0 commit comments

Comments
 (0)