Skip to content

cache DriverSupport capabilities across targets #7057

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

Merged
merged 5 commits into from
Nov 8, 2023
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
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,6 @@ import PackageModel
import OrderedCollections
import SPMBuildCore

#if USE_IMPL_ONLY_IMPORTS
@_implementationOnly import DriverSupport
#else
import DriverSupport
#endif

import struct TSCBasic.SortedArray

/// The build description for a product.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,6 @@ public final class SwiftTargetBuildDescription {
/// These are the resource files derived from plugins.
private var pluginDerivedResources: [Resource]

private let driverSupport = DriverSupport()

/// Path to the bundle generated for this module (if any).
var bundlePath: AbsolutePath? {
if let bundleName = target.underlyingTarget.potentialBundleName, needsResourceBundle {
Expand Down Expand Up @@ -255,6 +253,7 @@ public final class SwiftTargetBuildDescription {
guard target.underlyingTarget is SwiftTarget else {
throw InternalError("underlying target type mismatch \(target)")
}

self.package = package
self.target = target
self.toolsVersion = toolsVersion
Expand All @@ -267,13 +266,14 @@ public final class SwiftTargetBuildDescription {
} else {
self.testTargetRole = nil
}
self.fileSystem = fileSystem

self.tempsPath = buildParameters.buildPath.appending(component: target.c99name + ".build")
self.derivedSources = Sources(paths: [], root: self.tempsPath.appending("DerivedSources"))
self.buildToolPluginInvocationResults = buildToolPluginInvocationResults
self.prebuildCommandResults = prebuildCommandResults
self.requiredMacroProducts = requiredMacroProducts
self.shouldGenerateTestObservation = shouldGenerateTestObservation
self.fileSystem = fileSystem
self.observabilityScope = observabilityScope

(self.pluginDerivedSources, self.pluginDerivedResources) = SharedTargetBuildDescription.computePluginGeneratedFiles(
Expand Down Expand Up @@ -411,7 +411,7 @@ public final class SwiftTargetBuildDescription {
private func packageNameArgumentIfSupported(with pkg: ResolvedPackage, packageAccess: Bool) -> [String] {
let flag = "-package-name"
if pkg.manifest.usePackageNameFlag,
driverSupport.checkToolchainDriverFlags(flags: [flag], toolchain: self.buildParameters.toolchain, fileSystem: self.fileSystem) {
DriverSupport.checkToolchainDriverFlags(flags: [flag], toolchain: self.buildParameters.toolchain, fileSystem: self.fileSystem) {
if packageAccess {
let pkgID = pkg.identity.description.spm_mangledToC99ExtendedIdentifier()
return [flag, pkgID]
Expand Down Expand Up @@ -439,7 +439,7 @@ public final class SwiftTargetBuildDescription {
#endif

// If we're using an OSS toolchain, add the required arguments bringing in the plugin server from the default toolchain if available.
if self.buildParameters.toolchain.isSwiftDevelopmentToolchain, driverSupport.checkSupportedFrontendFlags(flags: ["-external-plugin-path"], toolchain: self.buildParameters.toolchain, fileSystem: self.fileSystem), let pluginServer = try self.buildParameters.toolchain.swiftPluginServerPath {
if self.buildParameters.toolchain.isSwiftDevelopmentToolchain, DriverSupport.checkSupportedFrontendFlags(flags: ["-external-plugin-path"], toolchain: self.buildParameters.toolchain, fileSystem: self.fileSystem), let pluginServer = try self.buildParameters.toolchain.swiftPluginServerPath {
let toolchainUsrPath = pluginServer.parentDirectory.parentDirectory
let pluginPathComponents = ["lib", "swift", "host", "plugins"]

Expand Down
2 changes: 0 additions & 2 deletions Sources/Build/BuildManifest/LLBuildManifestBuilder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,8 @@ import PackageModel
import SPMBuildCore

#if USE_IMPL_ONLY_IMPORTS
@_implementationOnly import DriverSupport
@_implementationOnly import SwiftDriver
#else
import DriverSupport
import SwiftDriver
#endif

Expand Down
4 changes: 1 addition & 3 deletions Sources/Build/BuildOperation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,6 @@ public final class BuildOperation: PackageStructureDelegate, SPMBuildCore.BuildS
/// Alternative path to search for pkg-config `.pc` files.
private let pkgConfigDirectories: [AbsolutePath]

private let driverSupport = DriverSupport()

public init(
buildParameters: BuildParameters,
cacheBuildManifest: Bool,
Expand Down Expand Up @@ -186,7 +184,7 @@ public final class BuildOperation: PackageStructureDelegate, SPMBuildCore.BuildS
return
}
// Ensure the compiler supports the import-scan operation
guard driverSupport.checkSupportedFrontendFlags(flags: ["import-prescan"], toolchain: self.buildParameters.toolchain, fileSystem: localFileSystem) else {
guard DriverSupport.checkSupportedFrontendFlags(flags: ["import-prescan"], toolchain: self.buildParameters.toolchain, fileSystem: localFileSystem) else {
return
}

Expand Down
7 changes: 6 additions & 1 deletion Sources/Build/BuildPlan/BuildPlan.swift
Original file line number Diff line number Diff line change
Expand Up @@ -374,7 +374,12 @@ public class BuildPlan: SPMBuildCore.BuildPlan {

// Plan the derived test targets, if necessary.
if buildParameters.testingParameters.testProductStyle.requiresAdditionalDerivedTestTargets {
let derivedTestTargets = try Self.makeDerivedTestTargets(buildParameters, graph, self.fileSystem, self.observabilityScope)
let derivedTestTargets = try Self.makeDerivedTestTargets(
buildParameters,
graph,
self.fileSystem,
self.observabilityScope
)
for item in derivedTestTargets {
var derivedTestTargets = [item.entryPointTargetBuildDescription.target]

Expand Down
3 changes: 1 addition & 2 deletions Sources/Commands/Utilities/SymbolGraphExtract.swift
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ public struct SymbolGraphExtract {
var includeSPISymbols = false
var emitExtensionBlockSymbols = false
var outputFormat = OutputFormat.json(pretty: false)
private let driverSupport = DriverSupport()

/// Access control levels.
public enum AccessLevel: String, RawRepresentable, CaseIterable, ExpressibleByArgument {
Expand Down Expand Up @@ -82,7 +81,7 @@ public struct SymbolGraphExtract {
}

let extensionBlockSymbolsFlag = emitExtensionBlockSymbols ? "-emit-extension-block-symbols" : "-omit-extension-block-symbols"
if driverSupport.checkSupportedFrontendFlags(flags: [extensionBlockSymbolsFlag.trimmingCharacters(in: ["-"])], toolchain: buildParameters.toolchain, fileSystem: fileSystem) {
if DriverSupport.checkSupportedFrontendFlags(flags: [extensionBlockSymbolsFlag.trimmingCharacters(in: ["-"])], toolchain: buildParameters.toolchain, fileSystem: fileSystem) {
commandLine += [extensionBlockSymbolsFlag]
} else {
observabilityScope.emit(warning: "dropped \(extensionBlockSymbolsFlag) flag because it is not supported by this compiler version")
Expand Down
8 changes: 3 additions & 5 deletions Sources/CoreCommands/SwiftTool.swift
Original file line number Diff line number Diff line change
Expand Up @@ -253,8 +253,6 @@ public final class SwiftTool {

fileprivate var buildSystemProvider: BuildSystemProvider?

private let driverSupport = DriverSupport()

/// Create an instance of this tool.
///
/// - parameter options: The command line options to be passed to this tool.
Expand Down Expand Up @@ -707,7 +705,7 @@ public final class SwiftTool {
omitFramePointers: options.build.omitFramePointers
),
driverParameters: .init(
canRenameEntrypointFunctionName: driverSupport.checkSupportedFrontendFlags(
canRenameEntrypointFunctionName: DriverSupport.checkSupportedFrontendFlags(
flags: ["entry-point-function-name"],
toolchain: toolchain,
fileSystem: self.fileSystem
Expand Down Expand Up @@ -859,11 +857,11 @@ public final class SwiftTool {

var extraManifestFlags = self.options.build.manifestFlags
// Disable the implicit concurrency import if the compiler in use supports it to avoid warnings if we are building against an older SDK that does not contain a Concurrency module.
if driverSupport.checkSupportedFrontendFlags(flags: ["disable-implicit-concurrency-module-import"], toolchain: try self.buildParameters().toolchain, fileSystem: self.fileSystem) {
if DriverSupport.checkSupportedFrontendFlags(flags: ["disable-implicit-concurrency-module-import"], toolchain: try self.buildParameters().toolchain, fileSystem: self.fileSystem) {
extraManifestFlags += ["-Xfrontend", "-disable-implicit-concurrency-module-import"]
}
// Disable the implicit string processing import if the compiler in use supports it to avoid warnings if we are building against an older SDK that does not contain a StringProcessing module.
if driverSupport.checkSupportedFrontendFlags(flags: ["disable-implicit-string-processing-module-import"], toolchain: try self.buildParameters().toolchain, fileSystem: self.fileSystem) {
if DriverSupport.checkSupportedFrontendFlags(flags: ["disable-implicit-string-processing-module-import"], toolchain: try self.buildParameters().toolchain, fileSystem: self.fileSystem) {
extraManifestFlags += ["-Xfrontend", "-disable-implicit-string-processing-module-import"]
}

Expand Down
9 changes: 4 additions & 5 deletions Sources/DriverSupport/DriverSupportUtils.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,11 @@ import class TSCBasic.Process
import enum TSCBasic.ProcessEnv
import struct TSCBasic.ProcessResult

public class DriverSupport {
private var flagsMap = ThreadSafeBox<[String: Set<String>]>()
public init() {}
public enum DriverSupport {
private static var flagsMap = ThreadSafeBox<[String: Set<String>]>()

// This checks _frontend_ supported flags, which are not necessarily supported in the driver.
public func checkSupportedFrontendFlags(
public static func checkSupportedFrontendFlags(
flags: Set<String>,
toolchain: PackageModel.Toolchain,
fileSystem: FileSystem
Expand Down Expand Up @@ -55,7 +54,7 @@ public class DriverSupport {
// This checks if given flags are supported in the built-in toolchain driver. Currently
// there's no good way to get the supported flags from it, so run `swiftc -h` directly
// to get the flags and cache the result.
public func checkToolchainDriverFlags(
public static func checkToolchainDriverFlags(
flags: Set<String>,
toolchain: PackageModel.Toolchain,
fileSystem: FileSystem
Expand Down
1 change: 1 addition & 0 deletions Sources/SPMTestSupport/misc.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import PackageGraph
import PackageLoading
import PackageModel
import SourceControl
import struct SPMBuildCore.BuildParameters
import TSCTestSupport
import Workspace
import func XCTest.XCTFail
Expand Down
12 changes: 3 additions & 9 deletions Tests/BuildTests/BuildPlanTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

@testable import Basics
@testable import Build
import DriverSupport
import PackageLoading
@testable import PackageGraph
@testable import PackageModel
Expand All @@ -21,20 +22,13 @@ import SwiftDriver
import Workspace
import XCTest

#if USE_IMPL_ONLY_IMPORTS
@_implementationOnly import DriverSupport
#else
import DriverSupport
#endif

import struct TSCBasic.ByteString
import class TSCBasic.InMemoryFileSystem

import enum TSCUtility.Diagnostics

final class BuildPlanTests: XCTestCase {
let inputsDir = AbsolutePath(#file).parentDirectory.appending(components: "Inputs")
private let driverSupport = DriverSupport()

/// The j argument.
private var j: String {
Expand Down Expand Up @@ -533,7 +527,7 @@ final class BuildPlanTests: XCTestCase {
}

func testPackageNameFlag() throws {
let isFlagSupportedInDriver = try driverSupport.checkToolchainDriverFlags(flags: ["package-name"], toolchain: UserToolchain.default, fileSystem: localFileSystem)
let isFlagSupportedInDriver = try DriverSupport.checkToolchainDriverFlags(flags: ["package-name"], toolchain: UserToolchain.default, fileSystem: localFileSystem)
try fixture(name: "Miscellaneous/PackageNameFlag") { fixturePath in
let (stdout, _) = try executeSwiftBuild(fixturePath.appending("appPkg"), extraArgs: ["-v"])
XCTAssertMatch(stdout, .contains("-module-name Foo"))
Expand All @@ -555,7 +549,7 @@ final class BuildPlanTests: XCTestCase {
}

func testTargetsWithPackageAccess() throws {
let isFlagSupportedInDriver = try driverSupport.checkToolchainDriverFlags(flags: ["package-name"], toolchain: UserToolchain.default, fileSystem: localFileSystem)
let isFlagSupportedInDriver = try DriverSupport.checkToolchainDriverFlags(flags: ["package-name"], toolchain: UserToolchain.default, fileSystem: localFileSystem)
try fixture(name: "Miscellaneous/TargetPackageAccess") { fixturePath in
let (stdout, _) = try executeSwiftBuild(fixturePath.appending("libPkg"), extraArgs: ["-v"])
if isFlagSupportedInDriver {
Expand Down
11 changes: 2 additions & 9 deletions Tests/CommandsTests/APIDiffTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,24 +13,17 @@
import Basics
import Build
import Commands
import DriverSupport
import Foundation
import PackageModel
import SourceControl
import SPMTestSupport
import Workspace
import XCTest

#if USE_IMPL_ONLY_IMPORTS
@_implementationOnly import DriverSupport
#else
import DriverSupport
#endif

import enum TSCBasic.ProcessEnv

final class APIDiffTests: CommandsTestCase {
private let driverSupport = DriverSupport()

@discardableResult
private func execute(
_ args: [String],
Expand Down Expand Up @@ -61,7 +54,7 @@ final class APIDiffTests: CommandsTestCase {
// not all of which can be tested for easily. Fortunately, we can test for the
// `-disable-fail-on-error` option, and any version which supports this flag
// will meet the other requirements.
guard driverSupport.checkSupportedFrontendFlags(flags: ["disable-fail-on-error"], toolchain: try UserToolchain.default, fileSystem: localFileSystem) else {
guard DriverSupport.checkSupportedFrontendFlags(flags: ["disable-fail-on-error"], toolchain: try UserToolchain.default, fileSystem: localFileSystem) else {
throw XCTSkip("swift-api-digester is too old")
}
}
Expand Down