From ee341095134871054efc542934e375ca44f6d25b Mon Sep 17 00:00:00 2001 From: Max Desiatov Date: Tue, 5 Dec 2023 17:20:27 +0000 Subject: [PATCH 01/33] Keep separate build parameters for host and target `BuildParameters` to date explicitly mentioned both host and target triples, but assumed you can use the same toolchain for both, which is not true. Additionally, it would assume that all other build parameters can be shared between the host and target, like debug info format, build configuration, sanitizers etc. That's not true either, one would use CodeView for build tools on Windows when compiling targets with DWARF for Linux, or build macros in release mode for performance when cross-compiling code that uses debug configuration itself. --- .../ClangTargetBuildDescription.swift | 17 +-- .../ProductBuildDescription.swift | 24 ++-- .../SwiftTargetBuildDescription.swift | 14 +- .../LLBuildManifestBuilder+Product.swift | 4 +- .../LLBuildManifestBuilder.swift | 4 +- Sources/Build/BuildOperation.swift | 79 ++++++---- ...dOperationBuildSystemDelegateHandler.swift | 48 ++++--- Sources/Build/BuildPlan/BuildPlan+Clang.swift | 6 +- .../Build/BuildPlan/BuildPlan+Product.swift | 28 ++-- Sources/Build/BuildPlan/BuildPlan+Swift.swift | 5 +- Sources/Build/BuildPlan/BuildPlan.swift | 136 ++++++++++++++---- Sources/Build/TestObservation.swift | 2 +- .../Commands/PackageTools/DumpCommands.swift | 2 +- .../PackageTools/InstalledPackages.swift | 2 +- .../Commands/PackageTools/PluginCommand.swift | 6 +- Sources/Commands/SwiftBuildTool.swift | 2 +- .../Commands/Utilities/PluginDelegate.swift | 4 +- .../Commands/Utilities/TestingSupport.swift | 4 +- Sources/Commands/Utilities/XCTEvents.swift | 18 +-- Sources/CoreCommands/BuildSystemSupport.swift | 56 +++++--- Sources/CoreCommands/SwiftTool.swift | 49 ++++--- Sources/PackageGraph/BuildTriple.swift | 22 +++ Sources/PackageGraph/CMakeLists.txt | 1 + .../Resolution/ResolvedProduct.swift | 5 + .../Resolution/ResolvedTarget.swift | 4 + .../BuildParameters+Debugging.swift | 8 +- .../BuildParameters/BuildParameters.swift | 58 ++++---- .../BuildSystem/BuildSystem.swift | 33 +++-- Sources/XCBuildSupport/XcodeBuildSystem.swift | 2 +- Sources/swift-bootstrap/main.swift | 7 +- Tests/BuildTests/BuildPlanTests.swift | 2 +- .../LLBuildManifestBuilderTests.swift | 12 +- Tests/BuildTests/MockBuildTestHelper.swift | 5 +- Tests/CommandsTests/SwiftToolTests.swift | 13 +- 34 files changed, 435 insertions(+), 247 deletions(-) create mode 100644 Sources/PackageGraph/BuildTriple.swift diff --git a/Sources/Build/BuildDescription/ClangTargetBuildDescription.swift b/Sources/Build/BuildDescription/ClangTargetBuildDescription.swift index 5bc56f647f3..81d0b2bd0bf 100644 --- a/Sources/Build/BuildDescription/ClangTargetBuildDescription.swift +++ b/Sources/Build/BuildDescription/ClangTargetBuildDescription.swift @@ -216,7 +216,7 @@ public final class ClangTargetBuildDescription { var args = [String]() // Only enable ARC on macOS. - if buildParameters.targetTriple.isDarwin() { + if self.buildParameters.triple.isDarwin() { args += ["-fobjc-arc"] } args += try buildParameters.targetTripleArgs(for: target) @@ -225,32 +225,33 @@ public final class ClangTargetBuildDescription { args += activeCompilationConditions args += ["-fblocks"] + let buildTriple = self.buildParameters.triple // Enable index store, if appropriate. // // This feature is not widely available in OSS clang. So, we only enable // index store for Apple's clang or if explicitly asked to. if ProcessEnv.vars.keys.contains("SWIFTPM_ENABLE_CLANG_INDEX_STORE") { - args += buildParameters.indexStoreArguments(for: target) - } else if buildParameters.targetTriple.isDarwin(), - (try? buildParameters.toolchain._isClangCompilerVendorApple()) == true + args += self.buildParameters.indexStoreArguments(for: target) + } else if buildTriple.isDarwin(), + (try? self.buildParameters.toolchain._isClangCompilerVendorApple()) == true { - args += buildParameters.indexStoreArguments(for: target) + args += self.buildParameters.indexStoreArguments(for: target) } // Enable Clang module flags, if appropriate. let enableModules: Bool + let triple = self.buildParameters.triple if toolsVersion < .v5_8 { // For version < 5.8, we enable them except in these cases: // 1. on Darwin when compiling for C++, because C++ modules are disabled on Apple-built Clang releases // 2. on Windows when compiling for any language, because of issues with the Windows SDK // 3. on Android when compiling for any language, because of issues with the Android SDK - enableModules = !(buildParameters.targetTriple.isDarwin() && isCXX) && !buildParameters.targetTriple - .isWindows() && !buildParameters.targetTriple.isAndroid() + enableModules = !(triple.isDarwin() && isCXX) && !triple.isWindows() && !triple.isAndroid() } else { // For version >= 5.8, we disable them when compiling for C++ regardless of platforms, see: // https://github.com/llvm/llvm-project/issues/55980 for clang frontend crash when module // enabled for C++ on c++17 standard and above. - enableModules = !isCXX && !buildParameters.targetTriple.isWindows() && !buildParameters.targetTriple.isAndroid() + enableModules = !isCXX && !triple.isWindows() && !triple.isAndroid() } if enableModules { diff --git a/Sources/Build/BuildDescription/ProductBuildDescription.swift b/Sources/Build/BuildDescription/ProductBuildDescription.swift index bd63fa749c4..23e9ea21293 100644 --- a/Sources/Build/BuildDescription/ProductBuildDescription.swift +++ b/Sources/Build/BuildDescription/ProductBuildDescription.swift @@ -110,15 +110,16 @@ public final class ProductBuildDescription: SPMBuildCore.ProductBuildDescription return [] } + let triple = self.buildParameters.triple switch self.buildParameters.configuration { case .debug: return [] case .release: - if self.buildParameters.targetTriple.isApple() { + if triple.isApple() { return ["-Xlinker", "-dead_strip"] - } else if self.buildParameters.targetTriple.isWindows() { + } else if triple.isWindows() { return ["-Xlinker", "/OPT:REF"] - } else if self.buildParameters.targetTriple.arch == .wasm32 { + } else if triple.arch == .wasm32 { // FIXME: wasm-ld strips data segments referenced through __start/__stop symbols // during GC, and it removes Swift metadata sections like swift5_protocols // We should add support of SHF_GNU_RETAIN-like flag for __attribute__((retain)) @@ -136,7 +137,7 @@ public final class ProductBuildDescription: SPMBuildCore.ProductBuildDescription /// The arguments to the librarian to create a static library. public func archiveArguments() throws -> [String] { let librarian = self.buildParameters.toolchain.librarianPath.pathString - let triple = self.buildParameters.targetTriple + let triple = self.buildParameters.triple if triple.isWindows(), librarian.hasSuffix("link") || librarian.hasSuffix("link.exe") { return try [librarian, "/LIB", "/OUT:\(binaryPath.pathString)", "@\(self.linkFileListPath.pathString)"] } @@ -187,6 +188,7 @@ public final class ProductBuildDescription: SPMBuildCore.ProductBuildDescription } var isLinkingStaticStdlib = false + let triple = self.buildParameters.triple switch derivedProductType { case .macro: throw InternalError("macro not supported") // should never be reached @@ -206,7 +208,7 @@ public final class ProductBuildDescription: SPMBuildCore.ProductBuildDescription args += self.deadStripArguments case .library(.dynamic): args += ["-emit-library"] - if self.buildParameters.targetTriple.isDarwin() { + if triple.isDarwin() { let relativePath = try "@rpath/\(buildParameters.binaryRelativePath(for: self.product).pathString)" args += ["-Xlinker", "-install_name", "-Xlinker", relativePath] } @@ -215,9 +217,9 @@ public final class ProductBuildDescription: SPMBuildCore.ProductBuildDescription // Link the Swift stdlib statically, if requested. // TODO: unify this logic with SwiftTargetBuildDescription.stdlibArguments if self.buildParameters.linkingParameters.shouldLinkStaticSwiftStdlib { - if self.buildParameters.targetTriple.isDarwin() { + if triple.isDarwin() { self.observabilityScope.emit(.swiftBackDeployError) - } else if self.buildParameters.targetTriple.isSupportingStaticStdlib { + } else if triple.isSupportingStaticStdlib { args += ["-static-stdlib"] isLinkingStaticStdlib = true } @@ -260,9 +262,9 @@ public final class ProductBuildDescription: SPMBuildCore.ProductBuildDescription // Set rpath such that dynamic libraries are looked up // adjacent to the product, unless overridden. if !self.buildParameters.linkingParameters.shouldDisableLocalRpath { - if self.buildParameters.targetTriple.isLinux() { + if triple.isLinux() { args += ["-Xlinker", "-rpath=$ORIGIN"] - } else if self.buildParameters.targetTriple.isDarwin() { + } else if triple.isDarwin() { let rpath = self.product.type == .test ? "@loader_path/../../../" : "@loader_path" args += ["-Xlinker", "-rpath", "-Xlinker", rpath] } @@ -283,7 +285,7 @@ public final class ProductBuildDescription: SPMBuildCore.ProductBuildDescription // When deploying to macOS prior to macOS 12, add an rpath to the // back-deployed concurrency libraries. - if useStdlibRpath, self.buildParameters.targetTriple.isMacOSX { + if useStdlibRpath, triple.isMacOSX { let macOSSupportedPlatform = self.package.platforms.getDerived(for: .macOS, usingXCTest: product.isLinkingXCTest) if macOSSupportedPlatform.version.major < 12 { let backDeployedStdlib = try buildParameters.toolchain.macosSwiftStdlib @@ -351,7 +353,7 @@ public final class ProductBuildDescription: SPMBuildCore.ProductBuildDescription flags += libraries.map { "-l" + $0 } // Linked frameworks. - if self.buildParameters.targetTriple.supportsFrameworks { + if self.buildParameters.triple.supportsFrameworks { let frameworks = OrderedSet(self.staticTargets.reduce([]) { $0 + self.buildParameters.createScope(for: $1).evaluate(.LINK_FRAMEWORKS) }) diff --git a/Sources/Build/BuildDescription/SwiftTargetBuildDescription.swift b/Sources/Build/BuildDescription/SwiftTargetBuildDescription.swift index 1816daef37a..7bc502518a0 100644 --- a/Sources/Build/BuildDescription/SwiftTargetBuildDescription.swift +++ b/Sources/Build/BuildDescription/SwiftTargetBuildDescription.swift @@ -106,8 +106,10 @@ public final class SwiftTargetBuildDescription { /// The path to the swiftmodule file after compilation. var moduleOutputPath: AbsolutePath { // If we're an executable and we're not allowing test targets to link against us, we hide the module. - let allowLinkingAgainstExecutables = (buildParameters.targetTriple.isDarwin() || self.buildParameters.targetTriple - .isLinux() || self.buildParameters.targetTriple.isWindows()) && self.toolsVersion >= .v5_5 + let allowLinkingAgainstExecutables = ( + self.buildParameters.triple.isDarwin() || + self.buildParameters.triple.isLinux() || + self.buildParameters.triple.isWindows()) && self.toolsVersion >= .v5_5 let dirPath = (target.type == .executable && !allowLinkingAgainstExecutables) ? self.tempsPath : self .buildParameters.buildPath return dirPath.appending(component: self.target.c99name + ".swiftmodule") @@ -317,7 +319,7 @@ public final class SwiftTargetBuildDescription { return } - guard buildParameters.targetTriple.isDarwin(), buildParameters.testingParameters.experimentalTestOutput else { + guard self.buildParameters.triple.isDarwin(), self.buildParameters.testingParameters.experimentalTestOutput else { return } @@ -361,7 +363,7 @@ public final class SwiftTargetBuildDescription { guard let bundlePath else { return } let mainPathSubstitution: String - if self.buildParameters.targetTriple.isWASI() { + if self.buildParameters.triple.isWASI() { // We prefer compile-time evaluation of the bundle path here for WASI. There's no benefit in evaluating this // at runtime, especially as `Bundle` support in WASI Foundation is partial. We expect all resource paths to // evaluate to `/\(resourceBundleName)/\(resourcePath)`, which allows us to pass this path to JS APIs like @@ -646,7 +648,7 @@ public final class SwiftTargetBuildDescription { /// Returns true if ObjC compatibility header should be emitted. private var shouldEmitObjCCompatibilityHeader: Bool { - self.buildParameters.targetTriple.isDarwin() && self.target.type == .library + self.buildParameters.triple.isDarwin() && self.target.type == .library } func writeOutputFileMap() throws -> AbsolutePath { @@ -849,7 +851,7 @@ public final class SwiftTargetBuildDescription { var arguments: [String] = [] let isLinkingStaticStdlib = self.buildParameters.linkingParameters.shouldLinkStaticSwiftStdlib - && self.buildParameters.targetTriple.isSupportingStaticStdlib + && self.buildParameters.triple.isSupportingStaticStdlib if isLinkingStaticStdlib { arguments += ["-static-stdlib"] } diff --git a/Sources/Build/BuildManifest/LLBuildManifestBuilder+Product.swift b/Sources/Build/BuildManifest/LLBuildManifestBuilder+Product.swift index 5dc406bb264..fd19267315f 100644 --- a/Sources/Build/BuildManifest/LLBuildManifestBuilder+Product.swift +++ b/Sources/Build/BuildManifest/LLBuildManifestBuilder+Product.swift @@ -20,7 +20,7 @@ extension LLBuildManifestBuilder { // Add dependency on Info.plist generation on Darwin platforms. let testInputs: [AbsolutePath] if buildProduct.product.type == .test - && buildProduct.buildParameters.targetTriple.isDarwin() + && buildProduct.buildParameters.triple.isDarwin() && buildProduct.buildParameters.testingParameters.experimentalTestOutput { let testBundleInfoPlistPath = try buildProduct.binaryPath.parentDirectory.parentDirectory.appending(component: "Info.plist") testInputs = [testBundleInfoPlistPath] @@ -59,7 +59,7 @@ extension LLBuildManifestBuilder { let linkedBinaryNode: Node let linkedBinaryPath = try buildProduct.binaryPath if case .executable = buildProduct.product.type, - buildParameters.targetTriple.isMacOSX, + buildProduct.buildParameters.triple.isMacOSX, buildParameters.debuggingParameters.shouldEnableDebuggingEntitlement { shouldCodeSign = true linkedBinaryNode = try .file(buildProduct.binaryPath, isMutated: true) diff --git a/Sources/Build/BuildManifest/LLBuildManifestBuilder.swift b/Sources/Build/BuildManifest/LLBuildManifestBuilder.swift index 2257ec2eaa9..dadf574ec80 100644 --- a/Sources/Build/BuildManifest/LLBuildManifestBuilder.swift +++ b/Sources/Build/BuildManifest/LLBuildManifestBuilder.swift @@ -85,9 +85,9 @@ public class LLBuildManifestBuilder { self.observabilityScope = observabilityScope } - // MARK: - Generate Manifest + // MARK: - Generate Build Manifest - /// Generate manifest at the given path. + /// Generate build manifest at the given path. @discardableResult public func generateManifest(at path: AbsolutePath) throws -> LLBuildManifest { self.swiftGetVersionFiles.removeAll() diff --git a/Sources/Build/BuildOperation.swift b/Sources/Build/BuildOperation.swift index 94b8328502a..5624d4d4e3d 100644 --- a/Sources/Build/BuildOperation.swift +++ b/Sources/Build/BuildOperation.swift @@ -42,8 +42,15 @@ public final class BuildOperation: PackageStructureDelegate, SPMBuildCore.BuildS /// The delegate used by the build system. public weak var delegate: SPMBuildCore.BuildSystemDelegate? - /// The build parameters. - public let buildParameters: BuildParameters + /// Build parameters for products + @available(*, deprecated, renamed: "productsBuildParameters") + public var buildParameters: BuildParameters { self.productsBuildParameters } + + /// Build parameters for products. + let productsBuildParameters: BuildParameters + + /// Build parameters for build tools: plugins and macros. + let toolsBuildParameters: BuildParameters /// The closure for loading the package graph. let packageGraphLoader: () throws -> PackageGraph @@ -102,7 +109,8 @@ public final class BuildOperation: PackageStructureDelegate, SPMBuildCore.BuildS private let pkgConfigDirectories: [AbsolutePath] public init( - buildParameters: BuildParameters, + productsBuildParameters: BuildParameters, + toolsBuildParameters: BuildParameters, cacheBuildManifest: Bool, packageGraphLoader: @escaping () throws -> PackageGraph, pluginConfiguration: PluginConfiguration? = .none, @@ -114,10 +122,14 @@ public final class BuildOperation: PackageStructureDelegate, SPMBuildCore.BuildS observabilityScope: ObservabilityScope ) { /// Checks if stdout stream is tty. - var buildParameters = buildParameters - buildParameters.outputParameters.isColorized = outputStream.isTTY + var productsBuildParameters = productsBuildParameters + productsBuildParameters.outputParameters.isColorized = outputStream.isTTY - self.buildParameters = buildParameters + var toolsBuildParameters = toolsBuildParameters + toolsBuildParameters.outputParameters.isColorized = outputStream.isTTY + + self.productsBuildParameters = productsBuildParameters + self.toolsBuildParameters = toolsBuildParameters self.cacheBuildManifest = cacheBuildManifest self.packageGraphLoader = packageGraphLoader self.additionalFileRules = additionalFileRules @@ -147,7 +159,7 @@ public final class BuildOperation: PackageStructureDelegate, SPMBuildCore.BuildS if try self.buildPackageStructure() { // confirm the step above created the build description as expected // we trust it to update the build description when needed - let buildDescriptionPath = self.buildParameters.buildDescriptionPath + let buildDescriptionPath = self.productsBuildParameters.buildDescriptionPath guard self.fileSystem.exists(buildDescriptionPath) else { throw InternalError("could not find build descriptor at \(buildDescriptionPath)") } @@ -184,7 +196,11 @@ 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.productsBuildParameters.toolchain, + fileSystem: localFileSystem + ) else { return } @@ -240,7 +256,7 @@ public final class BuildOperation: PackageStructureDelegate, SPMBuildCore.BuildS /// Perform a build using the given build description and subset. public func build(subset: BuildSubset) throws { - guard !buildParameters.shouldSkipBuilding else { + guard !self.productsBuildParameters.shouldSkipBuilding else { return } @@ -266,7 +282,7 @@ public final class BuildOperation: PackageStructureDelegate, SPMBuildCore.BuildS } // delegate is only available after createBuildSystem is called - self.buildSystemDelegate?.buildStart(configuration: self.buildParameters.configuration) + self.buildSystemDelegate?.buildStart(configuration: self.productsBuildParameters.configuration) // Perform the build. let llbuildTarget = try computeLLBuildTargetName(for: subset) @@ -279,8 +295,8 @@ public final class BuildOperation: PackageStructureDelegate, SPMBuildCore.BuildS guard success else { throw Diagnostics.fatalError } // Create backwards-compatibility symlink to old build path. - let oldBuildPath = buildParameters.dataPath.parentDirectory.appending( - component: buildParameters.configuration.dirname + let oldBuildPath = productsBuildParameters.dataPath.parentDirectory.appending( + component: productsBuildParameters.configuration.dirname ) if self.fileSystem.exists(oldBuildPath) { do { try self.fileSystem.removeFileTree(oldBuildPath) } @@ -294,7 +310,7 @@ public final class BuildOperation: PackageStructureDelegate, SPMBuildCore.BuildS } do { - try self.fileSystem.createSymbolicLink(oldBuildPath, pointingAt: buildParameters.buildPath, relative: true) + try self.fileSystem.createSymbolicLink(oldBuildPath, pointingAt: productsBuildParameters.buildPath, relative: true) } catch { self.observabilityScope.emit( warning: "unable to create symbolic link at \(oldBuildPath)", @@ -411,8 +427,8 @@ public final class BuildOperation: PackageStructureDelegate, SPMBuildCore.BuildS let graph = try getPackageGraph() if let result = subset.llbuildTargetName( for: graph, - config: buildParameters.configuration.dirname, - observabilityScope: self.observabilityScope + config: productsBuildParameters.configuration.dirname, + observabilityScope: self.observabilityScope ) { return result } @@ -428,9 +444,10 @@ public final class BuildOperation: PackageStructureDelegate, SPMBuildCore.BuildS let buildToolPluginInvocationResults: [ResolvedTarget: [BuildToolPluginInvocationResult]] let prebuildCommandResults: [ResolvedTarget: [PrebuildCommandResult]] // Invoke any build tool plugins in the graph to generate prebuild commands and build commands. - if let pluginConfiguration, !self.buildParameters.shouldSkipBuilding { - let buildOperationForPluginDependencies = try BuildOperation( - buildParameters: self.buildParameters.forTriple(self.buildParameters.hostTriple), + if let pluginConfiguration, !self.productsBuildParameters.shouldSkipBuilding { + let buildOperationForPluginDependencies = BuildOperation( + productsBuildParameters: self.productsBuildParameters, + toolsBuildParameters: self.toolsBuildParameters, cacheBuildManifest: false, packageGraphLoader: { return graph }, additionalFileRules: self.additionalFileRules, @@ -442,11 +459,11 @@ public final class BuildOperation: PackageStructureDelegate, SPMBuildCore.BuildS ) buildToolPluginInvocationResults = try graph.invokeBuildToolPlugins( outputDir: pluginConfiguration.workDirectory.appending("outputs"), - builtToolsDir: self.buildParameters.buildPath, - buildEnvironment: self.buildParameters.buildEnvironment, - toolSearchDirectories: [self.buildParameters.toolchain.swiftCompilerPath.parentDirectory], + builtToolsDir: self.toolsBuildParameters.buildPath, + buildEnvironment: self.toolsBuildParameters.buildEnvironment, + toolSearchDirectories: [self.toolsBuildParameters.toolchain.swiftCompilerPath.parentDirectory], pkgConfigDirectories: self.pkgConfigDirectories, - sdkRootPath: self.buildParameters.toolchain.sdkRootPath, + sdkRootPath: self.toolsBuildParameters.toolchain.sdkRootPath, pluginScriptRunner: pluginConfiguration.scriptRunner, observabilityScope: self.observabilityScope, fileSystem: self.fileSystem @@ -526,7 +543,8 @@ public final class BuildOperation: PackageStructureDelegate, SPMBuildCore.BuildS // Create the build plan based, on the graph and any information from plugins. let plan = try BuildPlan( - buildParameters: buildParameters, + productsBuildParameters: self.productsBuildParameters, + toolsBuildParameters: self.toolsBuildParameters, graph: graph, additionalFileRules: additionalFileRules, buildToolPluginInvocationResults: buildToolPluginInvocationResults, @@ -567,7 +585,8 @@ public final class BuildOperation: PackageStructureDelegate, SPMBuildCore.BuildS : NinjaProgressAnimation(stream: self.outputStream) let buildExecutionContext = BuildExecutionContext( - buildParameters, + productsBuildParameters: self.productsBuildParameters, + toolsBuildParameters: self.toolsBuildParameters, buildDescription: buildDescription, fileSystem: self.fileSystem, observabilityScope: self.observabilityScope, @@ -587,12 +606,12 @@ public final class BuildOperation: PackageStructureDelegate, SPMBuildCore.BuildS ) self.buildSystemDelegate = buildSystemDelegate - let databasePath = buildParameters.dataPath.appending("build.db").pathString + let databasePath = self.productsBuildParameters.dataPath.appending("build.db").pathString let buildSystem = SPMLLBuild.BuildSystem( - buildFile: buildParameters.llbuildManifest.pathString, + buildFile: self.productsBuildParameters.llbuildManifest.pathString, databaseFile: databasePath, delegate: buildSystemDelegate, - schedulerLanes: buildParameters.workers + schedulerLanes: self.productsBuildParameters.workers ) // TODO: this seems fragile, perhaps we replace commandFailureHandler by adding relevant calls in the delegates chain @@ -709,7 +728,7 @@ extension BuildDescription { static func create(with plan: BuildPlan, disableSandboxForPluginCommands: Bool, fileSystem: Basics.FileSystem, observabilityScope: ObservabilityScope) throws -> (BuildDescription, LLBuildManifest) { // Generate the llbuild manifest. let llbuild = LLBuildManifestBuilder(plan, disableSandboxForPluginCommands: disableSandboxForPluginCommands, fileSystem: fileSystem, observabilityScope: observabilityScope) - let buildManifest = try llbuild.generateManifest(at: plan.buildParameters.llbuildManifest) + let buildManifest = try llbuild.generateManifest(at: plan.productsBuildParameters.llbuildManifest) let swiftCommands = llbuild.manifest.getCmdToolMap(kind: SwiftCompilerTool.self) let swiftFrontendCommands = llbuild.manifest.getCmdToolMap(kind: SwiftFrontendTool.self) @@ -730,10 +749,10 @@ extension BuildDescription { pluginDescriptions: plan.pluginDescriptions ) try fileSystem.createDirectory( - plan.buildParameters.buildDescriptionPath.parentDirectory, + plan.productsBuildParameters.buildDescriptionPath.parentDirectory, recursive: true ) - try buildDescription.write(fileSystem: fileSystem, path: plan.buildParameters.buildDescriptionPath) + try buildDescription.write(fileSystem: fileSystem, path: plan.productsBuildParameters.buildDescriptionPath) return (buildDescription, buildManifest) } } diff --git a/Sources/Build/BuildOperationBuildSystemDelegateHandler.swift b/Sources/Build/BuildOperationBuildSystemDelegateHandler.swift index 99feb123f1b..c03553203b7 100644 --- a/Sources/Build/BuildOperationBuildSystemDelegateHandler.swift +++ b/Sources/Build/BuildOperationBuildSystemDelegateHandler.swift @@ -111,13 +111,13 @@ final class TestDiscoveryCommand: CustomLLBuildCommand, TestBuildCommand { private func execute(fileSystem: Basics.FileSystem, tool: TestDiscoveryTool) throws { let outputs = tool.outputs.compactMap { try? AbsolutePath(validating: $0.name) } - switch self.context.buildParameters.testingParameters.library { + switch self.context.productsBuildParameters.testingParameters.library { case .swiftTesting: for file in outputs { try fileSystem.writeIfChanged(path: file, string: "") } case .xctest: - let index = self.context.buildParameters.indexStore + let index = self.context.productsBuildParameters.indexStore let api = try self.context.indexStoreAPI.get() let store = try IndexStore.open(store: TSCAbsolutePath(index), api: api) @@ -221,7 +221,7 @@ final class TestEntryPointCommand: CustomLLBuildCommand, TestBuildCommand { // Write the main file. let stream = try LocalFileOutputByteStream(mainFile) - switch self.context.buildParameters.testingParameters.library { + switch self.context.productsBuildParameters.testingParameters.library { case .swiftTesting: stream.send( #""" @@ -244,8 +244,8 @@ final class TestEntryPointCommand: CustomLLBuildCommand, TestBuildCommand { let discoveryModuleNames = inputs.map(\.basenameWithoutExt) let testObservabilitySetup: String - if self.context.buildParameters.testingParameters.experimentalTestOutput - && self.context.buildParameters.targetTriple.supportsTestSummary { + let buildParameters = self.context.productsBuildParameters + if buildParameters.testingParameters.experimentalTestOutput && buildParameters.triple.supportsTestSummary { testObservabilitySetup = "_ = SwiftPMXCTestObserver()\n" } else { testObservabilitySetup = "" @@ -253,7 +253,7 @@ final class TestEntryPointCommand: CustomLLBuildCommand, TestBuildCommand { stream.send( #""" - \#(generateTestObservationCode(buildParameters: self.context.buildParameters)) + \#(generateTestObservationCode(buildParameters: buildParameters)) import XCTest \#(discoveryModuleNames.map { "import \($0)" }.joined(separator: "\n")) @@ -369,12 +369,14 @@ public struct BuildDescription: Codable { self.testEntryPointCommands = testEntryPointCommands self.copyCommands = copyCommands self.writeCommands = writeCommands - self.explicitTargetDependencyImportCheckingMode = plan.buildParameters.driverParameters + self.explicitTargetDependencyImportCheckingMode = plan.productsBuildParameters.driverParameters .explicitTargetDependencyImportCheckingMode - self.targetDependencyMap = try plan.targets.reduce(into: [TargetName: [TargetName]]()) { - let deps = try $1.target.recursiveDependencies(satisfying: plan.buildParameters.buildEnvironment) + self.targetDependencyMap = try plan.targets.reduce(into: [TargetName: [TargetName]]()) { partial, resolvedTarget in + let deps = try resolvedTarget.target.recursiveDependencies( + satisfying: plan.buildParameters(for: resolvedTarget).buildEnvironment + ) .compactMap(\.target).map(\.c99name) - $0[$1.target.c99name] = deps + partial[resolvedTarget.target.c99name] = deps } var targetCommandLines: [TargetName: [CommandLineFlag]] = [:] var generatedSourceTargets: [TargetName] = [] @@ -429,8 +431,15 @@ public protocol BuildErrorAdviceProvider { /// The context available during build execution. public final class BuildExecutionContext { - /// The build parameters. - let buildParameters: BuildParameters + /// Build parameters for products. + @available(*, deprecated, message: "use either `productsBuildParameters` or `toolsBuildParameters`") + var buildParameters: BuildParameters { self.productsBuildParameters } + + /// Build parameters for products. + let productsBuildParameters: BuildParameters + + /// Build parameters for build tools. + let toolsBuildParameters: BuildParameters /// The build description. /// @@ -449,14 +458,16 @@ public final class BuildExecutionContext { let observabilityScope: ObservabilityScope public init( - _ buildParameters: BuildParameters, + productsBuildParameters: BuildParameters, + toolsBuildParameters: BuildParameters, buildDescription: BuildDescription? = nil, fileSystem: Basics.FileSystem, observabilityScope: ObservabilityScope, packageStructureDelegate: PackageStructureDelegate, buildErrorAdviceProvider: BuildErrorAdviceProvider? = nil ) { - self.buildParameters = buildParameters + self.productsBuildParameters = productsBuildParameters + self.toolsBuildParameters = toolsBuildParameters self.buildDescription = buildDescription self.fileSystem = fileSystem self.observabilityScope = observabilityScope @@ -474,7 +485,7 @@ public final class BuildExecutionContext { do { #if os(Windows) // The library's runtime component is in the `bin` directory on - // Windows rather than the `lib` directory as on unicies. The `lib` + // Windows rather than the `lib` directory as on Unix. The `lib` // directory contains the import library (and possibly static // archives) which are used for linking. The runtime component is // not (necessarily) part of the SDK distributions. @@ -488,8 +499,8 @@ public final class BuildExecutionContext { .parentDirectory .appending("libIndexStore.dll") #else - let ext = buildParameters.hostTriple.dynamicLibraryExtension - let indexStoreLib = try buildParameters.toolchain.toolchainLibDir + let ext = toolsBuildParameters.triple.dynamicLibraryExtension + let indexStoreLib = try toolsBuildParameters.toolchain.toolchainLibDir .appending("libIndexStore" + ext) #endif return try .success(IndexStoreAPI(dylib: TSCAbsolutePath(indexStoreLib))) @@ -581,7 +592,8 @@ final class PackageStructureCommand: CustomLLBuildCommand { let encoder = JSONEncoder.makeWithDefaults() // Include build parameters and process env in the signature. var hash = Data() - hash += try! encoder.encode(self.context.buildParameters) + hash += try! encoder.encode(self.context.productsBuildParameters) + hash += try! encoder.encode(self.context.toolsBuildParameters) hash += try! encoder.encode(ProcessEnv.vars) return [UInt8](hash) } diff --git a/Sources/Build/BuildPlan/BuildPlan+Clang.swift b/Sources/Build/BuildPlan/BuildPlan+Clang.swift index 616fdf9b85b..e46758f19df 100644 --- a/Sources/Build/BuildPlan/BuildPlan+Clang.swift +++ b/Sources/Build/BuildPlan/BuildPlan+Clang.swift @@ -18,7 +18,9 @@ import class PackageModel.SystemLibraryTarget extension BuildPlan { /// Plan a Clang target. func plan(clangTarget: ClangTargetBuildDescription) throws { - for case .target(let dependency, _) in try clangTarget.target.recursiveDependencies(satisfying: buildEnvironment) { + let dependencies = try clangTarget.target.recursiveDependencies(satisfying: clangTarget.buildEnvironment) + + for case .target(let dependency, _) in dependencies { switch dependency.underlyingTarget { case is SwiftTarget: if case let .swift(dependencyTargetDescription)? = targetMap[dependency] { @@ -42,7 +44,7 @@ extension BuildPlan { clangTarget.additionalFlags += try pkgConfig(for: target).cFlags case let target as BinaryTarget: if case .xcframework = target.kind { - let libraries = try self.parseXCFramework(for: target) + let libraries = try self.parseXCFramework(for: target, triple: clangTarget.buildParameters.triple) for library in libraries { library.headersPaths.forEach { clangTarget.additionalFlags += ["-I", $0.pathString] diff --git a/Sources/Build/BuildPlan/BuildPlan+Product.swift b/Sources/Build/BuildPlan/BuildPlan+Product.swift index 78af6a044a5..bb792e9c340 100644 --- a/Sources/Build/BuildPlan/BuildPlan+Product.swift +++ b/Sources/Build/BuildPlan/BuildPlan+Product.swift @@ -11,6 +11,7 @@ //===----------------------------------------------------------------------===// import struct Basics.AbsolutePath +import struct Basics.Triple import struct Basics.InternalError import class PackageGraph.ResolvedProduct import class PackageGraph.ResolvedTarget @@ -19,6 +20,7 @@ import class PackageModel.ClangTarget import class PackageModel.Target import class PackageModel.SwiftTarget import class PackageModel.SystemLibraryTarget +import struct SPMBuildCore.BuildParameters import struct SPMBuildCore.ExecutableInfo import func TSCBasic.topologicalSort @@ -26,7 +28,7 @@ extension BuildPlan { /// Plan a product. func plan(buildProduct: ProductBuildDescription) throws { // Compute the product's dependency. - let dependencies = try computeDependencies(of: buildProduct.product) + let dependencies = try computeDependencies(of: buildProduct.product, buildParameters: buildProduct.buildParameters) // Add flags for system targets. for systemModule in dependencies.systemModules { @@ -52,9 +54,10 @@ extension BuildPlan { // Note: This will come from build settings in future. for target in dependencies.staticTargets { if case let target as ClangTarget = target.underlyingTarget, target.isCXX { - if buildParameters.targetTriple.isDarwin() { + let triple = buildProduct.buildParameters.triple + if triple.isDarwin() { buildProduct.additionalFlags += ["-lc++"] - } else if buildParameters.targetTriple.isWindows() { + } else if triple.isWindows() { // Don't link any C++ library. } else { buildProduct.additionalFlags += ["-lstdc++"] @@ -75,7 +78,7 @@ extension BuildPlan { // product or link in the wrapped module object. This is required for properly debugging // Swift products. Debugging strategy is computed based on the current platform we're // building for and is nil for the release configuration. - switch buildParameters.debuggingStrategy { + switch buildProduct.buildParameters.debuggingStrategy { case .swiftAST: buildProduct.swiftASTs.insert(description.moduleOutputPath) case .modulewrap: @@ -107,7 +110,8 @@ extension BuildPlan { /// Computes the dependencies of a product. private func computeDependencies( - of product: ResolvedProduct + of product: ResolvedProduct, + buildParameters: BuildParameters ) throws -> ( dylibs: [ResolvedProduct], staticTargets: [ResolvedTarget], @@ -156,12 +160,12 @@ extension BuildPlan { if shouldExcludePlugins, !topLevelIsPlugin && !topLevelIsTest && target.type == .plugin { return [] } - return target.dependencies.filter { $0.satisfies(self.buildEnvironment) } + return target.dependencies.filter { $0.satisfies(buildParameters.buildEnvironment) } // For a product dependency, we only include its content only if we // need to statically link it. case .product(let product, _): - guard dependency.satisfies(self.buildEnvironment) else { + guard dependency.satisfies(buildParameters.buildEnvironment) else { return [] } @@ -221,12 +225,12 @@ extension BuildPlan { } switch binaryTarget.kind { case .xcframework: - let libraries = try self.parseXCFramework(for: binaryTarget) + let libraries = try self.parseXCFramework(for: binaryTarget, triple: buildParameters.triple) for library in libraries { libraryBinaryPaths.insert(library.libraryPath) } case .artifactsArchive: - let tools = try self.parseArtifactsArchive(for: binaryTarget) + let tools = try self.parseArtifactsArchive(for: binaryTarget, triple: buildParameters.triple) tools.forEach { availableTools[$0.name] = $0.executablePath } case.unknown: throw InternalError("unknown binary target '\(target.name)' type") @@ -254,9 +258,9 @@ extension BuildPlan { } /// Extracts the artifacts from an artifactsArchive - private func parseArtifactsArchive(for target: BinaryTarget) throws -> [ExecutableInfo] { - try self.externalExecutablesCache.memoize(key: target) { - let execInfos = try target.parseArtifactArchives(for: self.buildParameters.targetTriple, fileSystem: self.fileSystem) + private func parseArtifactsArchive(for binaryTarget: BinaryTarget, triple: Triple) throws -> [ExecutableInfo] { + try self.externalExecutablesCache.memoize(key: binaryTarget) { + let execInfos = try binaryTarget.parseArtifactArchives(for: triple, fileSystem: self.fileSystem) return execInfos.filter{!$0.supportedTriples.isEmpty} } } diff --git a/Sources/Build/BuildPlan/BuildPlan+Swift.swift b/Sources/Build/BuildPlan/BuildPlan+Swift.swift index c5183f4d72c..614b5aa48eb 100644 --- a/Sources/Build/BuildPlan/BuildPlan+Swift.swift +++ b/Sources/Build/BuildPlan/BuildPlan+Swift.swift @@ -19,7 +19,8 @@ extension BuildPlan { func plan(swiftTarget: SwiftTargetBuildDescription) throws { // We need to iterate recursive dependencies because Swift compiler needs to see all the targets a target // depends on. - for case .target(let dependency, _) in try swiftTarget.target.recursiveDependencies(satisfying: buildEnvironment) { + let environment = swiftTarget.buildParameters.buildEnvironment + for case .target(let dependency, _) in try swiftTarget.target.recursiveDependencies(satisfying: environment) { switch dependency.underlyingTarget { case let underlyingTarget as ClangTarget where underlyingTarget.type == .library: guard case let .clang(target)? = targetMap[dependency] else { @@ -39,7 +40,7 @@ extension BuildPlan { swiftTarget.additionalFlags += try pkgConfig(for: target).cFlags case let target as BinaryTarget: if case .xcframework = target.kind { - let libraries = try self.parseXCFramework(for: target) + let libraries = try self.parseXCFramework(for: target, triple: swiftTarget.buildParameters.triple) for library in libraries { library.headersPaths.forEach { swiftTarget.additionalFlags += ["-I", $0.pathString, "-Xcc", "-I", "-Xcc", $0.pathString] diff --git a/Sources/Build/BuildPlan/BuildPlan.swift b/Sources/Build/BuildPlan/BuildPlan.swift index fadea472769..39a9f3a55f9 100644 --- a/Sources/Build/BuildPlan/BuildPlan.swift +++ b/Sources/Build/BuildPlan/BuildPlan.swift @@ -130,13 +130,14 @@ extension BuildParameters { /// Computes the target triple arguments for a given resolved target. public func targetTripleArgs(for target: ResolvedTarget) throws -> [String] { var args = ["-target"] + // Compute the triple string for Darwin platform using the platform version. - if targetTriple.isDarwin() { + if self.triple.isDarwin() { let platform = buildEnvironment.platform let supportedPlatform = target.platforms.getDerived(for: platform, usingXCTest: target.type == .test) - args += [targetTriple.tripleString(forPlatformVersion: supportedPlatform.version.versionString)] + args += [self.triple.tripleString(forPlatformVersion: supportedPlatform.version.versionString)] } else { - args += [targetTriple.tripleString] + args += [self.triple.tripleString] } return args } @@ -144,13 +145,11 @@ extension BuildParameters { /// Computes the linker flags to use in order to rename a module-named main function to 'main' for the target platform, or nil if the linker doesn't support it for the platform. func linkerFlagsForRenamingMainFunction(of target: ResolvedTarget) -> [String]? { let args: [String] - if self.targetTriple.isApple() { + if self.triple.isApple() { args = ["-alias", "_\(target.c99name)_main", "_main"] - } - else if self.targetTriple.isLinux() { + } else if self.triple.isLinux() { args = ["--defsym", "main=\(target.c99name)_main"] - } - else { + } else { return nil } return args.asSwiftcLinkerFlags() @@ -164,7 +163,6 @@ extension BuildParameters { /// A build plan for a package graph. public class BuildPlan: SPMBuildCore.BuildPlan { - public enum Error: Swift.Error, CustomStringConvertible, Equatable { /// There is no buildable target in the graph. case noBuildableTarget @@ -180,12 +178,49 @@ public class BuildPlan: SPMBuildCore.BuildPlan { } } - /// The build parameters. - public let buildParameters: BuildParameters + @available(*, deprecated, message: "use either `productsBuildParameters` or `toolsBuildParameters`") + public var buildParameters: BuildParameters { self.productsBuildParameters } + + /// Build parameters used for products. + public let productsBuildParameters: BuildParameters + + /// Build parameters used for tools. + public let toolsBuildParameters: BuildParameters + + /// Parameters used for building this target. + func buildParameters(for target: ResolvedTarget) -> BuildParameters { + switch target.buildTriple { + case .buildTools: + return self.toolsBuildParameters + case .buildProducts: + return self.productsBuildParameters + } + } + + /// Parameters used for building this product. + func buildParameters(for product: ResolvedProduct) -> BuildParameters { + switch product.buildTriple { + case .buildTools: + return self.toolsBuildParameters + case .buildProducts: + return self.productsBuildParameters + } + } + + /// Triple for which this target is compiled. + private func buildTriple(for target: ResolvedTarget) -> Basics.Triple { + self.buildParameters(for: target).triple + } + + /// Triple for which this product is compiled. + private func buildTriple(for product: ResolvedProduct) -> Basics.Triple { + self.buildParameters(for: product).triple + } /// The build environment. + @available(*, deprecated, message: "Use `buildParameters(for:)` to get build parameters instead") var buildEnvironment: BuildEnvironment { - buildParameters.buildEnvironment + self.buildParameters.buildEnvironment } /// The package graph. @@ -230,22 +265,47 @@ public class BuildPlan: SPMBuildCore.BuildPlan { var externalExecutablesCache = [BinaryTarget: [ExecutableInfo]]() /// The filesystem to operate on. - let fileSystem: FileSystem + let fileSystem: any FileSystem /// ObservabilityScope with which to emit diagnostics let observabilityScope: ObservabilityScope - /// Create a build plan with build parameters and a package graph. - public init( + /// Create a build plan with a package graph and same build parameters for products and tools. Provided for + /// testing purposes only. + convenience init( buildParameters: BuildParameters, graph: PackageGraph, additionalFileRules: [FileRuleDescription] = [], buildToolPluginInvocationResults: [ResolvedTarget: [BuildToolPluginInvocationResult]] = [:], prebuildCommandResults: [ResolvedTarget: [PrebuildCommandResult]] = [:], - fileSystem: FileSystem, + fileSystem: any FileSystem, observabilityScope: ObservabilityScope ) throws { - self.buildParameters = buildParameters + try self.init( + productsBuildParameters: buildParameters, + toolsBuildParameters: buildParameters, + graph: graph, + additionalFileRules: additionalFileRules, + buildToolPluginInvocationResults: buildToolPluginInvocationResults, + prebuildCommandResults: prebuildCommandResults, + fileSystem: fileSystem, + observabilityScope: observabilityScope + ) + } + + /// Create a build plan with a package graph and explicitly distinct build parameters for products and tools. + public init( + productsBuildParameters: BuildParameters, + toolsBuildParameters: BuildParameters, + graph: PackageGraph, + additionalFileRules: [FileRuleDescription] = [], + buildToolPluginInvocationResults: [ResolvedTarget: [BuildToolPluginInvocationResult]] = [:], + prebuildCommandResults: [ResolvedTarget: [PrebuildCommandResult]] = [:], + fileSystem: any FileSystem, + observabilityScope: ObservabilityScope + ) throws { + self.productsBuildParameters = productsBuildParameters + self.toolsBuildParameters = toolsBuildParameters self.graph = graph self.buildToolPluginInvocationResults = buildToolPluginInvocationResults self.prebuildCommandResults = prebuildCommandResults @@ -255,6 +315,14 @@ public class BuildPlan: SPMBuildCore.BuildPlan { var productMap: [ResolvedProduct: ProductBuildDescription] = [:] // Create product description for each product we have in the package graph that is eligible. for product in graph.allProducts where product.shouldCreateProductDescription { + let buildParameters: BuildParameters + switch product.buildTriple { + case .buildTools: + buildParameters = toolsBuildParameters + case .buildProducts: + buildParameters = productsBuildParameters + } + guard let package = graph.package(for: product) else { throw InternalError("unknown package for \(product)") } @@ -284,6 +352,14 @@ public class BuildPlan: SPMBuildCore.BuildPlan { var pluginDescriptions = [PluginDescription]() var shouldGenerateTestObservation = true for target in graph.allTargets.sorted(by: { $0.name < $1.name }) { + let buildParameters: BuildParameters + switch target.buildTriple { + case .buildTools: + buildParameters = toolsBuildParameters + case .buildProducts: + buildParameters = productsBuildParameters + } + // Validate the product dependencies of this target. for dependency in target.dependencies { guard dependency.satisfies(buildParameters.buildEnvironment) else { @@ -293,7 +369,7 @@ public class BuildPlan: SPMBuildCore.BuildPlan { switch dependency { case .target: break case .product(let product, _): - if buildParameters.targetTriple.isDarwin() { + if buildParameters.triple.isDarwin() { try BuildPlan.validateDeploymentVersionOfProductDependency( product: product, forTarget: target, @@ -373,9 +449,9 @@ public class BuildPlan: SPMBuildCore.BuildPlan { } // Plan the derived test targets, if necessary. - if buildParameters.testingParameters.testProductStyle.requiresAdditionalDerivedTestTargets { + if productsBuildParameters.testingParameters.testProductStyle.requiresAdditionalDerivedTestTargets { let derivedTestTargets = try Self.makeDerivedTestTargets( - buildParameters, + productsBuildParameters, graph, self.fileSystem, self.observabilityScope @@ -447,14 +523,16 @@ public class BuildPlan: SPMBuildCore.BuildPlan { } public func createAPIToolCommonArgs(includeLibrarySearchPaths: Bool) throws -> [String] { - let buildPath = buildParameters.buildPath.pathString + // API tool runs on products, hence using `self.productsBuildParameters`, not `self.toolsBuildParameters` + let buildPath = self.productsBuildParameters.buildPath.pathString var arguments = ["-I", buildPath] // swift-symbolgraph-extract does not support parsing `-use-ld=lld` and // will silently error failing the operation. Filter out this flag // similar to how we filter out the library search path unless // explicitly requested. - var extraSwiftCFlags = buildParameters.toolchain.extraFlags.swiftCompilerFlags.filter { !$0.starts(with: "-use-ld=") } + var extraSwiftCFlags = self.productsBuildParameters.toolchain.extraFlags.swiftCompilerFlags + .filter { !$0.starts(with: "-use-ld=") } if !includeLibrarySearchPaths { for index in extraSwiftCFlags.indices.dropLast().reversed() { if extraSwiftCFlags[index] == "-L" { @@ -493,7 +571,7 @@ public class BuildPlan: SPMBuildCore.BuildPlan { /// Creates arguments required to launch the Swift REPL that will allow /// importing the modules in the package graph. public func createREPLArguments() throws -> [String] { - let buildPath = buildParameters.buildPath.pathString + let buildPath = self.toolsBuildParameters.buildPath.pathString var arguments = ["repl", "-I" + buildPath, "-L" + buildPath] // Link the special REPL product that contains all of the library targets. @@ -535,8 +613,8 @@ public class BuildPlan: SPMBuildCore.BuildPlan { } let results = try pkgConfigArgs( for: target, - pkgConfigDirectories: buildParameters.pkgConfigDirectories, - sdkRootPath: buildParameters.toolchain.sdkRootPath, + pkgConfigDirectories: self.productsBuildParameters.pkgConfigDirectories, + sdkRootPath: self.productsBuildParameters.toolchain.sdkRootPath, fileSystem: fileSystem, observabilityScope: observabilityScope ) @@ -562,9 +640,9 @@ public class BuildPlan: SPMBuildCore.BuildPlan { } /// Extracts the library information from an XCFramework. - func parseXCFramework(for target: BinaryTarget) throws -> [LibraryInfo] { - try self.externalLibrariesCache.memoize(key: target) { - return try target.parseXCFrameworks(for: self.buildParameters.targetTriple, fileSystem: self.fileSystem) + func parseXCFramework(for binaryTarget: BinaryTarget, triple: Basics.Triple) throws -> [LibraryInfo] { + try self.externalLibrariesCache.memoize(key: binaryTarget) { + return try binaryTarget.parseXCFrameworks(for: triple, fileSystem: self.fileSystem) } } } @@ -600,7 +678,7 @@ extension Basics.Diagnostic { extension BuildParameters { /// Returns a named bundle's path inside the build directory. func bundlePath(named name: String) -> AbsolutePath { - return buildPath.appending(component: name + targetTriple.nsbundleExtension) + return buildPath.appending(component: name + self.triple.nsbundleExtension) } } diff --git a/Sources/Build/TestObservation.swift b/Sources/Build/TestObservation.swift index 30001761c70..6ecf10b988e 100644 --- a/Sources/Build/TestObservation.swift +++ b/Sources/Build/TestObservation.swift @@ -13,7 +13,7 @@ import SPMBuildCore public func generateTestObservationCode(buildParameters: BuildParameters) -> String { - guard buildParameters.targetTriple.supportsTestSummary else { + guard buildParameters.triple.supportsTestSummary else { return "" } diff --git a/Sources/Commands/PackageTools/DumpCommands.swift b/Sources/Commands/PackageTools/DumpCommands.swift index 53e1815ceb1..d7f024aba6e 100644 --- a/Sources/Commands/PackageTools/DumpCommands.swift +++ b/Sources/Commands/PackageTools/DumpCommands.swift @@ -140,7 +140,7 @@ struct DumpPIF: SwiftCommand { func run(_ swiftTool: SwiftTool) throws { let graph = try swiftTool.loadPackageGraph() let pif = try PIFBuilder.generatePIF( - buildParameters: swiftTool.buildParameters(), + buildParameters: swiftTool.productsBuildParameters, packageGraph: graph, fileSystem: swiftTool.fileSystem, observabilityScope: swiftTool.observabilityScope, diff --git a/Sources/Commands/PackageTools/InstalledPackages.swift b/Sources/Commands/PackageTools/InstalledPackages.swift index fb6b5bf9640..62e93e40c6f 100644 --- a/Sources/Commands/PackageTools/InstalledPackages.swift +++ b/Sources/Commands/PackageTools/InstalledPackages.swift @@ -83,7 +83,7 @@ extension SwiftPackageTool { try tool.createBuildSystem(explicitProduct: productToInstall.name) .build(subset: .product(productToInstall.name)) - let binPath = try tool.buildParameters().buildPath.appending(component: productToInstall.name) + let binPath = try tool.productsBuildParameters.buildPath.appending(component: productToInstall.name) let finalBinPath = swiftpmBinDir.appending(component: binPath.basename) try tool.fileSystem.copy(from: binPath, to: finalBinPath) diff --git a/Sources/Commands/PackageTools/PluginCommand.swift b/Sources/Commands/PackageTools/PluginCommand.swift index 648656ebc6a..81778636d5e 100644 --- a/Sources/Commands/PackageTools/PluginCommand.swift +++ b/Sources/Commands/PackageTools/PluginCommand.swift @@ -255,16 +255,17 @@ struct PluginCommand: SwiftCommand { let toolSearchDirs = [try swiftTool.getTargetToolchain().swiftCompilerPath.parentDirectory] + getEnvSearchPaths(pathString: ProcessEnv.path, currentWorkingDirectory: .none) + let buildParameters = try swiftTool.toolsBuildParameters // Build or bring up-to-date any executable host-side tools on which this plugin depends. Add them and any binary dependencies to the tool-names-to-path map. let buildSystem = try swiftTool.createBuildSystem( explicitBuildSystem: .native, cacheBuildManifest: false, - customBuildParameters: swiftTool.hostBuildParameters() + customBuildParameters: buildParameters ) let accessibleTools = try plugin.processAccessibleTools( packageGraph: packageGraph, fileSystem: swiftTool.fileSystem, - environment: try swiftTool.buildParameters().buildEnvironment, + environment: buildParameters.buildEnvironment, for: try pluginScriptRunner.hostTriple ) { name, _ in // Build the product referenced by the tool, and add the executable to the tool map. Product dependencies are not supported within a package, so if the tool happens to be from the same package, we instead find the executable that corresponds to the product. There is always one, because of autogeneration of implicit executables with the same name as the target if there isn't an explicit one. @@ -281,7 +282,6 @@ struct PluginCommand: SwiftCommand { let delegateQueue = DispatchQueue(label: "plugin-invocation") // Run the command plugin. - let buildParameters = try swiftTool.buildParameters() let buildEnvironment = buildParameters.buildEnvironment let _ = try temp_await { plugin.invoke( action: .performCommand(package: package, arguments: arguments), diff --git a/Sources/Commands/SwiftBuildTool.swift b/Sources/Commands/SwiftBuildTool.swift index 243d61dc543..7af5d38d353 100644 --- a/Sources/Commands/SwiftBuildTool.swift +++ b/Sources/Commands/SwiftBuildTool.swift @@ -109,7 +109,7 @@ public struct SwiftBuildTool: SwiftCommand { public func run(_ swiftTool: SwiftTool) throws { if options.shouldPrintBinPath { - return try print(swiftTool.buildParameters().buildPath.description) + return try print(swiftTool.productsBuildParameters.buildPath.description) } if options.printManifestGraphviz { diff --git a/Sources/Commands/Utilities/PluginDelegate.swift b/Sources/Commands/Utilities/PluginDelegate.swift index 9cbba1b3589..8ff64372b7d 100644 --- a/Sources/Commands/Utilities/PluginDelegate.swift +++ b/Sources/Commands/Utilities/PluginDelegate.swift @@ -71,7 +71,7 @@ final class PluginDelegate: PluginInvocationDelegate { parameters: PluginInvocationBuildParameters ) throws -> PluginInvocationBuildResult { // Configure the build parameters. - var buildParameters = try self.swiftTool.buildParameters() + var buildParameters = try self.swiftTool.toolsBuildParameters switch parameters.configuration { case .debug: buildParameters.configuration = .debug @@ -171,7 +171,7 @@ final class PluginDelegate: PluginInvocationDelegate { // Build the tests. Ideally we should only build those that match the subset, but we don't have a way to know // which ones they are until we've built them and can examine the binaries. let toolchain = try swiftTool.getTargetToolchain() - var buildParameters = try swiftTool.buildParameters() + var buildParameters = try swiftTool.toolsBuildParameters buildParameters.testingParameters.enableTestability = true buildParameters.testingParameters.enableCodeCoverage = parameters.enableCodeCoverage let buildSystem = try swiftTool.createBuildSystem(customBuildParameters: buildParameters) diff --git a/Sources/Commands/Utilities/TestingSupport.swift b/Sources/Commands/Utilities/TestingSupport.swift index 727f73cf63c..236feaa072e 100644 --- a/Sources/Commands/Utilities/TestingSupport.swift +++ b/Sources/Commands/Utilities/TestingSupport.swift @@ -211,7 +211,7 @@ extension SwiftTool { experimentalTestOutput: Bool = false, library: BuildParameters.Testing.Library ) throws -> BuildParameters { - var parameters = try self.buildParameters() + var parameters = try self.productsBuildParameters var explicitlyEnabledDiscovery = false var explicitlySpecifiedPath: AbsolutePath? @@ -224,7 +224,7 @@ extension SwiftTool { } parameters.testingParameters = .init( configuration: parameters.configuration, - targetTriple: parameters.targetTriple, + targetTriple: parameters.triple, forceTestDiscovery: explicitlyEnabledDiscovery, testEntryPointPath: explicitlySpecifiedPath, library: library diff --git a/Sources/Commands/Utilities/XCTEvents.swift b/Sources/Commands/Utilities/XCTEvents.swift index d68ada249c2..88ef1ef7983 100644 --- a/Sources/Commands/Utilities/XCTEvents.swift +++ b/Sources/Commands/Utilities/XCTEvents.swift @@ -237,12 +237,12 @@ extension TestErrorInfo { extension TestIssue { init(_ issue: XCTIssue) { self.init( - type: .init(issue.type), + type: .init(productsBuildParameters: issue.type), compactDescription: issue.compactDescription, detailedDescription: issue.detailedDescription, - associatedError: issue.associatedError.map { .init($0) }, - sourceCodeContext: .init(issue.sourceCodeContext), - attachments: issue.attachments.map { .init($0) } + associatedError: issue.associatedError.map { .init(productsBuildParameters: $0) }, + sourceCodeContext: .init(productsBuildParameters: issue.sourceCodeContext), + attachments: issue.attachments.map { .init(productsBuildParameters: $0) } ) } } @@ -275,8 +275,8 @@ extension TestLocation { extension TestSourceCodeContext { init(_ context: XCTSourceCodeContext) { self.init( - callStack: context.callStack.map { .init($0) }, - location: context.location.map { .init($0) } + callStack: context.callStack.map { .init(productsBuildParameters: $0) }, + location: context.location.map { .init(productsBuildParameters: $0) } ) } } @@ -285,8 +285,8 @@ extension TestSourceCodeFrame { init(_ frame: XCTSourceCodeFrame) { self.init( address: frame.address, - symbolInfo: (try? frame.symbolInfo()).map { .init($0) }, - symbolicationError: frame.symbolicationError.map { .init($0) } + symbolInfo: (try? frame.symbolInfo()).map { .init(productsBuildParameters: $0) }, + symbolicationError: frame.symbolicationError.map { .init(productsBuildParameters: $0) } ) } } @@ -296,7 +296,7 @@ extension TestSourceCodeSymbolInfo { self.init( imageName: symbolInfo.imageName, symbolName: symbolInfo.symbolName, - location: symbolInfo.location.map { .init($0) } + location: symbolInfo.location.map { .init(productsBuildParameters: $0) } ) } } diff --git a/Sources/CoreCommands/BuildSystemSupport.swift b/Sources/CoreCommands/BuildSystemSupport.swift index e224c852aeb..dcbc8aa6bbc 100644 --- a/Sources/CoreCommands/BuildSystemSupport.swift +++ b/Sources/CoreCommands/BuildSystemSupport.swift @@ -25,18 +25,24 @@ private struct NativeBuildSystemFactory: BuildSystemFactory { func makeBuildSystem( explicitProduct: String?, cacheBuildManifest: Bool, - customBuildParameters: BuildParameters?, - customPackageGraphLoader: (() throws -> PackageGraph)?, - customOutputStream: OutputByteStream?, - customLogLevel: Diagnostic.Severity?, - customObservabilityScope: ObservabilityScope? + productsBuildParameters: BuildParameters?, + toolsBuildParameters: BuildParameters?, + packageGraphLoader: (() throws -> PackageGraph)?, + outputStream: OutputByteStream?, + logLevel: Diagnostic.Severity?, + observabilityScope: ObservabilityScope? ) throws -> any BuildSystem { - let testEntryPointPath = customBuildParameters?.testingParameters.testProductStyle.explicitlySpecifiedEntryPointPath - let graphLoader = { try self.swiftTool.loadPackageGraph(explicitProduct: explicitProduct, testEntryPointPath: testEntryPointPath) } + let testEntryPointPath = productsBuildParameters?.testingParameters.testProductStyle.explicitlySpecifiedEntryPointPath return try BuildOperation( - buildParameters: customBuildParameters ?? self.swiftTool.buildParameters(), + productsBuildParameters: try productsBuildParameters ?? self.swiftTool.productsBuildParameters, + toolsBuildParameters: try toolsBuildParameters ?? self.swiftTool.toolsBuildParameters, cacheBuildManifest: cacheBuildManifest && self.swiftTool.canUseCachedBuildManifest(), - packageGraphLoader: customPackageGraphLoader ?? graphLoader, + packageGraphLoader: packageGraphLoader ?? { + try self.swiftTool.loadPackageGraph( + explicitProduct: explicitProduct, + testEntryPointPath: testEntryPointPath + ) + }, pluginConfiguration: .init( scriptRunner: self.swiftTool.getPluginScriptRunner(), workDirectory: try self.swiftTool.getActiveWorkspace().location.pluginWorkingDirectory, @@ -44,10 +50,10 @@ private struct NativeBuildSystemFactory: BuildSystemFactory { ), additionalFileRules: FileRuleDescription.swiftpmFileTypes, pkgConfigDirectories: self.swiftTool.options.locations.pkgConfigDirectories, - outputStream: customOutputStream ?? self.swiftTool.outputStream, - logLevel: customLogLevel ?? self.swiftTool.logLevel, + outputStream: outputStream ?? self.swiftTool.outputStream, + logLevel: logLevel ?? self.swiftTool.logLevel, fileSystem: self.swiftTool.fileSystem, - observabilityScope: customObservabilityScope ?? self.swiftTool.observabilityScope) + observabilityScope: observabilityScope ?? self.swiftTool.observabilityScope) } } @@ -57,20 +63,24 @@ private struct XcodeBuildSystemFactory: BuildSystemFactory { func makeBuildSystem( explicitProduct: String?, cacheBuildManifest: Bool, - customBuildParameters: BuildParameters?, - customPackageGraphLoader: (() throws -> PackageGraph)?, - customOutputStream: OutputByteStream?, - customLogLevel: Diagnostic.Severity?, - customObservabilityScope: ObservabilityScope? + productsBuildParameters: BuildParameters?, + toolsBuildParameters: BuildParameters?, + packageGraphLoader: (() throws -> PackageGraph)?, + outputStream: OutputByteStream?, + logLevel: Diagnostic.Severity?, + observabilityScope: ObservabilityScope? ) throws -> any BuildSystem { - let graphLoader = { try self.swiftTool.loadPackageGraph(explicitProduct: explicitProduct) } return try XcodeBuildSystem( - buildParameters: customBuildParameters ?? self.swiftTool.buildParameters(), - packageGraphLoader: customPackageGraphLoader ?? graphLoader, - outputStream: customOutputStream ?? self.swiftTool.outputStream, - logLevel: customLogLevel ?? self.swiftTool.logLevel, + buildParameters: productsBuildParameters ?? self.swiftTool.productsBuildParameters, + packageGraphLoader: packageGraphLoader ?? { + try self.swiftTool.loadPackageGraph( + explicitProduct: explicitProduct + ) + }, + outputStream: outputStream ?? self.swiftTool.outputStream, + logLevel: logLevel ?? self.swiftTool.logLevel, fileSystem: self.swiftTool.fileSystem, - observabilityScope: customObservabilityScope ?? self.swiftTool.observabilityScope + observabilityScope: observabilityScope ?? self.swiftTool.observabilityScope ) } } diff --git a/Sources/CoreCommands/SwiftTool.swift b/Sources/CoreCommands/SwiftTool.swift index b40e9c59341..f70276082ca 100644 --- a/Sources/CoreCommands/SwiftTool.swift +++ b/Sources/CoreCommands/SwiftTool.swift @@ -613,7 +613,7 @@ public final class SwiftTool { return false } - let buildParameters = try self.buildParameters() + let buildParameters = try self.productsBuildParameters let haveBuildManifestAndDescription = self.fileSystem.exists(buildParameters.llbuildManifest) && self.fileSystem.exists(buildParameters.buildDescriptionPath) @@ -659,11 +659,11 @@ public final class SwiftTool { kind: explicitBuildSystem ?? options.build.buildSystem, explicitProduct: explicitProduct, cacheBuildManifest: cacheBuildManifest, - customBuildParameters: customBuildParameters, - customPackageGraphLoader: customPackageGraphLoader, - customOutputStream: customOutputStream, - customLogLevel: customLogLevel, - customObservabilityScope: customObservabilityScope + productsBuildParameters: customBuildParameters, + packageGraphLoader: customPackageGraphLoader, + outputStream: customOutputStream, + logLevel: customLogLevel, + observabilityScope: customObservabilityScope ) // register the build system with the cancellation handler @@ -677,14 +677,13 @@ public final class SwiftTool { """ private func _buildParams(toolchain: UserToolchain) throws -> BuildParameters { - let hostTriple = try self.getHostToolchain().targetTriple - let targetTriple = toolchain.targetTriple + let triple = toolchain.targetTriple let dataPath = self.scratchDirectory.appending( - component: targetTriple.platformBuildPathComponent(buildSystem: options.build.buildSystem) + component: triple.platformBuildPathComponent(buildSystem: options.build.buildSystem) ) - if options.build.getTaskAllowEntitlement != nil && !targetTriple.isMacOSX { + if options.build.getTaskAllowEntitlement != nil && !triple.isMacOSX { observabilityScope.emit(warning: Self.entitlementsMacOSWarning) } @@ -692,8 +691,7 @@ public final class SwiftTool { dataPath: dataPath, configuration: options.build.configuration, toolchain: toolchain, - hostTriple: hostTriple, - targetTriple: targetTriple, + triple: triple, flags: options.build.buildFlags, pkgConfigDirectories: options.locations.pkgConfigDirectories, architectures: options.build.architectures, @@ -703,7 +701,7 @@ public final class SwiftTool { isXcodeBuildSystemEnabled: options.build.buildSystem == .xcode, debuggingParameters: .init( debugInfoFormat: options.build.debugInfoFormat.buildParameter, - targetTriple: targetTriple, + triple: triple, shouldEnableDebuggingEntitlement: options.build.getTaskAllowEntitlement ?? (options.build.configuration == .debug), omitFramePointers: options.build.omitFramePointers @@ -729,7 +727,7 @@ public final class SwiftTool { ), testingParameters: .init( configuration: options.build.configuration, - targetTriple: targetTriple, + targetTriple: triple, forceTestDiscovery: options.build.enableTestDiscovery, // backwards compatibility, remove with --enable-test-discovery testEntryPointPath: options.build.testEntryPointPath ) @@ -737,28 +735,37 @@ public final class SwiftTool { } /// Return the build parameters for the host toolchain. - public func hostBuildParameters() throws -> BuildParameters { - return try _hostBuildParameters.get() + public var toolsBuildParameters: BuildParameters { + get throws { + try _toolsBuildParameters.get() + } } - private lazy var _hostBuildParameters: Result = { - return Result(catching: { + private lazy var _toolsBuildParameters: Result = { + Result(catching: { try _buildParams(toolchain: self.getHostToolchain()) }) }() + public var productsBuildParameters: BuildParameters { + get throws { + try _productsBuildParameters.get() + } + } + /// Return the build parameters. + @available(*, deprecated, renamed: "productsBuildParameters") public func buildParameters() throws -> BuildParameters { - return try _buildParameters.get() + try _productsBuildParameters.get() } - private lazy var _buildParameters: Result = { + private lazy var _productsBuildParameters: Result = { return Result(catching: { try _buildParams(toolchain: self.getTargetToolchain()) }) }() - /// Lazily compute the target toolchain. + /// Lazily compute the target toolchain.z private lazy var _targetToolchain: Result = { var swiftSDK: SwiftSDK let hostSwiftSDK: SwiftSDK diff --git a/Sources/PackageGraph/BuildTriple.swift b/Sources/PackageGraph/BuildTriple.swift new file mode 100644 index 00000000000..e82bdd49e58 --- /dev/null +++ b/Sources/PackageGraph/BuildTriple.swift @@ -0,0 +1,22 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the Swift open source project +// +// Copyright (c) 2023 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See http://swift.org/LICENSE.txt for license information +// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// + +/// Triple for which code should be compiled for. +/// > Note: We're not using "host" and "target" triple terminology in this enum, as that clashes with build +/// > system "targets" and can lead to confusion in this context. +public enum BuildTriple { + /// Triple for which build tools are compiled (the host triple). + case buildTools + + /// Triple for which build products are compiled (the target triple). + case buildProducts +} diff --git a/Sources/PackageGraph/CMakeLists.txt b/Sources/PackageGraph/CMakeLists.txt index 9d70abc6546..30dce2f22a3 100644 --- a/Sources/PackageGraph/CMakeLists.txt +++ b/Sources/PackageGraph/CMakeLists.txt @@ -8,6 +8,7 @@ add_library(PackageGraph BoundVersion.swift + BuildTriple.swift DependencyMirrors.swift Diagnostics.swift GraphLoadingNode.swift diff --git a/Sources/PackageGraph/Resolution/ResolvedProduct.swift b/Sources/PackageGraph/Resolution/ResolvedProduct.swift index e27b13883e3..8fd38f8302a 100644 --- a/Sources/PackageGraph/Resolution/ResolvedProduct.swift +++ b/Sources/PackageGraph/Resolution/ResolvedProduct.swift @@ -39,6 +39,9 @@ public final class ResolvedProduct { /// The list of platforms that are supported by this product. public let platforms: SupportedPlatforms + /// Triple for which this resolved product should be compiled for. + public let buildTriple: BuildTriple + /// The main executable target of product. /// /// Note: This property is only valid for executable products. @@ -81,6 +84,8 @@ public final class ResolvedProduct { platforms: platforms ) } + + self.buildTriple = .buildProducts } /// True if this product contains Swift targets. diff --git a/Sources/PackageGraph/Resolution/ResolvedTarget.swift b/Sources/PackageGraph/Resolution/ResolvedTarget.swift index e6c478f1763..c1e8dca1b36 100644 --- a/Sources/PackageGraph/Resolution/ResolvedTarget.swift +++ b/Sources/PackageGraph/Resolution/ResolvedTarget.swift @@ -141,6 +141,9 @@ public final class ResolvedTarget { /// The list of platforms that are supported by this target. public let platforms: SupportedPlatforms + /// Triple for which this resolved target should be compiled for. + public let buildTriple: BuildTriple + /// Create a resolved target instance. public init( target: Target, @@ -152,6 +155,7 @@ public final class ResolvedTarget { self.dependencies = dependencies self.defaultLocalization = defaultLocalization self.platforms = platforms + self.buildTriple = .buildProducts } } diff --git a/Sources/SPMBuildCore/BuildParameters/BuildParameters+Debugging.swift b/Sources/SPMBuildCore/BuildParameters/BuildParameters+Debugging.swift index 5c0950d6aea..1c27a2fa469 100644 --- a/Sources/SPMBuildCore/BuildParameters/BuildParameters+Debugging.swift +++ b/Sources/SPMBuildCore/BuildParameters/BuildParameters+Debugging.swift @@ -17,7 +17,7 @@ extension BuildParameters { public struct Debugging: Encodable { public init( debugInfoFormat: DebugInfoFormat = .dwarf, - targetTriple: Triple, + triple: Triple, shouldEnableDebuggingEntitlement: Bool, omitFramePointers: Bool? ) { @@ -25,13 +25,13 @@ extension BuildParameters { // Per rdar://112065568 for backtraces to work on macOS a special entitlement needs to be granted on the final // executable. - self.shouldEnableDebuggingEntitlement = targetTriple.isMacOSX && shouldEnableDebuggingEntitlement + self.shouldEnableDebuggingEntitlement = triple.isMacOSX && shouldEnableDebuggingEntitlement // rdar://117578677: frame-pointer to support backtraces // this can be removed once the backtracer uses DWARF instead of frame pointers if let omitFramePointers { // if set, we respect user's preference self.omitFramePointers = omitFramePointers - } else if targetTriple.isLinux() { + } else if triple.isLinux() { // on Linux we preserve frame pointers by default self.omitFramePointers = false } else { @@ -67,7 +67,7 @@ extension BuildParameters { return nil } - if targetTriple.isApple() { + if self.triple.isApple() { return .swiftAST } return .modulewrap diff --git a/Sources/SPMBuildCore/BuildParameters/BuildParameters.swift b/Sources/SPMBuildCore/BuildParameters/BuildParameters.swift index 9d6f9beec2f..65d6df86626 100644 --- a/Sources/SPMBuildCore/BuildParameters/BuildParameters.swift +++ b/Sources/SPMBuildCore/BuildParameters/BuildParameters.swift @@ -37,10 +37,15 @@ public struct BuildParameters: Encodable { private let _toolchain: _Toolchain /// Host triple. - public var hostTriple: Triple + @available(*, deprecated, message: "use separate `BuildParameters` values to distinguish between host and target") + public var hostTriple: Triple { self.triple } /// Target triple. - public var targetTriple: Triple + @available(*, deprecated, message: "use separate `BuildParameters` values to distinguish between host and target") + public var targetTriple: Triple { self.triple } + + /// The triple for which the code is built using these build parameters. + public var triple: Triple /// Extra build flags. public var flags: BuildFlags @@ -71,8 +76,8 @@ public struct BuildParameters: Encodable { /// The current platform we're building for. var currentPlatform: PackageModel.Platform { - if self.targetTriple.isDarwin() { - switch self.targetTriple.darwinPlatform { + if self.triple.isDarwin() { + switch self.triple.darwinPlatform { case .iOS(.catalyst): return .macCatalyst case .iOS(.device), .iOS(.simulator): @@ -84,13 +89,13 @@ public struct BuildParameters: Encodable { case .macOS, nil: return .macOS } - } else if self.targetTriple.isAndroid() { + } else if self.triple.isAndroid() { return .android - } else if self.targetTriple.isWASI() { + } else if self.triple.isWASI() { return .wasi - } else if self.targetTriple.isWindows() { + } else if self.triple.isWindows() { return .windows - } else if self.targetTriple.isOpenBSD() { + } else if self.triple.isOpenBSD() { return .openbsd } else { return .linux @@ -121,8 +126,7 @@ public struct BuildParameters: Encodable { dataPath: AbsolutePath, configuration: BuildConfiguration, toolchain: Toolchain, - hostTriple: Triple? = nil, - targetTriple: Triple? = nil, + triple: Triple? = nil, flags: BuildFlags, pkgConfigDirectories: [AbsolutePath] = [], architectures: [String]? = nil, @@ -138,9 +142,9 @@ public struct BuildParameters: Encodable { outputParameters: Output = .init(), testingParameters: Testing? = nil ) throws { - let targetTriple = try targetTriple ?? .getHostTriple(usingSwiftCompiler: toolchain.swiftCompilerPath) + let triple = try triple ?? .getHostTriple(usingSwiftCompiler: toolchain.swiftCompilerPath) self.debuggingParameters = debuggingParameters ?? .init( - targetTriple: targetTriple, + triple: triple, shouldEnableDebuggingEntitlement: configuration == .debug, omitFramePointers: nil ) @@ -148,21 +152,20 @@ public struct BuildParameters: Encodable { self.dataPath = dataPath self.configuration = configuration self._toolchain = _Toolchain(toolchain: toolchain) - self.hostTriple = try hostTriple ?? .getHostTriple(usingSwiftCompiler: toolchain.swiftCompilerPath) - self.targetTriple = targetTriple + self.triple = triple switch self.debuggingParameters.debugInfoFormat { case .dwarf: var flags = flags // DWARF requires lld as link.exe expects CodeView debug info. - self.flags = flags.merging(targetTriple.isWindows() ? BuildFlags( + self.flags = flags.merging(triple.isWindows() ? BuildFlags( cCompilerFlags: ["-gdwarf"], cxxCompilerFlags: ["-gdwarf"], swiftCompilerFlags: ["-g", "-use-ld=lld"], linkerFlags: ["-debug:dwarf"] ) : BuildFlags(cCompilerFlags: ["-g"], cxxCompilerFlags: ["-g"], swiftCompilerFlags: ["-g"])) case .codeview: - if !targetTriple.isWindows() { - throw StringError("CodeView debug information is currently not supported on \(targetTriple.osName)") + if !triple.isWindows() { + throw StringError("CodeView debug information is currently not supported on \(triple.osName)") } var flags = flags self.flags = flags.merging(BuildFlags( @@ -190,9 +193,10 @@ public struct BuildParameters: Encodable { self.driverParameters = driverParameters self.linkingParameters = linkingParameters self.outputParameters = outputParameters - self.testingParameters = testingParameters ?? .init(configuration: configuration, targetTriple: targetTriple) + self.testingParameters = testingParameters ?? .init(configuration: configuration, targetTriple: triple) } + @available(*, deprecated, message: "Use build parameters value separately created at a higher value instead") public func forTriple(_ targetTriple: Triple) throws -> BuildParameters { var hostSDK = try SwiftSDK.hostSwiftSDK() hostSDK.targetTriple = targetTriple @@ -201,8 +205,7 @@ public struct BuildParameters: Encodable { dataPath: self.dataPath.parentDirectory.appending(components: ["plugins", "tools"]), configuration: self.configuration, toolchain: try UserToolchain(swiftSDK: hostSDK), - hostTriple: self.hostTriple, - targetTriple: targetTriple, + triple: nil, flags: BuildFlags(), pkgConfigDirectories: self.pkgConfigDirectories, architectures: nil, @@ -245,14 +248,19 @@ public struct BuildParameters: Encodable { } public var llbuildManifest: AbsolutePath { + // FIXME: this path isn't specific to `BuildParameters` due to its use of `..` + // FIXME: it should be calculated in a different place return dataPath.appending(components: "..", configuration.dirname + ".yaml") } public var pifManifest: AbsolutePath { + // FIXME: this path isn't specific to `BuildParameters` due to its use of `..` + // FIXME: it should be calculated in a different place return dataPath.appending(components: "..", "manifest.pif") } public var buildDescriptionPath: AbsolutePath { + // FIXME: this path isn't specific to `BuildParameters`, should be moved one directory level higher return buildPath.appending(components: "description.json") } @@ -266,30 +274,30 @@ public struct BuildParameters: Encodable { /// Returns the path to the dynamic library of a product for the current build parameters. func potentialDynamicLibraryPath(for product: ResolvedProduct) throws -> RelativePath { - try RelativePath(validating: "\(targetTriple.dynamicLibraryPrefix)\(product.name)\(targetTriple.dynamicLibraryExtension)") + try RelativePath(validating: "\(self.triple.dynamicLibraryPrefix)\(product.name)\(self.triple.dynamicLibraryExtension)") } /// Returns the path to the binary of a product for the current build parameters, relative to the build directory. public func binaryRelativePath(for product: ResolvedProduct) throws -> RelativePath { - let potentialExecutablePath = try RelativePath(validating: "\(product.name)\(targetTriple.executableExtension)") + let potentialExecutablePath = try RelativePath(validating: "\(product.name)\(self.triple.executableExtension)") switch product.type { case .executable, .snippet: return potentialExecutablePath case .library(.static): - return try RelativePath(validating: "lib\(product.name)\(targetTriple.staticLibraryExtension)") + return try RelativePath(validating: "lib\(product.name)\(self.triple.staticLibraryExtension)") case .library(.dynamic): return try potentialDynamicLibraryPath(for: product) case .library(.automatic), .plugin: fatalError() case .test: - guard !targetTriple.isWASI() else { + guard !self.triple.isWASI() else { return try RelativePath(validating: "\(product.name).wasm") } switch testingParameters.library { case .xctest: let base = "\(product.name).xctest" - if targetTriple.isDarwin() { + if self.triple.isDarwin() { return try RelativePath(validating: "\(base)/Contents/MacOS/\(product.name)") } else { return try RelativePath(validating: base) diff --git a/Sources/SPMBuildCore/BuildSystem/BuildSystem.swift b/Sources/SPMBuildCore/BuildSystem/BuildSystem.swift index b9216ca5048..e6490b2ae3b 100644 --- a/Sources/SPMBuildCore/BuildSystem/BuildSystem.swift +++ b/Sources/SPMBuildCore/BuildSystem/BuildSystem.swift @@ -91,11 +91,12 @@ public protocol BuildSystemFactory { func makeBuildSystem( explicitProduct: String?, cacheBuildManifest: Bool, - customBuildParameters: BuildParameters?, - customPackageGraphLoader: (() throws -> PackageGraph)?, - customOutputStream: OutputByteStream?, - customLogLevel: Diagnostic.Severity?, - customObservabilityScope: ObservabilityScope? + productsBuildParameters: BuildParameters?, + toolsBuildParameters: BuildParameters?, + packageGraphLoader: (() throws -> PackageGraph)?, + outputStream: OutputByteStream?, + logLevel: Diagnostic.Severity?, + observabilityScope: ObservabilityScope? ) throws -> any BuildSystem } @@ -116,11 +117,12 @@ public struct BuildSystemProvider { kind: Kind, explicitProduct: String? = .none, cacheBuildManifest: Bool = true, - customBuildParameters: BuildParameters? = .none, - customPackageGraphLoader: (() throws -> PackageGraph)? = .none, - customOutputStream: OutputByteStream? = .none, - customLogLevel: Diagnostic.Severity? = .none, - customObservabilityScope: ObservabilityScope? = .none + productsBuildParameters: BuildParameters? = .none, + toolsBuildParameters: BuildParameters? = .none, + packageGraphLoader: (() throws -> PackageGraph)? = .none, + outputStream: OutputByteStream? = .none, + logLevel: Diagnostic.Severity? = .none, + observabilityScope: ObservabilityScope? = .none ) throws -> any BuildSystem { guard let buildSystemFactory = self.providers[kind] else { throw Errors.buildSystemProviderNotRegistered(kind: kind) @@ -128,11 +130,12 @@ public struct BuildSystemProvider { return try buildSystemFactory.makeBuildSystem( explicitProduct: explicitProduct, cacheBuildManifest: cacheBuildManifest, - customBuildParameters: customBuildParameters, - customPackageGraphLoader: customPackageGraphLoader, - customOutputStream: customOutputStream, - customLogLevel: customLogLevel, - customObservabilityScope: customObservabilityScope + productsBuildParameters: productsBuildParameters, + toolsBuildParameters: toolsBuildParameters, + packageGraphLoader: packageGraphLoader, + outputStream: outputStream, + logLevel: logLevel, + observabilityScope: observabilityScope ) } } diff --git a/Sources/XCBuildSupport/XcodeBuildSystem.swift b/Sources/XCBuildSupport/XcodeBuildSystem.swift index d51eb6f8de6..9eeb82ac32d 100644 --- a/Sources/XCBuildSupport/XcodeBuildSystem.swift +++ b/Sources/XCBuildSupport/XcodeBuildSystem.swift @@ -190,7 +190,7 @@ public final class XcodeBuildSystem: SPMBuildCore.BuildSystem { platform: "macosx", sdk: "macosx", sdkVariant: nil, - targetArchitecture: buildParameters.targetTriple.archName, + targetArchitecture: buildParameters.triple.archName, supportedArchitectures: [], disableOnlyActiveArch: true ) diff --git a/Sources/swift-bootstrap/main.swift b/Sources/swift-bootstrap/main.swift index 86ce514687a..51c22c56750 100644 --- a/Sources/swift-bootstrap/main.swift +++ b/Sources/swift-bootstrap/main.swift @@ -281,8 +281,7 @@ struct SwiftBootstrapBuildTool: ParsableCommand { dataPath: dataPath, configuration: configuration, toolchain: self.targetToolchain, - hostTriple: self.hostToolchain.targetTriple, - targetTriple: self.targetToolchain.targetTriple, + triple: self.hostToolchain.targetTriple, flags: buildFlags, architectures: architectures, isXcodeBuildSystemEnabled: buildSystem == .xcode, @@ -308,7 +307,9 @@ struct SwiftBootstrapBuildTool: ParsableCommand { switch buildSystem { case .native: return BuildOperation( - buildParameters: buildParameters, + // when building `swift-bootstrap`, host and target build parameters are the same + productsBuildParameters: buildParameters, + toolsBuildParameters: buildParameters, cacheBuildManifest: false, packageGraphLoader: packageGraphLoader, additionalFileRules: [], diff --git a/Tests/BuildTests/BuildPlanTests.swift b/Tests/BuildTests/BuildPlanTests.swift index 0b74061652d..8c08fde4e8e 100644 --- a/Tests/BuildTests/BuildPlanTests.swift +++ b/Tests/BuildTests/BuildPlanTests.swift @@ -3740,7 +3740,7 @@ final class BuildPlanTests: XCTestCase { var copy = extraBuildParameters copy.linkingParameters.shouldLinkStaticSwiftStdlib = true // pick a triple with support for static linking - copy.targetTriple = .x86_64Linux + copy.triple = .x86_64Linux return copy }() let staticResult = try BuildPlanResult(plan: BuildPlan( diff --git a/Tests/BuildTests/LLBuildManifestBuilderTests.swift b/Tests/BuildTests/LLBuildManifestBuilderTests.swift index 5f8b4a3279c..d577e577c7a 100644 --- a/Tests/BuildTests/LLBuildManifestBuilderTests.swift +++ b/Tests/BuildTests/LLBuildManifestBuilderTests.swift @@ -50,7 +50,8 @@ final class LLBuildManifestBuilderTests: XCTestCase { configuration: .release )) var plan = try BuildPlan( - buildParameters: buildParameters, + productsBuildParameters: buildParameters, + toolsBuildParameters: buildParameters, graph: graph, fileSystem: fs, observabilityScope: observability.topScope @@ -84,7 +85,8 @@ final class LLBuildManifestBuilderTests: XCTestCase { configuration: .debug )) plan = try BuildPlan( - buildParameters: buildParameters, + productsBuildParameters: buildParameters, + toolsBuildParameters: buildParameters, graph: graph, fileSystem: fs, observabilityScope: observability.topScope @@ -137,7 +139,8 @@ final class LLBuildManifestBuilderTests: XCTestCase { configuration: .release )) plan = try BuildPlan( - buildParameters: buildParameters, + productsBuildParameters: buildParameters, + toolsBuildParameters: buildParameters, graph: graph, fileSystem: fs, observabilityScope: observability.topScope @@ -161,7 +164,8 @@ final class LLBuildManifestBuilderTests: XCTestCase { configuration: .debug )) plan = try BuildPlan( - buildParameters: buildParameters, + productsBuildParameters: buildParameters, + toolsBuildParameters: buildParameters, graph: graph, fileSystem: fs, observabilityScope: observability.topScope diff --git a/Tests/BuildTests/MockBuildTestHelper.swift b/Tests/BuildTests/MockBuildTestHelper.swift index 39f8b5465c9..850ff3008e0 100644 --- a/Tests/BuildTests/MockBuildTestHelper.swift +++ b/Tests/BuildTests/MockBuildTestHelper.swift @@ -85,14 +85,13 @@ func mockBuildParameters( dataPath: buildPath, configuration: config, toolchain: toolchain, - hostTriple: hostTriple, - targetTriple: targetTriple, + triple: targetTriple, flags: flags, pkgConfigDirectories: [], workers: 3, indexStoreMode: indexStoreMode, debuggingParameters: .init( - targetTriple: targetTriple, + triple: targetTriple, shouldEnableDebuggingEntitlement: config == .debug, omitFramePointers: omitFramePointers ), diff --git a/Tests/CommandsTests/SwiftToolTests.swift b/Tests/CommandsTests/SwiftToolTests.swift index e421677ab19..098f9d237ef 100644 --- a/Tests/CommandsTests/SwiftToolTests.swift +++ b/Tests/CommandsTests/SwiftToolTests.swift @@ -255,7 +255,8 @@ final class SwiftToolTests: CommandsTestCase { let explicitDwarfOptions = try GlobalOptions.parse(["--triple", "x86_64-unknown-windows-msvc", "-debug-info-format", "dwarf"]) let explicitDwarf = try SwiftTool.createSwiftToolForTest(options: explicitDwarfOptions) plan = try BuildPlan( - buildParameters: explicitDwarf.buildParameters(), + productsBuildParameters: explicitDwarf.productsBuildParameters, + toolsBuildParameters: explicitDwarf.toolsBuildParameters, graph: graph, fileSystem: fs, observabilityScope: observer.topScope @@ -269,7 +270,7 @@ final class SwiftToolTests: CommandsTestCase { let explicitCodeView = try SwiftTool.createSwiftToolForTest(options: explicitCodeViewOptions) plan = try BuildPlan( - buildParameters: explicitCodeView.buildParameters(), + buildParameters: explicitCodeView.productsBuildParameters, graph: graph, fileSystem: fs, observabilityScope: observer.topScope @@ -283,7 +284,7 @@ final class SwiftToolTests: CommandsTestCase { let unsupportedCodeViewOptions = try GlobalOptions.parse(["--triple", "x86_64-unknown-linux-gnu", "-debug-info-format", "codeview"]) let unsupportedCodeView = try SwiftTool.createSwiftToolForTest(options: unsupportedCodeViewOptions) - XCTAssertThrowsError(try unsupportedCodeView.buildParameters()) { + XCTAssertThrowsError(try unsupportedCodeView.productsBuildParameters) { XCTAssertEqual($0 as? StringError, StringError("CodeView debug information is currently not supported on linux")) } @@ -291,7 +292,8 @@ final class SwiftToolTests: CommandsTestCase { let implicitDwarfOptions = try GlobalOptions.parse(["--triple", "x86_64-unknown-windows-msvc"]) let implicitDwarf = try SwiftTool.createSwiftToolForTest(options: implicitDwarfOptions) plan = try BuildPlan( - buildParameters: implicitDwarf.buildParameters(), + productsBuildParameters: implicitDwarf.productsBuildParameters, + toolsBuildParameters: implicitDwarf.toolsBuildParameters, graph: graph, fileSystem: fs, observabilityScope: observer.topScope @@ -303,7 +305,8 @@ final class SwiftToolTests: CommandsTestCase { let explicitNoDebugInfoOptions = try GlobalOptions.parse(["--triple", "x86_64-unknown-windows-msvc", "-debug-info-format", "none"]) let explicitNoDebugInfo = try SwiftTool.createSwiftToolForTest(options: explicitNoDebugInfoOptions) plan = try BuildPlan( - buildParameters: explicitNoDebugInfo.buildParameters(), + productsBuildParameters: explicitNoDebugInfo.productsBuildParameters, + toolsBuildParameters: explicitNoDebugInfo.toolsBuildParameters, graph: graph, fileSystem: fs, observabilityScope: observer.topScope From 12a1ea09dd0fde55c88c173cdf3180c116d5524b Mon Sep 17 00:00:00 2001 From: Max Desiatov Date: Wed, 6 Dec 2023 10:27:35 +0000 Subject: [PATCH 02/33] Fix build errors --- ...dOperationBuildSystemDelegateHandler.swift | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/Sources/Build/BuildOperationBuildSystemDelegateHandler.swift b/Sources/Build/BuildOperationBuildSystemDelegateHandler.swift index c03553203b7..b8d69d42435 100644 --- a/Sources/Build/BuildOperationBuildSystemDelegateHandler.swift +++ b/Sources/Build/BuildOperationBuildSystemDelegateHandler.swift @@ -211,7 +211,9 @@ final class TestEntryPointCommand: CustomLLBuildCommand, TestBuildCommand { let outputs = tool.outputs.compactMap { try? AbsolutePath(validating: $0.name) } // Find the main output file - let mainFileName = TestEntryPointTool.mainFileName(for: self.context.buildParameters.testingParameters.library) + let mainFileName = TestEntryPointTool.mainFileName( + for: self.context.productsBuildParameters.testingParameters.library + ) guard let mainFile = outputs.first(where: { path in path.basename == mainFileName }) else { @@ -371,12 +373,12 @@ public struct BuildDescription: Codable { self.writeCommands = writeCommands self.explicitTargetDependencyImportCheckingMode = plan.productsBuildParameters.driverParameters .explicitTargetDependencyImportCheckingMode - self.targetDependencyMap = try plan.targets.reduce(into: [TargetName: [TargetName]]()) { partial, resolvedTarget in - let deps = try resolvedTarget.target.recursiveDependencies( - satisfying: plan.buildParameters(for: resolvedTarget).buildEnvironment + self.targetDependencyMap = try plan.targets.reduce(into: [TargetName: [TargetName]]()) { partial, targetBuildDescription in + let deps = try targetBuildDescription.target.recursiveDependencies( + satisfying: plan.buildParameters(for: targetBuildDescription.target).buildEnvironment ) .compactMap(\.target).map(\.c99name) - partial[resolvedTarget.target.c99name] = deps + partial[targetBuildDescription.target.c99name] = deps } var targetCommandLines: [TargetName: [CommandLineFlag]] = [:] var generatedSourceTargets: [TargetName] = [] @@ -384,10 +386,11 @@ public struct BuildDescription: Codable { guard case .swift(let desc) = description else { continue } + let buildParameters = plan.buildParameters(for: target) targetCommandLines[target.c99name] = - try desc.emitCommandLine(scanInvocation: true) + ["-driver-use-frontend-path", - plan.buildParameters.toolchain.swiftCompilerPath - .pathString] + try desc.emitCommandLine(scanInvocation: true) + [ + "-driver-use-frontend-path", buildParameters.toolchain.swiftCompilerPath.pathString + ] if case .discovery = desc.testTargetRole { generatedSourceTargets.append(target.c99name) } From d020e28bff7d12f5cd545745b7ffa7bf4a334247 Mon Sep 17 00:00:00 2001 From: Max Desiatov Date: Wed, 6 Dec 2023 13:12:35 +0000 Subject: [PATCH 03/33] Fix tests, restore SourceKit-LSP compatibility --- Sources/Build/BuildPlan/BuildPlan.swift | 22 +- Sources/Commands/PackageTools/APIDiff.swift | 5 +- .../Commands/PackageTools/DumpCommands.swift | 2 +- .../Commands/PackageTools/PluginCommand.swift | 3 +- .../Commands/Snippets/Cards/SnippetCard.swift | 2 +- Sources/Commands/SwiftBuildTool.swift | 2 +- Sources/Commands/SwiftRunTool.swift | 8 +- Sources/Commands/SwiftTestTool.swift | 11 +- Sources/Commands/Utilities/APIDigester.swift | 26 +- .../Commands/Utilities/PluginDelegate.swift | 34 +- .../Utilities/SymbolGraphExtract.swift | 6 +- Sources/CoreCommands/SwiftTool.swift | 38 +- .../BuildParameters/BuildParameters.swift | 8 - .../BuildSystem/BuildSystem.swift | 31 +- Tests/BuildTests/BuildPlanTests.swift | 521 ++++++++++++++---- 15 files changed, 523 insertions(+), 196 deletions(-) diff --git a/Sources/Build/BuildPlan/BuildPlan.swift b/Sources/Build/BuildPlan/BuildPlan.swift index 39a9f3a55f9..4697c43ca44 100644 --- a/Sources/Build/BuildPlan/BuildPlan.swift +++ b/Sources/Build/BuildPlan/BuildPlan.swift @@ -187,26 +187,6 @@ public class BuildPlan: SPMBuildCore.BuildPlan { /// Build parameters used for tools. public let toolsBuildParameters: BuildParameters - /// Parameters used for building this target. - func buildParameters(for target: ResolvedTarget) -> BuildParameters { - switch target.buildTriple { - case .buildTools: - return self.toolsBuildParameters - case .buildProducts: - return self.productsBuildParameters - } - } - - /// Parameters used for building this product. - func buildParameters(for product: ResolvedProduct) -> BuildParameters { - switch product.buildTriple { - case .buildTools: - return self.toolsBuildParameters - case .buildProducts: - return self.productsBuildParameters - } - } - /// Triple for which this target is compiled. private func buildTriple(for target: ResolvedTarget) -> Basics.Triple { self.buildParameters(for: target).triple @@ -272,7 +252,7 @@ public class BuildPlan: SPMBuildCore.BuildPlan { /// Create a build plan with a package graph and same build parameters for products and tools. Provided for /// testing purposes only. - convenience init( + public convenience init( buildParameters: BuildParameters, graph: PackageGraph, additionalFileRules: [FileRuleDescription] = [], diff --git a/Sources/Commands/PackageTools/APIDiff.swift b/Sources/Commands/PackageTools/APIDiff.swift index 3f60f0204cd..eb690acdfd2 100644 --- a/Sources/Commands/PackageTools/APIDiff.swift +++ b/Sources/Commands/PackageTools/APIDiff.swift @@ -98,7 +98,8 @@ struct APIDiff: SwiftCommand { let baselineDumper = try APIDigesterBaselineDumper( baselineRevision: baselineRevision, packageRoot: swiftTool.getPackageRoot(), - buildParameters: try buildSystem.buildPlan.buildParameters, + productsBuildParameters: try buildSystem.buildPlan.productsBuildParameters, + toolsBuildParameters: try buildSystem.buildPlan.toolsBuildParameters, apiDigesterTool: apiDigesterTool, observabilityScope: swiftTool.observabilityScope ) @@ -113,7 +114,7 @@ struct APIDiff: SwiftCommand { let results = ThreadSafeArrayStore() let group = DispatchGroup() - let semaphore = DispatchSemaphore(value: Int(try buildSystem.buildPlan.buildParameters.workers)) + let semaphore = DispatchSemaphore(value: Int(try buildSystem.buildPlan.productsBuildParameters.workers)) var skippedModules: Set = [] for module in modulesToDiff { diff --git a/Sources/Commands/PackageTools/DumpCommands.swift b/Sources/Commands/PackageTools/DumpCommands.swift index d7f024aba6e..49adaffa3aa 100644 --- a/Sources/Commands/PackageTools/DumpCommands.swift +++ b/Sources/Commands/PackageTools/DumpCommands.swift @@ -65,7 +65,7 @@ struct DumpSymbolGraph: SwiftCommand { // Run the tool once for every library and executable target in the root package. let buildPlan = try buildSystem.buildPlan - let symbolGraphDirectory = buildPlan.buildParameters.dataPath.appending("symbolgraph") + let symbolGraphDirectory = buildPlan.productsBuildParameters.dataPath.appending("symbolgraph") let targets = try buildSystem.getPackageGraph().rootPackages.flatMap{ $0.targets }.filter{ $0.type == .library } for target in targets { print("-- Emitting symbol graph for", target.name) diff --git a/Sources/Commands/PackageTools/PluginCommand.swift b/Sources/Commands/PackageTools/PluginCommand.swift index 81778636d5e..24744ac539d 100644 --- a/Sources/Commands/PackageTools/PluginCommand.swift +++ b/Sources/Commands/PackageTools/PluginCommand.swift @@ -259,8 +259,7 @@ struct PluginCommand: SwiftCommand { // Build or bring up-to-date any executable host-side tools on which this plugin depends. Add them and any binary dependencies to the tool-names-to-path map. let buildSystem = try swiftTool.createBuildSystem( explicitBuildSystem: .native, - cacheBuildManifest: false, - customBuildParameters: buildParameters + cacheBuildManifest: false ) let accessibleTools = try plugin.processAccessibleTools( packageGraph: packageGraph, diff --git a/Sources/Commands/Snippets/Cards/SnippetCard.swift b/Sources/Commands/Snippets/Cards/SnippetCard.swift index a1ef7b53666..8d5492e9416 100644 --- a/Sources/Commands/Snippets/Cards/SnippetCard.swift +++ b/Sources/Commands/Snippets/Cards/SnippetCard.swift @@ -95,7 +95,7 @@ struct SnippetCard: Card { print("Building '\(snippet.path)'\n") let buildSystem = try swiftTool.createBuildSystem(explicitProduct: snippet.name) try buildSystem.build(subset: .product(snippet.name)) - let executablePath = try swiftTool.buildParameters().buildPath.appending(component: snippet.name) + let executablePath = try swiftTool.productsBuildParameters.buildPath.appending(component: snippet.name) if let exampleTarget = try buildSystem.getPackageGraph().allTargets.first(where: { $0.name == snippet.name }) { try ProcessEnv.chdir(exampleTarget.sources.paths[0].parentDirectory) } diff --git a/Sources/Commands/SwiftBuildTool.swift b/Sources/Commands/SwiftBuildTool.swift index 7af5d38d353..521eb0c9405 100644 --- a/Sources/Commands/SwiftBuildTool.swift +++ b/Sources/Commands/SwiftBuildTool.swift @@ -134,7 +134,7 @@ public struct SwiftBuildTool: SwiftCommand { shouldLinkStaticSwiftStdlib: options.shouldLinkStaticSwiftStdlib, // command result output goes on stdout // ie "swift build" should output to stdout - customOutputStream: TSCBasic.stdoutStream + outputStream: TSCBasic.stdoutStream ) do { try buildSystem.build(subset: subset) diff --git a/Sources/Commands/SwiftRunTool.swift b/Sources/Commands/SwiftRunTool.swift index 190d576872f..edc89214c1a 100644 --- a/Sources/Commands/SwiftRunTool.swift +++ b/Sources/Commands/SwiftRunTool.swift @@ -125,15 +125,13 @@ public struct SwiftRunTool: SwiftCommand { explicitProduct: self.options.executable ) } - let buildParameters = try swiftTool.buildParameters() // Construct the build operation. // FIXME: We need to implement the build tool invocation closure here so that build tool plugins work with the REPL. rdar://86112934 let buildSystem = try swiftTool.createBuildSystem( explicitBuildSystem: .native, cacheBuildManifest: false, - customBuildParameters: buildParameters, - customPackageGraphLoader: graphLoader + packageGraphLoader: graphLoader ) // Perform build. @@ -159,7 +157,7 @@ public struct SwiftRunTool: SwiftCommand { try buildSystem.build(subset: .product(productName)) } - let executablePath = try swiftTool.buildParameters().buildPath.appending(component: productName) + let executablePath = try swiftTool.productsBuildParameters.buildPath.appending(component: productName) // Make sure we are running from the original working directory. let cwd: AbsolutePath? = swiftTool.fileSystem.currentWorkingDirectory @@ -201,7 +199,7 @@ public struct SwiftRunTool: SwiftCommand { try buildSystem.build(subset: .product(productName)) } - let executablePath = try swiftTool.buildParameters().buildPath.appending(component: productName) + let executablePath = try swiftTool.productsBuildParameters.buildPath.appending(component: productName) try self.run( fileSystem: swiftTool.fileSystem, executablePath: executablePath, diff --git a/Sources/Commands/SwiftTestTool.swift b/Sources/Commands/SwiftTestTool.swift index ea0954c98c8..2bbbe326c94 100644 --- a/Sources/Commands/SwiftTestTool.swift +++ b/Sources/Commands/SwiftTestTool.swift @@ -217,7 +217,7 @@ public struct SwiftTestTool: SwiftCommand { let buildParameters = try swiftTool.buildParametersForTest(options: self.options, library: .xctest) // Remove test output from prior runs and validate priors. - if self.options.enableExperimentalTestOutput && buildParameters.targetTriple.supportsTestSummary { + if self.options.enableExperimentalTestOutput && buildParameters.triple.supportsTestSummary { _ = try? localFileSystem.removeFileTree(buildParameters.testOutputPath) } @@ -573,7 +573,7 @@ extension SwiftTestTool { func run(_ swiftTool: SwiftTool) throws { try SwiftTestTool.handleTestOutput( - buildParameters: try swiftTool.buildParameters(), + buildParameters: try swiftTool.productsBuildParameters, packagePath: localFileSystem.currentWorkingDirectory ?? .root // by definition runs in the current working directory ) } @@ -1201,7 +1201,10 @@ final class XUnitGenerator { } extension SwiftTool { - func buildParametersForTest(options: TestToolOptions, library: BuildParameters.Testing.Library) throws -> BuildParameters { + func buildParametersForTest( + options: TestToolOptions, + library: BuildParameters.Testing.Library + ) throws -> BuildParameters { var result = try self.buildParametersForTest( enableCodeCoverage: options.enableCodeCoverage, enableTestability: options.enableTestableImports, @@ -1269,7 +1272,7 @@ private extension Basics.Diagnostic { /// /// - Returns: The paths to the build test products. private func buildTestsIfNeeded(swiftTool: SwiftTool, buildParameters: BuildParameters, testProduct: String?) throws -> [BuiltTestProduct] { - let buildSystem = try swiftTool.createBuildSystem(customBuildParameters: buildParameters) + let buildSystem = try swiftTool.createBuildSystem(productsBuildParameters: buildParameters) let subset = testProduct.map(BuildSubset.product) ?? .allIncludingTests try buildSystem.build(subset: subset) diff --git a/Sources/Commands/Utilities/APIDigester.swift b/Sources/Commands/Utilities/APIDigester.swift index 6b67692418f..069c348b3ee 100644 --- a/Sources/Commands/Utilities/APIDigester.swift +++ b/Sources/Commands/Utilities/APIDigester.swift @@ -39,8 +39,11 @@ struct APIDigesterBaselineDumper { /// The root package path. let packageRoot: AbsolutePath - /// The input build parameters. - let inputBuildParameters: BuildParameters + /// Parameters used when building end products. + let productsBuildParameters: BuildParameters + + /// Parameters used when building tools (plugins and macros). + let toolsBuildParameters: BuildParameters /// The API digester tool. let apiDigesterTool: SwiftAPIDigester @@ -51,13 +54,15 @@ struct APIDigesterBaselineDumper { init( baselineRevision: Revision, packageRoot: AbsolutePath, - buildParameters: BuildParameters, + productsBuildParameters: BuildParameters, + toolsBuildParameters: BuildParameters, apiDigesterTool: SwiftAPIDigester, observabilityScope: ObservabilityScope ) { self.baselineRevision = baselineRevision self.packageRoot = packageRoot - self.inputBuildParameters = buildParameters + self.productsBuildParameters = productsBuildParameters + self.toolsBuildParameters = toolsBuildParameters self.apiDigesterTool = apiDigesterTool self.observabilityScope = observabilityScope } @@ -71,7 +76,7 @@ struct APIDigesterBaselineDumper { swiftTool: SwiftTool ) throws -> AbsolutePath { var modulesToDiff = modulesToDiff - let apiDiffDir = inputBuildParameters.apiDiff + let apiDiffDir = productsBuildParameters.apiDiff let baselineDir = (baselineDir ?? apiDiffDir).appending(component: baselineRevision.identifier) let baselinePath: (String)->AbsolutePath = { module in baselineDir.appending(component: module + ".json") @@ -127,23 +132,24 @@ struct APIDigesterBaselineDumper { } // Update the data path input build parameters so it's built in the sandbox. - var buildParameters = inputBuildParameters - buildParameters.dataPath = workspace.location.scratchDirectory + var productsBuildParameters = productsBuildParameters + productsBuildParameters.dataPath = workspace.location.scratchDirectory // Build the baseline module. // FIXME: We need to implement the build tool invocation closure here so that build tool plugins work with the APIDigester. rdar://86112934 let buildSystem = try swiftTool.createBuildSystem( explicitBuildSystem: .native, cacheBuildManifest: false, - customBuildParameters: buildParameters, - customPackageGraphLoader: { graph } + productsBuildParameters: productsBuildParameters, + toolsBuildParameters: toolsBuildParameters, + packageGraphLoader: { graph } ) try buildSystem.build() // Dump the SDK JSON. try swiftTool.fileSystem.createDirectory(baselineDir, recursive: true) let group = DispatchGroup() - let semaphore = DispatchSemaphore(value: Int(buildParameters.workers)) + let semaphore = DispatchSemaphore(value: Int(productsBuildParameters.workers)) let errors = ThreadSafeArrayStore() for module in modulesToDiff { semaphore.wait() diff --git a/Sources/Commands/Utilities/PluginDelegate.swift b/Sources/Commands/Utilities/PluginDelegate.swift index 8ff64372b7d..fb87deef308 100644 --- a/Sources/Commands/Utilities/PluginDelegate.swift +++ b/Sources/Commands/Utilities/PluginDelegate.swift @@ -71,7 +71,7 @@ final class PluginDelegate: PluginInvocationDelegate { parameters: PluginInvocationBuildParameters ) throws -> PluginInvocationBuildResult { // Configure the build parameters. - var buildParameters = try self.swiftTool.toolsBuildParameters + var buildParameters = try self.swiftTool.productsBuildParameters switch parameters.configuration { case .debug: buildParameters.configuration = .debug @@ -113,9 +113,9 @@ final class PluginDelegate: PluginInvocationDelegate { explicitBuildSystem: .native, explicitProduct: explicitProduct, cacheBuildManifest: false, - customBuildParameters: buildParameters, - customOutputStream: outputStream, - customLogLevel: logLevel + productsBuildParameters: buildParameters, + outputStream: outputStream, + logLevel: logLevel ) // Run the build. This doesn't return until the build is complete. @@ -170,23 +170,23 @@ final class PluginDelegate: PluginInvocationDelegate { ) throws -> PluginInvocationTestResult { // Build the tests. Ideally we should only build those that match the subset, but we don't have a way to know // which ones they are until we've built them and can examine the binaries. - let toolchain = try swiftTool.getTargetToolchain() - var buildParameters = try swiftTool.toolsBuildParameters - buildParameters.testingParameters.enableTestability = true - buildParameters.testingParameters.enableCodeCoverage = parameters.enableCodeCoverage - let buildSystem = try swiftTool.createBuildSystem(customBuildParameters: buildParameters) + let toolchain = try swiftTool.getHostToolchain() + var toolsBuildParameters = try swiftTool.toolsBuildParameters + toolsBuildParameters.testingParameters.enableTestability = true + toolsBuildParameters.testingParameters.enableCodeCoverage = parameters.enableCodeCoverage + let buildSystem = try swiftTool.createBuildSystem(toolsBuildParameters: toolsBuildParameters) try buildSystem.build(subset: .allIncludingTests) // Clean out the code coverage directory that may contain stale `profraw` files from a previous run of // the code coverage tool. if parameters.enableCodeCoverage { - try swiftTool.fileSystem.removeFileTree(buildParameters.codeCovPath) + try swiftTool.fileSystem.removeFileTree(toolsBuildParameters.codeCovPath) } // Construct the environment we'll pass down to the tests. let testEnvironment = try TestingSupport.constructTestEnvironment( toolchain: toolchain, - buildParameters: buildParameters, + buildParameters: toolsBuildParameters, sanitizers: swiftTool.options.build.sanitizers ) @@ -271,12 +271,12 @@ final class PluginDelegate: PluginInvocationDelegate { let codeCoverageDataFile: AbsolutePath? if parameters.enableCodeCoverage { // Use `llvm-prof` to merge all the `.profraw` files into a single `.profdata` file. - let mergedCovFile = buildParameters.codeCovDataFile - let codeCovFileNames = try swiftTool.fileSystem.getDirectoryContents(buildParameters.codeCovPath) + let mergedCovFile = toolsBuildParameters.codeCovDataFile + let codeCovFileNames = try swiftTool.fileSystem.getDirectoryContents(toolsBuildParameters.codeCovPath) var llvmProfCommand = [try toolchain.getLLVMProf().pathString] llvmProfCommand += ["merge", "-sparse"] for fileName in codeCovFileNames where fileName.hasSuffix(".profraw") { - let filePath = buildParameters.codeCovPath.appending(component: fileName) + let filePath = toolsBuildParameters.codeCovPath.appending(component: fileName) llvmProfCommand.append(filePath.pathString) } llvmProfCommand += ["-o", mergedCovFile.pathString] @@ -291,8 +291,8 @@ final class PluginDelegate: PluginInvocationDelegate { } // We get the output on stdout, and have to write it to a JSON ourselves. let jsonOutput = try TSCBasic.Process.checkNonZeroExit(arguments: llvmCovCommand) - let jsonCovFile = buildParameters.codeCovDataFile.parentDirectory.appending( - component: buildParameters.codeCovDataFile.basenameWithoutExt + ".json" + let jsonCovFile = toolsBuildParameters.codeCovDataFile.parentDirectory.appending( + component: toolsBuildParameters.codeCovDataFile.basenameWithoutExt + ".json" ) try swiftTool.fileSystem.writeFileContents(jsonCovFile, string: jsonOutput) @@ -369,7 +369,7 @@ final class PluginDelegate: PluginInvocationDelegate { guard let package = packageGraph.package(for: target) else { throw StringError("could not determine the package for target “\(target.name)”") } - let outputDir = try buildSystem.buildPlan.buildParameters.dataPath.appending( + let outputDir = try buildSystem.buildPlan.toolsBuildParameters.dataPath.appending( components: "extracted-symbols", package.identity.description, target.name diff --git a/Sources/Commands/Utilities/SymbolGraphExtract.swift b/Sources/Commands/Utilities/SymbolGraphExtract.swift index 1fd25ea58ff..f9423384c9b 100644 --- a/Sources/Commands/Utilities/SymbolGraphExtract.swift +++ b/Sources/Commands/Utilities/SymbolGraphExtract.swift @@ -50,7 +50,9 @@ public struct SymbolGraphExtract { case json(pretty: Bool) } - /// Creates a symbol graph for `target` in `outputDirectory` using the build information from `buildPlan`. The `outputDirection` determines how the output from the tool subprocess is handled, and `verbosity` specifies how much console output to ask the tool to emit. + /// Creates a symbol graph for `target` in `outputDirectory` using the build information from `buildPlan`. + /// The `outputDirection` determines how the output from the tool subprocess is handled, and `verbosity` specifies + /// how much console output to ask the tool to emit. public func extractSymbolGraph( target: ResolvedTarget, buildPlan: BuildPlan, @@ -58,7 +60,7 @@ public struct SymbolGraphExtract { outputDirectory: AbsolutePath, verboseOutput: Bool ) throws -> ProcessResult { - let buildParameters = buildPlan.buildParameters + let buildParameters = buildPlan.buildParameters(for: target) try self.fileSystem.createDirectory(outputDirectory, recursive: true) // Construct arguments for extracting symbols for a single target. diff --git a/Sources/CoreCommands/SwiftTool.swift b/Sources/CoreCommands/SwiftTool.swift index f70276082ca..cc6695a60ba 100644 --- a/Sources/CoreCommands/SwiftTool.swift +++ b/Sources/CoreCommands/SwiftTool.swift @@ -642,28 +642,30 @@ public final class SwiftTool { explicitProduct: String? = .none, cacheBuildManifest: Bool = true, shouldLinkStaticSwiftStdlib: Bool = false, - customBuildParameters: BuildParameters? = .none, - customPackageGraphLoader: (() throws -> PackageGraph)? = .none, - customOutputStream: OutputByteStream? = .none, - customLogLevel: Basics.Diagnostic.Severity? = .none, - customObservabilityScope: ObservabilityScope? = .none + productsBuildParameters: BuildParameters? = .none, + toolsBuildParameters: BuildParameters? = .none, + packageGraphLoader: (() throws -> PackageGraph)? = .none, + outputStream: OutputByteStream? = .none, + logLevel: Basics.Diagnostic.Severity? = .none, + observabilityScope: ObservabilityScope? = .none ) throws -> BuildSystem { guard let buildSystemProvider else { fatalError("build system provider not initialized") } - var buildParameters = try customBuildParameters ?? self.buildParameters() - buildParameters.linkingParameters.shouldLinkStaticSwiftStdlib = shouldLinkStaticSwiftStdlib + var productsParameters = try productsBuildParameters ?? self.productsBuildParameters + productsParameters.linkingParameters.shouldLinkStaticSwiftStdlib = shouldLinkStaticSwiftStdlib let buildSystem = try buildSystemProvider.createBuildSystem( kind: explicitBuildSystem ?? options.build.buildSystem, explicitProduct: explicitProduct, cacheBuildManifest: cacheBuildManifest, - productsBuildParameters: customBuildParameters, - packageGraphLoader: customPackageGraphLoader, - outputStream: customOutputStream, - logLevel: customLogLevel, - observabilityScope: customObservabilityScope + productsBuildParameters: productsParameters, + toolsBuildParameters: toolsBuildParameters, + packageGraphLoader: packageGraphLoader, + outputStream: outputStream, + logLevel: logLevel, + observabilityScope: observabilityScope ) // register the build system with the cancellation handler @@ -867,11 +869,19 @@ 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.toolsBuildParameters.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.toolsBuildParameters.toolchain, + fileSystem: self.fileSystem + ) { extraManifestFlags += ["-Xfrontend", "-disable-implicit-string-processing-module-import"] } diff --git a/Sources/SPMBuildCore/BuildParameters/BuildParameters.swift b/Sources/SPMBuildCore/BuildParameters/BuildParameters.swift index 65d6df86626..9021f05cc27 100644 --- a/Sources/SPMBuildCore/BuildParameters/BuildParameters.swift +++ b/Sources/SPMBuildCore/BuildParameters/BuildParameters.swift @@ -36,14 +36,6 @@ public struct BuildParameters: Encodable { public var toolchain: Toolchain { _toolchain.toolchain } private let _toolchain: _Toolchain - /// Host triple. - @available(*, deprecated, message: "use separate `BuildParameters` values to distinguish between host and target") - public var hostTriple: Triple { self.triple } - - /// Target triple. - @available(*, deprecated, message: "use separate `BuildParameters` values to distinguish between host and target") - public var targetTriple: Triple { self.triple } - /// The triple for which the code is built using these build parameters. public var triple: Triple diff --git a/Sources/SPMBuildCore/BuildSystem/BuildSystem.swift b/Sources/SPMBuildCore/BuildSystem/BuildSystem.swift index e6490b2ae3b..ca87dbbb069 100644 --- a/Sources/SPMBuildCore/BuildSystem/BuildSystem.swift +++ b/Sources/SPMBuildCore/BuildSystem/BuildSystem.swift @@ -74,19 +74,46 @@ extension ProductBuildDescription { /// The path to the product binary produced. public var binaryPath: AbsolutePath { get throws { - return try buildParameters.binaryPath(for: product) + return try self.buildParameters.binaryPath(for: product) } } } public protocol BuildPlan { - var buildParameters: BuildParameters { get } + /// Parameters used when building end products. + var productsBuildParameters: BuildParameters { get } + + /// Parameters used when building tools (macros and plugins). + var toolsBuildParameters: BuildParameters { get } + var buildProducts: AnySequence { get } func createAPIToolCommonArgs(includeLibrarySearchPaths: Bool) throws -> [String] func createREPLArguments() throws -> [String] } +extension BuildPlan { + /// Parameters used for building this target. + public func buildParameters(for target: ResolvedTarget) -> BuildParameters { + switch target.buildTriple { + case .buildTools: + return self.toolsBuildParameters + case .buildProducts: + return self.productsBuildParameters + } + } + + /// Parameters used for building this product. + public func buildParameters(for product: ResolvedProduct) -> BuildParameters { + switch product.buildTriple { + case .buildTools: + return self.toolsBuildParameters + case .buildProducts: + return self.productsBuildParameters + } + } +} + public protocol BuildSystemFactory { func makeBuildSystem( explicitProduct: String?, diff --git a/Tests/BuildTests/BuildPlanTests.swift b/Tests/BuildTests/BuildPlanTests.swift index 8c08fde4e8e..d6a8d675d49 100644 --- a/Tests/BuildTests/BuildPlanTests.swift +++ b/Tests/BuildTests/BuildPlanTests.swift @@ -27,6 +27,14 @@ import class TSCBasic.InMemoryFileSystem import enum TSCUtility.Diagnostics +extension Build.BuildPlan { + var productsBuildPath: AbsolutePath { + let buildParameters = self.productsBuildParameters + let buildConfigurationComponent = buildParameters.buildEnvironment.configuration == .release ? "release" : "debug" + return buildParameters.dataPath.appending(components: buildConfigurationComponent) + } +} + final class BuildPlanTests: XCTestCase { let inputsDir = AbsolutePath(#file).parentDirectory.appending(components: "Inputs") @@ -616,27 +624,58 @@ final class BuildPlanTests: XCTestCase { ) XCTAssertNoDiagnostics(observability.diagnostics) - let result = try BuildPlanResult(plan: BuildPlan( + let plan = try BuildPlan( buildParameters: mockBuildParameters(shouldLinkStaticSwiftStdlib: true), graph: graph, fileSystem: fs, observabilityScope: observability.topScope - )) + ) + let result = try BuildPlanResult(plan: plan) result.checkProductsCount(1) result.checkTargetsCount(2) - let buildPath = result.plan.buildParameters.dataPath.appending(components: "debug") + let buildPath = plan.productsBuildPath let exe = try result.target(for: "exe").swiftTarget().compileArguments() - XCTAssertMatch(exe, ["-swift-version", "4", "-enable-batch-mode", "-Onone", "-enable-testing", .equal(j), "-DSWIFT_PACKAGE", "-DDEBUG", "-module-cache-path", "\(buildPath.appending(components: "ModuleCache"))", .anySequence, "-g", .anySequence]) + XCTAssertMatch( + exe, + [ + "-swift-version", "4", + "-enable-batch-mode", + "-Onone", + "-enable-testing", + .equal(j), + "-DSWIFT_PACKAGE", + "-DDEBUG", + "-module-cache-path", "\(buildPath.appending(components: "ModuleCache"))", + .anySequence, + "-g", + .anySequence + ] + ) let lib = try result.target(for: "lib").swiftTarget().compileArguments() - XCTAssertMatch(lib, ["-swift-version", "4", "-enable-batch-mode", "-Onone", "-enable-testing", .equal(j), "-DSWIFT_PACKAGE", "-DDEBUG", "-module-cache-path", "\(buildPath.appending(components: "ModuleCache"))", .anySequence, "-g", .anySequence]) + XCTAssertMatch( + lib, + [ + "-swift-version", "4", + "-enable-batch-mode", + "-Onone", + "-enable-testing", + .equal(j), + "-DSWIFT_PACKAGE", + "-DDEBUG", + "-module-cache-path", "\(buildPath.appending(components: "ModuleCache"))", + .anySequence, + "-g", + .anySequence + ] + ) #if os(macOS) let linkArguments = [ - result.plan.buildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.productsBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "exe").pathString, "-module-name", "exe", @@ -854,7 +893,7 @@ final class BuildPlanTests: XCTestCase { observabilityScope: observability.topScope ) - let buildPath: AbsolutePath = plan.buildParameters.dataPath.appending(components: "release") + let buildPath = plan.productsBuildParameters.dataPath.appending(components: "release") let result = try BuildPlanResult(plan: plan) let buildProduct = try result.buildProduct(for: "exe") @@ -896,7 +935,7 @@ final class BuildPlanTests: XCTestCase { let llbuild = LLBuildManifestBuilder(plan, fileSystem: fs, observabilityScope: observability.topScope) try llbuild.generateManifest(at: yaml) let contents: String = try fs.readFileContents(yaml) - let buildPath = plan.buildParameters.dataPath.appending(components: "debug") + let buildPath = plan.productsBuildPath let swiftGetVersionFilePath = try XCTUnwrap(llbuild.swiftGetVersionFiles.first?.value) XCTAssertMatch(contents, .contains(""" inputs: ["\(Pkg.appending(components: "Sources", "exe", "main.swift").escapedPathString)","\(swiftGetVersionFilePath.escapedPathString)","\(buildPath.appending(components: "exe.build", "sources").escapedPathString)"] @@ -992,14 +1031,14 @@ final class BuildPlanTests: XCTestCase { result.checkProductsCount(1) result.checkTargetsCount(1) - let buildPath = result.plan.buildParameters.dataPath.appending(components: "release") + let buildPath = result.plan.productsBuildParameters.dataPath.appending(components: "release") let exe = try result.target(for: "exe").swiftTarget().compileArguments() XCTAssertMatch(exe, ["-swift-version", "4", "-O", .equal(j), "-DSWIFT_PACKAGE", "-module-cache-path", "\(buildPath.appending(components: "ModuleCache"))", .anySequence, "-g"]) #if os(macOS) XCTAssertEqual(try result.buildProduct(for: "exe").linkArguments(), [ - result.plan.buildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.productsBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "exe").pathString, "-module-name", "exe", @@ -1013,7 +1052,7 @@ final class BuildPlanTests: XCTestCase { ]) #elseif os(Windows) XCTAssertEqual(try result.buildProduct(for: "exe").linkArguments(), [ - result.plan.buildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.productsBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "exe.exe").pathString, "-module-name", "exe", @@ -1025,7 +1064,7 @@ final class BuildPlanTests: XCTestCase { ]) #else XCTAssertEqual(try result.buildProduct(for: "exe").linkArguments(), [ - result.plan.buildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.productsBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "exe").pathString, "-module-name", "exe", @@ -1069,14 +1108,14 @@ final class BuildPlanTests: XCTestCase { result.checkProductsCount(1) result.checkTargetsCount(1) - let buildPath = result.plan.buildParameters.dataPath.appending(components: "release") + let buildPath = result.plan.productsBuildParameters.dataPath.appending(components: "release") let exe = try result.target(for: "exe").swiftTarget().compileArguments() XCTAssertMatch(exe, ["-swift-version", "4", "-O", .equal(j), "-DSWIFT_PACKAGE", "-module-cache-path", "\(buildPath.appending(components: "ModuleCache"))", .anySequence, "-g"]) #if os(macOS) XCTAssertEqual(try result.buildProduct(for: "exe").linkArguments(), [ - result.plan.buildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.productsBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "exe").pathString, "-module-name", "exe", @@ -1089,7 +1128,7 @@ final class BuildPlanTests: XCTestCase { ]) #elseif os(Windows) XCTAssertEqual(try result.buildProduct(for: "exe").linkArguments(), [ - result.plan.buildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.productsBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "exe.exe").pathString, "-module-name", "exe", @@ -1100,7 +1139,7 @@ final class BuildPlanTests: XCTestCase { ]) #else XCTAssertEqual(try result.buildProduct(for: "exe").linkArguments(), [ - result.plan.buildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.productsBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "exe").pathString, "-module-name", "exe", @@ -1164,7 +1203,7 @@ final class BuildPlanTests: XCTestCase { result.checkProductsCount(1) result.checkTargetsCount(3) - let buildPath = result.plan.buildParameters.dataPath.appending(components: "debug") + let buildPath = result.plan.productsBuildParameters.dataPath.appending(components: "debug") let ext = try result.target(for: "extlib").clangTarget() var args: [String] = [] @@ -1229,7 +1268,7 @@ final class BuildPlanTests: XCTestCase { #if os(macOS) XCTAssertEqual(try result.buildProduct(for: "exe").linkArguments(), [ - result.plan.buildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.productsBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "exe").pathString, "-module-name", "exe", @@ -1406,11 +1445,11 @@ final class BuildPlanTests: XCTestCase { result.checkProductsCount(1) result.checkTargetsCount(4) - let buildPath = result.plan.buildParameters.dataPath.appending(components: "debug") + let buildPath = plan.productsBuildPath #if os(macOS) XCTAssertEqual(try result.buildProduct(for: "exe").linkArguments(), [ - result.plan.buildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.productsBuildParameters.toolchain.swiftCompilerPath.pathString, "-lc++", "-L", buildPath.pathString, "-o", buildPath.appending(components: "exe").pathString, @@ -1489,16 +1528,17 @@ final class BuildPlanTests: XCTestCase { ) XCTAssertNoDiagnostics(observability.diagnostics) - let result = try BuildPlanResult(plan: BuildPlan( + let plan = try BuildPlan( buildParameters: mockBuildParameters(), graph: graph, fileSystem: fs, observabilityScope: observability.topScope - )) + ) + let result = try BuildPlanResult(plan: plan) result.checkProductsCount(1) result.checkTargetsCount(2) - let buildPath = result.plan.buildParameters.dataPath.appending(components: "debug") + let buildPath = plan.productsBuildPath let lib = try result.target(for: "lib").clangTarget() var args: [String] = [] @@ -1528,11 +1568,30 @@ final class BuildPlanTests: XCTestCase { XCTAssertEqual(lib.moduleMap, buildPath.appending(components: "lib.build", "module.modulemap")) let exe = try result.target(for: "exe").swiftTarget().compileArguments() - XCTAssertMatch(exe, [.anySequence, "-swift-version", "4", "-enable-batch-mode", "-Onone", "-enable-testing", .equal(j), "-DSWIFT_PACKAGE", "-DDEBUG","-Xcc", "-fmodule-map-file=\(buildPath.appending(components: "lib.build", "module.modulemap"))", "-Xcc", "-I", "-Xcc", "\(Pkg.appending(components: "Sources", "lib", "include"))", "-module-cache-path", "\(buildPath.appending(components: "ModuleCache"))", .anySequence, "-g", .anySequence]) + XCTAssertMatch( + exe, + [ + .anySequence, + "-swift-version", "4", + "-enable-batch-mode", + "-Onone", + "-enable-testing", + .equal(j), + "-DSWIFT_PACKAGE", + "-DDEBUG", + "-Xcc", + "-fmodule-map-file=\(buildPath.appending(components: "lib.build", "module.modulemap"))", + "-Xcc", "-I", "-Xcc", "\(Pkg.appending(components: "Sources", "lib", "include"))", + "-module-cache-path", "\(buildPath.appending(components: "ModuleCache"))", + .anySequence, + "-g", + .anySequence + ] + ) #if os(macOS) XCTAssertEqual(try result.buildProduct(for: "exe").linkArguments(), [ - result.plan.buildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.productsBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "exe").pathString, "-module-name", "exe", @@ -1651,7 +1710,7 @@ final class BuildPlanTests: XCTestCase { ]), ], createREPLProduct: true, - observabilityScope: observability.topScope + observabilityScope: observability.topScope ) XCTAssertNoDiagnostics(observability.diagnostics) @@ -1662,9 +1721,18 @@ final class BuildPlanTests: XCTestCase { observabilityScope: observability.topScope ) - let buildPath = plan.buildParameters.dataPath.appending(components: "debug") - - XCTAssertEqual(try plan.createREPLArguments().sorted(), ["-I\(Dep.appending(components: "Sources", "CDep", "include"))", "-I\(buildPath)", "-I\(buildPath.appending(components: "lib.build"))", "-L\(buildPath)", "-lpkg__REPL", "repl"]) + let buildPath = plan.productsBuildPath + XCTAssertEqual( + try plan.createREPLArguments().sorted(), + [ + "-I\(Dep.appending(components: "Sources", "CDep", "include"))", + "-I\(buildPath)", + "-I\(buildPath.appending(components: "lib.build"))", + "-L\(buildPath)", + "-lpkg__REPL", + "repl" + ] + ) XCTAssertEqual(plan.graph.allProducts.map({ $0.name }).sorted(), [ "Dep", @@ -1710,13 +1778,45 @@ final class BuildPlanTests: XCTestCase { result.checkTargetsCount(3) #endif - let buildPath = result.plan.buildParameters.dataPath.appending(components: "debug") + let buildPath = result.plan.productsBuildPath let foo = try result.target(for: "Foo").swiftTarget().compileArguments() - XCTAssertMatch(foo, [.anySequence, "-swift-version", "4", "-enable-batch-mode", "-Onone", "-enable-testing", .equal(j), "-DSWIFT_PACKAGE", "-DDEBUG", "-module-cache-path", "\(buildPath.appending(components: "ModuleCache"))", .anySequence, "-g", .anySequence]) + XCTAssertMatch( + foo, + [ + .anySequence, + "-swift-version", "4", + "-enable-batch-mode", + "-Onone", + "-enable-testing", + .equal(j), + "-DSWIFT_PACKAGE", + "-DDEBUG", + "-module-cache-path", "\(buildPath.appending(components: "ModuleCache"))", + .anySequence, + "-g", + .anySequence + ] + ) let fooTests = try result.target(for: "FooTests").swiftTarget().compileArguments() - XCTAssertMatch(fooTests, [.anySequence, "-swift-version", "4", "-enable-batch-mode", "-Onone", "-enable-testing", .equal(j), "-DSWIFT_PACKAGE", "-DDEBUG", "-module-cache-path", "\(buildPath.appending(components: "ModuleCache"))", .anySequence, "-g", .anySequence]) + XCTAssertMatch( + fooTests, + [ + .anySequence, + "-swift-version", "4", + "-enable-batch-mode", + "-Onone", + "-enable-testing", + .equal(j), + "-DSWIFT_PACKAGE", + "-DDEBUG", + "-module-cache-path", "\(buildPath.appending(components: "ModuleCache"))", + .anySequence, + "-g", + .anySequence + ] + ) #if os(macOS) let version = MinimumDeploymentTarget.computeXCTestMinimumDeploymentTarget(for: .macOS).versionString @@ -1727,7 +1827,7 @@ final class BuildPlanTests: XCTestCase { rpathsForBackdeployment = [] } XCTAssertEqual(try result.buildProduct(for: "PkgPackageTests").linkArguments(), [ - result.plan.buildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.productsBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "PkgPackageTests.xctest", "Contents", "MacOS", "PkgPackageTests").pathString, "-module-name", "PkgPackageTests", @@ -1799,7 +1899,7 @@ final class BuildPlanTests: XCTestCase { result.checkProductsCount(1) result.checkTargetsCount(1) - let buildPath = result.plan.buildParameters.dataPath.appending(components: "release") + let buildPath = result.plan.productsBuildPath let exe = try result.target(for: "exe").swiftTarget().compileArguments() @@ -1807,7 +1907,7 @@ final class BuildPlanTests: XCTestCase { #if os(macOS) XCTAssertEqual(try result.buildProduct(for: "exe").linkArguments(), [ - result.plan.buildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.productsBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "exe").pathString, "-module-name", "exe", @@ -2142,13 +2242,13 @@ final class BuildPlanTests: XCTestCase { result.checkProductsCount(1) result.checkTargetsCount(1) - let buildPath = result.plan.buildParameters.dataPath.appending(components: "debug") + let buildPath = result.plan.productsBuildPath XCTAssertMatch(try result.target(for: "exe").swiftTarget().compileArguments(), ["-swift-version", "4", "-enable-batch-mode", "-Onone", "-enable-testing", .equal(j), "-DSWIFT_PACKAGE", "-DDEBUG", "-Xcc", "-fmodule-map-file=\(Clibgit.appending(components: "module.modulemap"))", "-module-cache-path", "\(buildPath.appending(components: "ModuleCache"))", .anySequence, "-g", .anySequence]) #if os(macOS) XCTAssertEqual(try result.buildProduct(for: "exe").linkArguments(), [ - result.plan.buildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.productsBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "exe").pathString, "-module-name", "exe", @@ -2162,7 +2262,7 @@ final class BuildPlanTests: XCTestCase { ]) #elseif os(Windows) XCTAssertEqual(try result.buildProduct(for: "exe").linkArguments(), [ - result.plan.buildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.productsBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "exe.exe").pathString, "-module-name", "exe", @@ -2173,7 +2273,7 @@ final class BuildPlanTests: XCTestCase { ]) #else XCTAssertEqual(try result.buildProduct(for: "exe").linkArguments(), [ - result.plan.buildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.productsBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "exe").pathString, "-module-name", "exe", @@ -2281,14 +2381,14 @@ final class BuildPlanTests: XCTestCase { result.checkProductsCount(2) result.checkTargetsCount(2) - let buildPath = result.plan.buildParameters.dataPath.appending(components: "debug") + let buildPath = result.plan.productsBuildPath let fooLinkArgs = try result.buildProduct(for: "Foo").linkArguments() let barLinkArgs = try result.buildProduct(for: "Bar-Baz").linkArguments() #if os(macOS) XCTAssertEqual(fooLinkArgs, [ - result.plan.buildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.productsBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "Foo").pathString, "-module-name", "Foo", @@ -2303,7 +2403,7 @@ final class BuildPlanTests: XCTestCase { ]) XCTAssertEqual(barLinkArgs, [ - result.plan.buildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.productsBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "libBar-Baz.dylib").pathString, "-module-name", "Bar_Baz", @@ -2318,7 +2418,7 @@ final class BuildPlanTests: XCTestCase { ]) #elseif os(Windows) XCTAssertEqual(fooLinkArgs, [ - result.plan.buildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.productsBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "Foo.exe").pathString, "-module-name", "Foo", @@ -2330,7 +2430,7 @@ final class BuildPlanTests: XCTestCase { ]) XCTAssertEqual(barLinkArgs, [ - result.plan.buildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.productsBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "Bar-Baz.dll").pathString, "-module-name", "Bar_Baz", @@ -2341,7 +2441,7 @@ final class BuildPlanTests: XCTestCase { ]) #else XCTAssertEqual(fooLinkArgs, [ - result.plan.buildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.productsBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "Foo").pathString, "-module-name", "Foo", @@ -2354,7 +2454,7 @@ final class BuildPlanTests: XCTestCase { ]) XCTAssertEqual(barLinkArgs, [ - result.plan.buildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.productsBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "libBar-Baz.so").pathString, "-module-name", "Bar_Baz", @@ -2412,7 +2512,7 @@ final class BuildPlanTests: XCTestCase { result.checkProductsCount(2) result.checkTargetsCount(2) - let buildPath = result.plan.buildParameters.dataPath.appending(components: "debug") + let buildPath = result.plan.productsBuildPath let exe = try result.target(for: "exe").swiftTarget().compileArguments() XCTAssertMatch(exe, ["-swift-version", "4", "-enable-batch-mode", "-Onone", "-enable-testing", .equal(j), "-DSWIFT_PACKAGE", "-DDEBUG", "-module-cache-path", "\(buildPath.appending(components: "ModuleCache"))", .anySequence, "-g", .anySequence]) @@ -2422,7 +2522,7 @@ final class BuildPlanTests: XCTestCase { #if os(macOS) let linkArguments = [ - result.plan.buildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.productsBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "liblib.dylib").pathString, "-module-name", "lib", @@ -2437,7 +2537,7 @@ final class BuildPlanTests: XCTestCase { ] #elseif os(Windows) let linkArguments = [ - result.plan.buildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.productsBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "lib.dll").pathString, "-module-name", "lib", @@ -2448,7 +2548,7 @@ final class BuildPlanTests: XCTestCase { ] #else let linkArguments = [ - result.plan.buildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.productsBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "liblib.so").pathString, "-module-name", "lib", @@ -2501,8 +2601,8 @@ final class BuildPlanTests: XCTestCase { result.checkProductsCount(2) result.checkTargetsCount(2) - let triple = result.plan.buildParameters.targetTriple - let buildPath = result.plan.buildParameters.dataPath.appending(components: "debug") + let triple = result.plan.productsBuildParameters.triple + let buildPath = result.plan.productsBuildPath let exe = try result.target(for: "exe").clangTarget() @@ -2556,7 +2656,7 @@ final class BuildPlanTests: XCTestCase { #if os(macOS) XCTAssertEqual(try result.buildProduct(for: "lib").linkArguments(), [ - result.plan.buildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.productsBuildParameters.toolchain.swiftCompilerPath.pathString, "-lc++", "-L", buildPath.pathString, "-o", buildPath.appending(components: "liblib.dylib").pathString, @@ -2571,7 +2671,7 @@ final class BuildPlanTests: XCTestCase { ]) XCTAssertEqual(try result.buildProduct(for: "exe").linkArguments(), [ - result.plan.buildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.productsBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "exe").pathString, "-module-name", "exe", @@ -2584,7 +2684,7 @@ final class BuildPlanTests: XCTestCase { ]) #elseif os(Windows) XCTAssertEqual(try result.buildProduct(for: "lib").linkArguments(), [ - result.plan.buildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.productsBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "lib.dll").pathString, "-module-name", "lib", @@ -2596,7 +2696,7 @@ final class BuildPlanTests: XCTestCase { ]) XCTAssertEqual(try result.buildProduct(for: "exe").linkArguments(), [ - result.plan.buildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.productsBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "exe.exe").pathString, "-module-name", "exe", @@ -2608,7 +2708,7 @@ final class BuildPlanTests: XCTestCase { ]) #else XCTAssertEqual(try result.buildProduct(for: "lib").linkArguments(), [ - result.plan.buildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.productsBuildParameters.toolchain.swiftCompilerPath.pathString, "-lstdc++", "-L", buildPath.pathString, "-o", buildPath.appending(components: "liblib.so").pathString, @@ -2622,7 +2722,7 @@ final class BuildPlanTests: XCTestCase { ]) XCTAssertEqual(try result.buildProduct(for: "exe").linkArguments(), [ - result.plan.buildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.productsBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "exe").pathString, "-module-name", "exe", @@ -2988,7 +3088,7 @@ final class BuildPlanTests: XCTestCase { result.checkProductsCount(1) result.checkTargetsCount(2) - let buildPath = result.plan.buildParameters.dataPath.appending(components: "debug") + let buildPath = result.plan.productsBuildParameters.dataPath.appending(components: "debug") let lib = try result.target(for: "lib").clangTarget() let args = [ @@ -3017,7 +3117,7 @@ final class BuildPlanTests: XCTestCase { ]) XCTAssertEqual(try result.buildProduct(for: "exe").linkArguments(), [ - result.plan.buildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.productsBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "exe.exe").pathString, "-module-name", "exe", "-emit-executable", @@ -3069,7 +3169,7 @@ final class BuildPlanTests: XCTestCase { result.checkProductsCount(2) result.checkTargetsCount(5) // There are two additional targets on non-Apple platforms, for test discovery and test entry point - let buildPath = result.plan.buildParameters.dataPath.appending(components: "debug") + let buildPath = result.plan.productsBuildPath let lib = try result.target(for: "lib").clangTarget() let args = [ @@ -3101,7 +3201,7 @@ final class BuildPlanTests: XCTestCase { XCTAssertEqual( try appBuildDescription.linkArguments(), [ - result.plan.buildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.productsBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "app.wasm").pathString, "-module-name", "app", "-static-stdlib", "-emit-executable", @@ -3118,7 +3218,7 @@ final class BuildPlanTests: XCTestCase { XCTAssertEqual( try testBuildDescription.linkArguments(), [ - result.plan.buildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.productsBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "PkgPackageTests.wasm").pathString, "-module-name", "PkgPackageTests", @@ -3213,7 +3313,7 @@ final class BuildPlanTests: XCTestCase { )) let lib = try result.target(for: "lib").clangTarget() - let path = StringPattern.equal(result.plan.buildParameters.indexStore.pathString) + let path = StringPattern.equal(result.plan.productsBuildParameters.indexStore.pathString) #if os(macOS) XCTAssertMatch(try lib.basicArguments(isCXX: false), [.anySequence, "-index-store-path", path, .anySequence]) @@ -3533,10 +3633,39 @@ final class BuildPlanTests: XCTestCase { XCTAssertMatch(dep, [.anySequence, "-DDEP", .anySequence]) let cbar = try result.target(for: "cbar").clangTarget().basicArguments(isCXX: false) - XCTAssertMatch(cbar, [.anySequence, "-DCCC=2", "-I\(A.appending(components: "Sources", "cbar", "Sources", "headers"))", "-I\(A.appending(components: "Sources", "cbar", "Sources", "cppheaders"))", "-Icfoo", "-L", "cbar", "-Icxxfoo", "-L", "cxxbar", "-g", "-fno-omit-frame-pointer", .end]) + XCTAssertMatch( + cbar, + [ + .anySequence, + "-DCCC=2", + "-I\(A.appending(components: "Sources", "cbar", "Sources", "headers"))", + "-I\(A.appending(components: "Sources", "cbar", "Sources", "cppheaders"))", + "-Icfoo", + "-L", "cbar", + "-Icxxfoo", + "-L", "cxxbar", + "-g", + "-fno-omit-frame-pointer", + .end + ] + ) let bar = try result.target(for: "bar").swiftTarget().compileArguments() - XCTAssertMatch(bar, [.anySequence, "-DLINUX", "-Isfoo", "-L", "sbar", "-cxx-interoperability-mode=default", "-enable-upcoming-feature", "BestFeature", "-g", "-Xcc", "-g", "-Xcc", "-fno-omit-frame-pointer", .end]) + XCTAssertMatch( + bar, + [ + .anySequence, + "-DLINUX", + "-Isfoo", + "-L", "sbar", + "-cxx-interoperability-mode=default", + "-enable-upcoming-feature", "BestFeature", + "-g", + "-Xcc", "-g", + "-Xcc", "-fno-omit-frame-pointer", + .end + ] + ) let exe = try result.target(for: "exe").swiftTarget().compileArguments() XCTAssertMatch(exe, [.anySequence, "-DFOO", "-g", "-Xcc", "-g", "-Xcc", "-fno-omit-frame-pointer", .end]) @@ -3561,10 +3690,40 @@ final class BuildPlanTests: XCTestCase { XCTAssertMatch(dep, [.anySequence, "-DDEP", .anySequence]) let cbar = try result.target(for: "cbar").clangTarget().basicArguments(isCXX: false) - XCTAssertMatch(cbar, [.anySequence, "-DCCC=2", "-I\(A.appending(components: "Sources", "cbar", "Sources", "headers"))", "-I\(A.appending(components: "Sources", "cbar", "Sources", "cppheaders"))", "-Icfoo", "-L", "cbar", "-Icxxfoo", "-L", "cxxbar", "-g", "-fomit-frame-pointer", .end]) + XCTAssertMatch( + cbar, + [ + .anySequence, + "-DCCC=2", + "-I\(A.appending(components: "Sources", "cbar", "Sources", "headers"))", + "-I\(A.appending(components: "Sources", "cbar", "Sources", "cppheaders"))", + "-Icfoo", + "-L", "cbar", + "-Icxxfoo", + "-L", "cxxbar", + "-g", + "-fomit-frame-pointer", + .end + ] + ) let bar = try result.target(for: "bar").swiftTarget().compileArguments() - XCTAssertMatch(bar, [.anySequence, "-DLINUX", "-Isfoo", "-L", "sbar", "-cxx-interoperability-mode=default", "-enable-upcoming-feature", "BestFeature", "-g", "-Xcc", "-g", "-Xcc", "-fomit-frame-pointer", .end]) + XCTAssertMatch( + bar, + [ + .anySequence, + "-DLINUX", + "-Isfoo", + "-L", "sbar", + "-cxx-interoperability-mode=default", + "-enable-upcoming-feature", + "BestFeature", + "-g", + "-Xcc", "-g", + "-Xcc", "-fomit-frame-pointer", + .end + ] + ) let exe = try result.target(for: "exe").swiftTarget().compileArguments() XCTAssertMatch(exe, [.anySequence, "-DFOO", "-g", "-Xcc", "-g", "-Xcc", "-fomit-frame-pointer", .end]) @@ -3586,10 +3745,40 @@ final class BuildPlanTests: XCTestCase { XCTAssertMatch(dep, [.anySequence, "-DDEP", .anySequence]) let cbar = try result.target(for: "cbar").clangTarget().basicArguments(isCXX: false) - XCTAssertMatch(cbar, [.anySequence, "-DCCC=2", "-I\(A.appending(components: "Sources", "cbar", "Sources", "headers"))", "-I\(A.appending(components: "Sources", "cbar", "Sources", "cppheaders"))", "-Icfoo", "-L", "cbar", "-Icxxfoo", "-L", "cxxbar", "-g", "-fno-omit-frame-pointer", .end]) + XCTAssertMatch( + cbar, + [ + .anySequence, + "-DCCC=2", + "-I\(A.appending(components: "Sources", "cbar", "Sources", "headers"))", + "-I\(A.appending(components: "Sources", "cbar", "Sources", "cppheaders"))", + "-Icfoo", + "-L", "cbar", + "-Icxxfoo", + "-L", "cxxbar", + "-g", + "-fno-omit-frame-pointer", + .end + ] + ) let bar = try result.target(for: "bar").swiftTarget().compileArguments() - XCTAssertMatch(bar, [.anySequence, "-DLINUX", "-Isfoo", "-L", "sbar", "-cxx-interoperability-mode=default", "-enable-upcoming-feature", "BestFeature", "-g", "-Xcc", "-g", "-Xcc", "-fno-omit-frame-pointer", .end]) + XCTAssertMatch( + bar, + [ + .anySequence, + "-DLINUX", + "-Isfoo", + "-L", "sbar", + "-cxx-interoperability-mode=default", + "-enable-upcoming-feature", + "BestFeature", + "-g", + "-Xcc", "-g", + "-Xcc", "-fno-omit-frame-pointer", + .end + ] + ) let exe = try result.target(for: "exe").swiftTarget().compileArguments() XCTAssertMatch(exe, [.anySequence, "-DFOO", "-g", "-Xcc", "-g", "-Xcc", "-fno-omit-frame-pointer", .end]) @@ -3599,16 +3788,56 @@ final class BuildPlanTests: XCTestCase { let result = try createResult(for: .x86_64MacOS) let cbar = try result.target(for: "cbar").clangTarget().basicArguments(isCXX: false) - XCTAssertMatch(cbar, [.anySequence, "-DCCC=2", "-I\(A.appending(components: "Sources", "cbar", "Sources", "headers"))", "-I\(A.appending(components: "Sources", "cbar", "Sources", "cppheaders"))", "-Icfoo", "-L", "cbar", "-Icxxfoo", "-L", "cxxbar", "-g", .end]) + XCTAssertMatch( + cbar, + [ + .anySequence, + "-DCCC=2", + "-I\(A.appending(components: "Sources", "cbar", "Sources", "headers"))", + "-I\(A.appending(components: "Sources", "cbar", "Sources", "cppheaders"))", + "-Icfoo", + "-L", "cbar", + "-Icxxfoo", + "-L", "cxxbar", + "-g", + .end + ] + ) let bar = try result.target(for: "bar").swiftTarget().compileArguments() - XCTAssertMatch(bar, [.anySequence, "-DDMACOS", "-Isfoo", "-L", "sbar", "-cxx-interoperability-mode=default", "-enable-upcoming-feature", "BestFeature", "-enable-upcoming-feature", "WorstFeature", "-g", "-Xcc", "-g", .end]) + XCTAssertMatch( + bar, + [ + .anySequence, + "-DDMACOS", + "-Isfoo", + "-L", "sbar", + "-cxx-interoperability-mode=default", + "-enable-upcoming-feature", "BestFeature", + "-enable-upcoming-feature", "WorstFeature", + "-g", + "-Xcc", "-g", + .end + ] + ) let exe = try result.target(for: "exe").swiftTarget().compileArguments() XCTAssertMatch(exe, [.anySequence, "-DFOO", "-cxx-interoperability-mode=default", "-g", "-Xcc", "-g", .end]) let linkExe = try result.buildProduct(for: "exe").linkArguments() - XCTAssertMatch(linkExe, [.anySequence, "-lsqlite3", "-llibz", "-framework", "CoreData", "-framework", "best", "-Ilfoo", "-L", "lbar", .anySequence]) + XCTAssertMatch( + linkExe, + [ + .anySequence, + "-lsqlite3", + "-llibz", + "-framework", "CoreData", + "-framework", "best", + "-Ilfoo", + "-L", "lbar", + .anySequence + ] + ) } } @@ -3645,7 +3874,17 @@ final class BuildPlanTests: XCTestCase { )) let exe = try result.buildProduct(for: "exe").linkArguments() - XCTAssertMatch(exe, [.anySequence, "-L", "/path/to/foo", "-L/path/to/foo", "-Xlinker", "-rpath=foo", "-Xlinker", "-rpath", "-Xlinker", "foo"]) + XCTAssertMatch( + exe, + [ + .anySequence, + "-L", "/path/to/foo", + "-L/path/to/foo", + "-Xlinker", "-rpath=foo", + "-Xlinker", "-rpath", + "-Xlinker", "foo" + ] + ) } func testUserToolchainCompileFlags() throws { @@ -3700,7 +3939,7 @@ final class BuildPlanTests: XCTestCase { result.checkProductsCount(1) result.checkTargetsCount(2) - let buildPath: AbsolutePath = result.plan.buildParameters.dataPath.appending(components: "debug") + let buildPath = result.plan.productsBuildPath let lib = try result.target(for: "lib").clangTarget() var args: [StringPattern] = [.anySequence] @@ -3709,7 +3948,13 @@ final class BuildPlanTests: XCTestCase { #else args += ["--sysroot"] #endif - args += ["\(userSwiftSDK.pathsConfiguration.sdkRootPath!)", "-I/fake/sdk/sysroot", "-clang-flag-from-json", .anySequence, "-clang-command-line-flag"] + args += [ + "\(userSwiftSDK.pathsConfiguration.sdkRootPath!)", + "-I/fake/sdk/sysroot", + "-clang-flag-from-json", + .anySequence, + "-clang-command-line-flag" + ] XCTAssertMatch(try lib.basicArguments(isCXX: false), args) let exe = try result.target(for: "exe").swiftTarget().compileArguments() @@ -4033,7 +4278,7 @@ final class BuildPlanTests: XCTestCase { observabilityScope: observability.topScope ) - let buildPath = plan.buildParameters.dataPath.appending(components: "debug") + let buildPath = plan.productsBuildPath let yaml = try fs.tempDirectory.appending(components: UUID().uuidString, "debug.yaml") try fs.createDirectory(yaml.parentDirectory, recursive: true) @@ -4086,7 +4331,7 @@ final class BuildPlanTests: XCTestCase { ) let result = try BuildPlanResult(plan: plan) - let buildPath = result.plan.buildParameters.dataPath.appending(components: "debug") + let buildPath = result.plan.productsBuildPath let fooTarget = try result.target(for: "Foo").swiftTarget().compileArguments() #if os(macOS) @@ -4160,20 +4405,52 @@ final class BuildPlanTests: XCTestCase { ) let result = try BuildPlanResult(plan: plan) - let buildPath = result.plan.buildParameters.dataPath.appending(components: "debug") + let buildPath = result.plan.productsBuildPath let fooTarget = try result.target(for: "Foo").swiftTarget().compileArguments() #if os(macOS) - XCTAssertMatch(fooTarget, [.anySequence, "-emit-objc-header", "-emit-objc-header-path", "/path/to/build/debug/Foo.build/Foo-Swift.h", .anySequence]) + XCTAssertMatch( + fooTarget, + [ + .anySequence, + "-emit-objc-header", + "-emit-objc-header-path", + "/path/to/build/debug/Foo.build/Foo-Swift.h", + .anySequence + ] + ) #else - XCTAssertNoMatch(fooTarget, [.anySequence, "-emit-objc-header", "-emit-objc-header-path", "/path/to/build/debug/Foo.build/Foo-Swift.h", .anySequence]) + XCTAssertNoMatch( + fooTarget, + [ + .anySequence, + "-emit-objc-header", + "-emit-objc-header-path", + "/path/to/build/debug/Foo.build/Foo-Swift.h", + .anySequence + ] + ) #endif let barTarget = try result.target(for: "Bar").clangTarget().basicArguments(isCXX: false) #if os(macOS) - XCTAssertMatch(barTarget, [.anySequence, "-fmodule-map-file=/path/to/build/debug/Foo.build/module.modulemap", .anySequence]) + XCTAssertMatch( + barTarget, + [ + .anySequence, + "-fmodule-map-file=/path/to/build/debug/Foo.build/module.modulemap", + .anySequence + ] + ) #else - XCTAssertNoMatch(barTarget, [.anySequence, "-fmodule-map-file=/path/to/build/debug/Foo.build/module.modulemap", .anySequence]) + XCTAssertNoMatch( + barTarget, + [ + .anySequence, + "-fmodule-map-file=/path/to/build/debug/Foo.build/module.modulemap", + .anySequence + ] + ) #endif let yaml = try fs.tempDirectory.appending(components: UUID().uuidString, "debug.yaml") @@ -4232,7 +4509,7 @@ final class BuildPlanTests: XCTestCase { fileSystem: fs, observabilityScope: observability.topScope ) - let dynamicLibraryExtension = plan.buildParameters.targetTriple.dynamicLibraryExtension + let dynamicLibraryExtension = plan.productsBuildParameters.triple.dynamicLibraryExtension #if os(Windows) let dynamicLibraryPrefix = "" #else @@ -4242,19 +4519,51 @@ final class BuildPlanTests: XCTestCase { let fooTarget = try result.target(for: "Foo").swiftTarget().compileArguments() #if os(macOS) - XCTAssertMatch(fooTarget, [.anySequence, "-emit-objc-header", "-emit-objc-header-path", "/path/to/build/debug/Foo.build/Foo-Swift.h", .anySequence]) + XCTAssertMatch( + fooTarget, + [ + .anySequence, + "-emit-objc-header", + "-emit-objc-header-path", + "/path/to/build/debug/Foo.build/Foo-Swift.h", + .anySequence + ] + ) #else - XCTAssertNoMatch(fooTarget, [.anySequence, "-emit-objc-header", "-emit-objc-header-path", "/path/to/build/debug/Foo.build/Foo-Swift.h", .anySequence]) + XCTAssertNoMatch( + fooTarget, + [ + .anySequence, + "-emit-objc-header", + "-emit-objc-header-path", + "/path/to/build/debug/Foo.build/Foo-Swift.h", + .anySequence + ] + ) #endif let barTarget = try result.target(for: "Bar").clangTarget().basicArguments(isCXX: false) #if os(macOS) - XCTAssertMatch(barTarget, [.anySequence, "-fmodule-map-file=/path/to/build/debug/Foo.build/module.modulemap", .anySequence]) + XCTAssertMatch( + barTarget, + [ + .anySequence, + "-fmodule-map-file=/path/to/build/debug/Foo.build/module.modulemap", + .anySequence + ] + ) #else - XCTAssertNoMatch(barTarget, [.anySequence, "-fmodule-map-file=/path/to/build/debug/Foo.build/module.modulemap", .anySequence]) + XCTAssertNoMatch( + barTarget, + [ + .anySequence, + "-fmodule-map-file=/path/to/build/debug/Foo.build/module.modulemap", + .anySequence + ] + ) #endif - let buildPath = result.plan.buildParameters.dataPath.appending(components: "debug") + let buildPath = result.plan.productsBuildPath let yaml = try fs.tempDirectory.appending(components: UUID().uuidString, "debug.yaml") try fs.createDirectory(yaml.parentDirectory, recursive: true) @@ -4300,7 +4609,7 @@ final class BuildPlanTests: XCTestCase { observabilityScope: observability.topScope )) - let buildPath = result.plan.buildParameters.dataPath.appending(components: "debug") + let buildPath = result.plan.productsBuildPath let objects = try result.buildProduct(for: "exe").objects XCTAssertTrue(objects.contains(buildPath.appending(components: "exe.build", "exe.swiftmodule.o")), objects.description) @@ -4317,7 +4626,7 @@ final class BuildPlanTests: XCTestCase { inputs: ["\(buildPath.appending(components: "exe.build", "exe.swiftmodule").escapedPathString)"] outputs: ["\(buildPath.appending(components: "exe.build", "exe.swiftmodule.o").escapedPathString)"] description: "Wrapping AST for exe for debugging" - args: ["\(result.plan.buildParameters.toolchain.swiftCompilerPath.escapedPathString)","-modulewrap","\(buildPath.appending(components: "exe.build", "exe.swiftmodule").escapedPathString)","-o","\(buildPath.appending(components: "exe.build", "exe.swiftmodule.o").escapedPathString)","-target","x86_64-unknown-linux-gnu"] + args: ["\(result.plan.productsBuildParameters.toolchain.swiftCompilerPath.escapedPathString)","-modulewrap","\(buildPath.appending(components: "exe.build", "exe.swiftmodule").escapedPathString)","-o","\(buildPath.appending(components: "exe.build", "exe.swiftmodule.o").escapedPathString)","-target","x86_64-unknown-linux-gnu"] """)) XCTAssertMatch(contents, .contains(""" "\(buildPath.appending(components: "lib.build", "lib.swiftmodule.o").escapedPathString)": @@ -4325,7 +4634,7 @@ final class BuildPlanTests: XCTestCase { inputs: ["\(buildPath.appending(components: "lib.swiftmodule").escapedPathString)"] outputs: ["\(buildPath.appending(components: "lib.build", "lib.swiftmodule.o").escapedPathString)"] description: "Wrapping AST for lib for debugging" - args: ["\(result.plan.buildParameters.toolchain.swiftCompilerPath.escapedPathString)","-modulewrap","\(buildPath.appending(components: "lib.swiftmodule").escapedPathString)","-o","\(buildPath.appending(components: "lib.build", "lib.swiftmodule.o").escapedPathString)","-target","x86_64-unknown-linux-gnu"] + args: ["\(result.plan.productsBuildParameters.toolchain.swiftCompilerPath.escapedPathString)","-modulewrap","\(buildPath.appending(components: "lib.swiftmodule").escapedPathString)","-o","\(buildPath.appending(components: "lib.build", "lib.swiftmodule.o").escapedPathString)","-target","x86_64-unknown-linux-gnu"] """)) } @@ -4360,7 +4669,7 @@ final class BuildPlanTests: XCTestCase { observabilityScope: observability.topScope )) - let buildPath = result.plan.buildParameters.dataPath.appending(components: "debug") + let buildPath = result.plan.productsBuildPath let yaml = try fs.tempDirectory.appending(components: UUID().uuidString, "debug.yaml") try fs.createDirectory(yaml.parentDirectory, recursive: true) @@ -4370,23 +4679,23 @@ final class BuildPlanTests: XCTestCase { let contents: String = try fs.readFileContents(yaml) - if result.plan.buildParameters.targetTriple.isWindows() { + if result.plan.productsBuildParameters.triple.isWindows() { XCTAssertMatch(contents, .contains(""" "C.rary-debug.a": tool: shell inputs: ["\(buildPath.appending(components: "rary.build", "rary.swift.o").escapedPathString)","\(buildPath.appending(components: "rary.build", "rary.swiftmodule.o").escapedPathString)","\(buildPath.appending(components: "rary.product", "Objects.LinkFileList").escapedPathString)"] outputs: ["\(buildPath.appending(components: "library.a").escapedPathString)"] description: "Archiving \(buildPath.appending(components: "library.a").escapedPathString)" - args: ["\(result.plan.buildParameters.toolchain.librarianPath.escapedPathString)","/LIB","/OUT:\(buildPath.appending(components: "library.a").escapedPathString)","@\(buildPath.appending(components: "rary.product", "Objects.LinkFileList").escapedPathString)"] + args: ["\(result.plan.productsBuildParameters.toolchain.librarianPath.escapedPathString)","/LIB","/OUT:\(buildPath.appending(components: "library.a").escapedPathString)","@\(buildPath.appending(components: "rary.product", "Objects.LinkFileList").escapedPathString)"] """)) - } else if result.plan.buildParameters.targetTriple.isDarwin() { + } else if result.plan.productsBuildParameters.triple.isDarwin() { XCTAssertMatch(contents, .contains(""" "C.rary-debug.a": tool: shell inputs: ["\(buildPath.appending(components: "rary.build", "rary.swift.o").escapedPathString)","\(buildPath.appending(components: "rary.product", "Objects.LinkFileList").escapedPathString)"] outputs: ["\(buildPath.appending(components: "library.a").escapedPathString)"] description: "Archiving \(buildPath.appending(components: "library.a").escapedPathString)" - args: ["\(result.plan.buildParameters.toolchain.librarianPath.escapedPathString)","-static","-o","\(buildPath.appending(components: "library.a").escapedPathString)","@\(buildPath.appending(components: "rary.product", "Objects.LinkFileList").escapedPathString)"] + args: ["\(result.plan.productsBuildParameters.toolchain.librarianPath.escapedPathString)","-static","-o","\(buildPath.appending(components: "library.a").escapedPathString)","@\(buildPath.appending(components: "rary.product", "Objects.LinkFileList").escapedPathString)"] """)) } else { // assume `llvm-ar` is the librarian XCTAssertMatch(contents, .contains(""" @@ -4395,7 +4704,7 @@ final class BuildPlanTests: XCTestCase { inputs: ["\(buildPath.appending(components: "rary.build", "rary.swift.o").escapedPathString)","\(buildPath.appending(components: "rary.build", "rary.swiftmodule.o").escapedPathString)","\(buildPath.appending(components: "rary.product", "Objects.LinkFileList").escapedPathString)"] outputs: ["\(buildPath.appending(components: "library.a").escapedPathString)"] description: "Archiving \(buildPath.appending(components: "library.a").escapedPathString)" - args: ["\(result.plan.buildParameters.toolchain.librarianPath.escapedPathString)","crs","\(buildPath.appending(components: "library.a").escapedPathString)","@\(buildPath.appending(components: "rary.product", "Objects.LinkFileList").escapedPathString)"] + args: ["\(result.plan.productsBuildParameters.toolchain.librarianPath.escapedPathString)","crs","\(buildPath.appending(components: "library.a").escapedPathString)","@\(buildPath.appending(components: "rary.product", "Objects.LinkFileList").escapedPathString)"] """)) } } @@ -4445,7 +4754,7 @@ final class BuildPlanTests: XCTestCase { ) let result = try BuildPlanResult(plan: plan) - let buildPath = result.plan.buildParameters.dataPath.appending(components: "debug") + let buildPath = result.plan.productsBuildPath let fooTarget = try result.target(for: "Foo").swiftTarget() XCTAssertEqual(try fooTarget.objects.map{ $0.pathString }, [ @@ -4511,7 +4820,7 @@ final class BuildPlanTests: XCTestCase { ) let result = try BuildPlanResult(plan: plan) - let buildPath = result.plan.buildParameters.dataPath.appending(components: "debug") + let buildPath = result.plan.productsBuildPath let fooTarget = try result.target(for: "Foo").swiftTarget() XCTAssertEqual(try fooTarget.objects.map{ $0.pathString }, [ @@ -4576,7 +4885,7 @@ final class BuildPlanTests: XCTestCase { ) let result = try BuildPlanResult(plan: plan) - let buildPath = result.plan.buildParameters.dataPath.appending("debug") + let buildPath = result.plan.productsBuildPath let fooTarget = try result.target(for: "Foo").clangTarget() XCTAssertEqual(try fooTarget.objects.map(\.pathString).sorted(), [ @@ -4766,7 +5075,7 @@ final class BuildPlanTests: XCTestCase { result.checkProductsCount(3) result.checkTargetsCount(3) - let buildPath = result.plan.buildParameters.dataPath.appending(components: "debug") + let buildPath = result.plan.productsBuildPath let libraryBasicArguments = try result.target(for: "Library").swiftTarget().compileArguments() XCTAssertMatch(libraryBasicArguments, [.anySequence, "-F", "\(buildPath)", .anySequence]) @@ -5161,11 +5470,11 @@ final class BuildPlanTests: XCTestCase { result.checkProductsCount(1) result.checkTargetsCount(2) - let buildPath = result.plan.buildParameters.dataPath.appending(components: "debug") + let buildPath = result.plan.productsBuildPath #if os(macOS) let linkArguments = [ - result.plan.buildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.productsBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "exe").pathString, "-module-name", "exe", @@ -5179,7 +5488,7 @@ final class BuildPlanTests: XCTestCase { ] #elseif os(Windows) let linkArguments = [ - result.plan.buildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.productsBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "exe.exe").pathString, "-module-name", "exe", @@ -5190,7 +5499,7 @@ final class BuildPlanTests: XCTestCase { ] #else let linkArguments = [ - result.plan.buildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.productsBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "exe").pathString, "-module-name", "exe", From 1270b44ee356ee75e343e2c3d3770cdb6c69115d Mon Sep 17 00:00:00 2001 From: Max Desiatov Date: Wed, 6 Dec 2023 15:35:55 +0000 Subject: [PATCH 04/33] Address remaining deprecations of `buildParameters` use --- .../TargetBuildDescription.swift | 10 ++++ .../LLBuildManifestBuilder+Clang.swift | 10 ++-- .../LLBuildManifestBuilder+Product.swift | 8 +-- .../LLBuildManifestBuilder+Resources.swift | 2 +- .../LLBuildManifestBuilder+Swift.swift | 50 +++++++++++-------- .../LLBuildManifestBuilder.swift | 33 ++++++++---- 6 files changed, 72 insertions(+), 41 deletions(-) diff --git a/Sources/Build/BuildDescription/TargetBuildDescription.swift b/Sources/Build/BuildDescription/TargetBuildDescription.swift index c177a0b7dcd..7a495d2742b 100644 --- a/Sources/Build/BuildDescription/TargetBuildDescription.swift +++ b/Sources/Build/BuildDescription/TargetBuildDescription.swift @@ -11,6 +11,7 @@ //===----------------------------------------------------------------------===// import Basics +import struct SPMBuildCore.BuildParameters import class PackageGraph.ResolvedTarget import struct PackageModel.Resource import struct SPMBuildCore.BuildToolPluginInvocationResult @@ -91,4 +92,13 @@ public enum TargetBuildDescription { return target.buildToolPluginInvocationResults } } + + var buildParameters: BuildParameters { + switch self { + case .swift(let swiftTargetBuildDescription): + swiftTargetBuildDescription.buildParameters + case .clang(let clangTargetBuildDescription): + clangTargetBuildDescription.buildParameters + } + } } diff --git a/Sources/Build/BuildManifest/LLBuildManifestBuilder+Clang.swift b/Sources/Build/BuildManifest/LLBuildManifestBuilder+Clang.swift index f5626357d4f..f759c98bba3 100644 --- a/Sources/Build/BuildManifest/LLBuildManifestBuilder+Clang.swift +++ b/Sources/Build/BuildManifest/LLBuildManifestBuilder+Clang.swift @@ -42,7 +42,7 @@ extension LLBuildManifestBuilder { } } - for dependency in target.target.dependencies(satisfying: self.buildEnvironment) { + for dependency in target.target.dependencies(satisfying: target.buildEnvironment) { switch dependency { case .target(let target, _): addStaticTargetInputs(target) @@ -68,7 +68,7 @@ extension LLBuildManifestBuilder { } for binaryPath in target.libraryBinaryPaths { - let path = destinationPath(forBinaryAt: binaryPath) + let path = target.buildParameters.destinationPath(forBinaryAt: binaryPath) if self.fileSystem.isDirectory(binaryPath) { inputs.append(directory: path) } else { @@ -97,7 +97,7 @@ extension LLBuildManifestBuilder { args += ["-c", path.source.pathString, "-o", path.object.pathString] - let clangCompiler = try buildParameters.toolchain.getClangCompiler().pathString + let clangCompiler = try target.buildParameters.toolchain.getClangCompiler().pathString args.insert(clangCompiler, at: 0) let objectFileNode: Node = .file(path.object) @@ -116,7 +116,7 @@ extension LLBuildManifestBuilder { try addBuildToolPlugins(.clang(target)) // Create a phony node to represent the entire target. - let targetName = target.target.getLLBuildTargetName(config: self.buildConfig) + let targetName = target.target.getLLBuildTargetName(config: target.buildParameters.buildConfig) let output: Node = .virtual(targetName) self.manifest.addNode(output, toTarget: targetName) @@ -126,7 +126,7 @@ extension LLBuildManifestBuilder { outputs: [output] ) - if self.plan.graph.isInRootPackages(target.target, satisfying: self.buildEnvironment) { + if self.plan.graph.isInRootPackages(target.target, satisfying: target.buildParameters.buildEnvironment) { if !target.isTestTarget { self.addNode(output, toTarget: .main) } diff --git a/Sources/Build/BuildManifest/LLBuildManifestBuilder+Product.swift b/Sources/Build/BuildManifest/LLBuildManifestBuilder+Product.swift index fd19267315f..c6a8a72699a 100644 --- a/Sources/Build/BuildManifest/LLBuildManifestBuilder+Product.swift +++ b/Sources/Build/BuildManifest/LLBuildManifestBuilder+Product.swift @@ -15,7 +15,7 @@ import struct LLBuildManifest.Node extension LLBuildManifestBuilder { func createProductCommand(_ buildProduct: ProductBuildDescription) throws { - let cmdName = try buildProduct.product.getCommandName(config: self.buildConfig) + let cmdName = try buildProduct.product.getCommandName(config: buildProduct.buildParameters.buildConfig) // Add dependency on Info.plist generation on Darwin platforms. let testInputs: [AbsolutePath] @@ -34,7 +34,7 @@ extension LLBuildManifestBuilder { } // Create a phony node to represent the entire target. - let targetName = try buildProduct.product.getLLBuildTargetName(config: self.buildConfig) + let targetName = try buildProduct.product.getLLBuildTargetName(config: buildProduct.buildParameters.buildConfig) let output: Node = .virtual(targetName) let finalProductNode: Node @@ -60,7 +60,7 @@ extension LLBuildManifestBuilder { let linkedBinaryPath = try buildProduct.binaryPath if case .executable = buildProduct.product.type, buildProduct.buildParameters.triple.isMacOSX, - buildParameters.debuggingParameters.shouldEnableDebuggingEntitlement { + buildProduct.buildParameters.debuggingParameters.shouldEnableDebuggingEntitlement { shouldCodeSign = true linkedBinaryNode = try .file(buildProduct.binaryPath, isMutated: true) } else { @@ -85,7 +85,7 @@ extension LLBuildManifestBuilder { outputPath: plistPath ) - let cmdName = try buildProduct.product.getCommandName(config: self.buildConfig) + let cmdName = try buildProduct.product.getCommandName(config: buildProduct.buildParameters.buildConfig) let codeSigningOutput = Node.virtual(targetName + "-CodeSigning") try self.manifest.addShellCmd( name: "\(cmdName)-entitlements", diff --git a/Sources/Build/BuildManifest/LLBuildManifestBuilder+Resources.swift b/Sources/Build/BuildManifest/LLBuildManifestBuilder+Resources.swift index 308618c3197..599c7c435d5 100644 --- a/Sources/Build/BuildManifest/LLBuildManifestBuilder+Resources.swift +++ b/Sources/Build/BuildManifest/LLBuildManifestBuilder+Resources.swift @@ -45,7 +45,7 @@ extension LLBuildManifestBuilder { outputs.append(output) } - let cmdName = target.target.getLLBuildResourcesCmdName(config: self.buildConfig) + let cmdName = target.target.getLLBuildResourcesCmdName(config: target.buildParameters.buildConfig) self.manifest.addPhonyCmd(name: cmdName, inputs: outputs, outputs: [.virtual(cmdName)]) return .virtual(cmdName) diff --git a/Sources/Build/BuildManifest/LLBuildManifestBuilder+Swift.swift b/Sources/Build/BuildManifest/LLBuildManifestBuilder+Swift.swift index 11403ec9ed7..9e1eca0cb7e 100644 --- a/Sources/Build/BuildManifest/LLBuildManifestBuilder+Swift.swift +++ b/Sources/Build/BuildManifest/LLBuildManifestBuilder+Swift.swift @@ -45,7 +45,7 @@ extension LLBuildManifestBuilder { let moduleNode = Node.file(target.moduleOutputPath) let cmdOutputs = objectNodes + [moduleNode] - if self.buildParameters.driverParameters.useIntegratedSwiftDriver { + if target.buildParameters.driverParameters.useIntegratedSwiftDriver { try self.addSwiftCmdsViaIntegratedDriver( target, inputs: inputs, @@ -68,7 +68,7 @@ extension LLBuildManifestBuilder { // jobs needed to build this Swift target. var commandLine = try target.emitCommandLine() commandLine.append("-driver-use-frontend-path") - commandLine.append(self.buildParameters.toolchain.swiftCompilerPath.pathString) + commandLine.append(target.buildParameters.toolchain.swiftCompilerPath.pathString) // FIXME: At some point SwiftPM should provide its own executor for // running jobs/launching processes during planning let resolver = try ArgsResolver(fileSystem: target.fileSystem) @@ -132,7 +132,7 @@ extension LLBuildManifestBuilder { // common intermediate dependency modules, such dependencies can lead // to cycles in the resulting manifest. var manifestNodeInputs: [Node] = [] - if self.buildParameters.driverParameters.useExplicitModuleBuild && !isMainModule(job) { + if targetDescription.buildParameters.driverParameters.useExplicitModuleBuild && !isMainModule(job) { manifestNodeInputs = jobInputs } else { manifestNodeInputs = (inputs + jobInputs).uniqued() @@ -276,7 +276,7 @@ extension LLBuildManifestBuilder { var dependencyModuleDetailsMap: SwiftDriver.ExternalTargetModuleDetailsMap = [:] // Collect paths for target dependencies of this target (direct and transitive) try self.collectTargetDependencyModuleDetails( - for: targetDescription.target, + for: .swift(targetDescription), dependencyModuleDetailsMap: &dependencyModuleDetailsMap ) @@ -284,7 +284,7 @@ extension LLBuildManifestBuilder { // jobs needed to build this Swift target. var commandLine = try targetDescription.emitCommandLine() commandLine.append("-driver-use-frontend-path") - commandLine.append(self.buildParameters.toolchain.swiftCompilerPath.pathString) + commandLine.append(targetDescription.buildParameters.toolchain.swiftCompilerPath.pathString) commandLine.append("-experimental-explicit-module-build") let resolver = try ArgsResolver(fileSystem: self.fileSystem) let executor = SPMSwiftDriverExecutor( @@ -316,10 +316,10 @@ extension LLBuildManifestBuilder { /// dependency, /// in the form of a path to a .swiftmodule file and the dependency's InterModuleDependencyGraph. private func collectTargetDependencyModuleDetails( - for target: ResolvedTarget, + for targetDescription: TargetBuildDescription, dependencyModuleDetailsMap: inout SwiftDriver.ExternalTargetModuleDetailsMap ) throws { - for dependency in target.dependencies(satisfying: self.buildEnvironment) { + for dependency in targetDescription.target.dependencies(satisfying: targetDescription.buildParameters.buildEnvironment) { switch dependency { case .product: // Product dependencies are broken down into the targets that make them up. @@ -327,18 +327,24 @@ extension LLBuildManifestBuilder { throw InternalError("unknown dependency product for \(dependency)") } for dependencyProductTarget in dependencyProduct.targets { + guard let dependencyTargetDescription = self.plan.targetMap[dependencyProductTarget] else { + throw InternalError("unknown dependency target for \(dependencyProductTarget)") + } try self.addTargetDependencyInfo( - for: dependencyProductTarget, + for: dependencyTargetDescription, dependencyModuleDetailsMap: &dependencyModuleDetailsMap ) } case .target: // Product dependencies are broken down into the targets that make them up. - guard let dependencyTarget = dependency.target else { + guard + let dependencyTarget = dependency.target, + let dependencyTargetDescription = self.plan.targetMap[dependencyTarget] + else { throw InternalError("unknown dependency target for \(dependency)") } try self.addTargetDependencyInfo( - for: dependencyTarget, + for: dependencyTargetDescription, dependencyModuleDetailsMap: &dependencyModuleDetailsMap ) } @@ -346,19 +352,19 @@ extension LLBuildManifestBuilder { } private func addTargetDependencyInfo( - for target: ResolvedTarget, + for targetDescription: TargetBuildDescription, dependencyModuleDetailsMap: inout SwiftDriver.ExternalTargetModuleDetailsMap ) throws { - guard case .swift(let dependencySwiftTargetDescription) = self.plan.targetMap[target] else { + guard case .swift(let dependencySwiftTargetDescription) = targetDescription else { return } - dependencyModuleDetailsMap[ModuleDependencyId.swiftPlaceholder(target.c99name)] = + dependencyModuleDetailsMap[ModuleDependencyId.swiftPlaceholder(targetDescription.target.c99name)] = SwiftDriver.ExternalTargetModuleDetails( path: TSCAbsolutePath(dependencySwiftTargetDescription.moduleOutputPath), isFramework: false ) try self.collectTargetDependencyModuleDetails( - for: target, + for: targetDescription, dependencyModuleDetailsMap: &dependencyModuleDetailsMap ) } @@ -369,7 +375,7 @@ extension LLBuildManifestBuilder { cmdOutputs: [Node] ) throws { let isLibrary = target.target.type == .library || target.target.type == .test - let cmdName = target.target.getCommandName(config: self.buildConfig) + let cmdName = target.target.getCommandName(config: target.buildParameters.buildConfig) self.manifest.addWriteSourcesFileListCommand(sources: target.sources, sourcesFileListPath: target.sourcesFileListPath) self.manifest.addSwiftCmd( @@ -443,7 +449,7 @@ extension LLBuildManifestBuilder { } } - for dependency in target.target.dependencies(satisfying: self.buildEnvironment) { + for dependency in target.target.dependencies(satisfying: target.buildParameters.buildEnvironment) { switch dependency { case .target(let target, _): try addStaticTargetInputs(target) @@ -470,7 +476,7 @@ extension LLBuildManifestBuilder { } for binaryPath in target.libraryBinaryPaths { - let path = self.destinationPath(forBinaryAt: binaryPath) + let path = target.buildParameters.destinationPath(forBinaryAt: binaryPath) if self.fileSystem.isDirectory(binaryPath) { inputs.append(directory: path) } else { @@ -482,7 +488,7 @@ extension LLBuildManifestBuilder { // Depend on any required macro product's output. try target.requiredMacroProducts.forEach { macro in - try inputs.append(.virtual(macro.getLLBuildTargetName(config: buildConfig))) + try inputs.append(.virtual(macro.getLLBuildTargetName(config: target.buildParameters.buildConfig))) } return inputs @@ -491,7 +497,7 @@ extension LLBuildManifestBuilder { /// Adds a top-level phony command that builds the entire target. private func addTargetCmd(_ target: SwiftTargetBuildDescription, cmdOutputs: [Node]) { // Create a phony node to represent the entire target. - let targetName = target.target.getLLBuildTargetName(config: self.buildConfig) + let targetName = target.target.getLLBuildTargetName(config: target.buildParameters.buildConfig) let targetOutput: Node = .virtual(targetName) self.manifest.addNode(targetOutput, toTarget: targetName) @@ -500,7 +506,7 @@ extension LLBuildManifestBuilder { inputs: cmdOutputs, outputs: [targetOutput] ) - if self.plan.graph.isInRootPackages(target.target, satisfying: self.buildEnvironment) { + if self.plan.graph.isInRootPackages(target.target, satisfying: target.buildParameters.buildEnvironment) { if !target.isTestTarget { self.addNode(targetOutput, toTarget: .main) } @@ -510,13 +516,13 @@ extension LLBuildManifestBuilder { private func addModuleWrapCmd(_ target: SwiftTargetBuildDescription) throws { // Add commands to perform the module wrapping Swift modules when debugging strategy is `modulewrap`. - guard self.buildParameters.debuggingStrategy == .modulewrap else { return } + guard target.buildParameters.debuggingStrategy == .modulewrap else { return } var moduleWrapArgs = [ target.buildParameters.toolchain.swiftCompilerPath.pathString, "-modulewrap", target.moduleOutputPath.pathString, "-o", target.wrappedModuleOutputPath.pathString, ] - moduleWrapArgs += try self.buildParameters.targetTripleArgs(for: target.target) + moduleWrapArgs += try target.buildParameters.targetTripleArgs(for: target.target) self.manifest.addShellCmd( name: target.wrappedModuleOutputPath.pathString, description: "Wrapping AST for \(target.target.name) for debugging", diff --git a/Sources/Build/BuildManifest/LLBuildManifestBuilder.swift b/Sources/Build/BuildManifest/LLBuildManifestBuilder.swift index dadf574ec80..c6688955ebc 100644 --- a/Sources/Build/BuildManifest/LLBuildManifestBuilder.swift +++ b/Sources/Build/BuildManifest/LLBuildManifestBuilder.swift @@ -65,8 +65,10 @@ public class LLBuildManifestBuilder { public internal(set) var manifest: LLBuildManifest = .init() - var buildConfig: String { self.buildParameters.configuration.dirname } + @available(*, deprecated, message: "use `productsBuildParameters` or `toolsBuildParameters` on `self.plan` instead") var buildParameters: BuildParameters { self.plan.buildParameters } + + @available(*, deprecated, message: "use `productsBuildParameters` or `toolsBuildParameters` on `self.plan` instead") var buildEnvironment: BuildEnvironment { self.buildParameters.buildEnvironment } /// Mapping from Swift compiler path to Swift get version files. @@ -98,7 +100,7 @@ public class LLBuildManifestBuilder { addPackageStructureCommand() addBinaryDependencyCommands() - if self.buildParameters.driverParameters.useExplicitModuleBuild { + if self.plan.productsBuildParameters.driverParameters.useExplicitModuleBuild { // Explicit module builds use the integrated driver directly and // require that every target's build jobs specify its dependencies explicitly to plan // its build. @@ -117,7 +119,7 @@ public class LLBuildManifestBuilder { } } - if self.buildParameters.testingParameters.library == .xctest { + if self.plan.productsBuildParameters.testingParameters.library == .xctest { try self.addTestDiscoveryGenerationCommand() } try self.addTestEntryPointGenerationCommand() @@ -181,10 +183,16 @@ extension LLBuildManifestBuilder { extension LLBuildManifestBuilder { // Creates commands for copying all binary artifacts depended on in the plan. private func addBinaryDependencyCommands() { - let binaryPaths = Set(plan.targetMap.values.flatMap(\.libraryBinaryPaths)) - for binaryPath in binaryPaths { - let destination = destinationPath(forBinaryAt: binaryPath) - addCopyCommand(from: binaryPath, to: destination) + // Make sure we don't have multiple copy commands for each destination by mapping each destination to + // its source binary. + var destinations = [AbsolutePath: AbsolutePath]() + for target in self.plan.targetMap.values { + for binaryPath in target.libraryBinaryPaths { + destinations[target.buildParameters.destinationPath(forBinaryAt: binaryPath)] = binaryPath + } + } + for (destination, source) in destinations { + self.addCopyCommand(from: source, to: destination) } } } @@ -268,7 +276,9 @@ extension LLBuildManifestBuilder { let outputs = testEntryPointTarget.target.sources.paths - let mainFileName = TestEntryPointTool.mainFileName(for: buildParameters.testingParameters.library) + let mainFileName = TestEntryPointTool.mainFileName( + for: self.plan.productsBuildParameters.testingParameters.library + ) guard let mainOutput = (outputs.first { $0.basename == mainFileName }) else { throw InternalError("main output (\(mainFileName)) not found") } @@ -353,10 +363,15 @@ extension LLBuildManifestBuilder { self.manifest.addCopyCmd(name: destination.pathString, inputs: [inputNode], outputs: [outputNode]) return (inputNode, outputNode) } +} +extension BuildParameters { func destinationPath(forBinaryAt path: AbsolutePath) -> AbsolutePath { - self.plan.buildParameters.buildPath.appending(component: path.basename) + self.buildPath.appending(component: path.basename) } + + var buildConfig: String { self.configuration.dirname } + } extension Sequence where Element: Hashable { From 172055ca6d8b83f20c4f026b9c67564316d1d013 Mon Sep 17 00:00:00 2001 From: Max Desiatov Date: Wed, 6 Dec 2023 15:42:46 +0000 Subject: [PATCH 05/33] Remove unused deprecated properties and functions --- .../LLBuildManifestBuilder.swift | 6 ----- Sources/Build/BuildOperation.swift | 4 --- ...dOperationBuildSystemDelegateHandler.swift | 4 --- Sources/Build/BuildPlan/BuildPlan.swift | 9 ------- Sources/CoreCommands/SwiftTool.swift | 8 +----- .../BuildParameters/BuildParameters.swift | 26 ------------------- 6 files changed, 1 insertion(+), 56 deletions(-) diff --git a/Sources/Build/BuildManifest/LLBuildManifestBuilder.swift b/Sources/Build/BuildManifest/LLBuildManifestBuilder.swift index c6688955ebc..6cf498b4851 100644 --- a/Sources/Build/BuildManifest/LLBuildManifestBuilder.swift +++ b/Sources/Build/BuildManifest/LLBuildManifestBuilder.swift @@ -65,12 +65,6 @@ public class LLBuildManifestBuilder { public internal(set) var manifest: LLBuildManifest = .init() - @available(*, deprecated, message: "use `productsBuildParameters` or `toolsBuildParameters` on `self.plan` instead") - var buildParameters: BuildParameters { self.plan.buildParameters } - - @available(*, deprecated, message: "use `productsBuildParameters` or `toolsBuildParameters` on `self.plan` instead") - var buildEnvironment: BuildEnvironment { self.buildParameters.buildEnvironment } - /// Mapping from Swift compiler path to Swift get version files. var swiftGetVersionFiles = [AbsolutePath: AbsolutePath]() diff --git a/Sources/Build/BuildOperation.swift b/Sources/Build/BuildOperation.swift index 5624d4d4e3d..d532d8caac0 100644 --- a/Sources/Build/BuildOperation.swift +++ b/Sources/Build/BuildOperation.swift @@ -42,10 +42,6 @@ public final class BuildOperation: PackageStructureDelegate, SPMBuildCore.BuildS /// The delegate used by the build system. public weak var delegate: SPMBuildCore.BuildSystemDelegate? - /// Build parameters for products - @available(*, deprecated, renamed: "productsBuildParameters") - public var buildParameters: BuildParameters { self.productsBuildParameters } - /// Build parameters for products. let productsBuildParameters: BuildParameters diff --git a/Sources/Build/BuildOperationBuildSystemDelegateHandler.swift b/Sources/Build/BuildOperationBuildSystemDelegateHandler.swift index b8d69d42435..17c2e026bdc 100644 --- a/Sources/Build/BuildOperationBuildSystemDelegateHandler.swift +++ b/Sources/Build/BuildOperationBuildSystemDelegateHandler.swift @@ -434,10 +434,6 @@ public protocol BuildErrorAdviceProvider { /// The context available during build execution. public final class BuildExecutionContext { - /// Build parameters for products. - @available(*, deprecated, message: "use either `productsBuildParameters` or `toolsBuildParameters`") - var buildParameters: BuildParameters { self.productsBuildParameters } - /// Build parameters for products. let productsBuildParameters: BuildParameters diff --git a/Sources/Build/BuildPlan/BuildPlan.swift b/Sources/Build/BuildPlan/BuildPlan.swift index 4697c43ca44..ac3fd0f5604 100644 --- a/Sources/Build/BuildPlan/BuildPlan.swift +++ b/Sources/Build/BuildPlan/BuildPlan.swift @@ -178,9 +178,6 @@ public class BuildPlan: SPMBuildCore.BuildPlan { } } - @available(*, deprecated, message: "use either `productsBuildParameters` or `toolsBuildParameters`") - public var buildParameters: BuildParameters { self.productsBuildParameters } - /// Build parameters used for products. public let productsBuildParameters: BuildParameters @@ -197,12 +194,6 @@ public class BuildPlan: SPMBuildCore.BuildPlan { self.buildParameters(for: product).triple } - /// The build environment. - @available(*, deprecated, message: "Use `buildParameters(for:)` to get build parameters instead") - var buildEnvironment: BuildEnvironment { - self.buildParameters.buildEnvironment - } - /// The package graph. public let graph: PackageGraph diff --git a/Sources/CoreCommands/SwiftTool.swift b/Sources/CoreCommands/SwiftTool.swift index cc6695a60ba..bed39798637 100644 --- a/Sources/CoreCommands/SwiftTool.swift +++ b/Sources/CoreCommands/SwiftTool.swift @@ -755,14 +755,8 @@ public final class SwiftTool { } } - /// Return the build parameters. - @available(*, deprecated, renamed: "productsBuildParameters") - public func buildParameters() throws -> BuildParameters { - try _productsBuildParameters.get() - } - private lazy var _productsBuildParameters: Result = { - return Result(catching: { + Result(catching: { try _buildParams(toolchain: self.getTargetToolchain()) }) }() diff --git a/Sources/SPMBuildCore/BuildParameters/BuildParameters.swift b/Sources/SPMBuildCore/BuildParameters/BuildParameters.swift index 9021f05cc27..55afe90922d 100644 --- a/Sources/SPMBuildCore/BuildParameters/BuildParameters.swift +++ b/Sources/SPMBuildCore/BuildParameters/BuildParameters.swift @@ -188,32 +188,6 @@ public struct BuildParameters: Encodable { self.testingParameters = testingParameters ?? .init(configuration: configuration, targetTriple: triple) } - @available(*, deprecated, message: "Use build parameters value separately created at a higher value instead") - public func forTriple(_ targetTriple: Triple) throws -> BuildParameters { - var hostSDK = try SwiftSDK.hostSwiftSDK() - hostSDK.targetTriple = targetTriple - - return try .init( - dataPath: self.dataPath.parentDirectory.appending(components: ["plugins", "tools"]), - configuration: self.configuration, - toolchain: try UserToolchain(swiftSDK: hostSDK), - triple: nil, - flags: BuildFlags(), - pkgConfigDirectories: self.pkgConfigDirectories, - architectures: nil, - workers: self.workers, - shouldCreateDylibForDynamicProducts: self.shouldCreateDylibForDynamicProducts, - sanitizers: self.sanitizers, - indexStoreMode: self.indexStoreMode, - isXcodeBuildSystemEnabled: self.isXcodeBuildSystemEnabled, - shouldSkipBuilding: self.shouldSkipBuilding, - driverParameters: self.driverParameters, - linkingParameters: self.linkingParameters, - outputParameters: self.outputParameters, - testingParameters: self.testingParameters - ) - } - /// The path to the build directory (inside the data directory). public var buildPath: AbsolutePath { if isXcodeBuildSystemEnabled { From 7592888e45187fc7815ec097ac09ec1dff9a2d4a Mon Sep 17 00:00:00 2001 From: Max Desiatov Date: Wed, 6 Dec 2023 16:14:11 +0000 Subject: [PATCH 06/33] Deprecate old `BuildPlan` initializer with no `BuildParameters` distinction --- .../SwiftTargetBuildDescription.swift | 7 +++--- Sources/Build/BuildOperation.swift | 4 ++-- Sources/Build/BuildPlan/BuildPlan.swift | 3 +-- Tests/BuildTests/BuildPlanTests.swift | 23 +++++++++++++++++++ Tests/CommandsTests/SwiftToolTests.swift | 3 ++- 5 files changed, 31 insertions(+), 9 deletions(-) diff --git a/Sources/Build/BuildDescription/SwiftTargetBuildDescription.swift b/Sources/Build/BuildDescription/SwiftTargetBuildDescription.swift index 7bc502518a0..0236d68766a 100644 --- a/Sources/Build/BuildDescription/SwiftTargetBuildDescription.swift +++ b/Sources/Build/BuildDescription/SwiftTargetBuildDescription.swift @@ -105,11 +105,10 @@ public final class SwiftTargetBuildDescription { /// The path to the swiftmodule file after compilation. var moduleOutputPath: AbsolutePath { + let triple = buildParameters.triple // If we're an executable and we're not allowing test targets to link against us, we hide the module. - let allowLinkingAgainstExecutables = ( - self.buildParameters.triple.isDarwin() || - self.buildParameters.triple.isLinux() || - self.buildParameters.triple.isWindows()) && self.toolsVersion >= .v5_5 + let allowLinkingAgainstExecutables = (triple.isDarwin() || triple.isLinux() || triple.isWindows()) && + self.toolsVersion >= .v5_5 let dirPath = (target.type == .executable && !allowLinkingAgainstExecutables) ? self.tempsPath : self .buildParameters.buildPath return dirPath.appending(component: self.target.c99name + ".swiftmodule") diff --git a/Sources/Build/BuildOperation.swift b/Sources/Build/BuildOperation.swift index d532d8caac0..f109883842b 100644 --- a/Sources/Build/BuildOperation.swift +++ b/Sources/Build/BuildOperation.swift @@ -412,7 +412,7 @@ public final class BuildOperation: PackageStructureDelegate, SPMBuildCore.BuildS } /// Compute the llbuild target name using the given subset. - func computeLLBuildTargetName(for subset: BuildSubset) throws -> String { + private func computeLLBuildTargetName(for subset: BuildSubset) throws -> String { switch subset { case .allExcludingTests: return LLBuildManifestBuilder.TargetKind.main.targetName @@ -423,7 +423,7 @@ public final class BuildOperation: PackageStructureDelegate, SPMBuildCore.BuildS let graph = try getPackageGraph() if let result = subset.llbuildTargetName( for: graph, - config: productsBuildParameters.configuration.dirname, + config: self.productsBuildParameters.configuration.dirname, observabilityScope: self.observabilityScope ) { return result diff --git a/Sources/Build/BuildPlan/BuildPlan.swift b/Sources/Build/BuildPlan/BuildPlan.swift index ac3fd0f5604..e916abb2981 100644 --- a/Sources/Build/BuildPlan/BuildPlan.swift +++ b/Sources/Build/BuildPlan/BuildPlan.swift @@ -241,8 +241,7 @@ public class BuildPlan: SPMBuildCore.BuildPlan { /// ObservabilityScope with which to emit diagnostics let observabilityScope: ObservabilityScope - /// Create a build plan with a package graph and same build parameters for products and tools. Provided for - /// testing purposes only. + @available(*, deprecated, renamed: "init(productsBuildParameters:toolsBuildParameters:graph:)") public convenience init( buildParameters: BuildParameters, graph: PackageGraph, diff --git a/Tests/BuildTests/BuildPlanTests.swift b/Tests/BuildTests/BuildPlanTests.swift index d6a8d675d49..f940a635b47 100644 --- a/Tests/BuildTests/BuildPlanTests.swift +++ b/Tests/BuildTests/BuildPlanTests.swift @@ -33,6 +33,29 @@ extension Build.BuildPlan { let buildConfigurationComponent = buildParameters.buildEnvironment.configuration == .release ? "release" : "debug" return buildParameters.dataPath.appending(components: buildConfigurationComponent) } + + /// Create a build plan with a package graph and same build parameters for products and tools. Provided for + /// testing purposes only. + convenience init( + buildParameters: BuildParameters, + graph: PackageGraph, + additionalFileRules: [FileRuleDescription] = [], + buildToolPluginInvocationResults: [ResolvedTarget: [BuildToolPluginInvocationResult]] = [:], + prebuildCommandResults: [ResolvedTarget: [PrebuildCommandResult]] = [:], + fileSystem: any FileSystem, + observabilityScope: ObservabilityScope + ) throws { + try self.init( + productsBuildParameters: buildParameters, + toolsBuildParameters: buildParameters, + graph: graph, + additionalFileRules: additionalFileRules, + buildToolPluginInvocationResults: buildToolPluginInvocationResults, + prebuildCommandResults: prebuildCommandResults, + fileSystem: fileSystem, + observabilityScope: observabilityScope + ) + } } final class BuildPlanTests: XCTestCase { diff --git a/Tests/CommandsTests/SwiftToolTests.swift b/Tests/CommandsTests/SwiftToolTests.swift index 098f9d237ef..cc5c291de0e 100644 --- a/Tests/CommandsTests/SwiftToolTests.swift +++ b/Tests/CommandsTests/SwiftToolTests.swift @@ -270,7 +270,8 @@ final class SwiftToolTests: CommandsTestCase { let explicitCodeView = try SwiftTool.createSwiftToolForTest(options: explicitCodeViewOptions) plan = try BuildPlan( - buildParameters: explicitCodeView.productsBuildParameters, + productsBuildParameters: explicitCodeView.productsBuildParameters, + toolsBuildParameters: explicitCodeView.productsBuildParameters, graph: graph, fileSystem: fs, observabilityScope: observer.topScope From 0fee29a59ff1ff9c2bb995c32b710b3b3f0dfbc3 Mon Sep 17 00:00:00 2001 From: Max Desiatov Date: Wed, 6 Dec 2023 16:17:54 +0000 Subject: [PATCH 07/33] Clean up formattin --- Sources/Build/BuildManifest/LLBuildManifestBuilder.swift | 1 - Sources/Build/BuildOperation.swift | 7 ++++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/Sources/Build/BuildManifest/LLBuildManifestBuilder.swift b/Sources/Build/BuildManifest/LLBuildManifestBuilder.swift index 6cf498b4851..d8c9235f92a 100644 --- a/Sources/Build/BuildManifest/LLBuildManifestBuilder.swift +++ b/Sources/Build/BuildManifest/LLBuildManifestBuilder.swift @@ -365,7 +365,6 @@ extension BuildParameters { } var buildConfig: String { self.configuration.dirname } - } extension Sequence where Element: Hashable { diff --git a/Sources/Build/BuildOperation.swift b/Sources/Build/BuildOperation.swift index f109883842b..5e48f2a56a4 100644 --- a/Sources/Build/BuildOperation.swift +++ b/Sources/Build/BuildOperation.swift @@ -721,7 +721,12 @@ extension BuildOperation { } extension BuildDescription { - static func create(with plan: BuildPlan, disableSandboxForPluginCommands: Bool, fileSystem: Basics.FileSystem, observabilityScope: ObservabilityScope) throws -> (BuildDescription, LLBuildManifest) { + static func create( + with plan: BuildPlan, + disableSandboxForPluginCommands: Bool, + fileSystem: Basics.FileSystem, + observabilityScope: ObservabilityScope + ) throws -> (BuildDescription, LLBuildManifest) { // Generate the llbuild manifest. let llbuild = LLBuildManifestBuilder(plan, disableSandboxForPluginCommands: disableSandboxForPluginCommands, fileSystem: fileSystem, observabilityScope: observabilityScope) let buildManifest = try llbuild.generateManifest(at: plan.productsBuildParameters.llbuildManifest) From fc8e92cd97ee21a11d5647c696067ad131acb16c Mon Sep 17 00:00:00 2001 From: Max Desiatov Date: Wed, 6 Dec 2023 16:25:15 +0000 Subject: [PATCH 08/33] Fix Linux build issues in tests --- Tests/BuildTests/BuildPlanTests.swift | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/Tests/BuildTests/BuildPlanTests.swift b/Tests/BuildTests/BuildPlanTests.swift index f940a635b47..b205bcc2958 100644 --- a/Tests/BuildTests/BuildPlanTests.swift +++ b/Tests/BuildTests/BuildPlanTests.swift @@ -713,7 +713,7 @@ final class BuildPlanTests: XCTestCase { ] #elseif os(Windows) let linkArguments = [ - result.plan.buildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.productsBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "exe.exe").pathString, "-module-name", "exe", @@ -725,7 +725,7 @@ final class BuildPlanTests: XCTestCase { ] #else let linkArguments = [ - result.plan.buildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.productsBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "exe").pathString, "-module-name", "exe", @@ -1304,7 +1304,7 @@ final class BuildPlanTests: XCTestCase { ]) #elseif os(Windows) XCTAssertEqual(try result.buildProduct(for: "exe").linkArguments(), [ - result.plan.buildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.productsBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "exe.exe").pathString, "-module-name", "exe", @@ -1316,7 +1316,7 @@ final class BuildPlanTests: XCTestCase { ]) #else XCTAssertEqual(try result.buildProduct(for: "exe").linkArguments(), [ - result.plan.buildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.productsBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "exe").pathString, "-module-name", "exe", @@ -1486,7 +1486,7 @@ final class BuildPlanTests: XCTestCase { ]) #elseif os(Windows) XCTAssertEqual(try result.buildProduct(for: "exe").linkArguments(), [ - result.plan.buildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.productsBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "exe.exe").pathString, "-module-name", "exe", @@ -1498,7 +1498,7 @@ final class BuildPlanTests: XCTestCase { ]) #else XCTAssertEqual(try result.buildProduct(for: "exe").linkArguments(), [ - result.plan.buildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.productsBuildParameters.toolchain.swiftCompilerPath.pathString, "-lstdc++", "-L", buildPath.pathString, "-o", buildPath.appending(components: "exe").pathString, @@ -1628,7 +1628,7 @@ final class BuildPlanTests: XCTestCase { ]) #elseif os(Windows) XCTAssertEqual(try result.buildProduct(for: "exe").linkArguments(), [ - result.plan.buildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.productsBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "exe.exe").pathString, "-module-name", "exe", @@ -1639,7 +1639,7 @@ final class BuildPlanTests: XCTestCase { ]) #else XCTAssertEqual(try result.buildProduct(for: "exe").linkArguments(), [ - result.plan.buildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.productsBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "exe").pathString, "-module-name", "exe", @@ -1865,7 +1865,7 @@ final class BuildPlanTests: XCTestCase { ]) #elseif os(Windows) XCTAssertEqual(try result.buildProduct(for: "PkgPackageTests").linkArguments(), [ - result.plan.buildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.productsBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "PkgPackageTests.xctest").pathString, "-module-name", "PkgPackageTests", @@ -1876,7 +1876,7 @@ final class BuildPlanTests: XCTestCase { ]) #else XCTAssertEqual(try result.buildProduct(for: "PkgPackageTests").linkArguments(), [ - result.plan.buildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.productsBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "PkgPackageTests.xctest").pathString, "-module-name", "PkgPackageTests", From 38ffcae36a880bbae6c7179b0c7d1d218368f910 Mon Sep 17 00:00:00 2001 From: Max Desiatov Date: Thu, 23 Nov 2023 18:37:30 +0000 Subject: [PATCH 09/33] Support macros when cross-compiling ### Motivation: Not supporting macros in cross-compilation is a major limitation, especially for libraries like https://github.com/apple/swift-mmio. ### Modifications: Added `enum BuildTriple { case buildTools, buildProducts }` and `var buildTriple: BuildTriple` on `ResolvedTarget` and `ResolvedProduct`. Corresponding value is assigned to this property depending on target and product type: `buildTools` for macros, plugins, and their dependencies, `buildProducts` for everything else (the default). Based on this property we can choose between `buildParameters.hostTriple` and `buildParameters.targetTriple` during build plan construction. ### Result: Resolves https://github.com/apple/swift-package-manager/issues/6950 Resolves rdar://105991372 --- .../ClangTargetBuildDescription.swift | 11 ++++-- .../ProductBuildDescription.swift | 7 +++- .../SwiftTargetBuildDescription.swift | 9 ++++- Sources/Build/BuildPlan/BuildPlan.swift | 28 +++++++++++++ .../Utilities/SymbolGraphExtract.swift | 2 +- .../PackageGraph/PackageGraph+Loading.swift | 39 ++++++++++++++----- .../Resolution/ResolvedProduct.swift | 3 +- .../Resolution/ResolvedTarget.swift | 8 +++- Sources/PackageModel/Target/Target.swift | 2 +- .../BuildParameters/BuildParameters.swift | 4 +- 10 files changed, 90 insertions(+), 23 deletions(-) diff --git a/Sources/Build/BuildDescription/ClangTargetBuildDescription.swift b/Sources/Build/BuildDescription/ClangTargetBuildDescription.swift index 81d0b2bd0bf..916e9c29ad7 100644 --- a/Sources/Build/BuildDescription/ClangTargetBuildDescription.swift +++ b/Sources/Build/BuildDescription/ClangTargetBuildDescription.swift @@ -50,12 +50,12 @@ public final class ClangTargetBuildDescription { /// Path to the bundle generated for this module (if any). var bundlePath: AbsolutePath? { - guard !resources.isEmpty else { + guard !self.resources.isEmpty else { return .none } if let bundleName = target.underlyingTarget.potentialBundleName { - return self.buildParameters.bundlePath(named: bundleName) + return self.buildParameters.bundlePath(named: bundleName, target: self.target) } else { return .none } @@ -105,6 +105,11 @@ public final class ClangTargetBuildDescription { target.type == .test } + /// Triple for which this target is compiled. + private var buildTriple: Triple { + self.buildParameters.buildTriple(for: self.target) + } + /// The results of applying any build tool plugins to this target. public let buildToolPluginInvocationResults: [BuildToolPluginInvocationResult] @@ -219,7 +224,7 @@ public final class ClangTargetBuildDescription { if self.buildParameters.triple.isDarwin() { args += ["-fobjc-arc"] } - args += try buildParameters.targetTripleArgs(for: target) + args += try self.buildParameters.buildTripleArgs(for: target) args += optimizationArguments args += activeCompilationConditions diff --git a/Sources/Build/BuildDescription/ProductBuildDescription.swift b/Sources/Build/BuildDescription/ProductBuildDescription.swift index 23e9ea21293..d6f5d86707d 100644 --- a/Sources/Build/BuildDescription/ProductBuildDescription.swift +++ b/Sources/Build/BuildDescription/ProductBuildDescription.swift @@ -68,6 +68,11 @@ public final class ProductBuildDescription: SPMBuildCore.ProductBuildDescription self.tempsPath.appending("Objects.LinkFileList") } + /// Triple for which this product is compiled. + var buildTriple: Triple { + self.buildParameters.buildTriple(for: self.product) + } + /// File system reference. private let fileSystem: FileSystem @@ -310,7 +315,7 @@ public final class ProductBuildDescription: SPMBuildCore.ProductBuildDescription // setting is the package-level right now. We might need to figure out a better // answer for libraries if/when we support specifying deployment target at the // target-level. - args += try self.buildParameters.targetTripleArgs(for: self.product.targets[0]) + args += try self.buildParameters.buildTripleArgs(for: self.product.targets[0]) // Add arguments from declared build settings. args += self.buildSettingsFlags diff --git a/Sources/Build/BuildDescription/SwiftTargetBuildDescription.swift b/Sources/Build/BuildDescription/SwiftTargetBuildDescription.swift index 0236d68766a..07e9d5882df 100644 --- a/Sources/Build/BuildDescription/SwiftTargetBuildDescription.swift +++ b/Sources/Build/BuildDescription/SwiftTargetBuildDescription.swift @@ -58,7 +58,7 @@ public final class SwiftTargetBuildDescription { /// Path to the bundle generated for this module (if any). var bundlePath: AbsolutePath? { if let bundleName = target.underlyingTarget.potentialBundleName, needsResourceBundle { - return self.buildParameters.bundlePath(named: bundleName) + return self.buildParameters.bundlePath(named: bundleName, target: self.target) } else { return .none } @@ -102,6 +102,11 @@ public final class SwiftTargetBuildDescription { } } } + + /// Triple for which this target is compiled. + private var buildTriple: Triple { + self.buildParameters.buildTriple(for: self.target) + } /// The path to the swiftmodule file after compilation. var moduleOutputPath: AbsolutePath { @@ -457,7 +462,7 @@ public final class SwiftTargetBuildDescription { /// The arguments needed to compile this target. public func compileArguments() throws -> [String] { var args = [String]() - args += try self.buildParameters.targetTripleArgs(for: self.target) + args += try self.buildParameters.buildTripleArgs(for: self.target) args += ["-swift-version", self.swiftVersion.rawValue] // pass `-v` during verbose builds. diff --git a/Sources/Build/BuildPlan/BuildPlan.swift b/Sources/Build/BuildPlan/BuildPlan.swift index e916abb2981..062b8f8b336 100644 --- a/Sources/Build/BuildPlan/BuildPlan.swift +++ b/Sources/Build/BuildPlan/BuildPlan.swift @@ -127,8 +127,34 @@ extension BuildParameters { return [] } + /// Triple for which this target is compiled. + func buildTriple(for target: ResolvedTarget) -> Basics.Triple { + switch target.buildTriple { + case .buildTools: + return self.hostTriple + case .buildProducts: + return self.targetTriple + } + } + + /// Triple for which this target is compiled. + func buildTriple(for product: ResolvedProduct) -> Basics.Triple { + switch product.buildTriple { + case .buildTools: + return self.hostTriple + case .buildProducts: + return self.targetTriple + } + } + /// Computes the target triple arguments for a given resolved target. + @available(*, deprecated, renamed: "buildTripleArgs(for:)") public func targetTripleArgs(for target: ResolvedTarget) throws -> [String] { + try buildTripleArgs(for: target) + } + + public func buildTripleArgs(for target: ResolvedTarget) throws -> [String] { + // confusingly enough this is the triple argument, not the target argument var args = ["-target"] // Compute the triple string for Darwin platform using the platform version. @@ -144,6 +170,8 @@ extension BuildParameters { /// Computes the linker flags to use in order to rename a module-named main function to 'main' for the target platform, or nil if the linker doesn't support it for the platform. func linkerFlagsForRenamingMainFunction(of target: ResolvedTarget) -> [String]? { + let buildTriple = buildTriple(for: target) + let args: [String] if self.triple.isApple() { args = ["-alias", "_\(target.c99name)_main", "_main"] diff --git a/Sources/Commands/Utilities/SymbolGraphExtract.swift b/Sources/Commands/Utilities/SymbolGraphExtract.swift index f9423384c9b..030e4577e18 100644 --- a/Sources/Commands/Utilities/SymbolGraphExtract.swift +++ b/Sources/Commands/Utilities/SymbolGraphExtract.swift @@ -66,7 +66,7 @@ public struct SymbolGraphExtract { // Construct arguments for extracting symbols for a single target. var commandLine = [self.tool.pathString] commandLine += ["-module-name", target.c99name] - commandLine += try buildParameters.targetTripleArgs(for: target) + commandLine += try buildParameters.buildTripleArgs(for: target) commandLine += try buildPlan.createAPIToolCommonArgs(includeLibrarySearchPaths: true) commandLine += ["-module-cache-path", try buildParameters.moduleCache.pathString] if verboseOutput { diff --git a/Sources/PackageGraph/PackageGraph+Loading.swift b/Sources/PackageGraph/PackageGraph+Loading.swift index 5fe6b21ec30..91ecb435831 100644 --- a/Sources/PackageGraph/PackageGraph+Loading.swift +++ b/Sources/PackageGraph/PackageGraph+Loading.swift @@ -798,7 +798,7 @@ private func resolveModuleAliases(packageBuilders: [ResolvedPackageBuilder], // Validate sources (Swift files only) for modules being aliased. // Needs to be done after `propagateAliases` since aliases defined - // upstream can be overriden. + // upstream can be overridden. for packageBuilder in packageBuilders { for product in packageBuilder.package.products { try aliasTracker.validateAndApplyAliases(product: product, @@ -890,6 +890,8 @@ private final class ResolvedTargetBuilder: ResolvedBuilder { /// The platforms supported by this package. var platforms: SupportedPlatforms = .init(declared: [], derivedXCTestPlatformProvider: .none) + private var buildTriple: BuildTriple + init( target: Target, observabilityScope: ObservabilityScope @@ -900,6 +902,7 @@ private final class ResolvedTargetBuilder: ResolvedBuilder { metadata.targetName = target.name return metadata } + self.buildTriple = target.isBuildTool ? .buildTools : .buildProducts } func diagnoseInvalidUseOfUnsafeFlags(_ product: ResolvedProduct) throws { @@ -916,6 +919,7 @@ private final class ResolvedTargetBuilder: ResolvedBuilder { switch dependency { case .target(let targetBuilder, let conditions): try self.target.validateDependency(target: targetBuilder.target) + targetBuilder.buildTriple = .buildTools return .target(try targetBuilder.construct(), conditions: conditions) case .product(let productBuilder, let conditions): try self.target.validateDependency( @@ -934,23 +938,38 @@ private final class ResolvedTargetBuilder: ResolvedBuilder { target: self.target, dependencies: dependencies, defaultLocalization: self.defaultLocalization, - platforms: self.platforms + platforms: self.platforms, + buildTriple: self.buildTriple ) } } extension Target { + var isBuildTool: Bool { + type == .macro || type == .plugin + } - func validateDependency(target: Target) throws { - if self.type == .plugin && target.type == .library { - throw PackageGraphError.unsupportedPluginDependency(targetName: self.name, dependencyName: target.name, dependencyType: target.type.rawValue, dependencyPackage: nil) + func validateDependency(target: Target) throws { + if self.type == .plugin && target.type == .library { + throw PackageGraphError.unsupportedPluginDependency( + targetName: self.name, + dependencyName: target.name, + dependencyType: target.type.rawValue, + dependencyPackage: nil + ) + } } - } - func validateDependency(product: Product, productPackage: PackageIdentity) throws { - if self.type == .plugin && product.type.isLibrary { - throw PackageGraphError.unsupportedPluginDependency(targetName: self.name, dependencyName: product.name, dependencyType: product.type.description, dependencyPackage: productPackage.description) + + func validateDependency(product: Product, productPackage: PackageIdentity) throws { + if self.type == .plugin && product.type.isLibrary { + throw PackageGraphError.unsupportedPluginDependency( + targetName: self.name, + dependencyName: product.name, + dependencyType: product.type.description, + dependencyPackage: productPackage.description + ) + } } - } } /// Builder for resolved package. private final class ResolvedPackageBuilder: ResolvedBuilder { diff --git a/Sources/PackageGraph/Resolution/ResolvedProduct.swift b/Sources/PackageGraph/Resolution/ResolvedProduct.swift index 8fd38f8302a..8cc91e86106 100644 --- a/Sources/PackageGraph/Resolution/ResolvedProduct.swift +++ b/Sources/PackageGraph/Resolution/ResolvedProduct.swift @@ -57,10 +57,11 @@ public final class ResolvedProduct { } } - public init(product: Product, targets: [ResolvedTarget]) { + public init(product: Product, targets: [ResolvedTarget], buildTriple: BuildTriple = .buildProducts) { assert(product.targets.count == targets.count && product.targets.map({ $0.name }) == targets.map({ $0.name })) self.underlyingProduct = product self.targets = targets + self.buildTriple = buildTriple // defaultLocalization is currently shared across the entire package // this may need to be enhanced if / when we support localization per target or product diff --git a/Sources/PackageGraph/Resolution/ResolvedTarget.swift b/Sources/PackageGraph/Resolution/ResolvedTarget.swift index c1e8dca1b36..7f72a278870 100644 --- a/Sources/PackageGraph/Resolution/ResolvedTarget.swift +++ b/Sources/PackageGraph/Resolution/ResolvedTarget.swift @@ -70,6 +70,9 @@ public final class ResolvedTarget { } } + /// Triple for which this resolved target should be compiled for. + public let buildTriple: BuildTriple + /// The underlying target represented in this resolved target. public let underlyingTarget: Target @@ -149,13 +152,14 @@ public final class ResolvedTarget { target: Target, dependencies: [Dependency], defaultLocalization: String?, - platforms: SupportedPlatforms + platforms: SupportedPlatforms, + buildTriple: BuildTriple = .buildProducts ) { self.underlyingTarget = target self.dependencies = dependencies self.defaultLocalization = defaultLocalization self.platforms = platforms - self.buildTriple = .buildProducts + self.buildTriple = buildTriple } } diff --git a/Sources/PackageModel/Target/Target.swift b/Sources/PackageModel/Target/Target.swift index faf1bb5cda0..55f8c29b93b 100644 --- a/Sources/PackageModel/Target/Target.swift +++ b/Sources/PackageModel/Target/Target.swift @@ -132,7 +132,7 @@ public class Target: PolymorphicCodableProtocol { /// The name of the target. /// /// NOTE: This name is not the language-level target (i.e., the importable - /// name) name in many cases, instead use c99name if you need uniqueness. + /// name) name in many cases, instead use ``Target/c99name`` if you need uniqueness. public private(set) var name: String /// Module aliases needed to build this target. The key is an original name of a diff --git a/Sources/SPMBuildCore/BuildParameters/BuildParameters.swift b/Sources/SPMBuildCore/BuildParameters/BuildParameters.swift index 55afe90922d..d80832abd40 100644 --- a/Sources/SPMBuildCore/BuildParameters/BuildParameters.swift +++ b/Sources/SPMBuildCore/BuildParameters/BuildParameters.swift @@ -249,7 +249,7 @@ public struct BuildParameters: Encodable { switch product.type { case .executable, .snippet: - return potentialExecutablePath + return try RelativePath(validating: "\(product.name)\(targetTriple.executableExtension)") case .library(.static): return try RelativePath(validating: "lib\(product.name)\(self.triple.staticLibraryExtension)") case .library(.dynamic): @@ -275,7 +275,7 @@ public struct BuildParameters: Encodable { #if BUILD_MACROS_AS_DYLIBS return try potentialDynamicLibraryPath(for: product) #else - return potentialExecutablePath + return try RelativePath(validating: "\(product.name)\(hostTriple.executableExtension)") #endif } } From 57e9c9d24dc01061fd6c7741154ddb6aaec5295f Mon Sep 17 00:00:00 2001 From: Max Desiatov Date: Wed, 6 Dec 2023 17:10:17 +0000 Subject: [PATCH 10/33] Fix build issues after rebase --- .../ClangTargetBuildDescription.swift | 7 +---- .../ProductBuildDescription.swift | 5 ---- .../SwiftTargetBuildDescription.swift | 7 +---- .../LLBuildManifestBuilder+Swift.swift | 2 +- Sources/Build/BuildPlan/BuildPlan.swift | 28 ------------------- .../Resolution/ResolvedProduct.swift | 2 -- .../Resolution/ResolvedTarget.swift | 3 -- .../BuildParameters/BuildParameters.swift | 4 +-- 8 files changed, 5 insertions(+), 53 deletions(-) diff --git a/Sources/Build/BuildDescription/ClangTargetBuildDescription.swift b/Sources/Build/BuildDescription/ClangTargetBuildDescription.swift index 916e9c29ad7..e51c9f2526b 100644 --- a/Sources/Build/BuildDescription/ClangTargetBuildDescription.swift +++ b/Sources/Build/BuildDescription/ClangTargetBuildDescription.swift @@ -55,7 +55,7 @@ public final class ClangTargetBuildDescription { } if let bundleName = target.underlyingTarget.potentialBundleName { - return self.buildParameters.bundlePath(named: bundleName, target: self.target) + return self.buildParameters.bundlePath(named: bundleName) } else { return .none } @@ -105,11 +105,6 @@ public final class ClangTargetBuildDescription { target.type == .test } - /// Triple for which this target is compiled. - private var buildTriple: Triple { - self.buildParameters.buildTriple(for: self.target) - } - /// The results of applying any build tool plugins to this target. public let buildToolPluginInvocationResults: [BuildToolPluginInvocationResult] diff --git a/Sources/Build/BuildDescription/ProductBuildDescription.swift b/Sources/Build/BuildDescription/ProductBuildDescription.swift index d6f5d86707d..3023243395e 100644 --- a/Sources/Build/BuildDescription/ProductBuildDescription.swift +++ b/Sources/Build/BuildDescription/ProductBuildDescription.swift @@ -68,11 +68,6 @@ public final class ProductBuildDescription: SPMBuildCore.ProductBuildDescription self.tempsPath.appending("Objects.LinkFileList") } - /// Triple for which this product is compiled. - var buildTriple: Triple { - self.buildParameters.buildTriple(for: self.product) - } - /// File system reference. private let fileSystem: FileSystem diff --git a/Sources/Build/BuildDescription/SwiftTargetBuildDescription.swift b/Sources/Build/BuildDescription/SwiftTargetBuildDescription.swift index 07e9d5882df..3f138202ba2 100644 --- a/Sources/Build/BuildDescription/SwiftTargetBuildDescription.swift +++ b/Sources/Build/BuildDescription/SwiftTargetBuildDescription.swift @@ -58,7 +58,7 @@ public final class SwiftTargetBuildDescription { /// Path to the bundle generated for this module (if any). var bundlePath: AbsolutePath? { if let bundleName = target.underlyingTarget.potentialBundleName, needsResourceBundle { - return self.buildParameters.bundlePath(named: bundleName, target: self.target) + return self.buildParameters.bundlePath(named: bundleName) } else { return .none } @@ -102,11 +102,6 @@ public final class SwiftTargetBuildDescription { } } } - - /// Triple for which this target is compiled. - private var buildTriple: Triple { - self.buildParameters.buildTriple(for: self.target) - } /// The path to the swiftmodule file after compilation. var moduleOutputPath: AbsolutePath { diff --git a/Sources/Build/BuildManifest/LLBuildManifestBuilder+Swift.swift b/Sources/Build/BuildManifest/LLBuildManifestBuilder+Swift.swift index 9e1eca0cb7e..337936271e3 100644 --- a/Sources/Build/BuildManifest/LLBuildManifestBuilder+Swift.swift +++ b/Sources/Build/BuildManifest/LLBuildManifestBuilder+Swift.swift @@ -522,7 +522,7 @@ extension LLBuildManifestBuilder { "-modulewrap", target.moduleOutputPath.pathString, "-o", target.wrappedModuleOutputPath.pathString, ] - moduleWrapArgs += try target.buildParameters.targetTripleArgs(for: target.target) + moduleWrapArgs += try target.buildParameters.buildTripleArgs(for: target.target) self.manifest.addShellCmd( name: target.wrappedModuleOutputPath.pathString, description: "Wrapping AST for \(target.target.name) for debugging", diff --git a/Sources/Build/BuildPlan/BuildPlan.swift b/Sources/Build/BuildPlan/BuildPlan.swift index 062b8f8b336..d3fe8848ba4 100644 --- a/Sources/Build/BuildPlan/BuildPlan.swift +++ b/Sources/Build/BuildPlan/BuildPlan.swift @@ -126,32 +126,6 @@ extension BuildParameters { } return [] } - - /// Triple for which this target is compiled. - func buildTriple(for target: ResolvedTarget) -> Basics.Triple { - switch target.buildTriple { - case .buildTools: - return self.hostTriple - case .buildProducts: - return self.targetTriple - } - } - - /// Triple for which this target is compiled. - func buildTriple(for product: ResolvedProduct) -> Basics.Triple { - switch product.buildTriple { - case .buildTools: - return self.hostTriple - case .buildProducts: - return self.targetTriple - } - } - - /// Computes the target triple arguments for a given resolved target. - @available(*, deprecated, renamed: "buildTripleArgs(for:)") - public func targetTripleArgs(for target: ResolvedTarget) throws -> [String] { - try buildTripleArgs(for: target) - } public func buildTripleArgs(for target: ResolvedTarget) throws -> [String] { // confusingly enough this is the triple argument, not the target argument @@ -170,8 +144,6 @@ extension BuildParameters { /// Computes the linker flags to use in order to rename a module-named main function to 'main' for the target platform, or nil if the linker doesn't support it for the platform. func linkerFlagsForRenamingMainFunction(of target: ResolvedTarget) -> [String]? { - let buildTriple = buildTriple(for: target) - let args: [String] if self.triple.isApple() { args = ["-alias", "_\(target.c99name)_main", "_main"] diff --git a/Sources/PackageGraph/Resolution/ResolvedProduct.swift b/Sources/PackageGraph/Resolution/ResolvedProduct.swift index 8cc91e86106..2679c2d4bc2 100644 --- a/Sources/PackageGraph/Resolution/ResolvedProduct.swift +++ b/Sources/PackageGraph/Resolution/ResolvedProduct.swift @@ -85,8 +85,6 @@ public final class ResolvedProduct { platforms: platforms ) } - - self.buildTriple = .buildProducts } /// True if this product contains Swift targets. diff --git a/Sources/PackageGraph/Resolution/ResolvedTarget.swift b/Sources/PackageGraph/Resolution/ResolvedTarget.swift index 7f72a278870..275498ede5a 100644 --- a/Sources/PackageGraph/Resolution/ResolvedTarget.swift +++ b/Sources/PackageGraph/Resolution/ResolvedTarget.swift @@ -70,9 +70,6 @@ public final class ResolvedTarget { } } - /// Triple for which this resolved target should be compiled for. - public let buildTriple: BuildTriple - /// The underlying target represented in this resolved target. public let underlyingTarget: Target diff --git a/Sources/SPMBuildCore/BuildParameters/BuildParameters.swift b/Sources/SPMBuildCore/BuildParameters/BuildParameters.swift index d80832abd40..15e7c91e25b 100644 --- a/Sources/SPMBuildCore/BuildParameters/BuildParameters.swift +++ b/Sources/SPMBuildCore/BuildParameters/BuildParameters.swift @@ -249,7 +249,7 @@ public struct BuildParameters: Encodable { switch product.type { case .executable, .snippet: - return try RelativePath(validating: "\(product.name)\(targetTriple.executableExtension)") + return potentialExecutablePath case .library(.static): return try RelativePath(validating: "lib\(product.name)\(self.triple.staticLibraryExtension)") case .library(.dynamic): @@ -275,7 +275,7 @@ public struct BuildParameters: Encodable { #if BUILD_MACROS_AS_DYLIBS return try potentialDynamicLibraryPath(for: product) #else - return try RelativePath(validating: "\(product.name)\(hostTriple.executableExtension)") + return try RelativePath(validating: "\(product.name)\(self.triple.executableExtension)") #endif } } From a1489109a087f291ee49f31d6e0a67ceb1caaa00 Mon Sep 17 00:00:00 2001 From: Max Desiatov Date: Fri, 15 Dec 2023 10:46:54 +0000 Subject: [PATCH 11/33] Clean up the diff --- Sources/SPMBuildCore/BuildParameters/BuildParameters.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/SPMBuildCore/BuildParameters/BuildParameters.swift b/Sources/SPMBuildCore/BuildParameters/BuildParameters.swift index 4aac240fb3c..cbc5cb5499c 100644 --- a/Sources/SPMBuildCore/BuildParameters/BuildParameters.swift +++ b/Sources/SPMBuildCore/BuildParameters/BuildParameters.swift @@ -278,7 +278,7 @@ public struct BuildParameters: Encodable { #if BUILD_MACROS_AS_DYLIBS return try potentialDynamicLibraryPath(for: product) #else - return try RelativePath(validating: "\(product.name)\(self.triple.executableExtension)") + return potentialExecutablePath #endif } } From e542e7a23c01eb74af0bde59b6777218a4ae6fcd Mon Sep 17 00:00:00 2001 From: Max Desiatov Date: Wed, 20 Dec 2023 17:58:54 +0000 Subject: [PATCH 12/33] Use `topologicalSort` with `Identifiable` on `ResolvedTarget` Fix fixes a serious performance regression introduced for deep target dependency graphs in https://github.com/apple/swift-package-manager/pull/7160. After converting `ResolvedTarget` to a value type, its synthesized `Hashable` conformance traversed the whole dependency tree multiple times when using `topologicalSort`. This made package resolution seemingly hang for packages that had a lot of nested target graphs. We already have an implementation of `topologicalSort` on `Identifiable`, thus we should use that instead. I've also added a performance test for this in `PackageGraphPerfTests` to prevent future regressions in this area. --- Sources/PackageGraph/GraphLoadingNode.swift | 4 + .../PackageGraph/PackageGraph+Loading.swift | 1 - .../Resolution/ResolvedTarget.swift | 22 ++--- .../SPMTestSupport/ResolvedTarget+Mock.swift | 42 +++++++++ .../PackageGraphPerfTests.swift | 20 +++- ...tTests.swift => ResolvedTargetTests.swift} | 94 +++++++------------ 6 files changed, 109 insertions(+), 74 deletions(-) create mode 100644 Sources/SPMTestSupport/ResolvedTarget+Mock.swift rename Tests/PackageGraphTests/{TargetTests.swift => ResolvedTargetTests.swift} (53%) diff --git a/Sources/PackageGraph/GraphLoadingNode.swift b/Sources/PackageGraph/GraphLoadingNode.swift index dc28a0d8652..7c66c751be7 100644 --- a/Sources/PackageGraph/GraphLoadingNode.swift +++ b/Sources/PackageGraph/GraphLoadingNode.swift @@ -51,3 +51,7 @@ extension GraphLoadingNode: CustomStringConvertible { } } } + +extension GraphLoadingNode: Identifiable { + public var id: PackageIdentity { self.identity } +} diff --git a/Sources/PackageGraph/PackageGraph+Loading.swift b/Sources/PackageGraph/PackageGraph+Loading.swift index 1e82171692f..46f1bae7fb8 100644 --- a/Sources/PackageGraph/PackageGraph+Loading.swift +++ b/Sources/PackageGraph/PackageGraph+Loading.swift @@ -15,7 +15,6 @@ import OrderedCollections import PackageLoading import PackageModel -import func TSCBasic.topologicalSort import func TSCBasic.bestMatch extension PackageGraph { diff --git a/Sources/PackageGraph/Resolution/ResolvedTarget.swift b/Sources/PackageGraph/Resolution/ResolvedTarget.swift index 63e53badfd0..ec0f83c584f 100644 --- a/Sources/PackageGraph/Resolution/ResolvedTarget.swift +++ b/Sources/PackageGraph/Resolution/ResolvedTarget.swift @@ -12,8 +12,6 @@ import PackageModel -import func TSCBasic.topologicalSort - /// Represents a fully resolved target. All the dependencies for this target are also stored as resolved. public struct ResolvedTarget: Hashable { /// Represents dependency of a resolved target. @@ -72,7 +70,7 @@ public struct ResolvedTarget: Hashable { /// The name of this target. public var name: String { - return underlying.name + self.underlying.name } /// Returns dependencies which satisfy the input build environment, based on their conditions. @@ -84,12 +82,12 @@ public struct ResolvedTarget: Hashable { /// Returns the recursive dependencies, across the whole package-graph. public func recursiveDependencies() throws -> [Dependency] { - return try TSCBasic.topologicalSort(self.dependencies) { $0.dependencies } + try topologicalSort(self.dependencies) { $0.dependencies } } /// Returns the recursive target dependencies, across the whole package-graph. public func recursiveTargetDependencies() throws -> [ResolvedTarget] { - return try TSCBasic.topologicalSort(self.dependencies) { $0.dependencies }.compactMap { $0.target } + try topologicalSort(self.dependencies) { $0.dependencies }.compactMap { $0.target } } /// Returns the recursive dependencies, across the whole package-graph, which satisfy the input build environment, @@ -97,36 +95,36 @@ public struct ResolvedTarget: Hashable { /// - Parameters: /// - environment: The build environment to use to filter dependencies on. public func recursiveDependencies(satisfying environment: BuildEnvironment) throws -> [Dependency] { - return try TSCBasic.topologicalSort(dependencies(satisfying: environment)) { dependency in - return dependency.dependencies.filter { $0.satisfies(environment) } + try topologicalSort(dependencies(satisfying: environment)) { dependency in + dependency.dependencies.filter { $0.satisfies(environment) } } } /// The language-level target name. public var c99name: String { - return underlying.c99name + self.underlying.c99name } /// Module aliases for dependencies of this target. The key is an /// original target name and the value is a new unique name mapped /// to the name of its .swiftmodule binary. public var moduleAliases: [String: String]? { - return underlying.moduleAliases + self.underlying.moduleAliases } /// Allows access to package symbols from other targets in the package public var packageAccess: Bool { - return underlying.packageAccess + self.underlying.packageAccess } /// The "type" of target. public var type: Target.Kind { - return underlying.type + self.underlying.type } /// The sources for the target. public var sources: Sources { - return underlying.sources + self.underlying.sources } let packageIdentity: PackageIdentity diff --git a/Sources/SPMTestSupport/ResolvedTarget+Mock.swift b/Sources/SPMTestSupport/ResolvedTarget+Mock.swift new file mode 100644 index 00000000000..0a95c7aa8e1 --- /dev/null +++ b/Sources/SPMTestSupport/ResolvedTarget+Mock.swift @@ -0,0 +1,42 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the Swift open source project +// +// Copyright (c) 2014-2017 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See http://swift.org/LICENSE.txt for license information +// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// + +import PackageGraph +import PackageModel + +extension ResolvedTarget { + public static func mock( + packageIdentity: PackageIdentity, + name: String, + deps: ResolvedTarget..., + conditions: [PackageCondition] = [] + ) -> ResolvedTarget { + ResolvedTarget( + packageIdentity: packageIdentity, + underlying: SwiftTarget( + name: name, + type: .library, + path: .root, + sources: Sources(paths: [], root: "/"), + dependencies: [], + packageAccess: false, + swiftVersion: .v4, + usesUnsafeFlags: false + ), + dependencies: deps.map { .target($0, conditions: conditions) }, + defaultLocalization: nil, + supportedPlatforms: [], + platformVersionProvider: .init(implementation: .minimumDeploymentTargetDefault) + ) + } +} + diff --git a/Tests/PackageGraphPerformanceTests/PackageGraphPerfTests.swift b/Tests/PackageGraphPerformanceTests/PackageGraphPerfTests.swift index 1b1c20ff25b..2016be310b3 100644 --- a/Tests/PackageGraphPerformanceTests/PackageGraphPerfTests.swift +++ b/Tests/PackageGraphPerformanceTests/PackageGraphPerfTests.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift open source project // -// Copyright (c) 2014-2017 Apple Inc. and the Swift project authors +// Copyright (c) 2014-2023 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -161,4 +161,22 @@ final class PackageGraphPerfTests: XCTestCasePerf { } } } + + func testRecursiveDependencies() throws { + var resolvedTarget = ResolvedTarget.mock(packageIdentity: "pkg", name: "t0") + for i in 1..<1000 { + resolvedTarget = ResolvedTarget.mock(packageIdentity: "pkg", name: "t\(i)", deps: resolvedTarget) + } + + let N = 100 + measure { + do { + for _ in 0.. Date: Thu, 21 Dec 2023 13:32:43 +0000 Subject: [PATCH 13/33] Reduce number of iterations in `testRecursiveDependencies` --- Tests/PackageGraphPerformanceTests/PackageGraphPerfTests.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tests/PackageGraphPerformanceTests/PackageGraphPerfTests.swift b/Tests/PackageGraphPerformanceTests/PackageGraphPerfTests.swift index 2016be310b3..6cd5f755c80 100644 --- a/Tests/PackageGraphPerformanceTests/PackageGraphPerfTests.swift +++ b/Tests/PackageGraphPerformanceTests/PackageGraphPerfTests.swift @@ -168,7 +168,7 @@ final class PackageGraphPerfTests: XCTestCasePerf { resolvedTarget = ResolvedTarget.mock(packageIdentity: "pkg", name: "t\(i)", deps: resolvedTarget) } - let N = 100 + let N = 10 measure { do { for _ in 0.. Date: Tue, 30 Jan 2024 15:45:40 +0000 Subject: [PATCH 14/33] Update `buildTriple` in `ResolvedTarget` and `ResolvedProduct` Also added `CrossCompiledPackageGraphTests`. --- .../Basics/Collections/IdentifiableSet.swift | 7 +- .../LLBuildManifestBuilder+Swift.swift | 4 +- .../Build/BuildPlan/BuildPlan+Product.swift | 11 +- Sources/PackageGraph/BuildTriple.swift | 23 +++ .../PackageGraph/PackageGraph+Loading.swift | 23 +-- Sources/PackageGraph/PackageGraph.swift | 8 +- .../Resolution/ResolvedProduct.swift | 32 +++- .../Resolution/ResolvedTarget.swift | 30 +++- .../SPMTestSupport/PackageGraphTester.swift | 69 +++++++- .../CrossCompiledPackageGraphTests.swift | 151 ++++++++++++++++++ .../PackageGraphTests/PackageGraphTests.swift | 3 +- 11 files changed, 326 insertions(+), 35 deletions(-) create mode 100644 Tests/PackageGraphTests/CrossCompiledPackageGraphTests.swift diff --git a/Sources/Basics/Collections/IdentifiableSet.swift b/Sources/Basics/Collections/IdentifiableSet.swift index b3bfec3071f..5e73bc33209 100644 --- a/Sources/Basics/Collections/IdentifiableSet.swift +++ b/Sources/Basics/Collections/IdentifiableSet.swift @@ -45,7 +45,12 @@ public struct IdentifiableSet: Collection { } public subscript(id: Element.ID) -> Element? { - self.storage[id] + get { + self.storage[id] + } + set { + self.storage[id] = newValue + } } public func index(after i: Index) -> Index { diff --git a/Sources/Build/BuildManifest/LLBuildManifestBuilder+Swift.swift b/Sources/Build/BuildManifest/LLBuildManifestBuilder+Swift.swift index 856b540dceb..be8265f43ff 100644 --- a/Sources/Build/BuildManifest/LLBuildManifestBuilder+Swift.swift +++ b/Sources/Build/BuildManifest/LLBuildManifestBuilder+Swift.swift @@ -192,7 +192,9 @@ extension LLBuildManifestBuilder { // Sort the product targets in topological order in order to collect and "bubble up" // their respective dependency graphs to the depending targets. let nodes: [ResolvedTarget.Dependency] = try self.plan.targetMap.keys.compactMap { - guard let target = self.plan.graph.allTargets[$0] else { throw InternalError("unknown target \($0)") } + guard let target = self.plan.graph.allTargets[$0] else { + throw InternalError("unknown target \($0)") + } return ResolvedTarget.Dependency.target(target, conditions: []) } let allPackageDependencies = try topologicalSort(nodes, successors: { $0.dependencies }) diff --git a/Sources/Build/BuildPlan/BuildPlan+Product.swift b/Sources/Build/BuildPlan/BuildPlan+Product.swift index d14ec2418ad..43cfacefb7b 100644 --- a/Sources/Build/BuildPlan/BuildPlan+Product.swift +++ b/Sources/Build/BuildPlan/BuildPlan+Product.swift @@ -70,7 +70,10 @@ extension BuildPlan { switch target.underlying { case is SwiftTarget: // Swift targets are guaranteed to have a corresponding Swift description. - guard case .swift(let description) = targetMap[target.id] else { + guard case .swift(let description) = self.targetMap[target.id] else { + for key in self.targetMap.keys { + print(key) + } throw InternalError("unknown target \(target)") } @@ -220,9 +223,11 @@ extension BuildPlan { if product.targets.contains(id: target.id) { staticTargets.append(target) } - // Library targets should always be included. + // Library targets should always be included for the same build triple. case .library: - staticTargets.append(target) + if target.buildTriple == product.buildTriple { + staticTargets.append(target) + } // Add system target to system targets array. case .systemModule: systemModules.append(target) diff --git a/Sources/PackageGraph/BuildTriple.swift b/Sources/PackageGraph/BuildTriple.swift index 4e121a2c7bb..87d2daf21f1 100644 --- a/Sources/PackageGraph/BuildTriple.swift +++ b/Sources/PackageGraph/BuildTriple.swift @@ -10,6 +10,9 @@ // //===----------------------------------------------------------------------===// +import class PackageModel.Target +import class PackageModel.Product + /// Triple for which code should be compiled for. /// > Note: We're not using "host" and "target" triple terminology in this enum, as that clashes with build /// > system "targets" and can lead to confusion in this context. @@ -20,3 +23,23 @@ public enum BuildTriple { /// Triple of the destination platform for which end products are compiled (the target triple). case destination } + +extension Target { + var buildTriple: BuildTriple { + if self.type == .macro || self.type == .plugin { + .tools + } else { + .destination + } + } +} + +extension Product { + var buildTriple: BuildTriple { + if self.type == .macro || self.type == .plugin { + .tools + } else { + .destination + } + } +} diff --git a/Sources/PackageGraph/PackageGraph+Loading.swift b/Sources/PackageGraph/PackageGraph+Loading.swift index 48bcd622d8e..4a9825d2f32 100644 --- a/Sources/PackageGraph/PackageGraph+Loading.swift +++ b/Sources/PackageGraph/PackageGraph+Loading.swift @@ -163,12 +163,12 @@ extension PackageGraph { observabilityScope: observabilityScope ) - let rootPackages = resolvedPackages.filter{ root.manifests.values.contains($0.manifest) } + let rootPackages = resolvedPackages.filter { root.manifests.values.contains($0.manifest) } checkAllDependenciesAreUsed(rootPackages, observabilityScope: observabilityScope) return try PackageGraph( rootPackages: rootPackages, - rootDependencies: resolvedPackages.filter{ rootDependencies.contains($0.manifest) }, + rootDependencies: resolvedPackages.filter { rootDependencies.contains($0.manifest) }, dependencies: requiredDependencies, binaryArtifacts: binaryArtifacts ) @@ -178,16 +178,16 @@ extension PackageGraph { private func checkAllDependenciesAreUsed(_ rootPackages: [ResolvedPackage], observabilityScope: ObservabilityScope) { for package in rootPackages { // List all dependency products dependent on by the package targets. - let productDependencies = IdentifiableSet(package.targets.flatMap({ target in - return target.dependencies.compactMap({ targetDependency in + let productDependencies = IdentifiableSet(package.targets.flatMap { target in + return target.dependencies.compactMap { targetDependency in switch targetDependency { case .product(let product, _): return product case .target: return nil } - }) - })) + } + }) for dependency in package.dependencies { // We continue if the dependency contains executable products to make sure we don't @@ -215,7 +215,12 @@ private func checkAllDependenciesAreUsed(_ rootPackages: [ResolvedPackage], obse ) // Otherwise emit a warning if none of the dependency package's products are used. - let dependencyIsUsed = dependency.products.contains(where: { productDependencies.contains(id: $0.id) }) + let dependencyIsUsed = dependency.products.contains { product in + // Don't compare by product ID, but by product name to make sure both build triples as properties of + // `ResolvedProduct.ID` are allowed. + productDependencies.contains { $0.name == product.name } + } + if !dependencyIsUsed && !observabilityScope.errorsReportedInAnyScope { packageDiagnosticsScope.emit(.unusedDependency(dependency.identity.description)) } @@ -618,12 +623,12 @@ private func createResolvedPackages( observabilityScope.emit( ModuleError.duplicateModule( targetName: entry.key, - packages: entry.value.map{ $0.identity }) + packages: entry.value.map { $0.identity }) ) } } - return try packageBuilders.map{ try $0.construct() } + return try packageBuilders.map { try $0.construct() } } private func emitDuplicateProductDiagnostic( diff --git a/Sources/PackageGraph/PackageGraph.swift b/Sources/PackageGraph/PackageGraph.swift index bd3446b0499..531f3d1901a 100644 --- a/Sources/PackageGraph/PackageGraph.swift +++ b/Sources/PackageGraph/PackageGraph.swift @@ -136,11 +136,11 @@ public struct PackageGraph { // Create a mapping from targets to the packages that define them. Here // we include all targets, including tests in non-root packages, since // this is intended for lookup and not traversal. - self.targetsToPackages = packages.reduce(into: [:], { partial, package in - package.targets.forEach{ partial[$0.id] = package } + self.targetsToPackages = self.packages.reduce(into: [:], { partial, package in + package.targets.forEach { partial[$0.id] = package } }) - let allTargets = IdentifiableSet(packages.flatMap({ package -> [ResolvedTarget] in + let allTargets = IdentifiableSet(packages.flatMap { package -> [ResolvedTarget] in if rootPackages.contains(id: package.id) { return package.targets } else { @@ -148,7 +148,7 @@ public struct PackageGraph { // try to run them. return package.targets.filter({ $0.type != .test }) } - })) + }) // Create a mapping from products to the packages that define them. Here // we include all products, including tests in non-root packages, since diff --git a/Sources/PackageGraph/Resolution/ResolvedProduct.swift b/Sources/PackageGraph/Resolution/ResolvedProduct.swift index 1208b5b0d7f..ea1a25085a2 100644 --- a/Sources/PackageGraph/Resolution/ResolvedProduct.swift +++ b/Sources/PackageGraph/Resolution/ResolvedProduct.swift @@ -30,7 +30,7 @@ public struct ResolvedProduct { public let underlying: Product /// The top level targets contained in this product. - public let targets: IdentifiableSet + public private(set) var targets: IdentifiableSet /// Executable target for test entry point file. public let testEntryPointTarget: ResolvedTarget? @@ -44,7 +44,11 @@ public struct ResolvedProduct { public let platformVersionProvider: PlatformVersionProvider /// Triple for which this resolved product should be compiled for. - public let buildTriple: BuildTriple + public internal(set) var buildTriple: BuildTriple { + didSet { + self.updateBuildTriplesOfDependencies() + } + } /// The main executable target of product. /// @@ -63,7 +67,12 @@ public struct ResolvedProduct { } } - public init(packageIdentity: PackageIdentity, product: Product, targets: IdentifiableSet) { + public init( + packageIdentity: PackageIdentity, + product: Product, + targets: IdentifiableSet, + buildTriple: BuildTriple = .destination + ) { assert(product.targets.count == targets.count && product.targets.map(\.name).sorted() == targets.map(\.name).sorted()) self.packageIdentity = packageIdentity self.underlying = product @@ -97,7 +106,18 @@ public struct ResolvedProduct { ) } - self.buildTriple = .destination + self.buildTriple = buildTriple + } + + private mutating func updateBuildTriplesOfDependencies() { + if case .tools = self.buildTriple { + self.targets = IdentifiableSet(self.targets.map { + var target = $0 + target.buildTriple = .tools + return target + }) + print(self.targets.map(\.id)) + } } /// True if this product contains Swift targets. @@ -166,13 +186,13 @@ extension ResolvedProduct { extension ResolvedProduct: Identifiable { /// Resolved target identity that uniquely identifies it in a resolution graph. public struct ID: Hashable { - public let targetName: String + public let productName: String let packageIdentity: PackageIdentity public let buildTriple: BuildTriple } public var id: ID { - ID(targetName: self.name, packageIdentity: self.packageIdentity, buildTriple: self.buildTriple) + ID(productName: self.name, packageIdentity: self.packageIdentity, buildTriple: self.buildTriple) } } diff --git a/Sources/PackageGraph/Resolution/ResolvedTarget.swift b/Sources/PackageGraph/Resolution/ResolvedTarget.swift index 4e9fecaf804..a36a4f9b37f 100644 --- a/Sources/PackageGraph/Resolution/ResolvedTarget.swift +++ b/Sources/PackageGraph/Resolution/ResolvedTarget.swift @@ -133,7 +133,7 @@ public struct ResolvedTarget { public let underlying: Target /// The dependencies of this target. - public let dependencies: [Dependency] + public private(set) var dependencies: [Dependency] /// The default localization for resources. public let defaultLocalization: String? @@ -144,7 +144,11 @@ public struct ResolvedTarget { private let platformVersionProvider: PlatformVersionProvider /// Triple for which this resolved target should be compiled for. - public let buildTriple: BuildTriple + public internal (set) var buildTriple: BuildTriple { + didSet { + self.updateBuildTriplesOfDependencies() + } + } /// Create a resolved target instance. public init( @@ -161,7 +165,27 @@ public struct ResolvedTarget { self.defaultLocalization = defaultLocalization self.supportedPlatforms = supportedPlatforms self.platformVersionProvider = platformVersionProvider - self.buildTriple = .destination + self.buildTriple = underlying.buildTriple + + self.updateBuildTriplesOfDependencies() + } + + private mutating func updateBuildTriplesOfDependencies() { + if case .tools = self.buildTriple { + for (i, dependency) in dependencies.enumerated() { + let updatedDependency: Dependency + switch dependency { + case .target(var target, let conditions): + target.buildTriple = .tools + updatedDependency = .target(target, conditions: conditions) + case .product(var product, let conditions): + product.buildTriple = .tools + updatedDependency = .product(product, conditions: conditions) + } + + dependencies[i] = updatedDependency + } + } } public func getSupportedPlatform(for platform: Platform, usingXCTest: Bool) -> SupportedPlatform { diff --git a/Sources/SPMTestSupport/PackageGraphTester.swift b/Sources/SPMTestSupport/PackageGraphTester.swift index fc4d3c231b5..0c1f8a8e38a 100644 --- a/Sources/SPMTestSupport/PackageGraphTester.swift +++ b/Sources/SPMTestSupport/PackageGraphTester.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift open source project // -// Copyright (c) 2014-2017 Apple Inc. and the Swift project authors +// Copyright (c) 2014-2024 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -98,6 +98,15 @@ public final class PackageGraphResult { body(ResolvedTargetResult(target)) } + public func checkTargets( + _ name: String, + file: StaticString = #file, + line: UInt = #line, + body: ([ResolvedTargetResult]) -> Void + ) { + body(graph.allTargets.filter { $0.name == name }.map(ResolvedTargetResult.init)) + } + public func checkProduct( _ name: String, file: StaticString = #file, @@ -176,7 +185,9 @@ public final class ResolvedTargetResult { } public func checkDeclaredPlatforms(_ platforms: [String: String], file: StaticString = #file, line: UInt = #line) { - let targetPlatforms = Dictionary(uniqueKeysWithValues: target.supportedPlatforms.map({ ($0.platform.name, $0.version.versionString) })) + let targetPlatforms = Dictionary( + uniqueKeysWithValues: target.supportedPlatforms.map { ($0.platform.name, $0.version.versionString) } + ) XCTAssertEqual(platforms, targetPlatforms, file: file, line: line) } @@ -187,16 +198,24 @@ public final class ResolvedTargetResult { return self.target.getSupportedPlatform(for: platform, usingXCTest: self.target.type == .test) } let targetPlatforms = Dictionary( - uniqueKeysWithValues: derived - .map { ($0.platform.name, $0.version.versionString) } + uniqueKeysWithValues: derived.map { ($0.platform.name, $0.version.versionString) } ) XCTAssertEqual(platforms, targetPlatforms, file: file, line: line) } - public func checkDerivedPlatformOptions(_ platform: PackageModel.Platform, options: [String], file: StaticString = #file, line: UInt = #line) { - let platform = target.getSupportedPlatform(for: platform, usingXCTest: target.type == .test) + public func checkDerivedPlatformOptions( + _ platform: PackageModel.Platform, + options: [String], + file: StaticString = #file, + line: UInt = #line + ) { + let platform = self.target.getSupportedPlatform(for: platform, usingXCTest: target.type == .test) XCTAssertEqual(platform.options, options, file: file, line: line) } + + public func check(buildTriple: BuildTriple, file: StaticString = #file, line: UInt = #line) { + XCTAssertEqual(self.target.buildTriple, buildTriple, file: file, line: line) + } } public final class ResolvedTargetDependencyResult { @@ -217,6 +236,28 @@ public final class ResolvedTargetDependencyResult { ) { XCTAssert(!dependency.conditions.allSatisfy({ $0.satisfies(environment) }), file: file, line: line) } + + public func checkTarget( + file: StaticString = #file, + line: UInt = #line, + body: (ResolvedTargetResult) -> Void + ) { + guard case let .target(target, _) = self.dependency else { + return XCTFail("Dependency \(dependency) is not a target", file: file, line: line) + } + body(ResolvedTargetResult(target)) + } + + public func checkProduct( + file: StaticString = #file, + line: UInt = #line, + body: (ResolvedProductResult) -> Void + ) { + guard case let .product(product, _) = self.dependency else { + return XCTFail("Dependency \(dependency) is not a product", file: file, line: line) + } + body(ResolvedProductResult(product)) + } } public final class ResolvedProductResult { @@ -252,6 +293,22 @@ public final class ResolvedProductResult { let platform = product.getSupportedPlatform(for: platform, usingXCTest: product.isLinkingXCTest) XCTAssertEqual(platform.options, options, file: file, line: line) } + + public func check(buildTriple: BuildTriple, file: StaticString = #file, line: UInt = #line) { + XCTAssertEqual(self.product.buildTriple, buildTriple, file: file, line: line) + } + + public func checkTarget( + _ name: String, + file: StaticString = #file, + line: UInt = #line, + body: (ResolvedTargetResult) -> Void + ) { + guard let target = product.targets.first(where: { $0.name == name }) else { + return XCTFail("Target \(name) not found", file: file, line: line) + } + body(ResolvedTargetResult(target)) + } } extension ResolvedTarget.Dependency { diff --git a/Tests/PackageGraphTests/CrossCompiledPackageGraphTests.swift b/Tests/PackageGraphTests/CrossCompiledPackageGraphTests.swift new file mode 100644 index 00000000000..dae2ec4527a --- /dev/null +++ b/Tests/PackageGraphTests/CrossCompiledPackageGraphTests.swift @@ -0,0 +1,151 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the Swift open source project +// +// Copyright (c) 2014-2024 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See http://swift.org/LICENSE.txt for license information +// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// + +import class Basics.ObservabilitySystem +import class PackageModel.Manifest +import struct PackageModel.ProductDescription +import struct PackageModel.TargetDescription +import func SPMTestSupport.loadPackageGraph +import func SPMTestSupport.PackageGraphTester +import func SPMTestSupport.XCTAssertNoDiagnostics +import class TSCBasic.InMemoryFileSystem + +@testable +import PackageGraph + +import XCTest + +final class CrossCompiledPackageGraphTests: XCTestCase { + func testMacros() throws { + let fs = InMemoryFileSystem(emptyFiles: + "/swift-firmware/Sources/Core/source.swift", + "/swift-firmware/Sources/HAL/source.swift", + "/swift-firmware/Tests/CoreTests/source.swift", + "/swift-firmware/Tests/HALTests/source.swift", + "/swift-mmio/Sources/MMIO/source.swift", + "/swift-mmio/Sources/MMIOMacros/source.swift", + "/swift-syntax/Sources/SwiftSyntax/source.swift", + "/swift-syntax/Tests/SwiftSyntaxTests/source.swift" + ) + + let observability = ObservabilitySystem.makeForTesting() + let g = try loadPackageGraph( + fileSystem: fs, + manifests: [ + Manifest.createRootManifest( + displayName: "swift-firmware", + path: "/swift-firmware", + dependencies: [ + .localSourceControl( + path: "/swift-mmio", + requirement: .upToNextMajor(from: "1.0.0") + ) + ], + products: [ + ProductDescription( + name: "Core", + type: .executable, + targets: ["Core"] + ) + ], + targets: [ + TargetDescription( + name: "Core", + dependencies: ["HAL"], + type: .executable + ), + TargetDescription( + name: "HAL", + dependencies: [.product(name: "MMIO", package: "swift-mmio")] + ), + TargetDescription(name: "CoreTests", dependencies: ["Core"], type: .test), + TargetDescription(name: "HALTests", dependencies: ["HAL"], type: .test), + ] + ), + Manifest.createFileSystemManifest( + displayName: "swift-mmio", + path: "/swift-mmio", + dependencies: [ + .localSourceControl( + path: "/swift-syntax", + requirement: .upToNextMajor(from: "1.0.0") + ) + ], + products: [ + ProductDescription( + name: "MMIO", + type: .library(.automatic), + targets: ["MMIO"] + ) + ], + targets: [ + TargetDescription( + name: "MMIO", + dependencies: [.target(name: "MMIOMacros")] + ), + TargetDescription( + name: "MMIOMacros", + dependencies: [.product(name: "SwiftSyntax", package: "swift-syntax")], + type: .macro + ) + ] + ), + Manifest.createFileSystemManifest( + displayName: "swift-syntax", + path: "/swift-syntax", + products: [ + ProductDescription( + name: "SwiftSyntax", + type: .library(.automatic), + targets: ["SwiftSyntax"] + ) + ], + targets: [ + TargetDescription(name: "SwiftSyntax", dependencies: []), + TargetDescription(name: "SwiftSyntaxTests", dependencies: ["SwiftSyntax"], type: .test), + ] + ), + ], + observabilityScope: observability.topScope + ) + + XCTAssertNoDiagnostics(observability.diagnostics) + PackageGraphTester(g) { result in + result.check(packages: "swift-firmware", "swift-mmio", "swift-syntax") + result.check(targets: "Core", "HAL", "MMIO", "MMIOMacros", "SwiftSyntax") + result.check(testModules: "CoreTests", "HALTests") + result.checkTarget("Core") { result in + result.check(buildTriple: .destination) + result.check(dependencies: "HAL") + } + result.checkTarget("HAL") { result in + result.check(buildTriple: .destination) + result.check(dependencies: "MMIO") + } + result.checkTarget("MMIO") { result in + result.check(buildTriple: .destination) + result.check(dependencies: "MMIOMacros") + } + result.checkTarget("MMIOMacros") { result in + result.check(buildTriple: .tools) + result.checkDependency("SwiftSyntax") { result in + result.checkProduct { result in + result.check(buildTriple: .tools) + result.checkTarget("SwiftSyntax") { result in + result.check(buildTriple: .tools) + } + } + } + } + } + } +} diff --git a/Tests/PackageGraphTests/PackageGraphTests.swift b/Tests/PackageGraphTests/PackageGraphTests.swift index 27af5fee6c4..ab86f67d6a8 100644 --- a/Tests/PackageGraphTests/PackageGraphTests.swift +++ b/Tests/PackageGraphTests/PackageGraphTests.swift @@ -19,8 +19,7 @@ import XCTest import struct TSCBasic.ByteString import class TSCBasic.InMemoryFileSystem -class PackageGraphTests: XCTestCase { - +final class PackageGraphTests: XCTestCase { func testBasic() throws { let fs = InMemoryFileSystem(emptyFiles: "/Foo/Sources/Foo/source.swift", From 779f7e853de38bfc4bfb3a953a62faeefd2ac6e7 Mon Sep 17 00:00:00 2001 From: Max Desiatov Date: Tue, 30 Jan 2024 15:46:28 +0000 Subject: [PATCH 15/33] Remove debug logging --- Sources/Build/BuildPlan/BuildPlan+Product.swift | 3 --- Sources/PackageGraph/Resolution/ResolvedProduct.swift | 1 - 2 files changed, 4 deletions(-) diff --git a/Sources/Build/BuildPlan/BuildPlan+Product.swift b/Sources/Build/BuildPlan/BuildPlan+Product.swift index 43cfacefb7b..2cbe8a8c46d 100644 --- a/Sources/Build/BuildPlan/BuildPlan+Product.swift +++ b/Sources/Build/BuildPlan/BuildPlan+Product.swift @@ -71,9 +71,6 @@ extension BuildPlan { case is SwiftTarget: // Swift targets are guaranteed to have a corresponding Swift description. guard case .swift(let description) = self.targetMap[target.id] else { - for key in self.targetMap.keys { - print(key) - } throw InternalError("unknown target \(target)") } diff --git a/Sources/PackageGraph/Resolution/ResolvedProduct.swift b/Sources/PackageGraph/Resolution/ResolvedProduct.swift index ea1a25085a2..9b8ae6571ac 100644 --- a/Sources/PackageGraph/Resolution/ResolvedProduct.swift +++ b/Sources/PackageGraph/Resolution/ResolvedProduct.swift @@ -116,7 +116,6 @@ public struct ResolvedProduct { target.buildTriple = .tools return target }) - print(self.targets.map(\.id)) } } From 2e144e183dc52712104afd830e2aacceddd975b0 Mon Sep 17 00:00:00 2001 From: Max Desiatov Date: Tue, 30 Jan 2024 18:39:59 +0000 Subject: [PATCH 16/33] Refine `ResolvedTarget/description` for logging --- Sources/PackageGraph/Resolution/ResolvedTarget.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/PackageGraph/Resolution/ResolvedTarget.swift b/Sources/PackageGraph/Resolution/ResolvedTarget.swift index a36a4f9b37f..93db29dd93e 100644 --- a/Sources/PackageGraph/Resolution/ResolvedTarget.swift +++ b/Sources/PackageGraph/Resolution/ResolvedTarget.swift @@ -199,7 +199,7 @@ public struct ResolvedTarget { extension ResolvedTarget: CustomStringConvertible { public var description: String { - return "" + return "" } } From 83aad66c95b6c269de4eee13a4f240c0bdd6addb Mon Sep 17 00:00:00 2001 From: Max Desiatov Date: Tue, 30 Jan 2024 21:58:42 +0000 Subject: [PATCH 17/33] Make sure host tools dependencies are in the build plan --- .../Basics/Collections/IdentifiableSet.swift | 4 + Sources/PackageGraph/PackageGraph.swift | 59 ++++--- .../SPMTestSupport/MockBuildTestHelper.swift | 38 +++-- .../SPMTestSupport/MockPackageGraphs.swift | 122 ++++++++++++++ .../SPMTestSupport/PackageGraphTester.swift | 2 +- Tests/BuildTests/BuildPlanTests.swift | 66 +++++--- .../CrossCompilationBuildTests.swift | 60 +++++++ .../CrossCompilationPackageGraphTests.swift | 61 +++++++ .../CrossCompiledPackageGraphTests.swift | 151 ------------------ 9 files changed, 356 insertions(+), 207 deletions(-) create mode 100644 Sources/SPMTestSupport/MockPackageGraphs.swift create mode 100644 Tests/BuildTests/CrossCompilationBuildTests.swift create mode 100644 Tests/PackageGraphTests/CrossCompilationPackageGraphTests.swift delete mode 100644 Tests/PackageGraphTests/CrossCompiledPackageGraphTests.swift diff --git a/Sources/Basics/Collections/IdentifiableSet.swift b/Sources/Basics/Collections/IdentifiableSet.swift index 5e73bc33209..59bda6bdd85 100644 --- a/Sources/Basics/Collections/IdentifiableSet.swift +++ b/Sources/Basics/Collections/IdentifiableSet.swift @@ -57,6 +57,10 @@ public struct IdentifiableSet: Collection { Index(storageIndex: self.storage.index(after: i.storageIndex)) } + public mutating func insert(_ element: Element) { + self.storage[element.id] = element + } + public func union(_ otherSequence: some Sequence) -> Self { var result = self for element in otherSequence { diff --git a/Sources/PackageGraph/PackageGraph.swift b/Sources/PackageGraph/PackageGraph.swift index 531f3d1901a..fb2146ba3a5 100644 --- a/Sources/PackageGraph/PackageGraph.swift +++ b/Sources/PackageGraph/PackageGraph.swift @@ -68,7 +68,6 @@ public struct PackageGraph { public let allTargets: IdentifiableSet /// Returns all the products in the graph, regardless if they are reachable from the root targets or not. - public let allProducts: IdentifiableSet /// Package dependencies required for a fully resolved graph. @@ -132,44 +131,68 @@ public struct PackageGraph { self.inputPackages = rootPackages + rootDependencies self.binaryArtifacts = binaryArtifacts self.packages = try topologicalSort(inputPackages, successors: { $0.dependencies }) + let identitiesToPackages = self.packages.spm_createDictionary { ($0.identity, $0) } // Create a mapping from targets to the packages that define them. Here // we include all targets, including tests in non-root packages, since // this is intended for lookup and not traversal. - self.targetsToPackages = self.packages.reduce(into: [:], { partial, package in + var targetsToPackages = self.packages.reduce(into: [:], { partial, package in package.targets.forEach { partial[$0.id] = package } }) - let allTargets = IdentifiableSet(packages.flatMap { package -> [ResolvedTarget] in + // Create a mapping from products to the packages that define them. Here + // we include all products, including tests in non-root packages, since + // this is intended for lookup and not traversal. + var productsToPackages = packages.reduce(into: [:], { partial, package in + package.products.forEach { partial[$0.id] = package } + }) + + var allTargets = IdentifiableSet() + var allProducts = IdentifiableSet() + for package in self.packages { + let targetsToInclude: [ResolvedTarget] if rootPackages.contains(id: package.id) { - return package.targets + targetsToInclude = package.targets } else { // Don't include tests targets from non-root packages so swift-test doesn't // try to run them. - return package.targets.filter({ $0.type != .test }) + targetsToInclude = package.targets.filter { $0.type != .test } } - }) - // Create a mapping from products to the packages that define them. Here - // we include all products, including tests in non-root packages, since - // this is intended for lookup and not traversal. - self.productsToPackages = packages.reduce(into: [:], { partial, package in - package.products.forEach { partial[$0.id] = package } - }) + for target in targetsToInclude { + allTargets.insert(target) + + // Explicitly include dependencies of host tools in the maps of all targets or all products + if target.buildTriple == .tools { + for dependency in try target.recursiveDependencies() { + switch dependency { + case .target(let targetDependency, _): + allTargets.insert(targetDependency) + targetsToPackages[targetDependency.id] = package + case .product(let productDependency, _): + allProducts.insert(productDependency) + productsToPackages[productDependency.id] = + identitiesToPackages[productDependency.packageIdentity] + } + } + } + } - let allProducts = IdentifiableSet(packages.flatMap({ package -> [ResolvedProduct] in if rootPackages.contains(id: package.id) { - return package.products + allProducts.formUnion(package.products) } else { // Don't include tests products from non-root packages so swift-test doesn't // try to run them. - return package.products.filter({ $0.type != .test }) + allProducts.formUnion(package.products.filter { $0.type != .test }) } - })) + } + + self.targetsToPackages = targetsToPackages + self.productsToPackages = productsToPackages // Compute the reachable targets and products. - let inputTargets = inputPackages.flatMap { $0.targets } - let inputProducts = inputPackages.flatMap { $0.products } + let inputTargets = self.inputPackages.flatMap { $0.targets } + let inputProducts = self.inputPackages.flatMap { $0.products } let recursiveDependencies = try inputTargets.lazy.flatMap { try $0.recursiveDependencies() } self.reachableTargets = IdentifiableSet(inputTargets).union(recursiveDependencies.compactMap { $0.target }) diff --git a/Sources/SPMTestSupport/MockBuildTestHelper.swift b/Sources/SPMTestSupport/MockBuildTestHelper.swift index d18050e953d..016092edc69 100644 --- a/Sources/SPMTestSupport/MockBuildTestHelper.swift +++ b/Sources/SPMTestSupport/MockBuildTestHelper.swift @@ -15,6 +15,8 @@ import Basics @_spi(SwiftPMInternal) import Build +import struct PackageGraph.ResolvedTarget +import struct PackageGraph.ResolvedProduct import PackageModel import SPMBuildCore import TSCUtility @@ -79,7 +81,7 @@ public func mockBuildParameters( shouldLinkStaticSwiftStdlib: Bool = false, shouldDisableLocalRpath: Bool = false, canRenameEntrypointFunctionName: Bool = false, - targetTriple: Basics.Triple = hostTriple, + triple: Basics.Triple = hostTriple, indexStoreMode: BuildParameters.IndexStoreMode = .off, useExplicitModuleBuild: Bool = false, linkerDeadStrip: Bool = true, @@ -90,13 +92,13 @@ public func mockBuildParameters( dataPath: buildPath, configuration: config, toolchain: toolchain, - triple: targetTriple, + triple: triple, flags: flags, pkgConfigDirectories: [], workers: 3, indexStoreMode: indexStoreMode, debuggingParameters: .init( - triple: targetTriple, + triple: triple, shouldEnableDebuggingEntitlement: config == .debug, omitFramePointers: omitFramePointers ), @@ -128,7 +130,7 @@ public func mockBuildParameters(environment: BuildEnvironment) -> BuildParameter fatalError("unsupported platform in tests") } - return mockBuildParameters(config: environment.configuration ?? .debug, targetTriple: triple) + return mockBuildParameters(config: environment.configuration ?? .debug, triple: triple) } enum BuildError: Swift.Error { @@ -137,15 +139,15 @@ enum BuildError: Swift.Error { public struct BuildPlanResult { public let plan: Build.BuildPlan - public let targetMap: [String: TargetBuildDescription] - public let productMap: [String: Build.ProductBuildDescription] + public let targetMap: [ResolvedTarget.ID: TargetBuildDescription] + public let productMap: [ResolvedProduct.ID: Build.ProductBuildDescription] public init(plan: Build.BuildPlan) throws { self.plan = plan self.productMap = try Dictionary( throwingUniqueKeysWithValues: plan.buildProducts .compactMap { $0 as? Build.ProductBuildDescription } - .map { ($0.product.name, $0) } + .map { ($0.product.id, $0) } ) self.targetMap = try Dictionary( throwingUniqueKeysWithValues: plan.targetMap.compactMap { @@ -155,7 +157,7 @@ public struct BuildPlanResult { else { throw BuildError.error("Target \($0) not found.") } - return (target.name, $1) + return (target.id, $1) } ) } @@ -169,16 +171,26 @@ public struct BuildPlanResult { } public func target(for name: String) throws -> TargetBuildDescription { - guard let target = targetMap[name] else { - throw BuildError.error("Target \(name) not found.") + let matchingIDs = targetMap.keys.filter({ $0.targetName == name }) + guard matchingIDs.count == 1, let target = targetMap[matchingIDs[0]] else { + if matchingIDs.isEmpty { + throw BuildError.error("Target \(name) not found.") + } else { + throw BuildError.error("More than one target \(name) found.") + } } return target } public func buildProduct(for name: String) throws -> Build.ProductBuildDescription { - guard let product = productMap[name] else { - // Display the thrown error on macOS - throw BuildError.error("Product \(name) not found.") + let matchingIDs = productMap.keys.filter({ $0.productName == name }) + guard matchingIDs.count == 1, let product = productMap[matchingIDs[0]] else { + if matchingIDs.isEmpty { + // Display the thrown error on macOS + throw BuildError.error("Product \(name) not found.") + } else { + throw BuildError.error("More than one target \(name) found.") + } } return product } diff --git a/Sources/SPMTestSupport/MockPackageGraphs.swift b/Sources/SPMTestSupport/MockPackageGraphs.swift new file mode 100644 index 00000000000..b84b897a257 --- /dev/null +++ b/Sources/SPMTestSupport/MockPackageGraphs.swift @@ -0,0 +1,122 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the Swift open source project +// +// Copyright (c) 2014-2024 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See http://swift.org/LICENSE.txt for license information +// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// + +import class Basics.ObservabilitySystem +import class Basics.ObservabilityScope +import struct PackageGraph.PackageGraph +import class PackageModel.Manifest +import struct PackageModel.ProductDescription +import struct PackageModel.TargetDescription +import protocol TSCBasic.FileSystem +import class TSCBasic.InMemoryFileSystem + +public func macrosPackageGraph() throws -> ( + graph: PackageGraph, + fileSystem: FileSystem, + observabilityScope: ObservabilityScope +) { + let fs = InMemoryFileSystem(emptyFiles: + "/swift-firmware/Sources/Core/source.swift", + "/swift-firmware/Sources/HAL/source.swift", + "/swift-firmware/Tests/CoreTests/source.swift", + "/swift-firmware/Tests/HALTests/source.swift", + "/swift-mmio/Sources/MMIO/source.swift", + "/swift-mmio/Sources/MMIOMacros/source.swift", + "/swift-syntax/Sources/SwiftSyntax/source.swift", + "/swift-syntax/Tests/SwiftSyntaxTests/source.swift" + ) + + let observability = ObservabilitySystem.makeForTesting() + let graph = try loadPackageGraph( + fileSystem: fs, + manifests: [ + Manifest.createRootManifest( + displayName: "swift-firmware", + path: "/swift-firmware", + dependencies: [ + .localSourceControl( + path: "/swift-mmio", + requirement: .upToNextMajor(from: "1.0.0") + ) + ], + products: [ + ProductDescription( + name: "Core", + type: .executable, + targets: ["Core"] + ) + ], + targets: [ + TargetDescription( + name: "Core", + dependencies: ["HAL"], + type: .executable + ), + TargetDescription( + name: "HAL", + dependencies: [.product(name: "MMIO", package: "swift-mmio")] + ), + TargetDescription(name: "CoreTests", dependencies: ["Core"], type: .test), + TargetDescription(name: "HALTests", dependencies: ["HAL"], type: .test), + ] + ), + Manifest.createFileSystemManifest( + displayName: "swift-mmio", + path: "/swift-mmio", + dependencies: [ + .localSourceControl( + path: "/swift-syntax", + requirement: .upToNextMajor(from: "1.0.0") + ) + ], + products: [ + ProductDescription( + name: "MMIO", + type: .library(.automatic), + targets: ["MMIO"] + ) + ], + targets: [ + TargetDescription( + name: "MMIO", + dependencies: [.target(name: "MMIOMacros")] + ), + TargetDescription( + name: "MMIOMacros", + dependencies: [.product(name: "SwiftSyntax", package: "swift-syntax")], + type: .macro + ) + ] + ), + Manifest.createFileSystemManifest( + displayName: "swift-syntax", + path: "/swift-syntax", + products: [ + ProductDescription( + name: "SwiftSyntax", + type: .library(.automatic), + targets: ["SwiftSyntax"] + ) + ], + targets: [ + TargetDescription(name: "SwiftSyntax", dependencies: []), + TargetDescription(name: "SwiftSyntaxTests", dependencies: ["SwiftSyntax"], type: .test), + ] + ), + ], + observabilityScope: observability.topScope + ) + + XCTAssertNoDiagnostics(observability.diagnostics) + + return (graph, fs, observability.topScope) +} diff --git a/Sources/SPMTestSupport/PackageGraphTester.swift b/Sources/SPMTestSupport/PackageGraphTester.swift index 0c1f8a8e38a..91d2d61d8e3 100644 --- a/Sources/SPMTestSupport/PackageGraphTester.swift +++ b/Sources/SPMTestSupport/PackageGraphTester.swift @@ -158,7 +158,7 @@ public final class PackageGraphResult { } public final class ResolvedTargetResult { - private let target: ResolvedTarget + let target: ResolvedTarget init(_ target: ResolvedTarget) { self.target = target diff --git a/Tests/BuildTests/BuildPlanTests.swift b/Tests/BuildTests/BuildPlanTests.swift index 4909f43d701..bddbd2fd432 100644 --- a/Tests/BuildTests/BuildPlanTests.swift +++ b/Tests/BuildTests/BuildPlanTests.swift @@ -888,7 +888,7 @@ final class BuildPlanTests: XCTestCase { buildPath: buildDirPath, config: .release, toolchain: UserToolchain.default, - targetTriple: UserToolchain.default.targetTriple, + triple: UserToolchain.default.targetTriple, useExplicitModuleBuild: true ), graph: graph, @@ -1118,11 +1118,11 @@ final class BuildPlanTests: XCTestCase { observabilityScope: observability.topScope )) - XCTAssertEqual(Set(result.productMap.keys), ["APackageTests"]) + XCTAssertEqual(Set(result.productMap.keys.map(\.productName)), ["APackageTests"]) #if os(macOS) - XCTAssertEqual(Set(result.targetMap.keys), ["ATarget", "BTarget", "ATargetTests"]) + XCTAssertEqual(Set(result.targetMap.keys.map(\.targetName)), ["ATarget", "BTarget", "ATargetTests"]) #else - XCTAssertEqual(Set(result.targetMap.keys), [ + XCTAssertEqual(Set(result.targetMap.keys.map(\.targetName)), [ "APackageTests", "APackageDiscoveredTests", "ATarget", @@ -1469,7 +1469,13 @@ final class BuildPlanTests: XCTestCase { ]) #endif - let buildProduct = try XCTUnwrap(result.productMap["exe"]) + let buildProduct = try XCTUnwrap( + result.productMap[.init( + productName: "exe", + packageIdentity: "Pkg", + buildTriple: .destination + )] + ) XCTAssertEqual(Array(buildProduct.objects), [ buildPath.appending(components: "exe.build", "main.c.o"), buildPath.appending(components: "extlib.build", "extlib.c.o"), @@ -2567,7 +2573,7 @@ final class BuildPlanTests: XCTestCase { // Verify that `-lstdc++` is passed instead of `-lc++` when cross-compiling to Linux. result = try BuildPlanResult(plan: BuildPlan( - buildParameters: mockBuildParameters(targetTriple: .arm64Linux), + buildParameters: mockBuildParameters(triple: .arm64Linux), graph: graph, fileSystem: fs, observabilityScope: observability.topScope @@ -3373,7 +3379,7 @@ final class BuildPlanTests: XCTestCase { XCTAssertNoDiagnostics(observability.diagnostics) let result = try BuildPlanResult(plan: BuildPlan( - buildParameters: mockBuildParameters(targetTriple: .windows), + buildParameters: mockBuildParameters(triple: .windows), graph: graph, fileSystem: fs, observabilityScope: observability.topScope @@ -3460,7 +3466,7 @@ final class BuildPlanTests: XCTestCase { ) XCTAssertNoDiagnostics(observability.diagnostics) - var parameters = mockBuildParameters(targetTriple: .wasi) + var parameters = mockBuildParameters(triple: .wasi) parameters.linkingParameters.shouldLinkStaticSwiftStdlib = true let result = try BuildPlanResult(plan: BuildPlan( buildParameters: parameters, @@ -3562,7 +3568,7 @@ final class BuildPlanTests: XCTestCase { try BuildPlanResult(plan: BuildPlan( buildParameters: mockBuildParameters( canRenameEntrypointFunctionName: true, - targetTriple: triple + triple: triple ), graph: graph, fileSystem: fs, @@ -3762,7 +3768,7 @@ final class BuildPlanTests: XCTestCase { XCTAssertNoDiagnostics(observability.diagnostics) let result = try BuildPlanResult(plan: BuildPlan( - buildParameters: mockBuildParameters(targetTriple: .init("arm64-apple-ios")), + buildParameters: mockBuildParameters(triple: .init("arm64-apple-ios")), graph: graph, fileSystem: fileSystem, observabilityScope: observability.topScope @@ -3839,7 +3845,7 @@ final class BuildPlanTests: XCTestCase { // constraints above are valid. XCTAssertNoThrow( _ = try BuildPlan( - buildParameters: mockBuildParameters(targetTriple: .arm64iOS), + buildParameters: mockBuildParameters(triple: .arm64iOS), graph: graph, fileSystem: fileSystem, observabilityScope: observability.topScope @@ -3849,7 +3855,7 @@ final class BuildPlanTests: XCTestCase { // For completeness, the invalid target should still throw an error. XCTAssertThrows(Diagnostics.fatalError) { _ = try BuildPlan( - buildParameters: mockBuildParameters(targetTriple: .x86_64MacOS), + buildParameters: mockBuildParameters(triple: .x86_64MacOS), graph: graph, fileSystem: fileSystem, observabilityScope: observability.topScope @@ -3912,7 +3918,7 @@ final class BuildPlanTests: XCTestCase { XCTAssertThrows(Diagnostics.fatalError) { _ = try BuildPlan( - buildParameters: mockBuildParameters(targetTriple: .x86_64MacOS), + buildParameters: mockBuildParameters(triple: .x86_64MacOS), graph: graph, fileSystem: fileSystem, observabilityScope: observability.topScope @@ -4066,7 +4072,7 @@ final class BuildPlanTests: XCTestCase { func createResult(for dest: Basics.Triple) throws -> BuildPlanResult { try BuildPlanResult(plan: BuildPlan( - buildParameters: mockBuildParameters(targetTriple: dest), + buildParameters: mockBuildParameters(triple: dest), graph: graph, fileSystem: fs, observabilityScope: observability.topScope @@ -4129,7 +4135,7 @@ final class BuildPlanTests: XCTestCase { do { let result = try BuildPlanResult(plan: BuildPlan( buildParameters: mockBuildParameters( - targetTriple: .x86_64Linux, + triple: .x86_64Linux, omitFramePointers: true ), graph: graph, @@ -4185,7 +4191,7 @@ final class BuildPlanTests: XCTestCase { do { let result = try BuildPlanResult(plan: BuildPlan( buildParameters: mockBuildParameters( - targetTriple: .x86_64Linux, + triple: .x86_64Linux, omitFramePointers: false ), graph: graph, @@ -4546,7 +4552,7 @@ final class BuildPlanTests: XCTestCase { swiftCompilerFlags: [cliFlag(tool: .swiftCompiler)], linkerFlags: [cliFlag(tool: .linker)] ), - targetTriple: targetTriple + triple: targetTriple ) let result = try BuildPlanResult(plan: BuildPlan( buildParameters: buildParameters, @@ -5145,7 +5151,7 @@ final class BuildPlanTests: XCTestCase { XCTAssertNoDiagnostics(observability.diagnostics) let result = try BuildPlanResult(plan: BuildPlan( - buildParameters: mockBuildParameters(targetTriple: .x86_64Linux), + buildParameters: mockBuildParameters(triple: .x86_64Linux), graph: graph, fileSystem: fs, observabilityScope: observability.topScope @@ -5449,7 +5455,7 @@ final class BuildPlanTests: XCTestCase { XCTAssertNoDiagnostics(observability.diagnostics) let plan = try BuildPlan( - buildParameters: mockBuildParameters(targetTriple: .wasi), + buildParameters: mockBuildParameters(triple: .wasi), graph: graph, fileSystem: fs, observabilityScope: observability.topScope @@ -5582,7 +5588,7 @@ final class BuildPlanTests: XCTestCase { let supportingTriples: [Basics.Triple] = [.x86_64Linux, .arm64Linux, .wasi] for triple in supportingTriples { let result = try BuildPlanResult(plan: BuildPlan( - buildParameters: mockBuildParameters(shouldLinkStaticSwiftStdlib: true, targetTriple: triple), + buildParameters: mockBuildParameters(shouldLinkStaticSwiftStdlib: true, triple: triple), graph: graph, fileSystem: fs, observabilityScope: observability.topScope @@ -5707,7 +5713,7 @@ final class BuildPlanTests: XCTestCase { XCTAssertNoDiagnostics(observability.diagnostics) let result = try BuildPlanResult(plan: BuildPlan( - buildParameters: mockBuildParameters(targetTriple: targetTriple), + buildParameters: mockBuildParameters(triple: targetTriple), graph: graph, fileSystem: fs, observabilityScope: observability.topScope @@ -5836,7 +5842,7 @@ final class BuildPlanTests: XCTestCase { XCTAssertNoDiagnostics(observability.diagnostics) let result = try BuildPlanResult(plan: BuildPlan( - buildParameters: mockBuildParameters(targetTriple: targetTriple), + buildParameters: mockBuildParameters(triple: targetTriple), graph: graph, fileSystem: fs, observabilityScope: observability.topScope @@ -6109,7 +6115,13 @@ final class BuildPlanTests: XCTestCase { observabilityScope: observability.topScope )) - switch try XCTUnwrap(result.targetMap["ExtLib"]) { + switch try XCTUnwrap( + result.targetMap[.init( + targetName: "ExtLib", + packageIdentity: "ExtPkg", + buildTriple: .destination + )] + ) { case .swift(let swiftTarget): if #available(macOS 13, *) { // `.contains` is only available in macOS 13 or newer XCTAssertTrue(try swiftTarget.compileArguments().contains(["-user-module-version", "1.0.0"])) @@ -6266,7 +6278,13 @@ final class BuildPlanTests: XCTestCase { result.checkTargetsCount(3) XCTAssertTrue(result.targetMap.values.contains { $0.target.name == "FooLogging" }) XCTAssertTrue(result.targetMap.values.contains { $0.target.name == "BarLogging" }) - let buildProduct = try XCTUnwrap(result.productMap["exe"]) + let buildProduct = try XCTUnwrap( + result.productMap[.init( + productName: "exe", + packageIdentity: "thisPkg", + buildTriple: .destination + )] + ) let dylibs = Array(buildProduct.dylibs.map({$0.product.name})).sorted() XCTAssertEqual(dylibs, ["BarLogging", "FooLogging"]) } diff --git a/Tests/BuildTests/CrossCompilationBuildTests.swift b/Tests/BuildTests/CrossCompilationBuildTests.swift new file mode 100644 index 00000000000..e9574735543 --- /dev/null +++ b/Tests/BuildTests/CrossCompilationBuildTests.swift @@ -0,0 +1,60 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the Swift open source project +// +// Copyright (c) 2014-2024 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See http://swift.org/LICENSE.txt for license information +// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// + +import class Basics.ObservabilitySystem +import struct Basics.Triple +import class Build.BuildPlan +import class Build.SwiftTargetBuildDescription +import func SPMTestSupport.macrosPackageGraph +import func SPMTestSupport.mockBuildParameters +import struct SPMTestSupport.BuildPlanResult +import func SPMTestSupport.XCTAssertMatch +import class TSCBasic.InMemoryFileSystem + +import XCTest + +extension BuildPlanResult { + func allTargets(named targetName: String) throws -> [SwiftTargetBuildDescription] { + try self.targetMap + .filter { $0.0.targetName == targetName } + .map { try $1.swiftTarget() } + } + + func check(triple: Triple, for target: String, file: StaticString = #file, line: UInt = #line) throws { + let target = try self.target(for: target).swiftTarget() + XCTAssertMatch(try target.emitCommandLine(), [.contains(triple.tripleString)], file: file, line: line) + } +} + +final class CrossCompilationBuildPlanTests: XCTestCase { + func testMacros() throws { + let (graph, fs, scope) = try macrosPackageGraph() + + let productsTriple = Triple.x86_64MacOS + let toolsTriple = Triple.arm64Linux + let result = try BuildPlanResult(plan: BuildPlan( + productsBuildParameters: mockBuildParameters(shouldLinkStaticSwiftStdlib: true, triple: productsTriple), + toolsBuildParameters: mockBuildParameters(triple: toolsTriple), + graph: graph, + fileSystem: fs, + observabilityScope: scope + )) + result.checkProductsCount(3) + result.checkTargetsCount(8) + + XCTAssertTrue(try result.allTargets(named: "SwiftSyntax").contains { $0.target.buildTriple == .tools }) + try result.check(triple: toolsTriple, for: "MMIOMacros") + try result.check(triple: productsTriple, for: "MMIO") + try result.check(triple: productsTriple, for: "Core") + try result.check(triple: productsTriple, for: "HAL") + } +} diff --git a/Tests/PackageGraphTests/CrossCompilationPackageGraphTests.swift b/Tests/PackageGraphTests/CrossCompilationPackageGraphTests.swift new file mode 100644 index 00000000000..79076d69adc --- /dev/null +++ b/Tests/PackageGraphTests/CrossCompilationPackageGraphTests.swift @@ -0,0 +1,61 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the Swift open source project +// +// Copyright (c) 2014-2024 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See http://swift.org/LICENSE.txt for license information +// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// + +@testable +import SPMTestSupport + +@testable +import PackageGraph + +import XCTest + +final class CrossCompilationPackageGraphTests: XCTestCase { + func testMacros() throws { + let graph = try macrosPackageGraph().graph + PackageGraphTester(graph) { result in + result.check(packages: "swift-firmware", "swift-mmio", "swift-syntax") + // "SwiftSyntax" is included for both host and target triples and is not pruned on this level + result.check(targets: "Core", "HAL", "MMIO", "MMIOMacros", "SwiftSyntax", "SwiftSyntax") + result.check(testModules: "CoreTests", "HALTests") + result.checkTarget("Core") { result in + result.check(buildTriple: .destination) + result.check(dependencies: "HAL") + } + result.checkTarget("HAL") { result in + result.check(buildTriple: .destination) + result.check(dependencies: "MMIO") + } + result.checkTarget("MMIO") { result in + result.check(buildTriple: .destination) + result.check(dependencies: "MMIOMacros") + } + result.checkTarget("MMIOMacros") { result in + result.check(buildTriple: .tools) + result.checkDependency("SwiftSyntax") { result in + result.checkProduct { result in + result.check(buildTriple: .tools) + result.checkTarget("SwiftSyntax") { result in + result.check(buildTriple: .tools) + } + } + } + } + + result.checkTargets("SwiftSyntax") { results in + XCTAssertEqual(results.count, 2) + + XCTAssertEqual(results.filter({ $0.target.buildTriple == .tools }).count, 1) + XCTAssertEqual(results.filter({ $0.target.buildTriple == .destination }).count, 1) + } + } + } +} diff --git a/Tests/PackageGraphTests/CrossCompiledPackageGraphTests.swift b/Tests/PackageGraphTests/CrossCompiledPackageGraphTests.swift deleted file mode 100644 index dae2ec4527a..00000000000 --- a/Tests/PackageGraphTests/CrossCompiledPackageGraphTests.swift +++ /dev/null @@ -1,151 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift open source project -// -// Copyright (c) 2014-2024 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See http://swift.org/LICENSE.txt for license information -// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -import class Basics.ObservabilitySystem -import class PackageModel.Manifest -import struct PackageModel.ProductDescription -import struct PackageModel.TargetDescription -import func SPMTestSupport.loadPackageGraph -import func SPMTestSupport.PackageGraphTester -import func SPMTestSupport.XCTAssertNoDiagnostics -import class TSCBasic.InMemoryFileSystem - -@testable -import PackageGraph - -import XCTest - -final class CrossCompiledPackageGraphTests: XCTestCase { - func testMacros() throws { - let fs = InMemoryFileSystem(emptyFiles: - "/swift-firmware/Sources/Core/source.swift", - "/swift-firmware/Sources/HAL/source.swift", - "/swift-firmware/Tests/CoreTests/source.swift", - "/swift-firmware/Tests/HALTests/source.swift", - "/swift-mmio/Sources/MMIO/source.swift", - "/swift-mmio/Sources/MMIOMacros/source.swift", - "/swift-syntax/Sources/SwiftSyntax/source.swift", - "/swift-syntax/Tests/SwiftSyntaxTests/source.swift" - ) - - let observability = ObservabilitySystem.makeForTesting() - let g = try loadPackageGraph( - fileSystem: fs, - manifests: [ - Manifest.createRootManifest( - displayName: "swift-firmware", - path: "/swift-firmware", - dependencies: [ - .localSourceControl( - path: "/swift-mmio", - requirement: .upToNextMajor(from: "1.0.0") - ) - ], - products: [ - ProductDescription( - name: "Core", - type: .executable, - targets: ["Core"] - ) - ], - targets: [ - TargetDescription( - name: "Core", - dependencies: ["HAL"], - type: .executable - ), - TargetDescription( - name: "HAL", - dependencies: [.product(name: "MMIO", package: "swift-mmio")] - ), - TargetDescription(name: "CoreTests", dependencies: ["Core"], type: .test), - TargetDescription(name: "HALTests", dependencies: ["HAL"], type: .test), - ] - ), - Manifest.createFileSystemManifest( - displayName: "swift-mmio", - path: "/swift-mmio", - dependencies: [ - .localSourceControl( - path: "/swift-syntax", - requirement: .upToNextMajor(from: "1.0.0") - ) - ], - products: [ - ProductDescription( - name: "MMIO", - type: .library(.automatic), - targets: ["MMIO"] - ) - ], - targets: [ - TargetDescription( - name: "MMIO", - dependencies: [.target(name: "MMIOMacros")] - ), - TargetDescription( - name: "MMIOMacros", - dependencies: [.product(name: "SwiftSyntax", package: "swift-syntax")], - type: .macro - ) - ] - ), - Manifest.createFileSystemManifest( - displayName: "swift-syntax", - path: "/swift-syntax", - products: [ - ProductDescription( - name: "SwiftSyntax", - type: .library(.automatic), - targets: ["SwiftSyntax"] - ) - ], - targets: [ - TargetDescription(name: "SwiftSyntax", dependencies: []), - TargetDescription(name: "SwiftSyntaxTests", dependencies: ["SwiftSyntax"], type: .test), - ] - ), - ], - observabilityScope: observability.topScope - ) - - XCTAssertNoDiagnostics(observability.diagnostics) - PackageGraphTester(g) { result in - result.check(packages: "swift-firmware", "swift-mmio", "swift-syntax") - result.check(targets: "Core", "HAL", "MMIO", "MMIOMacros", "SwiftSyntax") - result.check(testModules: "CoreTests", "HALTests") - result.checkTarget("Core") { result in - result.check(buildTriple: .destination) - result.check(dependencies: "HAL") - } - result.checkTarget("HAL") { result in - result.check(buildTriple: .destination) - result.check(dependencies: "MMIO") - } - result.checkTarget("MMIO") { result in - result.check(buildTriple: .destination) - result.check(dependencies: "MMIOMacros") - } - result.checkTarget("MMIOMacros") { result in - result.check(buildTriple: .tools) - result.checkDependency("SwiftSyntax") { result in - result.checkProduct { result in - result.check(buildTriple: .tools) - result.checkTarget("SwiftSyntax") { result in - result.check(buildTriple: .tools) - } - } - } - } - } - } -} From 63eaf8da1fb4d155700a22e54d02262a06b55874 Mon Sep 17 00:00:00 2001 From: Max Desiatov Date: Wed, 31 Jan 2024 14:47:39 +0000 Subject: [PATCH 18/33] Fix nodes naming collisions in the build plan --- .../ClangTargetBuildDescription.swift | 5 +++- .../ResolvedTarget+BuildDescription.swift | 23 ++++++++++++++++++ .../SwiftTargetBuildDescription.swift | 6 +++-- .../LLBuildManifestBuilder.swift | 6 +++-- Sources/Build/BuildOperation.swift | 2 +- Sources/Build/BuildPlan/BuildPlan.swift | 19 ++++++++------- Sources/Build/CMakeLists.txt | 1 + .../BuildParameters/BuildParameters.swift | 11 ++++++++- .../LLBuildManifestBuilderTests.swift | 24 +++++++++++++++++-- Tests/BuildTests/PluginsBuildPlanTests.swift | 2 +- .../PluginInvocationTests.swift | 3 ++- 11 files changed, 83 insertions(+), 19 deletions(-) create mode 100644 Sources/Build/BuildDescription/ResolvedTarget+BuildDescription.swift diff --git a/Sources/Build/BuildDescription/ClangTargetBuildDescription.swift b/Sources/Build/BuildDescription/ClangTargetBuildDescription.swift index 0d51e46b51a..0c6c704a2c7 100644 --- a/Sources/Build/BuildDescription/ClangTargetBuildDescription.swift +++ b/Sources/Build/BuildDescription/ClangTargetBuildDescription.swift @@ -19,6 +19,9 @@ import struct SPMBuildCore.BuildParameters import struct SPMBuildCore.BuildToolPluginInvocationResult import struct SPMBuildCore.PrebuildCommandResult +@_spi(SwiftPMInternal) +import SPMBuildCore + import enum TSCBasic.ProcessEnv /// Target description for a Clang target i.e. C language family target. @@ -127,7 +130,7 @@ public final class ClangTargetBuildDescription { self.target = target self.toolsVersion = toolsVersion self.buildParameters = buildParameters - self.tempsPath = buildParameters.buildPath.appending(component: target.c99name + ".build") + self.tempsPath = target.tempsPath(buildParameters) self.derivedSources = Sources(paths: [], root: tempsPath.appending("DerivedSources")) // We did not use to apply package plugins to C-family targets in prior tools-versions, this preserves the behavior. diff --git a/Sources/Build/BuildDescription/ResolvedTarget+BuildDescription.swift b/Sources/Build/BuildDescription/ResolvedTarget+BuildDescription.swift new file mode 100644 index 00000000000..10024bd0d10 --- /dev/null +++ b/Sources/Build/BuildDescription/ResolvedTarget+BuildDescription.swift @@ -0,0 +1,23 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the Swift open source project +// +// Copyright (c) 2015-2023 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See http://swift.org/LICENSE.txt for license information +// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// + +import struct Basics.AbsolutePath +import struct PackageGraph.ResolvedTarget + +@_spi(SwiftPMInternal) +import SPMBuildCore + +extension ResolvedTarget { + func tempsPath(_ buildParameters: BuildParameters) -> AbsolutePath { + buildParameters.buildPath.appending(component: self.c99name + "\(self.buildTriple.suffix).build") + } +} diff --git a/Sources/Build/BuildDescription/SwiftTargetBuildDescription.swift b/Sources/Build/BuildDescription/SwiftTargetBuildDescription.swift index 43302bcf542..abfb1123c24 100644 --- a/Sources/Build/BuildDescription/SwiftTargetBuildDescription.swift +++ b/Sources/Build/BuildDescription/SwiftTargetBuildDescription.swift @@ -15,6 +15,8 @@ import Foundation import PackageGraph import PackageLoading import PackageModel + +@_spi(SwiftPMInternal) import SPMBuildCore #if USE_IMPL_ONLY_IMPORTS @@ -115,7 +117,7 @@ public final class SwiftTargetBuildDescription { let triple = buildParameters.triple let allowLinkingAgainstExecutables = (triple.isDarwin() || triple.isLinux() || triple.isWindows()) && self.toolsVersion >= .v5_5 let dirPath = (target.type == .executable && !allowLinkingAgainstExecutables) ? self.tempsPath : self.modulesPath - return dirPath.appending(component: self.target.c99name + ".swiftmodule") + return dirPath.appending(component: self.target.c99name + "\(self.target.buildTriple.suffix).swiftmodule") } /// The path to the wrapped swift module which is created using the modulewrap tool. This is required @@ -277,7 +279,7 @@ public final class SwiftTargetBuildDescription { self.testTargetRole = nil } - self.tempsPath = buildParameters.buildPath.appending(component: target.c99name + ".build") + self.tempsPath = target.tempsPath(buildParameters) self.derivedSources = Sources(paths: [], root: self.tempsPath.appending("DerivedSources")) self.buildToolPluginInvocationResults = buildToolPluginInvocationResults self.prebuildCommandResults = prebuildCommandResults diff --git a/Sources/Build/BuildManifest/LLBuildManifestBuilder.swift b/Sources/Build/BuildManifest/LLBuildManifestBuilder.swift index 4d9b6d62787..25ebd089fec 100644 --- a/Sources/Build/BuildManifest/LLBuildManifestBuilder.swift +++ b/Sources/Build/BuildManifest/LLBuildManifestBuilder.swift @@ -14,6 +14,8 @@ import Basics import LLBuildManifest import PackageGraph import PackageModel + +@_spi(SwiftPMInternal) import SPMBuildCore #if USE_IMPL_ONLY_IMPORTS @@ -322,11 +324,11 @@ extension ResolvedTarget { } public func getLLBuildTargetName(config: String) -> String { - "\(name)-\(config).module" + "\(self.name)-\(config)\(self.buildTriple.suffix).module" } public func getLLBuildResourcesCmdName(config: String) -> String { - "\(name)-\(config).module-resources" + "\(self.name)-\(config).module-resources" } } diff --git a/Sources/Build/BuildOperation.swift b/Sources/Build/BuildOperation.swift index cde0828dba9..eeb539cf7f0 100644 --- a/Sources/Build/BuildOperation.swift +++ b/Sources/Build/BuildOperation.swift @@ -456,7 +456,7 @@ public final class BuildOperation: PackageStructureDelegate, SPMBuildCore.BuildS // Invoke any build tool plugins in the graph to generate prebuild commands and build commands. if let pluginConfiguration, !self.productsBuildParameters.shouldSkipBuilding { // Hacky workaround for rdar://120560817, but it replicates precisely enough the original behavior before - // products/tools build parameters were split. Ideally we want to have specify the correct path at the time + // products/tools build parameters were split. Ideally we want to specify the correct path at the time // when `toolsBuildParameters` is initialized, but we have too many places in the codebase where that's // done, which makes it hard to realign them all at once. var pluginsBuildParameters = self.toolsBuildParameters diff --git a/Sources/Build/BuildPlan/BuildPlan.swift b/Sources/Build/BuildPlan/BuildPlan.swift index c133b9a917c..c12faaca730 100644 --- a/Sources/Build/BuildPlan/BuildPlan.swift +++ b/Sources/Build/BuildPlan/BuildPlan.swift @@ -126,7 +126,7 @@ extension BuildParameters { } return [] } - + public func tripleArgs(for target: ResolvedTarget) throws -> [String] { // confusingly enough this is the triple argument, not the target argument var args = ["-target"] @@ -158,7 +158,7 @@ extension BuildParameters { /// Returns the scoped view of build settings for a given target. func createScope(for target: ResolvedTarget) -> BuildSettings.Scope { - return BuildSettings.Scope(target.underlying.buildSettings, environment: buildEnvironment) + BuildSettings.Scope(target.underlying.buildSettings, environment: buildEnvironment) } } @@ -279,7 +279,8 @@ public class BuildPlan: SPMBuildCore.BuildPlan { self.fileSystem = fileSystem self.observabilityScope = observabilityScope.makeChildScope(description: "Build Plan") - var productMap: [ResolvedProduct.ID: (product: ResolvedProduct, buildDescription: ProductBuildDescription)] = [:] + var productMap: [ResolvedProduct.ID: (product: ResolvedProduct, buildDescription: ProductBuildDescription)] = + [:] // Create product description for each product we have in the package graph that is eligible. for product in graph.allProducts where product.shouldCreateProductDescription { let buildParameters: BuildParameters @@ -437,7 +438,9 @@ public class BuildPlan: SPMBuildCore.BuildPlan { for item in derivedTestTargets { var derivedTestTargets = [item.entryPointTargetBuildDescription.target] - targetMap[item.entryPointTargetBuildDescription.target.id] = .swift(item.entryPointTargetBuildDescription) + targetMap[item.entryPointTargetBuildDescription.target.id] = .swift( + item.entryPointTargetBuildDescription + ) if let discoveryTargetBuildDescription = item.discoveryTargetBuildDescription { targetMap[discoveryTargetBuildDescription.target.id] = .swift(discoveryTargetBuildDescription) @@ -543,9 +546,9 @@ public class BuildPlan: SPMBuildCore.BuildPlan { } // Add search paths from the system library targets. - for target in graph.reachableTargets { + for target in self.graph.reachableTargets { if let systemLib = target.underlying as? SystemLibraryTarget { - arguments.append(contentsOf: try self.pkgConfig(for: systemLib).cFlags) + try arguments.append(contentsOf: self.pkgConfig(for: systemLib).cFlags) // Add the path to the module map. arguments += ["-I", systemLib.moduleMapPath.parentDirectory.pathString] } @@ -580,7 +583,7 @@ public class BuildPlan: SPMBuildCore.BuildPlan { } // Add search paths from the system library targets. - for target in graph.reachableTargets { + for target in self.graph.reachableTargets { if let systemLib = target.underlying as? SystemLibraryTarget { arguments += try self.pkgConfig(for: systemLib).cFlags } @@ -719,7 +722,7 @@ extension ResolvedProduct { } private var isBinaryOnly: Bool { - return self.targets.filter({ !($0.underlying is BinaryTarget) }).isEmpty + self.targets.filter { !($0.underlying is BinaryTarget) }.isEmpty } private var isPlugin: Bool { diff --git a/Sources/Build/CMakeLists.txt b/Sources/Build/CMakeLists.txt index 6f933c69f93..6aac9ce00c1 100644 --- a/Sources/Build/CMakeLists.txt +++ b/Sources/Build/CMakeLists.txt @@ -10,6 +10,7 @@ add_library(Build BuildDescription/ClangTargetBuildDescription.swift BuildDescription/PluginDescription.swift BuildDescription/ProductBuildDescription.swift + BuildDescription/ResolvedTarget+BuildDescription.swift BuildDescription/SwiftTargetBuildDescription.swift BuildDescription/TargetBuildDescription.swift BuildManifest/LLBuildManifestBuilder.swift diff --git a/Sources/SPMBuildCore/BuildParameters/BuildParameters.swift b/Sources/SPMBuildCore/BuildParameters/BuildParameters.swift index cbc5cb5499c..6e4ceb04aa2 100644 --- a/Sources/SPMBuildCore/BuildParameters/BuildParameters.swift +++ b/Sources/SPMBuildCore/BuildParameters/BuildParameters.swift @@ -248,7 +248,7 @@ public struct BuildParameters: Encodable { /// Returns the path to the binary of a product for the current build parameters, relative to the build directory. public func binaryRelativePath(for product: ResolvedProduct) throws -> RelativePath { - let potentialExecutablePath = try RelativePath(validating: "\(product.name)\(self.triple.executableExtension)") + let potentialExecutablePath = try RelativePath(validating: "\(product.name)\(product.buildTriple.suffix)\(self.triple.executableExtension)") switch product.type { case .executable, .snippet: @@ -329,3 +329,12 @@ extension Triple { return !self.isWindows() } } + +extension BuildTriple { + /// Suffix appended to build manifest nodes to distinguish nodes created for tools from nodes created for + /// end products, i.e. nodes for host vs target triples. + @_spi(SwiftPMInternal) + public var suffix: String { + if self == .tools { "-tool" } else { "" } + } +} diff --git a/Tests/BuildTests/LLBuildManifestBuilderTests.swift b/Tests/BuildTests/LLBuildManifestBuilderTests.swift index d577e577c7a..12de0d0057b 100644 --- a/Tests/BuildTests/LLBuildManifestBuilderTests.swift +++ b/Tests/BuildTests/LLBuildManifestBuilderTests.swift @@ -95,7 +95,7 @@ final class LLBuildManifestBuilderTests: XCTestCase { result = try BuildPlanResult(plan: plan) buildProduct = try result.buildProduct(for: "exe") - llbuild = LLBuildManifestBuilder(plan, fileSystem: localFileSystem, observabilityScope: observability.topScope) + llbuild = LLBuildManifestBuilder(plan, fileSystem: fs, observabilityScope: observability.topScope) try llbuild.createProductCommand(buildProduct) let entitlementsCommandName = "C.exe-debug.exe-entitlements" @@ -174,7 +174,7 @@ final class LLBuildManifestBuilderTests: XCTestCase { result = try BuildPlanResult(plan: plan) buildProduct = try result.buildProduct(for: "exe") - llbuild = LLBuildManifestBuilder(plan, fileSystem: localFileSystem, observabilityScope: observability.topScope) + llbuild = LLBuildManifestBuilder(plan, fileSystem: fs, observabilityScope: observability.topScope) try llbuild.createProductCommand(buildProduct) XCTAssertEqual( @@ -182,4 +182,24 @@ final class LLBuildManifestBuilderTests: XCTestCase { basicDebugCommandNames.sorted() ) } + + /// Verifies that two targets with the same name but different triples don't share same build manifest keys. + func testToolsBuildTriple() throws { + let (graph, fs, scope) = try macrosPackageGraph() + let productsTriple = Triple.x86_64MacOS + let toolsTriple = Triple.arm64Linux + + let plan = try BuildPlan( + productsBuildParameters: mockBuildParameters(shouldLinkStaticSwiftStdlib: true, triple: productsTriple), + toolsBuildParameters: mockBuildParameters(triple: toolsTriple), + graph: graph, + fileSystem: fs, + observabilityScope: scope + ) + + let builder = LLBuildManifestBuilder(plan, fileSystem: fs, observabilityScope: scope) + let manifest = try builder.generateManifest(at: "/manifest") + + XCTAssertNotNil(manifest.commands["C.SwiftSyntax-debug-tool.module"]) + } } diff --git a/Tests/BuildTests/PluginsBuildPlanTests.swift b/Tests/BuildTests/PluginsBuildPlanTests.swift index 5ef99e3fc59..892c3da6725 100644 --- a/Tests/BuildTests/PluginsBuildPlanTests.swift +++ b/Tests/BuildTests/PluginsBuildPlanTests.swift @@ -19,7 +19,7 @@ import PackageModel final class PluginsBuildPlanTests: XCTestCase { func testBuildToolsDatabasePath() throws { try fixture(name: "Miscellaneous/Plugins/MySourceGenPlugin") { fixturePath in - let (stdout, stderr) = try executeSwiftBuild(fixturePath) + let (stdout, _) = try executeSwiftBuild(fixturePath) XCTAssertMatch(stdout, .contains("Build complete!")) XCTAssertTrue(localFileSystem.exists(fixturePath.appending(RelativePath(".build/plugins/tools/build.db")))) } diff --git a/Tests/SPMBuildCoreTests/PluginInvocationTests.swift b/Tests/SPMBuildCoreTests/PluginInvocationTests.swift index f2ab3cb231d..8999d683895 100644 --- a/Tests/SPMBuildCoreTests/PluginInvocationTests.swift +++ b/Tests/SPMBuildCoreTests/PluginInvocationTests.swift @@ -74,7 +74,8 @@ class PluginInvocationTests: XCTestCase { XCTAssertNoDiagnostics(observability.diagnostics) PackageGraphTester(graph) { graph in graph.check(packages: "Foo") - graph.check(targets: "Foo", "FooPlugin", "FooTool") + // "FooTool" duplicated as it's present for both build tools and end products triples. + graph.check(targets: "Foo", "FooPlugin", "FooTool", "FooTool") graph.checkTarget("Foo") { target in target.check(dependencies: "FooPlugin") } From eabe05b86cf2e7d584b120ceb2088893805c001f Mon Sep 17 00:00:00 2001 From: Max Desiatov Date: Tue, 6 Feb 2024 16:41:29 +0000 Subject: [PATCH 19/33] Fix remaining name collisions in llbuild manifests --- .../LLBuildManifestBuilder.swift | 10 ++-- .../BuildSystem/BuildSystem.swift | 2 +- Tests/CommandsTests/PackageToolTests.swift | 47 ++++++++++++++----- 3 files changed, 42 insertions(+), 17 deletions(-) diff --git a/Sources/Build/BuildManifest/LLBuildManifestBuilder.swift b/Sources/Build/BuildManifest/LLBuildManifestBuilder.swift index 25ebd089fec..63038ce6a8a 100644 --- a/Sources/Build/BuildManifest/LLBuildManifestBuilder.swift +++ b/Sources/Build/BuildManifest/LLBuildManifestBuilder.swift @@ -334,16 +334,16 @@ extension ResolvedTarget { extension ResolvedProduct { public func getLLBuildTargetName(config: String) throws -> String { - let potentialExecutableTargetName = "\(name)-\(config).exe" - let potentialLibraryTargetName = "\(name)-\(config).dylib" + let potentialExecutableTargetName = "\(name)-\(config)\(self.buildTriple.suffix).exe" + let potentialLibraryTargetName = "\(name)-\(config)\(self.buildTriple.suffix).dylib" switch type { case .library(.dynamic): return potentialLibraryTargetName case .test: - return "\(name)-\(config).test" + return "\(name)-\(config)\(self.buildTriple.suffix).test" case .library(.static): - return "\(name)-\(config).a" + return "\(name)-\(config)\(self.buildTriple.suffix).a" case .library(.automatic): throw InternalError("automatic library not supported") case .executable, .snippet: @@ -360,7 +360,7 @@ extension ResolvedProduct { } public func getCommandName(config: String) throws -> String { - try "C." + self.getLLBuildTargetName(config: config) + try "C.\(self.getLLBuildTargetName(config: config))\(self.buildTriple.suffix)" } } diff --git a/Sources/SPMBuildCore/BuildSystem/BuildSystem.swift b/Sources/SPMBuildCore/BuildSystem/BuildSystem.swift index e8d1fd3efe1..5d9e1e0e982 100644 --- a/Sources/SPMBuildCore/BuildSystem/BuildSystem.swift +++ b/Sources/SPMBuildCore/BuildSystem/BuildSystem.swift @@ -74,7 +74,7 @@ extension ProductBuildDescription { /// The path to the product binary produced. public var binaryPath: AbsolutePath { get throws { - return try self.buildParameters.binaryPath(for: product) + try self.buildParameters.binaryPath(for: product) } } } diff --git a/Tests/CommandsTests/PackageToolTests.swift b/Tests/CommandsTests/PackageToolTests.swift index 4e770167975..8810cc908db 100644 --- a/Tests/CommandsTests/PackageToolTests.swift +++ b/Tests/CommandsTests/PackageToolTests.swift @@ -1714,9 +1714,15 @@ final class PackageToolTests: CommandsTestCase { """ ) let hostTriple = try UserToolchain(swiftSDK: .hostSwiftSDK()).targetTriple - let hostTripleString = hostTriple.isDarwin() ? hostTriple.tripleString(forPlatformVersion: "") : hostTriple.tripleString - try localFileSystem.writeFileContents(packageDir.appending(components: "Binaries", "LocalBinaryTool.artifactbundle", "info.json"), string: - """ + let hostTripleString = if hostTriple.isDarwin() { + hostTriple.tripleString(forPlatformVersion: "") + } else { + hostTriple.tripleString + } + + try localFileSystem.writeFileContents( + packageDir.appending(components: "Binaries", "LocalBinaryTool.artifactbundle", "info.json"), + string: """ { "schemaVersion": "1.0", "artifacts": { "LocalBinaryTool": { @@ -1732,11 +1738,13 @@ final class PackageToolTests: CommandsTestCase { } """ ) - try localFileSystem.writeFileContents(packageDir.appending(components: "Sources", "LocalBuiltTool", "main.swift"), string: - #"print("Hello")"# + try localFileSystem.writeFileContents( + packageDir.appending(components: "Sources", "LocalBuiltTool", "main.swift"), + string: #"print("Hello")"# ) - try localFileSystem.writeFileContents(packageDir.appending(components: "Plugins", "MyPlugin", "plugin.swift"), string: - """ + try localFileSystem.writeFileContents( + packageDir.appending(components: "Plugins", "MyPlugin", "plugin.swift"), + string: """ import PackagePlugin import Foundation @main @@ -1792,8 +1800,9 @@ final class PackageToolTests: CommandsTestCase { ) // Create the sample vendored dependency package. - try localFileSystem.writeFileContents(packageDir.appending(components: "VendoredDependencies", "HelperPackage", "Package.swift"), string: - """ + try localFileSystem.writeFileContents( + packageDir.appending(components: "VendoredDependencies", "HelperPackage", "Package.swift"), + string: """ // swift-tools-version: 5.5 import PackageDescription let package = Package( @@ -1819,9 +1828,25 @@ final class PackageToolTests: CommandsTestCase { ) """ ) - try localFileSystem.writeFileContents(packageDir.appending(components: "VendoredDependencies", "HelperPackage", "Sources", "HelperLibrary", "library.swift"), string: "public func Bar() { }" + try localFileSystem.writeFileContents( + packageDir.appending( + components: "VendoredDependencies", + "HelperPackage", + "Sources", + "HelperLibrary", + "library.swift" + ), + string: "public func Bar() { }" ) - try localFileSystem.writeFileContents(packageDir.appending(components: "VendoredDependencies", "HelperPackage", "Sources", "RemoteBuiltTool", "main.swift"), string: #"print("Hello")"# + try localFileSystem.writeFileContents( + packageDir.appending( + components: "VendoredDependencies", + "HelperPackage", + "Sources", + "RemoteBuiltTool", + "main.swift" + ), + string: #"print("Hello")"# ) // Check that we can invoke the plugin with the "plugin" subcommand. From a8b35efc57759057ec5061a95107351a9d9eaf3f Mon Sep 17 00:00:00 2001 From: Max Desiatov Date: Tue, 13 Feb 2024 18:20:26 +0000 Subject: [PATCH 20/33] Fix incorrect `-tool` suffix module paths, plugins build triple --- .../SwiftTargetBuildDescription.swift | 4 +- Sources/Build/BuildOperation.swift | 10 +++- Sources/PackageGraph/PackageGraph.swift | 48 ++++++++++++++++--- .../Resolution/ResolvedProduct.swift | 2 +- .../Resolution/ResolvedTarget.swift | 2 +- .../Plugins/PluginInvocation.swift | 4 +- 6 files changed, 57 insertions(+), 13 deletions(-) diff --git a/Sources/Build/BuildDescription/SwiftTargetBuildDescription.swift b/Sources/Build/BuildDescription/SwiftTargetBuildDescription.swift index 09379e461b0..c1872540ba5 100644 --- a/Sources/Build/BuildDescription/SwiftTargetBuildDescription.swift +++ b/Sources/Build/BuildDescription/SwiftTargetBuildDescription.swift @@ -108,7 +108,7 @@ public final class SwiftTargetBuildDescription { } var modulesPath: AbsolutePath { - return self.buildParameters.buildPath.appending(component: "Modules") + return self.buildParameters.buildPath.appending(component: "Modules\(self.target.buildTriple.suffix)") } /// The path to the swiftmodule file after compilation. @@ -117,7 +117,7 @@ public final class SwiftTargetBuildDescription { let triple = buildParameters.triple let allowLinkingAgainstExecutables = (triple.isDarwin() || triple.isLinux() || triple.isWindows()) && self.toolsVersion >= .v5_5 let dirPath = (target.type == .executable && !allowLinkingAgainstExecutables) ? self.tempsPath : self.modulesPath - return dirPath.appending(component: self.target.c99name + "\(self.target.buildTriple.suffix).swiftmodule") + return dirPath.appending(component: "\(self.target.c99name).swiftmodule") } /// The path to the wrapped swift module which is created using the modulewrap tool. This is required diff --git a/Sources/Build/BuildOperation.swift b/Sources/Build/BuildOperation.swift index 6aad0f85e8f..bf20391e763 100644 --- a/Sources/Build/BuildOperation.swift +++ b/Sources/Build/BuildOperation.swift @@ -12,7 +12,10 @@ import Basics import LLBuildManifest + +@_spi(SwiftPMInternal) import PackageGraph + import PackageLoading import PackageModel import SPMBuildCore @@ -460,12 +463,15 @@ public final class BuildOperation: PackageStructureDelegate, SPMBuildCore.BuildS // done, which makes it hard to realign them all at once. var pluginsBuildParameters = self.toolsBuildParameters pluginsBuildParameters.dataPath = pluginsBuildParameters.dataPath.parentDirectory.appending(components: ["plugins", "tools"]) + var buildToolsGraph = graph + try buildToolsGraph.updateBuildTripleRecursively(.tools) + let buildOperationForPluginDependencies = BuildOperation( // FIXME: this doesn't maintain the products/tools split cleanly productsBuildParameters: pluginsBuildParameters, toolsBuildParameters: pluginsBuildParameters, cacheBuildManifest: false, - packageGraphLoader: { return graph }, + packageGraphLoader: { buildToolsGraph }, additionalFileRules: self.additionalFileRules, pkgConfigDirectories: self.pkgConfigDirectories, outputStream: self.outputStream, @@ -473,7 +479,7 @@ public final class BuildOperation: PackageStructureDelegate, SPMBuildCore.BuildS fileSystem: self.fileSystem, observabilityScope: self.observabilityScope ) - buildToolPluginInvocationResults = try graph.invokeBuildToolPlugins( + buildToolPluginInvocationResults = try buildToolsGraph.invokeBuildToolPlugins( outputDir: pluginConfiguration.workDirectory.appending("outputs"), buildParameters: pluginsBuildParameters, additionalFileRules: self.additionalFileRules, diff --git a/Sources/PackageGraph/PackageGraph.swift b/Sources/PackageGraph/PackageGraph.swift index fb2146ba3a5..6ca5fc68b59 100644 --- a/Sources/PackageGraph/PackageGraph.swift +++ b/Sources/PackageGraph/PackageGraph.swift @@ -59,16 +59,16 @@ public struct PackageGraph { public let packages: [ResolvedPackage] /// The list of all targets reachable from root targets. - public let reachableTargets: IdentifiableSet + public private(set) var reachableTargets: IdentifiableSet /// The list of all products reachable from root targets. - public let reachableProducts: IdentifiableSet + public private(set) var reachableProducts: IdentifiableSet /// Returns all the targets in the graph, regardless if they are reachable from the root targets or not. - public let allTargets: IdentifiableSet + public private(set) var allTargets: IdentifiableSet /// Returns all the products in the graph, regardless if they are reachable from the root targets or not. - public let allProducts: IdentifiableSet + public private(set) var allProducts: IdentifiableSet /// Package dependencies required for a fully resolved graph. /// @@ -100,14 +100,14 @@ public struct PackageGraph { return self.rootPackages.contains(id: package.id) } - private let targetsToPackages: [ResolvedTarget.ID: ResolvedPackage] + private var targetsToPackages: [ResolvedTarget.ID: ResolvedPackage] /// Returns the package that contains the target, or nil if the target isn't in the graph. public func package(for target: ResolvedTarget) -> ResolvedPackage? { return self.targetsToPackages[target.id] } - private let productsToPackages: [ResolvedProduct.ID: ResolvedPackage] + private var productsToPackages: [ResolvedProduct.ID: ResolvedPackage] /// Returns the package that contains the product, or nil if the product isn't in the graph. public func package(for product: ResolvedProduct) -> ResolvedPackage? { return self.productsToPackages[product.id] @@ -202,6 +202,42 @@ public struct PackageGraph { self.allProducts = allProducts } + @_spi(SwiftPMInternal) + public mutating func updateBuildTripleRecursively(_ buildTriple: BuildTriple) throws { + self.reachableTargets = IdentifiableSet(self.reachableTargets.map { + var target = $0 + target.buildTriple = buildTriple + return target + }) + self.reachableProducts = IdentifiableSet(self.reachableProducts.map { + var product = $0 + product.buildTriple = buildTriple + return product + }) + + self.allTargets = IdentifiableSet(self.allTargets.map { + var target = $0 + target.buildTriple = buildTriple + return target + }) + self.allProducts = IdentifiableSet(self.allProducts.map { + var product = $0 + product.buildTriple = buildTriple + return product + }) + + self.targetsToPackages = .init(self.targetsToPackages.map { + var target = $0 + target.buildTriple = buildTriple + return (target, $1) + }, uniquingKeysWith: { $1 }) + self.productsToPackages = .init(self.productsToPackages.map { + var product = $0 + product.buildTriple = buildTriple + return (product, $1) + }, uniquingKeysWith: { $1 }) + } + /// Computes a map from each executable target in any of the root packages to the corresponding test targets. func computeTestTargetsForExecutableTargets() throws -> [ResolvedTarget.ID: [ResolvedTarget]] { var result = [ResolvedTarget.ID: [ResolvedTarget]]() diff --git a/Sources/PackageGraph/Resolution/ResolvedProduct.swift b/Sources/PackageGraph/Resolution/ResolvedProduct.swift index 9b8ae6571ac..a4a3724fdc6 100644 --- a/Sources/PackageGraph/Resolution/ResolvedProduct.swift +++ b/Sources/PackageGraph/Resolution/ResolvedProduct.swift @@ -187,7 +187,7 @@ extension ResolvedProduct: Identifiable { public struct ID: Hashable { public let productName: String let packageIdentity: PackageIdentity - public let buildTriple: BuildTriple + public var buildTriple: BuildTriple } public var id: ID { diff --git a/Sources/PackageGraph/Resolution/ResolvedTarget.swift b/Sources/PackageGraph/Resolution/ResolvedTarget.swift index 93db29dd93e..0bf70072cfd 100644 --- a/Sources/PackageGraph/Resolution/ResolvedTarget.swift +++ b/Sources/PackageGraph/Resolution/ResolvedTarget.swift @@ -268,7 +268,7 @@ extension ResolvedTarget: Identifiable { public struct ID: Hashable { public let targetName: String let packageIdentity: PackageIdentity - public let buildTriple: BuildTriple + public var buildTriple: BuildTriple } public var id: ID { diff --git a/Sources/SPMBuildCore/Plugins/PluginInvocation.swift b/Sources/SPMBuildCore/Plugins/PluginInvocation.swift index 72dcef42431..f948995f7e6 100644 --- a/Sources/SPMBuildCore/Plugins/PluginInvocation.swift +++ b/Sources/SPMBuildCore/Plugins/PluginInvocation.swift @@ -592,7 +592,9 @@ extension PackageGraph { } // Associate the list of results with the target. The list will have one entry for each plugin used by the target. - pluginResultsByTarget[target.id] = (target, buildToolPluginResults) + var targetID = target.id + targetID.buildTriple = .destination + pluginResultsByTarget[targetID] = (target, buildToolPluginResults) } return pluginResultsByTarget } From 2cd8150a828d3184ccdd86a8240755a3a0849ee7 Mon Sep 17 00:00:00 2001 From: Max Desiatov Date: Thu, 15 Feb 2024 14:34:50 +0000 Subject: [PATCH 21/33] Fix package plugins built without `-tool` suffix --- Sources/Build/BuildOperation.swift | 1 - Sources/Commands/PackageTools/PluginCommand.swift | 12 ++++++++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/Sources/Build/BuildOperation.swift b/Sources/Build/BuildOperation.swift index bf20391e763..89b0f78faf6 100644 --- a/Sources/Build/BuildOperation.swift +++ b/Sources/Build/BuildOperation.swift @@ -497,7 +497,6 @@ public final class BuildOperation: PackageStructureDelegate, SPMBuildCore.BuildS } } - // Surface any diagnostics from build tool plugins. var succeeded = true for (_, (target, results)) in buildToolPluginInvocationResults { diff --git a/Sources/Commands/PackageTools/PluginCommand.swift b/Sources/Commands/PackageTools/PluginCommand.swift index 1968dae8183..c90553d7b1c 100644 --- a/Sources/Commands/PackageTools/PluginCommand.swift +++ b/Sources/Commands/PackageTools/PluginCommand.swift @@ -14,7 +14,10 @@ import ArgumentParser import Basics import CoreCommands import Dispatch + +@_spi(SwiftPMInternal) import PackageGraph + import PackageModel import enum TSCBasic.ProcessEnv @@ -315,6 +318,9 @@ struct PluginCommand: SwiftCommand { let toolSearchDirs = [try swiftTool.getTargetToolchain().swiftCompilerPath.parentDirectory] + getEnvSearchPaths(pathString: ProcessEnv.path, currentWorkingDirectory: .none) + var buildToolsGraph = packageGraph + try buildToolsGraph.updateBuildTripleRecursively(.tools) + let buildParameters = try swiftTool.toolsBuildParameters // Build or bring up-to-date any executable host-side tools on which this plugin depends. Add them and any binary dependencies to the tool-names-to-path map. let buildSystem = try swiftTool.createBuildSystem( @@ -323,10 +329,12 @@ struct PluginCommand: SwiftCommand { // Force all dependencies to be built for the host, to work around the fact that BuildOperation.plan // knows to compile build tool plugin dependencies for the host but does not do the same for command // plugins. - productsBuildParameters: buildParameters + productsBuildParameters: buildParameters, + packageGraphLoader: { buildToolsGraph } ) + let accessibleTools = try plugin.processAccessibleTools( - packageGraph: packageGraph, + packageGraph: buildToolsGraph, fileSystem: swiftTool.fileSystem, environment: buildParameters.buildEnvironment, for: try pluginScriptRunner.hostTriple From 73a6a997a8d9cc421f52a46b252032f5bb438b29 Mon Sep 17 00:00:00 2001 From: Max Desiatov Date: Thu, 15 Feb 2024 14:52:58 +0000 Subject: [PATCH 22/33] Fix `PluginsBuildPlanTests` failure --- Tests/BuildTests/PluginsBuildPlanTests.swift | 24 ++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/Tests/BuildTests/PluginsBuildPlanTests.swift b/Tests/BuildTests/PluginsBuildPlanTests.swift index 892c3da6725..7b2a1a78378 100644 --- a/Tests/BuildTests/PluginsBuildPlanTests.swift +++ b/Tests/BuildTests/PluginsBuildPlanTests.swift @@ -48,8 +48,16 @@ final class PluginsBuildPlanTests: XCTestCase { let (stdout, stderr) = try executeSwiftPackage(fixturePath, extraArgs: ["-v", "build-plugin-dependency"]) XCTAssertMatch(stdout, .contains("Hello from dependencies-stub")) XCTAssertMatch(stderr, .contains("Build of product 'plugintool' complete!")) - XCTAssertTrue(localFileSystem.exists(fixturePath.appending(RelativePath(".build/\(hostTriple)/debug/plugintool")))) - XCTAssertTrue(localFileSystem.exists(fixturePath.appending(RelativePath(".build/\(hostTriple)/debug/placeholder")))) + XCTAssertTrue( + localFileSystem.exists( + fixturePath.appending(RelativePath(".build/\(hostTriple)/debug/plugintool-tool")) + ) + ) + XCTAssertTrue( + localFileSystem.exists( + fixturePath.appending(RelativePath(".build/\(hostTriple)/debug/placeholder")) + ) + ) } // When cross compiling the final product, plugin dependencies should still be built for the host @@ -57,8 +65,16 @@ final class PluginsBuildPlanTests: XCTestCase { let (stdout, stderr) = try executeSwiftPackage(fixturePath, extraArgs: ["--triple", targetTriple, "-v", "build-plugin-dependency"]) XCTAssertMatch(stdout, .contains("Hello from dependencies-stub")) XCTAssertMatch(stderr, .contains("Build of product 'plugintool' complete!")) - XCTAssertTrue(localFileSystem.exists(fixturePath.appending(RelativePath(".build/\(hostTriple)/debug/plugintool")))) - XCTAssertTrue(localFileSystem.exists(fixturePath.appending(RelativePath(".build/\(targetTriple)/debug/placeholder")))) + XCTAssertTrue( + localFileSystem.exists( + fixturePath.appending(RelativePath(".build/\(hostTriple)/debug/plugintool-tool")) + ) + ) + XCTAssertTrue( + localFileSystem.exists( + fixturePath.appending(RelativePath(".build/\(targetTriple)/debug/placeholder")) + ) + ) } } } From 3ade20f51d9beb01fde80a00e24d7399ace139d0 Mon Sep 17 00:00:00 2001 From: Max Desiatov Date: Thu, 15 Feb 2024 16:24:20 +0000 Subject: [PATCH 23/33] Assign correct triple to macro products, fix macros load path --- .../ProductBuildDescription.swift | 5 +- .../SwiftTargetBuildDescription.swift | 120 +++++++++--------- .../TargetBuildDescription.swift | 2 +- .../LLBuildManifestBuilder+Swift.swift | 32 ++--- Sources/Build/BuildOperation.swift | 2 +- Sources/Build/BuildPlan/BuildPlan+Swift.swift | 4 +- Sources/Build/BuildPlan/BuildPlan+Test.swift | 39 +++--- Sources/Build/BuildPlan/BuildPlan.swift | 30 +++-- Sources/Commands/SwiftTestTool.swift | 12 +- .../Commands/Utilities/PluginDelegate.swift | 2 +- .../Commands/Utilities/TestingSupport.swift | 6 +- .../PackageGraph/PackageGraph+Loading.swift | 4 - .../Resolution/ResolvedProduct.swift | 6 +- .../Resolution/ResolvedTarget.swift | 1 - .../SPMTestSupport/MockBuildTestHelper.swift | 4 +- Tests/BuildTests/BuildPlanTests.swift | 47 ++++--- .../CrossCompilationBuildTests.swift | 37 ++++-- .../LLBuildManifestBuilderTests.swift | 36 ++++-- .../BuildTests/ModuleAliasingBuildTests.swift | 26 ++-- Tests/CommandsTests/SwiftToolTests.swift | 8 +- .../PluginInvocationTests.swift | 9 +- .../SourceKitLSPAPITests.swift | 29 ++++- 22 files changed, 268 insertions(+), 193 deletions(-) diff --git a/Sources/Build/BuildDescription/ProductBuildDescription.swift b/Sources/Build/BuildDescription/ProductBuildDescription.swift index 57c72efb6b9..814aaefa1fe 100644 --- a/Sources/Build/BuildDescription/ProductBuildDescription.swift +++ b/Sources/Build/BuildDescription/ProductBuildDescription.swift @@ -65,7 +65,8 @@ public final class ProductBuildDescription: SPMBuildCore.ProductBuildDescription /// Path to the link filelist file. var linkFileListPath: AbsolutePath { - self.tempsPath.appending("Objects.LinkFileList") + print(self.product.name) + return self.tempsPath.appending("Objects.LinkFileList") } /// File system reference. @@ -346,7 +347,7 @@ public final class ProductBuildDescription: SPMBuildCore.ProductBuildDescription // Library search path for the toolchain's copy of SwiftSyntax. #if BUILD_MACROS_AS_DYLIBS if product.type == .macro { - args += try ["-L", buildParameters.toolchain.hostLibDir.pathString] + args += try ["-L", destinationBuildParameters.toolchain.hostLibDir.pathString] } #endif diff --git a/Sources/Build/BuildDescription/SwiftTargetBuildDescription.swift b/Sources/Build/BuildDescription/SwiftTargetBuildDescription.swift index c1872540ba5..cb1d0f8e13f 100644 --- a/Sources/Build/BuildDescription/SwiftTargetBuildDescription.swift +++ b/Sources/Build/BuildDescription/SwiftTargetBuildDescription.swift @@ -42,8 +42,11 @@ public final class SwiftTargetBuildDescription { /// a target is built. public let toolsVersion: ToolsVersion - /// The build parameters. - let buildParameters: BuildParameters + /// The build parameters for this target. + let destinationBuildParameters: BuildParameters + + /// The build parameters for build tools. + let toolsBuildParameters: BuildParameters /// Path to the temporary directory for this target. let tempsPath: AbsolutePath @@ -62,7 +65,7 @@ public final class SwiftTargetBuildDescription { /// Path to the bundle generated for this module (if any). var bundlePath: AbsolutePath? { if let bundleName = target.underlying.potentialBundleName, needsResourceBundle { - return self.buildParameters.bundlePath(named: bundleName) + return self.destinationBuildParameters.bundlePath(named: bundleName) } else { return .none } @@ -97,7 +100,7 @@ public final class SwiftTargetBuildDescription { let relativeSources = self.target.sources.relativePaths + self.derivedSources.relativePaths + self.pluginDerivedSources.relativePaths - let ltoEnabled = self.buildParameters.linkingParameters.linkTimeOptimizationMode != nil + let ltoEnabled = self.destinationBuildParameters.linkingParameters.linkTimeOptimizationMode != nil let objectFileExtension = ltoEnabled ? "bc" : "o" return try relativeSources.map { try AbsolutePath( @@ -108,13 +111,13 @@ public final class SwiftTargetBuildDescription { } var modulesPath: AbsolutePath { - return self.buildParameters.buildPath.appending(component: "Modules\(self.target.buildTriple.suffix)") + return self.destinationBuildParameters.buildPath.appending(component: "Modules\(self.target.buildTriple.suffix)") } /// The path to the swiftmodule file after compilation. public var moduleOutputPath: AbsolutePath { // note: needs to be public because of sourcekit-lsp // If we're an executable and we're not allowing test targets to link against us, we hide the module. - let triple = buildParameters.triple + let triple = destinationBuildParameters.triple let allowLinkingAgainstExecutables = (triple.isDarwin() || triple.isLinux() || triple.isWindows()) && self.toolsVersion >= .v5_5 let dirPath = (target.type == .executable && !allowLinkingAgainstExecutables) ? self.tempsPath : self.modulesPath return dirPath.appending(component: "\(self.target.c99name).swiftmodule") @@ -243,7 +246,7 @@ public final class SwiftTargetBuildDescription { private let shouldGenerateTestObservation: Bool /// Whether to disable sandboxing (e.g. for macros). - private let disableSandbox: Bool + private let shouldDisableSandbox: Bool /// Create a new target description with target and build parameters. init( @@ -251,13 +254,14 @@ public final class SwiftTargetBuildDescription { target: ResolvedTarget, toolsVersion: ToolsVersion, additionalFileRules: [FileRuleDescription] = [], - buildParameters: BuildParameters, + destinationBuildParameters: BuildParameters, + toolsBuildParameters: BuildParameters, buildToolPluginInvocationResults: [BuildToolPluginInvocationResult] = [], prebuildCommandResults: [PrebuildCommandResult] = [], requiredMacroProducts: [ResolvedProduct] = [], testTargetRole: TestTargetRole? = nil, shouldGenerateTestObservation: Bool = false, - disableSandbox: Bool, + shouldDisableSandbox: Bool, fileSystem: FileSystem, observabilityScope: ObservabilityScope ) throws { @@ -269,7 +273,9 @@ public final class SwiftTargetBuildDescription { self.package = package self.target = target self.toolsVersion = toolsVersion - self.buildParameters = buildParameters + self.destinationBuildParameters = destinationBuildParameters + self.toolsBuildParameters = toolsBuildParameters + // Unless mentioned explicitly, use the target type to determine if this is a test target. if let testTargetRole { self.testTargetRole = testTargetRole @@ -279,13 +285,13 @@ public final class SwiftTargetBuildDescription { self.testTargetRole = nil } - self.tempsPath = target.tempsPath(buildParameters) + self.tempsPath = target.tempsPath(destinationBuildParameters) self.derivedSources = Sources(paths: [], root: self.tempsPath.appending("DerivedSources")) self.buildToolPluginInvocationResults = buildToolPluginInvocationResults self.prebuildCommandResults = prebuildCommandResults self.requiredMacroProducts = requiredMacroProducts self.shouldGenerateTestObservation = shouldGenerateTestObservation - self.disableSandbox = disableSandbox + self.shouldDisableSandbox = shouldDisableSandbox self.fileSystem = fileSystem self.observabilityScope = observabilityScope @@ -293,7 +299,7 @@ public final class SwiftTargetBuildDescription { target: target, toolsVersion: toolsVersion, additionalFileRules: additionalFileRules, - buildParameters: buildParameters, + buildParameters: destinationBuildParameters, buildToolPluginInvocationResults: buildToolPluginInvocationResults, prebuildCommandResults: prebuildCommandResults, observabilityScope: observabilityScope @@ -330,11 +336,11 @@ public final class SwiftTargetBuildDescription { return } - guard self.buildParameters.triple.isDarwin(), self.buildParameters.testingParameters.experimentalTestOutput else { + guard self.destinationBuildParameters.triple.isDarwin(), self.destinationBuildParameters.testingParameters.experimentalTestOutput else { return } - let content = generateTestObservationCode(buildParameters: self.buildParameters) + let content = generateTestObservationCode(buildParameters: self.destinationBuildParameters) // FIXME: We should generate this file during the actual build. self.derivedSources.relativePaths.append(subpath) @@ -374,7 +380,7 @@ public final class SwiftTargetBuildDescription { guard let bundlePath else { return } let mainPathSubstitution: String - if self.buildParameters.triple.isWASI() { + if self.destinationBuildParameters.triple.isWASI() { // We prefer compile-time evaluation of the bundle path here for WASI. There's no benefit in evaluating this // at runtime, especially as `Bundle` support in WASI Foundation is partial. We expect all resource paths to // evaluate to `/\(resourceBundleName)/\(resourcePath)`, which allows us to pass this path to JS APIs like @@ -424,7 +430,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.destinationBuildParameters.toolchain, fileSystem: self.fileSystem) { if packageAccess { let pkgID = pkg.identity.description.spm_mangledToC99ExtendedIdentifier() return [flag, pkgID] @@ -438,12 +444,12 @@ public final class SwiftTargetBuildDescription { #if BUILD_MACROS_AS_DYLIBS self.requiredMacroProducts.forEach { macro in - args += ["-Xfrontend", "-load-plugin-library", "-Xfrontend", self.buildParameters.binaryPath(for: macro).pathString] + args += ["-Xfrontend", "-load-plugin-library", "-Xfrontend", self.destinationBuildParameters.binaryPath(for: macro).pathString] } #else try self.requiredMacroProducts.forEach { macro in if let macroTarget = macro.targets.first { - let executablePath = try self.buildParameters.binaryPath(for: macro).pathString + let executablePath = try self.toolsBuildParameters.binaryPath(for: macro).pathString args += ["-Xfrontend", "-load-plugin-executable", "-Xfrontend", "\(executablePath)#\(macroTarget.c99name)"] } else { throw InternalError("macro product \(macro.name) has no targets") // earlier validation should normally catch this @@ -452,7 +458,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.destinationBuildParameters.toolchain.isSwiftDevelopmentToolchain, DriverSupport.checkSupportedFrontendFlags(flags: ["-external-plugin-path"], toolchain: self.destinationBuildParameters.toolchain, fileSystem: self.fileSystem), let pluginServer = try self.destinationBuildParameters.toolchain.swiftPluginServerPath { let toolchainUsrPath = pluginServer.parentDirectory.parentDirectory let pluginPathComponents = ["lib", "swift", "host", "plugins"] @@ -463,8 +469,8 @@ public final class SwiftTargetBuildDescription { args += ["-Xfrontend", "-external-plugin-path", "-Xfrontend", "\(localPluginPath)#\(pluginServer.pathString)"] } - if self.disableSandbox { - let toolchainSupportsDisablingSandbox = DriverSupport.checkSupportedFrontendFlags(flags: ["-disable-sandbox"], toolchain: self.buildParameters.toolchain, fileSystem: fileSystem) + if self.shouldDisableSandbox { + let toolchainSupportsDisablingSandbox = DriverSupport.checkSupportedFrontendFlags(flags: ["-disable-sandbox"], toolchain: self.destinationBuildParameters.toolchain, fileSystem: fileSystem) if toolchainSupportsDisablingSandbox { args += ["-disable-sandbox"] } else { @@ -481,11 +487,11 @@ public final class SwiftTargetBuildDescription { /// The arguments needed to compile this target. public func compileArguments() throws -> [String] { var args = [String]() - args += try self.buildParameters.tripleArgs(for: self.target) + args += try self.destinationBuildParameters.tripleArgs(for: self.target) args += ["-swift-version", self.swiftVersion.rawValue] // pass `-v` during verbose builds. - if self.buildParameters.outputParameters.isVerbose { + if self.destinationBuildParameters.outputParameters.isVerbose { args += ["-v"] } @@ -493,22 +499,22 @@ public final class SwiftTargetBuildDescription { // // Technically, it should be enabled whenever WMO is off but we // don't currently make that distinction in SwiftPM - switch self.buildParameters.configuration { + switch self.destinationBuildParameters.configuration { case .debug: args += ["-enable-batch-mode"] case .release: break } - args += self.buildParameters.indexStoreArguments(for: self.target) + args += self.destinationBuildParameters.indexStoreArguments(for: self.target) args += self.optimizationArguments args += self.testingArguments - args += ["-j\(self.buildParameters.workers)"] + args += ["-j\(self.destinationBuildParameters.workers)"] args += self.activeCompilationConditions args += self.additionalFlags args += try self.moduleCacheArgs args += self.stdlibArguments - args += self.buildParameters.sanitizers.compileSwiftFlags() + args += self.destinationBuildParameters.sanitizers.compileSwiftFlags() args += ["-parseable-output"] // If we're compiling the main module of an executable other than the one that @@ -528,8 +534,8 @@ public final class SwiftTargetBuildDescription { // we can rename the symbol unconditionally. // No `-` for these flags because the set of Strings in driver.supportedFrontendFlags do // not have a leading `-` - if self.buildParameters.driverParameters.canRenameEntrypointFunctionName, - self.buildParameters.linkerFlagsForRenamingMainFunction(of: self.target) != nil + if self.destinationBuildParameters.driverParameters.canRenameEntrypointFunctionName, + self.destinationBuildParameters.linkerFlagsForRenamingMainFunction(of: self.target) != nil { args += ["-Xfrontend", "-entry-point-function-name", "-Xfrontend", "\(self.target.c99name)_main"] } @@ -542,7 +548,7 @@ public final class SwiftTargetBuildDescription { // Only add the build path to the framework search path if there are binary frameworks to link against. if !self.libraryBinaryPaths.isEmpty { - args += ["-F", self.buildParameters.buildPath.pathString] + args += ["-F", self.destinationBuildParameters.buildPath.pathString] } // Emit the ObjC compatibility header if enabled. @@ -551,12 +557,12 @@ public final class SwiftTargetBuildDescription { } // Add arguments needed for code coverage if it is enabled. - if self.buildParameters.testingParameters.enableCodeCoverage { + if self.destinationBuildParameters.testingParameters.enableCodeCoverage { args += ["-profile-coverage-mapping", "-profile-generate"] } // Add arguments to colorize output if stdout is tty - if self.buildParameters.outputParameters.isColorized { + if self.destinationBuildParameters.outputParameters.isColorized { args += ["-color-diagnostics"] } @@ -566,7 +572,7 @@ public final class SwiftTargetBuildDescription { switch testTargetRole { case .discovery: for dependency in try self.target.recursiveTargetDependencies() { - let dependencyScope = self.buildParameters.createScope(for: dependency) + let dependencyScope = self.destinationBuildParameters.createScope(for: dependency) let dependencySwiftFlags = dependencyScope.evaluate(.OTHER_SWIFT_FLAGS) if let interopModeFlag = dependencySwiftFlags.first(where: { $0.hasPrefix("-cxx-interoperability-mode=") }) { args += [interopModeFlag] @@ -586,17 +592,17 @@ public final class SwiftTargetBuildDescription { // Add the output for the `.swiftinterface`, if requested or if library evolution has been enabled some other // way. - if self.buildParameters.driverParameters.enableParseableModuleInterfaces || args.contains("-enable-library-evolution") { + if self.destinationBuildParameters.driverParameters.enableParseableModuleInterfaces || args.contains("-enable-library-evolution") { args += ["-emit-module-interface-path", self.parseableModuleInterfaceOutputPath.pathString] } - args += self.buildParameters.toolchain.extraFlags.swiftCompilerFlags + args += self.destinationBuildParameters.toolchain.extraFlags.swiftCompilerFlags // User arguments (from -Xswiftc) should follow generated arguments to allow user overrides - args += self.buildParameters.flags.swiftCompilerFlags + args += self.destinationBuildParameters.flags.swiftCompilerFlags - args += self.buildParameters.toolchain.extraFlags.cCompilerFlags.asSwiftcCCompilerFlags() + args += self.destinationBuildParameters.toolchain.extraFlags.cCompilerFlags.asSwiftcCCompilerFlags() // User arguments (from -Xcc) should follow generated arguments to allow user overrides - args += self.buildParameters.flags.cCompilerFlags.asSwiftcCCompilerFlags() + args += self.destinationBuildParameters.flags.cCompilerFlags.asSwiftcCCompilerFlags() // TODO: Pass -Xcxx flags to swiftc (#6491) // Uncomment when downstream support arrives. @@ -605,7 +611,7 @@ public final class SwiftTargetBuildDescription { // args += self.buildParameters.flags.cxxCompilerFlags.asSwiftcCXXCompilerFlags() // Enable the correct LTO mode if requested. - switch self.buildParameters.linkingParameters.linkTimeOptimizationMode { + switch self.destinationBuildParameters.linkingParameters.linkTimeOptimizationMode { case nil: break case .full: @@ -615,7 +621,7 @@ public final class SwiftTargetBuildDescription { } // Pass default include paths from the toolchain. - for includeSearchPath in self.buildParameters.toolchain.includeSearchPaths { + for includeSearchPath in self.destinationBuildParameters.toolchain.includeSearchPaths { args += ["-I", includeSearchPath.pathString] } @@ -639,7 +645,7 @@ public final class SwiftTargetBuildDescription { // rdar://117578677 // Pass -fno-omit-frame-pointer to support backtraces // this can be removed once the backtracer uses DWARF instead of frame pointers - if let omitFramePointers = self.buildParameters.debuggingParameters.omitFramePointers { + if let omitFramePointers = self.destinationBuildParameters.debuggingParameters.omitFramePointers { if omitFramePointers { args += ["-Xcc", "-fomit-frame-pointer"] } else { @@ -654,7 +660,7 @@ public final class SwiftTargetBuildDescription { /// such as emitting a module or supplementary outputs. public func emitCommandLine(scanInvocation: Bool = false) throws -> [String] { var result: [String] = [] - result.append(self.buildParameters.toolchain.swiftCompilerPath.pathString) + result.append(self.destinationBuildParameters.toolchain.swiftCompilerPath.pathString) result.append("-module-name") result.append(self.target.c99name) @@ -672,7 +678,7 @@ public final class SwiftTargetBuildDescription { result.append(try self.writeOutputFileMap().pathString) } - if self.buildParameters.useWholeModuleOptimization { + if self.destinationBuildParameters.useWholeModuleOptimization { result.append("-whole-module-optimization") result.append("-num-threads") result.append(String(ProcessInfo.processInfo.activeProcessorCount)) @@ -692,7 +698,7 @@ public final class SwiftTargetBuildDescription { /// Returns true if ObjC compatibility header should be emitted. private var shouldEmitObjCCompatibilityHeader: Bool { - self.buildParameters.triple.isDarwin() && self.target.type == .library + self.destinationBuildParameters.triple.isDarwin() && self.target.type == .library } func writeOutputFileMap() throws -> AbsolutePath { @@ -706,7 +712,7 @@ public final class SwiftTargetBuildDescription { """# - if self.buildParameters.useWholeModuleOptimization { + if self.destinationBuildParameters.useWholeModuleOptimization { let moduleName = self.target.c99name content += #""" @@ -737,7 +743,7 @@ public final class SwiftTargetBuildDescription { // Write out the entries for each source file. let sources = self.sources let objects = try self.objects - let ltoEnabled = self.buildParameters.linkingParameters.linkTimeOptimizationMode != nil + let ltoEnabled = self.destinationBuildParameters.linkingParameters.linkTimeOptimizationMode != nil let objectKey = ltoEnabled ? "llvm-bc" : "object" for idx in 0.. [String] { - let scope = self.buildParameters.createScope(for: self.target) + let scope = self.destinationBuildParameters.createScope(for: self.target) var flags: [String] = [] // Swift defines. @@ -840,7 +846,7 @@ public final class SwiftTargetBuildDescription { // Include path for the toolchain's copy of SwiftSyntax. #if BUILD_MACROS_AS_DYLIBS if target.type == .macro { - flags += try ["-I", self.buildParameters.toolchain.hostLibDir.pathString] + flags += try ["-I", self.destinationBuildParameters.toolchain.hostLibDir.pathString] } #endif @@ -851,7 +857,7 @@ public final class SwiftTargetBuildDescription { private var activeCompilationConditions: [String] { var compilationConditions = ["-DSWIFT_PACKAGE"] - switch self.buildParameters.configuration { + switch self.destinationBuildParameters.configuration { case .debug: compilationConditions += ["-DDEBUG"] case .release: @@ -863,7 +869,7 @@ public final class SwiftTargetBuildDescription { /// Optimization arguments according to the build configuration. private var optimizationArguments: [String] { - switch self.buildParameters.configuration { + switch self.destinationBuildParameters.configuration { case .debug: return ["-Onone"] case .release: @@ -877,7 +883,7 @@ public final class SwiftTargetBuildDescription { // test targets must be built with -enable-testing // since its required for test discovery (the non objective-c reflection kind) return ["-enable-testing"] - } else if self.buildParameters.testingParameters.enableTestability { + } else if self.destinationBuildParameters.testingParameters.enableTestability { return ["-enable-testing"] } else { return [] @@ -887,20 +893,20 @@ public final class SwiftTargetBuildDescription { /// Module cache arguments. private var moduleCacheArgs: [String] { get throws { - ["-module-cache-path", try self.buildParameters.moduleCache.pathString] + ["-module-cache-path", try self.destinationBuildParameters.moduleCache.pathString] } } private var stdlibArguments: [String] { var arguments: [String] = [] - let isLinkingStaticStdlib = self.buildParameters.linkingParameters.shouldLinkStaticSwiftStdlib - && self.buildParameters.triple.isSupportingStaticStdlib + let isLinkingStaticStdlib = self.destinationBuildParameters.linkingParameters.shouldLinkStaticSwiftStdlib + && self.destinationBuildParameters.triple.isSupportingStaticStdlib if isLinkingStaticStdlib { arguments += ["-static-stdlib"] } - if let resourcesPath = self.buildParameters.toolchain.swiftResourcesPath(isStatic: isLinkingStaticStdlib) { + if let resourcesPath = self.destinationBuildParameters.toolchain.swiftResourcesPath(isStatic: isLinkingStaticStdlib) { arguments += ["-resource-dir", "\(resourcesPath)"] } diff --git a/Sources/Build/BuildDescription/TargetBuildDescription.swift b/Sources/Build/BuildDescription/TargetBuildDescription.swift index 4fae9198680..e2c15d47697 100644 --- a/Sources/Build/BuildDescription/TargetBuildDescription.swift +++ b/Sources/Build/BuildDescription/TargetBuildDescription.swift @@ -101,7 +101,7 @@ public enum TargetBuildDescription { var buildParameters: BuildParameters { switch self { case .swift(let swiftTargetBuildDescription): - return swiftTargetBuildDescription.buildParameters + return swiftTargetBuildDescription.destinationBuildParameters case .clang(let clangTargetBuildDescription): return clangTargetBuildDescription.buildParameters } diff --git a/Sources/Build/BuildManifest/LLBuildManifestBuilder+Swift.swift b/Sources/Build/BuildManifest/LLBuildManifestBuilder+Swift.swift index be8265f43ff..040f195a01b 100644 --- a/Sources/Build/BuildManifest/LLBuildManifestBuilder+Swift.swift +++ b/Sources/Build/BuildManifest/LLBuildManifestBuilder+Swift.swift @@ -45,7 +45,7 @@ extension LLBuildManifestBuilder { let moduleNode = Node.file(target.moduleOutputPath) let cmdOutputs = objectNodes + [moduleNode] - if target.buildParameters.driverParameters.useIntegratedSwiftDriver { + if target.destinationBuildParameters.driverParameters.useIntegratedSwiftDriver { try self.addSwiftCmdsViaIntegratedDriver( target, inputs: inputs, @@ -68,7 +68,7 @@ extension LLBuildManifestBuilder { // jobs needed to build this Swift target. var commandLine = try target.emitCommandLine() commandLine.append("-driver-use-frontend-path") - commandLine.append(target.buildParameters.toolchain.swiftCompilerPath.pathString) + commandLine.append(target.destinationBuildParameters.toolchain.swiftCompilerPath.pathString) // FIXME: At some point SwiftPM should provide its own executor for // running jobs/launching processes during planning let resolver = try ArgsResolver(fileSystem: target.fileSystem) @@ -132,7 +132,7 @@ extension LLBuildManifestBuilder { // common intermediate dependency modules, such dependencies can lead // to cycles in the resulting manifest. var manifestNodeInputs: [Node] = [] - if targetDescription.buildParameters.driverParameters.useExplicitModuleBuild && !isMainModule(job) { + if targetDescription.destinationBuildParameters.driverParameters.useExplicitModuleBuild && !isMainModule(job) { manifestNodeInputs = jobInputs } else { manifestNodeInputs = (inputs + jobInputs).uniqued() @@ -287,7 +287,7 @@ extension LLBuildManifestBuilder { // jobs needed to build this Swift target. var commandLine = try targetDescription.emitCommandLine() commandLine.append("-driver-use-frontend-path") - commandLine.append(targetDescription.buildParameters.toolchain.swiftCompilerPath.pathString) + commandLine.append(targetDescription.destinationBuildParameters.toolchain.swiftCompilerPath.pathString) commandLine.append("-experimental-explicit-module-build") let resolver = try ArgsResolver(fileSystem: self.fileSystem) let executor = SPMSwiftDriverExecutor( @@ -378,14 +378,14 @@ extension LLBuildManifestBuilder { cmdOutputs: [Node] ) throws { let isLibrary = target.target.type == .library || target.target.type == .test - let cmdName = target.target.getCommandName(config: target.buildParameters.buildConfig) + let cmdName = target.target.getCommandName(config: target.destinationBuildParameters.buildConfig) self.manifest.addWriteSourcesFileListCommand(sources: target.sources, sourcesFileListPath: target.sourcesFileListPath) self.manifest.addSwiftCmd( name: cmdName, inputs: inputs + [Node.file(target.sourcesFileListPath)], outputs: cmdOutputs, - executable: target.buildParameters.toolchain.swiftCompilerPath, + executable: target.destinationBuildParameters.toolchain.swiftCompilerPath, moduleName: target.target.c99name, moduleAliases: target.target.moduleAliases, moduleOutputPath: target.moduleOutputPath, @@ -396,7 +396,7 @@ extension LLBuildManifestBuilder { sources: target.sources, fileList: target.sourcesFileListPath, isLibrary: isLibrary, - wholeModuleOptimization: target.buildParameters.configuration == .release, + wholeModuleOptimization: target.destinationBuildParameters.configuration == .release, outputFileMapPath: try target.writeOutputFileMap() // FIXME: Eliminate side effect. ) } @@ -406,7 +406,7 @@ extension LLBuildManifestBuilder { ) throws -> [Node] { var inputs = target.sources.map(Node.file) - let swiftVersionFilePath = addSwiftGetVersionCommand(buildParameters: target.buildParameters) + let swiftVersionFilePath = addSwiftGetVersionCommand(buildParameters: target.destinationBuildParameters) inputs.append(.file(swiftVersionFilePath)) // Add resources node as the input to the target. This isn't great because we @@ -452,7 +452,7 @@ extension LLBuildManifestBuilder { } } - for dependency in target.target.dependencies(satisfying: target.buildParameters.buildEnvironment) { + for dependency in target.target.dependencies(satisfying: target.destinationBuildParameters.buildEnvironment) { switch dependency { case .target(let target, _): try addStaticTargetInputs(target) @@ -479,7 +479,7 @@ extension LLBuildManifestBuilder { } for binaryPath in target.libraryBinaryPaths { - let path = target.buildParameters.destinationPath(forBinaryAt: binaryPath) + let path = target.destinationBuildParameters.destinationPath(forBinaryAt: binaryPath) if self.fileSystem.isDirectory(binaryPath) { inputs.append(directory: path) } else { @@ -491,7 +491,7 @@ extension LLBuildManifestBuilder { // Depend on any required macro product's output. try target.requiredMacroProducts.forEach { macro in - try inputs.append(.virtual(macro.getLLBuildTargetName(config: target.buildParameters.buildConfig))) + try inputs.append(.virtual(macro.getLLBuildTargetName(config: target.destinationBuildParameters.buildConfig))) } return inputs + additionalInputs @@ -500,7 +500,7 @@ extension LLBuildManifestBuilder { /// Adds a top-level phony command that builds the entire target. private func addTargetCmd(_ target: SwiftTargetBuildDescription, cmdOutputs: [Node]) { // Create a phony node to represent the entire target. - let targetName = target.target.getLLBuildTargetName(config: target.buildParameters.buildConfig) + let targetName = target.target.getLLBuildTargetName(config: target.destinationBuildParameters.buildConfig) let targetOutput: Node = .virtual(targetName) self.manifest.addNode(targetOutput, toTarget: targetName) @@ -509,7 +509,7 @@ extension LLBuildManifestBuilder { inputs: cmdOutputs, outputs: [targetOutput] ) - if self.plan.graph.isInRootPackages(target.target, satisfying: target.buildParameters.buildEnvironment) { + if self.plan.graph.isInRootPackages(target.target, satisfying: target.destinationBuildParameters.buildEnvironment) { if !target.isTestTarget { self.addNode(targetOutput, toTarget: .main) } @@ -519,13 +519,13 @@ extension LLBuildManifestBuilder { private func addModuleWrapCmd(_ target: SwiftTargetBuildDescription) throws { // Add commands to perform the module wrapping Swift modules when debugging strategy is `modulewrap`. - guard target.buildParameters.debuggingStrategy == .modulewrap else { return } + guard target.destinationBuildParameters.debuggingStrategy == .modulewrap else { return } var moduleWrapArgs = [ - target.buildParameters.toolchain.swiftCompilerPath.pathString, + target.destinationBuildParameters.toolchain.swiftCompilerPath.pathString, "-modulewrap", target.moduleOutputPath.pathString, "-o", target.wrappedModuleOutputPath.pathString, ] - moduleWrapArgs += try target.buildParameters.tripleArgs(for: target.target) + moduleWrapArgs += try target.destinationBuildParameters.tripleArgs(for: target.target) self.manifest.addShellCmd( name: target.wrappedModuleOutputPath.pathString, description: "Wrapping AST for \(target.target.name) for debugging", diff --git a/Sources/Build/BuildOperation.swift b/Sources/Build/BuildOperation.swift index 89b0f78faf6..67b5d6b9e8a 100644 --- a/Sources/Build/BuildOperation.swift +++ b/Sources/Build/BuildOperation.swift @@ -576,7 +576,7 @@ public final class BuildOperation: PackageStructureDelegate, SPMBuildCore.BuildS // Create the build plan based, on the graph and any information from plugins. let plan = try BuildPlan( - productsBuildParameters: self.productsBuildParameters, + destinationBuildParameters: self.productsBuildParameters, toolsBuildParameters: self.toolsBuildParameters, graph: graph, additionalFileRules: additionalFileRules, diff --git a/Sources/Build/BuildPlan/BuildPlan+Swift.swift b/Sources/Build/BuildPlan/BuildPlan+Swift.swift index 36b1cacde0c..dbddbe58ff6 100644 --- a/Sources/Build/BuildPlan/BuildPlan+Swift.swift +++ b/Sources/Build/BuildPlan/BuildPlan+Swift.swift @@ -19,7 +19,7 @@ extension BuildPlan { func plan(swiftTarget: SwiftTargetBuildDescription) throws { // We need to iterate recursive dependencies because Swift compiler needs to see all the targets a target // depends on. - let environment = swiftTarget.buildParameters.buildEnvironment + let environment = swiftTarget.destinationBuildParameters.buildEnvironment for case .target(let dependency, _) in try swiftTarget.target.recursiveDependencies(satisfying: environment) { switch dependency.underlying { case let underlyingTarget as ClangTarget where underlyingTarget.type == .library: @@ -40,7 +40,7 @@ extension BuildPlan { swiftTarget.additionalFlags += try pkgConfig(for: target).cFlags case let target as BinaryTarget: if case .xcframework = target.kind { - let libraries = try self.parseXCFramework(for: target, triple: swiftTarget.buildParameters.triple) + let libraries = try self.parseXCFramework(for: target, triple: swiftTarget.destinationBuildParameters.triple) for library in libraries { library.headersPaths.forEach { swiftTarget.additionalFlags += ["-I", $0.pathString, "-Xcc", "-I", "-Xcc", $0.pathString] diff --git a/Sources/Build/BuildPlan/BuildPlan+Test.swift b/Sources/Build/BuildPlan/BuildPlan+Test.swift index 93fd9da29c7..9d11d012d6e 100644 --- a/Sources/Build/BuildPlan/BuildPlan+Test.swift +++ b/Sources/Build/BuildPlan/BuildPlan+Test.swift @@ -26,15 +26,16 @@ import protocol TSCBasic.FileSystem extension BuildPlan { static func makeDerivedTestTargets( - _ buildParameters: BuildParameters, + destinationBuildParameters: BuildParameters, + toolsBuildParameters: BuildParameters, _ graph: PackageGraph, - _ disableSandbox: Bool, + shouldDisableSandbox: Bool, _ fileSystem: FileSystem, _ observabilityScope: ObservabilityScope ) throws -> [(product: ResolvedProduct, discoveryTargetBuildDescription: SwiftTargetBuildDescription?, entryPointTargetBuildDescription: SwiftTargetBuildDescription)] { - guard buildParameters.testingParameters.testProductStyle.requiresAdditionalDerivedTestTargets, - case .entryPointExecutable(let explicitlyEnabledDiscovery, let explicitlySpecifiedPath) = - buildParameters.testingParameters.testProductStyle + guard destinationBuildParameters.testingParameters.testProductStyle.requiresAdditionalDerivedTestTargets, + case .entryPointExecutable(let explicitlyEnabledDiscovery, let explicitlySpecifiedPath) = + destinationBuildParameters.testingParameters.testProductStyle else { throw InternalError("makeTestManifestTargets should not be used for build plan which does not require additional derived test targets") } @@ -68,7 +69,7 @@ extension BuildPlan { /// Generates test discovery targets, which contain derived sources listing the discovered tests. func generateDiscoveryTargets() throws -> (target: SwiftTarget, resolved: ResolvedTarget, buildDescription: SwiftTargetBuildDescription) { let discoveryTargetName = "\(package.manifest.displayName)PackageDiscoveredTests" - let discoveryDerivedDir = buildParameters.buildPath.appending(components: "\(discoveryTargetName).derived") + let discoveryDerivedDir = destinationBuildParameters.buildPath.appending(components: "\(discoveryTargetName).derived") let discoveryMainFile = discoveryDerivedDir.appending(component: TestDiscoveryTool.mainFileName) var discoveryPaths: [AbsolutePath] = [] @@ -96,9 +97,10 @@ extension BuildPlan { package: package, target: discoveryResolvedTarget, toolsVersion: toolsVersion, - buildParameters: buildParameters, + destinationBuildParameters: destinationBuildParameters, + toolsBuildParameters: toolsBuildParameters, testTargetRole: .discovery, - disableSandbox: disableSandbox, + shouldDisableSandbox: shouldDisableSandbox, fileSystem: fileSystem, observabilityScope: observabilityScope ) @@ -112,8 +114,8 @@ extension BuildPlan { swiftTargetDependencies: [Target.Dependency], resolvedTargetDependencies: [ResolvedTarget.Dependency] ) throws -> SwiftTargetBuildDescription { - let entryPointDerivedDir = buildParameters.buildPath.appending(components: "\(testProduct.name).derived") - let entryPointMainFileName = TestEntryPointTool.mainFileName(for: buildParameters.testingParameters.library) + let entryPointDerivedDir = destinationBuildParameters.buildPath.appending(components: "\(testProduct.name).derived") + let entryPointMainFileName = TestEntryPointTool.mainFileName(for: destinationBuildParameters.testingParameters.library) let entryPointMainFile = entryPointDerivedDir.appending(component: entryPointMainFileName) let entryPointSources = Sources(paths: [entryPointMainFile], root: entryPointDerivedDir) @@ -136,9 +138,10 @@ extension BuildPlan { package: package, target: entryPointResolvedTarget, toolsVersion: toolsVersion, - buildParameters: buildParameters, + destinationBuildParameters: destinationBuildParameters, + toolsBuildParameters: toolsBuildParameters, testTargetRole: .entryPoint(isSynthesized: true), - disableSandbox: disableSandbox, + shouldDisableSandbox: shouldDisableSandbox, fileSystem: fileSystem, observabilityScope: observabilityScope ) @@ -148,7 +151,7 @@ extension BuildPlan { let swiftTargetDependencies: [Target.Dependency] let resolvedTargetDependencies: [ResolvedTarget.Dependency] - switch buildParameters.testingParameters.library { + switch destinationBuildParameters.testingParameters.library { case .xctest: discoveryTargets = try generateDiscoveryTargets() swiftTargetDependencies = [.target(discoveryTargets!.target, conditions: [])] @@ -181,9 +184,10 @@ extension BuildPlan { package: package, target: entryPointResolvedTarget, toolsVersion: toolsVersion, - buildParameters: buildParameters, + destinationBuildParameters: destinationBuildParameters, + toolsBuildParameters: toolsBuildParameters, testTargetRole: .entryPoint(isSynthesized: false), - disableSandbox: disableSandbox, + shouldDisableSandbox: shouldDisableSandbox, fileSystem: fileSystem, observabilityScope: observabilityScope ) @@ -203,9 +207,10 @@ extension BuildPlan { package: package, target: entryPointResolvedTarget, toolsVersion: toolsVersion, - buildParameters: buildParameters, + destinationBuildParameters: destinationBuildParameters, + toolsBuildParameters: toolsBuildParameters, testTargetRole: .entryPoint(isSynthesized: false), - disableSandbox: disableSandbox, + shouldDisableSandbox: shouldDisableSandbox, fileSystem: fileSystem, observabilityScope: observabilityScope ) diff --git a/Sources/Build/BuildPlan/BuildPlan.swift b/Sources/Build/BuildPlan/BuildPlan.swift index c12faaca730..4d9a9360b59 100644 --- a/Sources/Build/BuildPlan/BuildPlan.swift +++ b/Sources/Build/BuildPlan/BuildPlan.swift @@ -221,14 +221,14 @@ public class BuildPlan: SPMBuildCore.BuildPlan { /// Cache for pkgConfig flags. private var pkgConfigCache = [SystemLibraryTarget: (cFlags: [String], libs: [String])]() - /// Cache for library information. + /// Cache for library information. private var externalLibrariesCache = [BinaryTarget: [LibraryInfo]]() - /// Cache for tools information. + /// Cache for tools information. var externalExecutablesCache = [BinaryTarget: [ExecutableInfo]]() /// Whether to disable sandboxing (e.g. for macros). - private let disableSandbox: Bool + private let shouldDisableSandbox: Bool /// The filesystem to operate on. let fileSystem: any FileSystem @@ -247,7 +247,7 @@ public class BuildPlan: SPMBuildCore.BuildPlan { observabilityScope: ObservabilityScope ) throws { try self.init( - productsBuildParameters: buildParameters, + destinationBuildParameters: buildParameters, toolsBuildParameters: buildParameters, graph: graph, additionalFileRules: additionalFileRules, @@ -260,7 +260,7 @@ public class BuildPlan: SPMBuildCore.BuildPlan { /// Create a build plan with a package graph and explicitly distinct build parameters for products and tools. public init( - productsBuildParameters: BuildParameters, + destinationBuildParameters: BuildParameters, toolsBuildParameters: BuildParameters, graph: PackageGraph, additionalFileRules: [FileRuleDescription] = [], @@ -270,12 +270,12 @@ public class BuildPlan: SPMBuildCore.BuildPlan { fileSystem: any FileSystem, observabilityScope: ObservabilityScope ) throws { - self.destinationBuildParameters = productsBuildParameters + self.destinationBuildParameters = destinationBuildParameters self.toolsBuildParameters = toolsBuildParameters self.graph = graph self.buildToolPluginInvocationResults = buildToolPluginInvocationResults self.prebuildCommandResults = prebuildCommandResults - self.disableSandbox = disableSandbox + self.shouldDisableSandbox = disableSandbox self.fileSystem = fileSystem self.observabilityScope = observabilityScope.makeChildScope(description: "Build Plan") @@ -288,7 +288,7 @@ public class BuildPlan: SPMBuildCore.BuildPlan { case .tools: buildParameters = toolsBuildParameters case .destination: - buildParameters = productsBuildParameters + buildParameters = destinationBuildParameters } guard let package = graph.package(for: product) else { @@ -326,7 +326,7 @@ public class BuildPlan: SPMBuildCore.BuildPlan { case .tools: buildParameters = toolsBuildParameters case .destination: - buildParameters = productsBuildParameters + buildParameters = destinationBuildParameters } // Validate the product dependencies of this target. @@ -375,12 +375,13 @@ public class BuildPlan: SPMBuildCore.BuildPlan { target: target, toolsVersion: toolsVersion, additionalFileRules: additionalFileRules, - buildParameters: buildParameters, + destinationBuildParameters: buildParameters, + toolsBuildParameters: toolsBuildParameters, buildToolPluginInvocationResults: buildToolPluginInvocationResults[target.id] ?? [], prebuildCommandResults: prebuildCommandResults[target.id] ?? [], requiredMacroProducts: requiredMacroProducts, shouldGenerateTestObservation: generateTestObservation, - disableSandbox: self.disableSandbox, + shouldDisableSandbox: self.shouldDisableSandbox, fileSystem: fileSystem, observabilityScope: observabilityScope ) @@ -427,11 +428,12 @@ public class BuildPlan: SPMBuildCore.BuildPlan { } // Plan the derived test targets, if necessary. - if productsBuildParameters.testingParameters.testProductStyle.requiresAdditionalDerivedTestTargets { + if destinationBuildParameters.testingParameters.testProductStyle.requiresAdditionalDerivedTestTargets { let derivedTestTargets = try Self.makeDerivedTestTargets( - productsBuildParameters, + destinationBuildParameters: destinationBuildParameters, + toolsBuildParameters: toolsBuildParameters, graph, - self.disableSandbox, + shouldDisableSandbox: self.shouldDisableSandbox, self.fileSystem, self.observabilityScope ) diff --git a/Sources/Commands/SwiftTestTool.swift b/Sources/Commands/SwiftTestTool.swift index 806ec17d09f..426c6f8917d 100644 --- a/Sources/Commands/SwiftTestTool.swift +++ b/Sources/Commands/SwiftTestTool.swift @@ -424,7 +424,7 @@ public struct SwiftTestTool: SwiftCommand { let toolchain = try swiftTool.getTargetToolchain() let testEnv = try TestingSupport.constructTestEnvironment( toolchain: toolchain, - buildParameters: buildParameters, + destinationBuildParameters: buildParameters, sanitizers: globalOptions.build.sanitizers ) @@ -665,13 +665,17 @@ extension SwiftTestTool { // MARK: - swift-testing private func swiftTestingRun(_ swiftTool: SwiftTool) throws { - let buildParameters = try swiftTool.buildParametersForTest(enableCodeCoverage: false, shouldSkipBuilding: sharedOptions.shouldSkipBuilding, library: .swiftTesting) + let buildParameters = try swiftTool.buildParametersForTest( + enableCodeCoverage: false, + shouldSkipBuilding: sharedOptions.shouldSkipBuilding, + library: .swiftTesting + ) let testProducts = try buildTestsIfNeeded(swiftTool: swiftTool, buildParameters: buildParameters) let toolchain = try swiftTool.getTargetToolchain() let testEnv = try TestingSupport.constructTestEnvironment( toolchain: toolchain, - buildParameters: buildParameters, + destinationBuildParameters: buildParameters, sanitizers: globalOptions.build.sanitizers ) @@ -966,7 +970,7 @@ final class ParallelTestRunner { let testEnv = try TestingSupport.constructTestEnvironment( toolchain: self.toolchain, - buildParameters: self.buildParameters, + destinationBuildParameters: self.buildParameters, sanitizers: self.buildOptions.sanitizers ) diff --git a/Sources/Commands/Utilities/PluginDelegate.swift b/Sources/Commands/Utilities/PluginDelegate.swift index d4ad1554444..ec1257fcece 100644 --- a/Sources/Commands/Utilities/PluginDelegate.swift +++ b/Sources/Commands/Utilities/PluginDelegate.swift @@ -235,7 +235,7 @@ final class PluginDelegate: PluginInvocationDelegate { // Construct the environment we'll pass down to the tests. let testEnvironment = try TestingSupport.constructTestEnvironment( toolchain: toolchain, - buildParameters: toolsBuildParameters, + destinationBuildParameters: toolsBuildParameters, sanitizers: swiftTool.options.build.sanitizers ) diff --git a/Sources/Commands/Utilities/TestingSupport.swift b/Sources/Commands/Utilities/TestingSupport.swift index 236feaa072e..9c3f0392600 100644 --- a/Sources/Commands/Utilities/TestingSupport.swift +++ b/Sources/Commands/Utilities/TestingSupport.swift @@ -110,7 +110,7 @@ enum TestingSupport { args = [try Self.xctestHelperPath(swiftTool: swiftTool).pathString, path.pathString, tempFile.path.pathString] let env = try Self.constructTestEnvironment( toolchain: try swiftTool.getTargetToolchain(), - buildParameters: swiftTool.buildParametersForTest( + destinationBuildParameters: swiftTool.buildParametersForTest( enableCodeCoverage: enableCodeCoverage, shouldSkipBuilding: shouldSkipBuilding, experimentalTestOutput: experimentalTestOutput, @@ -126,7 +126,7 @@ enum TestingSupport { #else let env = try Self.constructTestEnvironment( toolchain: try swiftTool.getTargetToolchain(), - buildParameters: swiftTool.buildParametersForTest( + destinationBuildParameters: swiftTool.buildParametersForTest( enableCodeCoverage: enableCodeCoverage, shouldSkipBuilding: shouldSkipBuilding, library: .xctest @@ -143,7 +143,7 @@ enum TestingSupport { /// Creates the environment needed to test related tools. static func constructTestEnvironment( toolchain: UserToolchain, - buildParameters: BuildParameters, + destinationBuildParameters buildParameters: BuildParameters, sanitizers: [Sanitizer] ) throws -> EnvironmentVariables { var env = EnvironmentVariables.process() diff --git a/Sources/PackageGraph/PackageGraph+Loading.swift b/Sources/PackageGraph/PackageGraph+Loading.swift index 4a9825d2f32..6e99b50da02 100644 --- a/Sources/PackageGraph/PackageGraph+Loading.swift +++ b/Sources/PackageGraph/PackageGraph+Loading.swift @@ -903,8 +903,6 @@ private final class ResolvedTargetBuilder: ResolvedBuilder { let observabilityScope: ObservabilityScope let platformVersionProvider: PlatformVersionProvider - private var buildTriple: BuildTriple - init( packageIdentity: PackageIdentity, target: Target, @@ -915,8 +913,6 @@ private final class ResolvedTargetBuilder: ResolvedBuilder { self.target = target self.observabilityScope = observabilityScope self.platformVersionProvider = platformVersionProvider - - self.buildTriple = .destination } override func constructImpl() throws -> ResolvedTarget { diff --git a/Sources/PackageGraph/Resolution/ResolvedProduct.swift b/Sources/PackageGraph/Resolution/ResolvedProduct.swift index a4a3724fdc6..b2d23135c2f 100644 --- a/Sources/PackageGraph/Resolution/ResolvedProduct.swift +++ b/Sources/PackageGraph/Resolution/ResolvedProduct.swift @@ -70,8 +70,7 @@ public struct ResolvedProduct { public init( packageIdentity: PackageIdentity, product: Product, - targets: IdentifiableSet, - buildTriple: BuildTriple = .destination + targets: IdentifiableSet ) { assert(product.targets.count == targets.count && product.targets.map(\.name).sorted() == targets.map(\.name).sorted()) self.packageIdentity = packageIdentity @@ -106,7 +105,8 @@ public struct ResolvedProduct { ) } - self.buildTriple = buildTriple + self.buildTriple = product.buildTriple + self.updateBuildTriplesOfDependencies() } private mutating func updateBuildTriplesOfDependencies() { diff --git a/Sources/PackageGraph/Resolution/ResolvedTarget.swift b/Sources/PackageGraph/Resolution/ResolvedTarget.swift index 0bf70072cfd..674df077510 100644 --- a/Sources/PackageGraph/Resolution/ResolvedTarget.swift +++ b/Sources/PackageGraph/Resolution/ResolvedTarget.swift @@ -166,7 +166,6 @@ public struct ResolvedTarget { self.supportedPlatforms = supportedPlatforms self.platformVersionProvider = platformVersionProvider self.buildTriple = underlying.buildTriple - self.updateBuildTriplesOfDependencies() } diff --git a/Sources/SPMTestSupport/MockBuildTestHelper.swift b/Sources/SPMTestSupport/MockBuildTestHelper.swift index 016092edc69..bb51488f233 100644 --- a/Sources/SPMTestSupport/MockBuildTestHelper.swift +++ b/Sources/SPMTestSupport/MockBuildTestHelper.swift @@ -74,7 +74,7 @@ public let defaultTargetTriple: String = hostTriple.tripleString #endif public func mockBuildParameters( - buildPath: AbsolutePath = "/path/to/build", + buildPath: AbsolutePath? = nil, config: BuildConfiguration = .debug, toolchain: PackageModel.Toolchain = MockToolchain(), flags: PackageModel.BuildFlags = PackageModel.BuildFlags(), @@ -89,7 +89,7 @@ public func mockBuildParameters( omitFramePointers: Bool? = nil ) -> BuildParameters { try! BuildParameters( - dataPath: buildPath, + dataPath: buildPath ?? AbsolutePath("/path/to/build").appending(triple.tripleString), configuration: config, toolchain: toolchain, triple: triple, diff --git a/Tests/BuildTests/BuildPlanTests.swift b/Tests/BuildTests/BuildPlanTests.swift index cd31c8275f2..5ea4e286dac 100644 --- a/Tests/BuildTests/BuildPlanTests.swift +++ b/Tests/BuildTests/BuildPlanTests.swift @@ -47,7 +47,7 @@ extension Build.BuildPlan { observabilityScope: ObservabilityScope ) throws { try self.init( - productsBuildParameters: buildParameters, + destinationBuildParameters: buildParameters, toolsBuildParameters: buildParameters, graph: graph, additionalFileRules: additionalFileRules, @@ -1718,8 +1718,9 @@ final class BuildPlanTests: XCTestCase { ) XCTAssertNoDiagnostics(observability.diagnostics) + let buildParameters = mockBuildParameters() let plan = try BuildPlan( - buildParameters: mockBuildParameters(), + buildParameters: buildParameters, graph: graph, fileSystem: fs, observabilityScope: observability.topScope @@ -1790,7 +1791,7 @@ final class BuildPlanTests: XCTestCase { "@\(buildPath.appending(components: "exe.product", "Objects.LinkFileList"))", "-Xlinker", "-rpath", "-Xlinker", "/fake/path/lib/swift-5.5/macosx", "-target", defaultTargetTriple, - "-Xlinker", "-add_ast_path", "-Xlinker", "/path/to/build/debug/exe.build/exe.swiftmodule", + "-Xlinker", "-add_ast_path", "-Xlinker", "/path/to/build/\(buildParameters.triple)/debug/exe.build/exe.swiftmodule", "-g", ]) #elseif os(Windows) @@ -1846,8 +1847,9 @@ final class BuildPlanTests: XCTestCase { ) XCTAssertNoDiagnostics(observability.diagnostics) + let buildParameters = mockBuildParameters() let result = try BuildPlanResult(plan: BuildPlan( - buildParameters: mockBuildParameters(), + buildParameters: buildParameters, graph: graph, fileSystem: fs, observabilityScope: observability.topScope @@ -1857,8 +1859,8 @@ final class BuildPlanTests: XCTestCase { let lib = try result.target(for: "lib").clangTarget() XCTAssertEqual(try lib.objects, [ - AbsolutePath("/path/to/build/debug/lib.build/lib.S.o"), - AbsolutePath("/path/to/build/debug/lib.build/lib.c.o"), + AbsolutePath("/path/to/build/\(buildParameters.triple)/debug/lib.build/lib.S.o"), + AbsolutePath("/path/to/build/\(buildParameters.triple)/debug/lib.build/lib.c.o"), ]) } @@ -4834,8 +4836,9 @@ final class BuildPlanTests: XCTestCase { ) XCTAssertNoDiagnostics(observability.diagnostics) + let buildParameters = mockBuildParameters() let plan = try BuildPlan( - buildParameters: mockBuildParameters(), + buildParameters: buildParameters, graph: graph, fileSystem: fs, observabilityScope: observability.topScope @@ -4851,7 +4854,7 @@ final class BuildPlanTests: XCTestCase { [ .anySequence, "-emit-objc-header", - "-emit-objc-header-path", "/path/to/build/debug/Foo.build/Foo-Swift.h", + "-emit-objc-header-path", "/path/to/build/\(buildParameters.triple)/debug/Foo.build/Foo-Swift.h", .anySequence, ] ) @@ -4861,7 +4864,7 @@ final class BuildPlanTests: XCTestCase { [ .anySequence, "-emit-objc-header", - "-emit-objc-header-path", "/path/to/build/debug/Foo.build/Foo-Swift.h", + "-emit-objc-header-path", "/path/to/build/\(buildParameters.triple)/Foo.build/Foo-Swift.h", .anySequence, ] ) @@ -4871,12 +4874,12 @@ final class BuildPlanTests: XCTestCase { #if os(macOS) XCTAssertMatch( barTarget, - [.anySequence, "-fmodule-map-file=/path/to/build/debug/Foo.build/module.modulemap", .anySequence] + [.anySequence, "-fmodule-map-file=/path/to/build/\(buildParameters.triple)/debug/Foo.build/module.modulemap", .anySequence] ) #else XCTAssertNoMatch( barTarget, - [.anySequence, "-fmodule-map-file=/path/to/build/debug/Foo.build/module.modulemap", .anySequence] + [.anySequence, "-fmodule-map-file=/path/to/build/\(buildParameters.triple)/debug/Foo.build/module.modulemap", .anySequence] ) #endif @@ -4934,8 +4937,9 @@ final class BuildPlanTests: XCTestCase { ) XCTAssertNoDiagnostics(observability.diagnostics) + let buildParameters = mockBuildParameters() let plan = try BuildPlan( - buildParameters: mockBuildParameters(), + buildParameters: buildParameters, graph: graph, fileSystem: fs, observabilityScope: observability.topScope @@ -4952,7 +4956,7 @@ final class BuildPlanTests: XCTestCase { .anySequence, "-emit-objc-header", "-emit-objc-header-path", - "/path/to/build/debug/Foo.build/Foo-Swift.h", + "/path/to/build/\(buildParameters.triple)/debug/Foo.build/Foo-Swift.h", .anySequence, ] ) @@ -4963,7 +4967,7 @@ final class BuildPlanTests: XCTestCase { .anySequence, "-emit-objc-header", "-emit-objc-header-path", - "/path/to/build/debug/Foo.build/Foo-Swift.h", + "/path/to/build/\(buildParameters.triple)/debug/Foo.build/Foo-Swift.h", .anySequence, ] ) @@ -4975,7 +4979,7 @@ final class BuildPlanTests: XCTestCase { barTarget, [ .anySequence, - "-fmodule-map-file=/path/to/build/debug/Foo.build/module.modulemap", + "-fmodule-map-file=/path/to/build/\(buildParameters.triple)/debug/Foo.build/module.modulemap", .anySequence, ] ) @@ -4984,7 +4988,7 @@ final class BuildPlanTests: XCTestCase { barTarget, [ .anySequence, - "-fmodule-map-file=/path/to/build/debug/Foo.build/module.modulemap", + "-fmodule-map-file=/path/to/build/\(buildParameters.triple)/debug/Foo.build/module.modulemap", .anySequence, ] ) @@ -5044,8 +5048,9 @@ final class BuildPlanTests: XCTestCase { ) XCTAssertNoDiagnostics(observability.diagnostics) + let buildParameters = mockBuildParameters() let plan = try BuildPlan( - buildParameters: mockBuildParameters(), + buildParameters: buildParameters, graph: graph, fileSystem: fs, observabilityScope: observability.topScope @@ -5066,7 +5071,7 @@ final class BuildPlanTests: XCTestCase { .anySequence, "-emit-objc-header", "-emit-objc-header-path", - "/path/to/build/debug/Foo.build/Foo-Swift.h", + "/path/to/build/\(buildParameters.triple)/debug/Foo.build/Foo-Swift.h", .anySequence, ] ) @@ -5077,7 +5082,7 @@ final class BuildPlanTests: XCTestCase { .anySequence, "-emit-objc-header", "-emit-objc-header-path", - "/path/to/build/debug/Foo.build/Foo-Swift.h", + "/path/to/build/\(buildParameters.triple)/debug/Foo.build/Foo-Swift.h", .anySequence, ] ) @@ -5089,7 +5094,7 @@ final class BuildPlanTests: XCTestCase { barTarget, [ .anySequence, - "-fmodule-map-file=/path/to/build/debug/Foo.build/module.modulemap", + "-fmodule-map-file=/path/to/build/\(buildParameters.triple)/debug/Foo.build/module.modulemap", .anySequence, ] ) @@ -5098,7 +5103,7 @@ final class BuildPlanTests: XCTestCase { barTarget, [ .anySequence, - "-fmodule-map-file=/path/to/build/debug/Foo.build/module.modulemap", + "-fmodule-map-file=/path/to/build/\(buildParameters.triple)/debug/Foo.build/module.modulemap", .anySequence, ] ) diff --git a/Tests/BuildTests/CrossCompilationBuildTests.swift b/Tests/BuildTests/CrossCompilationBuildTests.swift index e9574735543..5026abbc443 100644 --- a/Tests/BuildTests/CrossCompilationBuildTests.swift +++ b/Tests/BuildTests/CrossCompilationBuildTests.swift @@ -13,6 +13,7 @@ import class Basics.ObservabilitySystem import struct Basics.Triple import class Build.BuildPlan +import class Build.ProductBuildDescription import class Build.SwiftTargetBuildDescription import func SPMTestSupport.macrosPackageGraph import func SPMTestSupport.mockBuildParameters @@ -23,11 +24,17 @@ import class TSCBasic.InMemoryFileSystem import XCTest extension BuildPlanResult { - func allTargets(named targetName: String) throws -> [SwiftTargetBuildDescription] { + func allTargets(named name: String) throws -> [SwiftTargetBuildDescription] { try self.targetMap - .filter { $0.0.targetName == targetName } + .filter { $0.0.targetName == name } .map { try $1.swiftTarget() } } + + func allProducts(named name: String) -> [ProductBuildDescription] { + self.productMap + .filter { $0.0.productName == name } + .map { $1 } + } func check(triple: Triple, for target: String, file: StaticString = #file, line: UInt = #line) throws { let target = try self.target(for: target).swiftTarget() @@ -39,22 +46,36 @@ final class CrossCompilationBuildPlanTests: XCTestCase { func testMacros() throws { let (graph, fs, scope) = try macrosPackageGraph() - let productsTriple = Triple.x86_64MacOS - let toolsTriple = Triple.arm64Linux - let result = try BuildPlanResult(plan: BuildPlan( - productsBuildParameters: mockBuildParameters(shouldLinkStaticSwiftStdlib: true, triple: productsTriple), + let productsTriple = Triple.arm64Linux + let toolsTriple = Triple.x86_64MacOS + let plan = try BuildPlan( + destinationBuildParameters: mockBuildParameters(shouldLinkStaticSwiftStdlib: true, triple: productsTriple), toolsBuildParameters: mockBuildParameters(triple: toolsTriple), graph: graph, fileSystem: fs, observabilityScope: scope - )) + ) + let result = try BuildPlanResult(plan: plan) result.checkProductsCount(3) - result.checkTargetsCount(8) + result.checkTargetsCount(10) XCTAssertTrue(try result.allTargets(named: "SwiftSyntax").contains { $0.target.buildTriple == .tools }) try result.check(triple: toolsTriple, for: "MMIOMacros") try result.check(triple: productsTriple, for: "MMIO") try result.check(triple: productsTriple, for: "Core") try result.check(triple: productsTriple, for: "HAL") + + let macroProducts = result.allProducts(named: "MMIOMacros") + XCTAssertEqual(macroProducts.count, 1) + let macroProduct = try XCTUnwrap(macroProducts.first) + XCTAssertEqual(macroProduct.buildParameters.triple, toolsTriple) + + // FIXME: check for *toolsTriple* + let mmioTarget = try XCTUnwrap(plan.targets.first { try $0.swiftTarget().target.name == "MMIO" }?.swiftTarget()) + let compileArguments = try mmioTarget.compileArguments() + XCTAssertMatch( + compileArguments, + ["-Xfrontend", "-load-plugin-executable", "-Xfrontend", .contains(toolsTriple.tripleString)] + ) } } diff --git a/Tests/BuildTests/LLBuildManifestBuilderTests.swift b/Tests/BuildTests/LLBuildManifestBuilderTests.swift index 12de0d0057b..0450fcd8f39 100644 --- a/Tests/BuildTests/LLBuildManifestBuilderTests.swift +++ b/Tests/BuildTests/LLBuildManifestBuilderTests.swift @@ -50,7 +50,7 @@ final class LLBuildManifestBuilderTests: XCTestCase { configuration: .release )) var plan = try BuildPlan( - productsBuildParameters: buildParameters, + destinationBuildParameters: buildParameters, toolsBuildParameters: buildParameters, graph: graph, fileSystem: fs, @@ -67,8 +67,8 @@ final class LLBuildManifestBuilderTests: XCTestCase { ) try llbuild.createProductCommand(buildProduct) - let basicReleaseCommandNames = [ - AbsolutePath("/path/to/build/release/exe.product/Objects.LinkFileList").pathString, + var basicReleaseCommandNames = [ + AbsolutePath("/path/to/build/\(buildParameters.triple)/release/exe.product/Objects.LinkFileList").pathString, "", "C.exe-release.exe", ] @@ -85,7 +85,7 @@ final class LLBuildManifestBuilderTests: XCTestCase { configuration: .debug )) plan = try BuildPlan( - productsBuildParameters: buildParameters, + destinationBuildParameters: buildParameters, toolsBuildParameters: buildParameters, graph: graph, fileSystem: fs, @@ -99,8 +99,8 @@ final class LLBuildManifestBuilderTests: XCTestCase { try llbuild.createProductCommand(buildProduct) let entitlementsCommandName = "C.exe-debug.exe-entitlements" - let basicDebugCommandNames = [ - AbsolutePath("/path/to/build/debug/exe.product/Objects.LinkFileList").pathString, + var basicDebugCommandNames = [ + AbsolutePath("/path/to/build/\(buildParameters.triple)/debug/exe.product/Objects.LinkFileList").pathString, "", "C.exe-debug.exe", ] @@ -108,7 +108,7 @@ final class LLBuildManifestBuilderTests: XCTestCase { XCTAssertEqual( llbuild.manifest.commands.map(\.key).sorted(), (basicDebugCommandNames + [ - AbsolutePath("/path/to/build/debug/exe-entitlement.plist").pathString, + AbsolutePath("/path/to/build/\(buildParameters.triple)/debug/exe-entitlement.plist").pathString, entitlementsCommandName, ]).sorted() ) @@ -121,8 +121,8 @@ final class LLBuildManifestBuilderTests: XCTestCase { XCTAssertEqual( entitlementsCommand.inputs, [ - .file("/path/to/build/debug/exe", isMutated: true), - .file("/path/to/build/debug/exe-entitlement.plist"), + .file("/path/to/build/\(buildParameters.triple)/debug/exe", isMutated: true), + .file("/path/to/build/\(buildParameters.triple)/debug/exe-entitlement.plist"), ] ) XCTAssertEqual( @@ -139,7 +139,7 @@ final class LLBuildManifestBuilderTests: XCTestCase { configuration: .release )) plan = try BuildPlan( - productsBuildParameters: buildParameters, + destinationBuildParameters: buildParameters, toolsBuildParameters: buildParameters, graph: graph, fileSystem: fs, @@ -152,6 +152,12 @@ final class LLBuildManifestBuilderTests: XCTestCase { llbuild = LLBuildManifestBuilder(plan, fileSystem: localFileSystem, observabilityScope: observability.topScope) try llbuild.createProductCommand(buildProduct) + basicReleaseCommandNames = [ + AbsolutePath("/path/to/build/\(buildParameters.triple)/release/exe.product/Objects.LinkFileList").pathString, + "", + "C.exe-release.exe", + ] + XCTAssertEqual( llbuild.manifest.commands.map(\.key).sorted(), basicReleaseCommandNames.sorted() @@ -164,7 +170,7 @@ final class LLBuildManifestBuilderTests: XCTestCase { configuration: .debug )) plan = try BuildPlan( - productsBuildParameters: buildParameters, + destinationBuildParameters: buildParameters, toolsBuildParameters: buildParameters, graph: graph, fileSystem: fs, @@ -177,6 +183,12 @@ final class LLBuildManifestBuilderTests: XCTestCase { llbuild = LLBuildManifestBuilder(plan, fileSystem: fs, observabilityScope: observability.topScope) try llbuild.createProductCommand(buildProduct) + basicDebugCommandNames = [ + AbsolutePath("/path/to/build/\(buildParameters.triple)/debug/exe.product/Objects.LinkFileList").pathString, + "", + "C.exe-debug.exe", + ] + XCTAssertEqual( llbuild.manifest.commands.map(\.key).sorted(), basicDebugCommandNames.sorted() @@ -190,7 +202,7 @@ final class LLBuildManifestBuilderTests: XCTestCase { let toolsTriple = Triple.arm64Linux let plan = try BuildPlan( - productsBuildParameters: mockBuildParameters(shouldLinkStaticSwiftStdlib: true, triple: productsTriple), + destinationBuildParameters: mockBuildParameters(shouldLinkStaticSwiftStdlib: true, triple: productsTriple), toolsBuildParameters: mockBuildParameters(triple: toolsTriple), graph: graph, fileSystem: fs, diff --git a/Tests/BuildTests/ModuleAliasingBuildTests.swift b/Tests/BuildTests/ModuleAliasingBuildTests.swift index 090dedb431a..6101be96fb1 100644 --- a/Tests/BuildTests/ModuleAliasingBuildTests.swift +++ b/Tests/BuildTests/ModuleAliasingBuildTests.swift @@ -694,8 +694,9 @@ final class ModuleAliasingBuildTests: XCTestCase { XCTAssertNoDiagnostics(observability.diagnostics) + let buildParameters = mockBuildParameters(shouldLinkStaticSwiftStdlib: true) let result = try BuildPlanResult(plan: try BuildPlan( - buildParameters: mockBuildParameters(shouldLinkStaticSwiftStdlib: true), + buildParameters: buildParameters, graph: graph, fileSystem: fs, observabilityScope: observability.topScope @@ -724,33 +725,33 @@ final class ModuleAliasingBuildTests: XCTestCase { XCTAssertMatch( fooLoggingArgs, [.anySequence, "-emit-objc-header", "-emit-objc-header-path", - "/path/to/build/debug/FooLogging.build/FooLogging-Swift.h", .anySequence] + "/path/to/build/\(buildParameters.triple)/debug/FooLogging.build/FooLogging-Swift.h", .anySequence] ) XCTAssertMatch( barLoggingArgs, [.anySequence, "-emit-objc-header", "-emit-objc-header-path", - "/path/to/build/debug/BarLogging.build/BarLogging-Swift.h", .anySequence] + "/path/to/build/\(buildParameters.triple)/debug/BarLogging.build/BarLogging-Swift.h", .anySequence] ) XCTAssertMatch( loggingArgs, [.anySequence, "-emit-objc-header", "-emit-objc-header-path", - "/path/to/build/debug/Logging.build/Logging-Swift.h", .anySequence] + "/path/to/build/\(buildParameters.triple)/debug/Logging.build/Logging-Swift.h", .anySequence] ) #else XCTAssertNoMatch( fooLoggingArgs, [.anySequence, "-emit-objc-header", "-emit-objc-header-path", - "/path/to/build/debug/FooLogging.build/FooLogging-Swift.h", .anySequence] + "/path/to/build/\(buildParameters.triple)/debug/FooLogging.build/FooLogging-Swift.h", .anySequence] ) XCTAssertNoMatch( barLoggingArgs, [.anySequence, "-emit-objc-header", "-emit-objc-header-path", - "/path/to/build/debug/BarLogging.build/BarLogging-Swift.h", .anySequence] + "/path/to/build/\(buildParameters.triple)/debug/BarLogging.build/BarLogging-Swift.h", .anySequence] ) XCTAssertNoMatch( loggingArgs, [.anySequence, "-emit-objc-header", "-emit-objc-header-path", - "/path/to/build/debug/Logging.build/Logging-Swift.h", .anySequence] + "/path/to/build/\(buildParameters.triple)/debug/Logging.build/Logging-Swift.h", .anySequence] ) #endif } @@ -812,8 +813,9 @@ final class ModuleAliasingBuildTests: XCTestCase { ) XCTAssertNoDiagnostics(observability.diagnostics) + let buildParameters = mockBuildParameters(shouldLinkStaticSwiftStdlib: true) let result = try BuildPlanResult(plan: try BuildPlan( - buildParameters: mockBuildParameters(shouldLinkStaticSwiftStdlib: true), + buildParameters: buildParameters, graph: graph, fileSystem: fs, observabilityScope: observability.topScope @@ -842,23 +844,23 @@ final class ModuleAliasingBuildTests: XCTestCase { XCTAssertMatch( otherLoggingArgs, [.anySequence, "-emit-objc-header", "-emit-objc-header-path", - "/path/to/build/debug/OtherLogging.build/OtherLogging-Swift.h", .anySequence] + "/path/to/build/\(buildParameters.triple)/debug/OtherLogging.build/OtherLogging-Swift.h", .anySequence] ) XCTAssertMatch( loggingArgs, [.anySequence, "-emit-objc-header", "-emit-objc-header-path", - "/path/to/build/debug/Logging.build/Logging-Swift.h", .anySequence] + "/path/to/build/\(buildParameters.triple)/debug/Logging.build/Logging-Swift.h", .anySequence] ) #else XCTAssertNoMatch( otherLoggingArgs, [.anySequence, "-emit-objc-header", "-emit-objc-header-path", - "/path/to/build/debug/OtherLogging.build/OtherLogging-Swift.h", .anySequence] + "/path/to/build/\(buildParameters.triple)/debug/OtherLogging.build/OtherLogging-Swift.h", .anySequence] ) XCTAssertNoMatch( loggingArgs, [.anySequence, "-emit-objc-header", "-emit-objc-header-path", - "/path/to/build/debug/Logging.build/Logging-Swift.h", .anySequence] + "/path/to/build/\(buildParameters.triple)/debug/Logging.build/Logging-Swift.h", .anySequence] ) #endif } diff --git a/Tests/CommandsTests/SwiftToolTests.swift b/Tests/CommandsTests/SwiftToolTests.swift index cc5c291de0e..44e8ea2c75a 100644 --- a/Tests/CommandsTests/SwiftToolTests.swift +++ b/Tests/CommandsTests/SwiftToolTests.swift @@ -255,7 +255,7 @@ final class SwiftToolTests: CommandsTestCase { let explicitDwarfOptions = try GlobalOptions.parse(["--triple", "x86_64-unknown-windows-msvc", "-debug-info-format", "dwarf"]) let explicitDwarf = try SwiftTool.createSwiftToolForTest(options: explicitDwarfOptions) plan = try BuildPlan( - productsBuildParameters: explicitDwarf.productsBuildParameters, + destinationBuildParameters: explicitDwarf.productsBuildParameters, toolsBuildParameters: explicitDwarf.toolsBuildParameters, graph: graph, fileSystem: fs, @@ -270,7 +270,7 @@ final class SwiftToolTests: CommandsTestCase { let explicitCodeView = try SwiftTool.createSwiftToolForTest(options: explicitCodeViewOptions) plan = try BuildPlan( - productsBuildParameters: explicitCodeView.productsBuildParameters, + destinationBuildParameters: explicitCodeView.productsBuildParameters, toolsBuildParameters: explicitCodeView.productsBuildParameters, graph: graph, fileSystem: fs, @@ -293,7 +293,7 @@ final class SwiftToolTests: CommandsTestCase { let implicitDwarfOptions = try GlobalOptions.parse(["--triple", "x86_64-unknown-windows-msvc"]) let implicitDwarf = try SwiftTool.createSwiftToolForTest(options: implicitDwarfOptions) plan = try BuildPlan( - productsBuildParameters: implicitDwarf.productsBuildParameters, + destinationBuildParameters: implicitDwarf.productsBuildParameters, toolsBuildParameters: implicitDwarf.toolsBuildParameters, graph: graph, fileSystem: fs, @@ -306,7 +306,7 @@ final class SwiftToolTests: CommandsTestCase { let explicitNoDebugInfoOptions = try GlobalOptions.parse(["--triple", "x86_64-unknown-windows-msvc", "-debug-info-format", "none"]) let explicitNoDebugInfo = try SwiftTool.createSwiftToolForTest(options: explicitNoDebugInfoOptions) plan = try BuildPlan( - productsBuildParameters: explicitNoDebugInfo.productsBuildParameters, + destinationBuildParameters: explicitNoDebugInfo.productsBuildParameters, toolsBuildParameters: explicitNoDebugInfo.toolsBuildParameters, graph: graph, fileSystem: fs, diff --git a/Tests/SPMBuildCoreTests/PluginInvocationTests.swift b/Tests/SPMBuildCoreTests/PluginInvocationTests.swift index 05d019ac1c6..91d69f0f257 100644 --- a/Tests/SPMBuildCoreTests/PluginInvocationTests.swift +++ b/Tests/SPMBuildCoreTests/PluginInvocationTests.swift @@ -189,13 +189,13 @@ class PluginInvocationTests: XCTestCase { // Construct a canned input and run plugins using our MockPluginScriptRunner(). let outputDir = AbsolutePath("/Foo/.build") - let builtToolsDir = AbsolutePath("/path/to/build/debug") let pluginRunner = MockPluginScriptRunner() + let buildParameters = mockBuildParameters( + environment: BuildEnvironment(platform: .macOS, configuration: .debug) + ) let results = try graph.invokeBuildToolPlugins( outputDir: outputDir, - buildParameters: mockBuildParameters( - environment: BuildEnvironment(platform: .macOS, configuration: .debug) - ), + buildParameters: buildParameters, additionalFileRules: [], toolSearchDirectories: [UserToolchain.default.swiftCompilerPath.parentDirectory], pkgConfigDirectories: [], @@ -203,6 +203,7 @@ class PluginInvocationTests: XCTestCase { observabilityScope: observability.topScope, fileSystem: fileSystem ) + let builtToolsDir = AbsolutePath("/path/to/build/\(buildParameters.triple)/debug") // Check the canned output to make sure nothing was lost in transport. XCTAssertNoDiagnostics(observability.diagnostics) diff --git a/Tests/SourceKitLSPAPITests/SourceKitLSPAPITests.swift b/Tests/SourceKitLSPAPITests/SourceKitLSPAPITests.swift index 18cbcd13d14..7541f543566 100644 --- a/Tests/SourceKitLSPAPITests/SourceKitLSPAPITests.swift +++ b/Tests/SourceKitLSPAPITests/SourceKitLSPAPITests.swift @@ -42,17 +42,38 @@ class SourceKitLSPAPITests: XCTestCase { ) XCTAssertNoDiagnostics(observability.diagnostics) + let buildParameters = mockBuildParameters(shouldLinkStaticSwiftStdlib: true) let plan = try BuildPlan( - productsBuildParameters: mockBuildParameters(shouldLinkStaticSwiftStdlib: true), - toolsBuildParameters: mockBuildParameters(shouldLinkStaticSwiftStdlib: true), + destinationBuildParameters: buildParameters, + toolsBuildParameters: buildParameters, graph: graph, fileSystem: fs, observabilityScope: observability.topScope ) let description = BuildDescription(buildPlan: plan) - try description.checkArguments(for: "exe", graph: graph, partialArguments: ["/fake/path/to/swiftc", "-module-name", "exe", "-emit-dependencies", "-emit-module", "-emit-module-path", "/path/to/build/debug/exe.build/exe.swiftmodule"]) - try description.checkArguments(for: "lib", graph: graph, partialArguments: ["/fake/path/to/swiftc", "-module-name", "lib", "-emit-dependencies", "-emit-module", "-emit-module-path", "/path/to/build/debug/Modules/lib.swiftmodule"]) + try description.checkArguments( + for: "exe", + graph: graph, + partialArguments: [ + "/fake/path/to/swiftc", + "-module-name", "exe", + "-emit-dependencies", + "-emit-module", + "-emit-module-path", "/path/to/build/\(buildParameters.triple)/debug/exe.build/exe.swiftmodule" + ] + ) + try description.checkArguments( + for: "lib", + graph: graph, + partialArguments: [ + "/fake/path/to/swiftc", + "-module-name", "lib", + "-emit-dependencies", + "-emit-module", + "-emit-module-path", "/path/to/build/\(buildParameters.triple)/debug/Modules/lib.swiftmodule" + ] + ) } } From d083be627067963784c0240e7016993aaa86d1b6 Mon Sep 17 00:00:00 2001 From: Max Desiatov Date: Thu, 15 Feb 2024 16:39:55 +0000 Subject: [PATCH 24/33] Fix stray debug printer --- Sources/Build/BuildDescription/ProductBuildDescription.swift | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Sources/Build/BuildDescription/ProductBuildDescription.swift b/Sources/Build/BuildDescription/ProductBuildDescription.swift index 814aaefa1fe..8410e7e5e36 100644 --- a/Sources/Build/BuildDescription/ProductBuildDescription.swift +++ b/Sources/Build/BuildDescription/ProductBuildDescription.swift @@ -65,8 +65,7 @@ public final class ProductBuildDescription: SPMBuildCore.ProductBuildDescription /// Path to the link filelist file. var linkFileListPath: AbsolutePath { - print(self.product.name) - return self.tempsPath.appending("Objects.LinkFileList") + self.tempsPath.appending("Objects.LinkFileList") } /// File system reference. From 379bf0ffba08d9119633f8311e8177f66507213c Mon Sep 17 00:00:00 2001 From: Max Desiatov Date: Fri, 16 Feb 2024 13:36:43 +0000 Subject: [PATCH 25/33] Restore `BuildPlan(productsBuildParameters:...)` compat --- Sources/Build/BuildPlan/BuildPlan.swift | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/Sources/Build/BuildPlan/BuildPlan.swift b/Sources/Build/BuildPlan/BuildPlan.swift index 4d9a9360b59..2f366bb8121 100644 --- a/Sources/Build/BuildPlan/BuildPlan.swift +++ b/Sources/Build/BuildPlan/BuildPlan.swift @@ -236,7 +236,7 @@ public class BuildPlan: SPMBuildCore.BuildPlan { /// ObservabilityScope with which to emit diagnostics let observabilityScope: ObservabilityScope - @available(*, deprecated, renamed: "init(productsBuildParameters:toolsBuildParameters:graph:)") + @available(*, deprecated, renamed: "init(destinationBuildParameters:toolsBuildParameters:graph:)") public convenience init( buildParameters: BuildParameters, graph: PackageGraph, @@ -258,6 +258,23 @@ public class BuildPlan: SPMBuildCore.BuildPlan { ) } + @available(*, deprecated, renamed: "init(destinationBuildParameters:toolsBuildParameters:graph:fileSystem:observabilityScope:)") + public convenience init( + productsBuildParameters: BuildParameters, + toolsBuildParameters: BuildParameters, + graph: PackageGraph, + fileSystem: any FileSystem, + observabilityScope: ObservabilityScope + ) throws { + try self.init( + destinationBuildParameters: productsBuildParameters, + toolsBuildParameters: toolsBuildParameters, + graph: graph, + fileSystem: fileSystem, + observabilityScope: observabilityScope + ) + } + /// Create a build plan with a package graph and explicitly distinct build parameters for products and tools. public init( destinationBuildParameters: BuildParameters, From 99b7bd6004ed805c7c02b5d742f53ddf941b5d67 Mon Sep 17 00:00:00 2001 From: Max Desiatov Date: Fri, 16 Feb 2024 13:39:58 +0000 Subject: [PATCH 26/33] Fix doc comment --- Sources/Build/BuildPlan/BuildPlan.swift | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Sources/Build/BuildPlan/BuildPlan.swift b/Sources/Build/BuildPlan/BuildPlan.swift index 2f366bb8121..2c4c7519fd8 100644 --- a/Sources/Build/BuildPlan/BuildPlan.swift +++ b/Sources/Build/BuildPlan/BuildPlan.swift @@ -275,7 +275,8 @@ public class BuildPlan: SPMBuildCore.BuildPlan { ) } - /// Create a build plan with a package graph and explicitly distinct build parameters for products and tools. + /// Create a build plan with a package graph and explicitly distinct build parameters for destination platform and + /// tools platform. public init( destinationBuildParameters: BuildParameters, toolsBuildParameters: BuildParameters, From b83db6432c43ee75f5daa11d1db6fccb1e1642a6 Mon Sep 17 00:00:00 2001 From: Max Desiatov Date: Fri, 16 Feb 2024 20:29:45 +0000 Subject: [PATCH 27/33] Address PR feedback --- .../ProductBuildDescription.swift | 2 +- .../SwiftTargetBuildDescription.swift | 117 ++++++++++-------- .../TargetBuildDescription.swift | 2 +- .../LLBuildManifestBuilder+Swift.swift | 32 ++--- Sources/Build/BuildPlan/BuildPlan+Swift.swift | 4 +- .../Commands/Utilities/TestingSupport.swift | 16 ++- Sources/Commands/Utilities/XCTEvents.swift | 18 +-- Tests/BuildTests/BuildPlanTests.swift | 86 ++++++------- 8 files changed, 152 insertions(+), 125 deletions(-) diff --git a/Sources/Build/BuildDescription/ProductBuildDescription.swift b/Sources/Build/BuildDescription/ProductBuildDescription.swift index 8410e7e5e36..d5e0e9ba8f9 100644 --- a/Sources/Build/BuildDescription/ProductBuildDescription.swift +++ b/Sources/Build/BuildDescription/ProductBuildDescription.swift @@ -346,7 +346,7 @@ public final class ProductBuildDescription: SPMBuildCore.ProductBuildDescription // Library search path for the toolchain's copy of SwiftSyntax. #if BUILD_MACROS_AS_DYLIBS if product.type == .macro { - args += try ["-L", destinationBuildParameters.toolchain.hostLibDir.pathString] + args += try ["-L", defaultBuildParameters.toolchain.hostLibDir.pathString] } #endif diff --git a/Sources/Build/BuildDescription/SwiftTargetBuildDescription.swift b/Sources/Build/BuildDescription/SwiftTargetBuildDescription.swift index cb1d0f8e13f..9edafd7bb9c 100644 --- a/Sources/Build/BuildDescription/SwiftTargetBuildDescription.swift +++ b/Sources/Build/BuildDescription/SwiftTargetBuildDescription.swift @@ -43,7 +43,7 @@ public final class SwiftTargetBuildDescription { public let toolsVersion: ToolsVersion /// The build parameters for this target. - let destinationBuildParameters: BuildParameters + let defaultBuildParameters: BuildParameters /// The build parameters for build tools. let toolsBuildParameters: BuildParameters @@ -65,7 +65,7 @@ public final class SwiftTargetBuildDescription { /// Path to the bundle generated for this module (if any). var bundlePath: AbsolutePath? { if let bundleName = target.underlying.potentialBundleName, needsResourceBundle { - return self.destinationBuildParameters.bundlePath(named: bundleName) + return self.defaultBuildParameters.bundlePath(named: bundleName) } else { return .none } @@ -100,7 +100,7 @@ public final class SwiftTargetBuildDescription { let relativeSources = self.target.sources.relativePaths + self.derivedSources.relativePaths + self.pluginDerivedSources.relativePaths - let ltoEnabled = self.destinationBuildParameters.linkingParameters.linkTimeOptimizationMode != nil + let ltoEnabled = self.defaultBuildParameters.linkingParameters.linkTimeOptimizationMode != nil let objectFileExtension = ltoEnabled ? "bc" : "o" return try relativeSources.map { try AbsolutePath( @@ -111,13 +111,13 @@ public final class SwiftTargetBuildDescription { } var modulesPath: AbsolutePath { - return self.destinationBuildParameters.buildPath.appending(component: "Modules\(self.target.buildTriple.suffix)") + return self.defaultBuildParameters.buildPath.appending(component: "Modules\(self.target.buildTriple.suffix)") } /// The path to the swiftmodule file after compilation. public var moduleOutputPath: AbsolutePath { // note: needs to be public because of sourcekit-lsp // If we're an executable and we're not allowing test targets to link against us, we hide the module. - let triple = destinationBuildParameters.triple + let triple = defaultBuildParameters.triple let allowLinkingAgainstExecutables = (triple.isDarwin() || triple.isLinux() || triple.isWindows()) && self.toolsVersion >= .v5_5 let dirPath = (target.type == .executable && !allowLinkingAgainstExecutables) ? self.tempsPath : self.modulesPath return dirPath.appending(component: "\(self.target.c99name).swiftmodule") @@ -273,7 +273,7 @@ public final class SwiftTargetBuildDescription { self.package = package self.target = target self.toolsVersion = toolsVersion - self.destinationBuildParameters = destinationBuildParameters + self.defaultBuildParameters = destinationBuildParameters self.toolsBuildParameters = toolsBuildParameters // Unless mentioned explicitly, use the target type to determine if this is a test target. @@ -336,18 +336,22 @@ public final class SwiftTargetBuildDescription { return } - guard self.destinationBuildParameters.triple.isDarwin(), self.destinationBuildParameters.testingParameters.experimentalTestOutput else { + guard + self.defaultBuildParameters.triple.isDarwin() && + self.defaultBuildParameters.testingParameters.experimentalTestOutput + else { return } - let content = generateTestObservationCode(buildParameters: self.destinationBuildParameters) + let content = generateTestObservationCode(buildParameters: self.defaultBuildParameters) // FIXME: We should generate this file during the actual build. self.derivedSources.relativePaths.append(subpath) try self.fileSystem.writeIfChanged(path: path, string: content) } - // FIXME: This will not work well for large files, as we will store the entire contents, plus its byte array representation in memory and also `writeIfChanged()` will read the entire generated file again. + // FIXME: This will not work well for large files, as we will store the entire contents, plus its byte array + // representation in memory and also `writeIfChanged()` will read the entire generated file again. private func generateResourceEmbeddingCode() throws { guard needsResourceEmbedding else { return } @@ -380,7 +384,7 @@ public final class SwiftTargetBuildDescription { guard let bundlePath else { return } let mainPathSubstitution: String - if self.destinationBuildParameters.triple.isWASI() { + if self.defaultBuildParameters.triple.isWASI() { // We prefer compile-time evaluation of the bundle path here for WASI. There's no benefit in evaluating this // at runtime, especially as `Bundle` support in WASI Foundation is partial. We expect all resource paths to // evaluate to `/\(resourceBundleName)/\(resourcePath)`, which allows us to pass this path to JS APIs like @@ -430,7 +434,11 @@ 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.destinationBuildParameters.toolchain, fileSystem: self.fileSystem) { + DriverSupport.checkToolchainDriverFlags( + flags: [flag], + toolchain: self.defaultBuildParameters.toolchain, + fileSystem: self.fileSystem + ) { if packageAccess { let pkgID = pkg.identity.description.spm_mangledToC99ExtendedIdentifier() return [flag, pkgID] @@ -444,7 +452,7 @@ public final class SwiftTargetBuildDescription { #if BUILD_MACROS_AS_DYLIBS self.requiredMacroProducts.forEach { macro in - args += ["-Xfrontend", "-load-plugin-library", "-Xfrontend", self.destinationBuildParameters.binaryPath(for: macro).pathString] + args += ["-Xfrontend", "-load-plugin-library", "-Xfrontend", self.toolsBuildParameters.binaryPath(for: macro).pathString] } #else try self.requiredMacroProducts.forEach { macro in @@ -458,7 +466,14 @@ 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.destinationBuildParameters.toolchain.isSwiftDevelopmentToolchain, DriverSupport.checkSupportedFrontendFlags(flags: ["-external-plugin-path"], toolchain: self.destinationBuildParameters.toolchain, fileSystem: self.fileSystem), let pluginServer = try self.destinationBuildParameters.toolchain.swiftPluginServerPath { + if self.defaultBuildParameters.toolchain.isSwiftDevelopmentToolchain, + DriverSupport.checkSupportedFrontendFlags( + flags: ["-external-plugin-path"], + toolchain: self.defaultBuildParameters.toolchain, + fileSystem: self.fileSystem + ), + let pluginServer = try self.defaultBuildParameters.toolchain.swiftPluginServerPath + { let toolchainUsrPath = pluginServer.parentDirectory.parentDirectory let pluginPathComponents = ["lib", "swift", "host", "plugins"] @@ -470,7 +485,11 @@ public final class SwiftTargetBuildDescription { } if self.shouldDisableSandbox { - let toolchainSupportsDisablingSandbox = DriverSupport.checkSupportedFrontendFlags(flags: ["-disable-sandbox"], toolchain: self.destinationBuildParameters.toolchain, fileSystem: fileSystem) + let toolchainSupportsDisablingSandbox = DriverSupport.checkSupportedFrontendFlags( + flags: ["-disable-sandbox"], + toolchain: self.defaultBuildParameters.toolchain, + fileSystem: fileSystem + ) if toolchainSupportsDisablingSandbox { args += ["-disable-sandbox"] } else { @@ -487,11 +506,11 @@ public final class SwiftTargetBuildDescription { /// The arguments needed to compile this target. public func compileArguments() throws -> [String] { var args = [String]() - args += try self.destinationBuildParameters.tripleArgs(for: self.target) + args += try self.defaultBuildParameters.tripleArgs(for: self.target) args += ["-swift-version", self.swiftVersion.rawValue] // pass `-v` during verbose builds. - if self.destinationBuildParameters.outputParameters.isVerbose { + if self.defaultBuildParameters.outputParameters.isVerbose { args += ["-v"] } @@ -499,22 +518,22 @@ public final class SwiftTargetBuildDescription { // // Technically, it should be enabled whenever WMO is off but we // don't currently make that distinction in SwiftPM - switch self.destinationBuildParameters.configuration { + switch self.defaultBuildParameters.configuration { case .debug: args += ["-enable-batch-mode"] case .release: break } - args += self.destinationBuildParameters.indexStoreArguments(for: self.target) + args += self.defaultBuildParameters.indexStoreArguments(for: self.target) args += self.optimizationArguments args += self.testingArguments - args += ["-j\(self.destinationBuildParameters.workers)"] + args += ["-j\(self.defaultBuildParameters.workers)"] args += self.activeCompilationConditions args += self.additionalFlags args += try self.moduleCacheArgs args += self.stdlibArguments - args += self.destinationBuildParameters.sanitizers.compileSwiftFlags() + args += self.defaultBuildParameters.sanitizers.compileSwiftFlags() args += ["-parseable-output"] // If we're compiling the main module of an executable other than the one that @@ -534,8 +553,8 @@ public final class SwiftTargetBuildDescription { // we can rename the symbol unconditionally. // No `-` for these flags because the set of Strings in driver.supportedFrontendFlags do // not have a leading `-` - if self.destinationBuildParameters.driverParameters.canRenameEntrypointFunctionName, - self.destinationBuildParameters.linkerFlagsForRenamingMainFunction(of: self.target) != nil + if self.defaultBuildParameters.driverParameters.canRenameEntrypointFunctionName, + self.defaultBuildParameters.linkerFlagsForRenamingMainFunction(of: self.target) != nil { args += ["-Xfrontend", "-entry-point-function-name", "-Xfrontend", "\(self.target.c99name)_main"] } @@ -548,7 +567,7 @@ public final class SwiftTargetBuildDescription { // Only add the build path to the framework search path if there are binary frameworks to link against. if !self.libraryBinaryPaths.isEmpty { - args += ["-F", self.destinationBuildParameters.buildPath.pathString] + args += ["-F", self.defaultBuildParameters.buildPath.pathString] } // Emit the ObjC compatibility header if enabled. @@ -557,12 +576,12 @@ public final class SwiftTargetBuildDescription { } // Add arguments needed for code coverage if it is enabled. - if self.destinationBuildParameters.testingParameters.enableCodeCoverage { + if self.defaultBuildParameters.testingParameters.enableCodeCoverage { args += ["-profile-coverage-mapping", "-profile-generate"] } // Add arguments to colorize output if stdout is tty - if self.destinationBuildParameters.outputParameters.isColorized { + if self.defaultBuildParameters.outputParameters.isColorized { args += ["-color-diagnostics"] } @@ -572,7 +591,7 @@ public final class SwiftTargetBuildDescription { switch testTargetRole { case .discovery: for dependency in try self.target.recursiveTargetDependencies() { - let dependencyScope = self.destinationBuildParameters.createScope(for: dependency) + let dependencyScope = self.defaultBuildParameters.createScope(for: dependency) let dependencySwiftFlags = dependencyScope.evaluate(.OTHER_SWIFT_FLAGS) if let interopModeFlag = dependencySwiftFlags.first(where: { $0.hasPrefix("-cxx-interoperability-mode=") }) { args += [interopModeFlag] @@ -592,17 +611,17 @@ public final class SwiftTargetBuildDescription { // Add the output for the `.swiftinterface`, if requested or if library evolution has been enabled some other // way. - if self.destinationBuildParameters.driverParameters.enableParseableModuleInterfaces || args.contains("-enable-library-evolution") { + if self.defaultBuildParameters.driverParameters.enableParseableModuleInterfaces || args.contains("-enable-library-evolution") { args += ["-emit-module-interface-path", self.parseableModuleInterfaceOutputPath.pathString] } - args += self.destinationBuildParameters.toolchain.extraFlags.swiftCompilerFlags + args += self.defaultBuildParameters.toolchain.extraFlags.swiftCompilerFlags // User arguments (from -Xswiftc) should follow generated arguments to allow user overrides - args += self.destinationBuildParameters.flags.swiftCompilerFlags + args += self.defaultBuildParameters.flags.swiftCompilerFlags - args += self.destinationBuildParameters.toolchain.extraFlags.cCompilerFlags.asSwiftcCCompilerFlags() + args += self.defaultBuildParameters.toolchain.extraFlags.cCompilerFlags.asSwiftcCCompilerFlags() // User arguments (from -Xcc) should follow generated arguments to allow user overrides - args += self.destinationBuildParameters.flags.cCompilerFlags.asSwiftcCCompilerFlags() + args += self.defaultBuildParameters.flags.cCompilerFlags.asSwiftcCCompilerFlags() // TODO: Pass -Xcxx flags to swiftc (#6491) // Uncomment when downstream support arrives. @@ -611,7 +630,7 @@ public final class SwiftTargetBuildDescription { // args += self.buildParameters.flags.cxxCompilerFlags.asSwiftcCXXCompilerFlags() // Enable the correct LTO mode if requested. - switch self.destinationBuildParameters.linkingParameters.linkTimeOptimizationMode { + switch self.defaultBuildParameters.linkingParameters.linkTimeOptimizationMode { case nil: break case .full: @@ -621,7 +640,7 @@ public final class SwiftTargetBuildDescription { } // Pass default include paths from the toolchain. - for includeSearchPath in self.destinationBuildParameters.toolchain.includeSearchPaths { + for includeSearchPath in self.defaultBuildParameters.toolchain.includeSearchPaths { args += ["-I", includeSearchPath.pathString] } @@ -645,7 +664,7 @@ public final class SwiftTargetBuildDescription { // rdar://117578677 // Pass -fno-omit-frame-pointer to support backtraces // this can be removed once the backtracer uses DWARF instead of frame pointers - if let omitFramePointers = self.destinationBuildParameters.debuggingParameters.omitFramePointers { + if let omitFramePointers = self.defaultBuildParameters.debuggingParameters.omitFramePointers { if omitFramePointers { args += ["-Xcc", "-fomit-frame-pointer"] } else { @@ -660,7 +679,7 @@ public final class SwiftTargetBuildDescription { /// such as emitting a module or supplementary outputs. public func emitCommandLine(scanInvocation: Bool = false) throws -> [String] { var result: [String] = [] - result.append(self.destinationBuildParameters.toolchain.swiftCompilerPath.pathString) + result.append(self.defaultBuildParameters.toolchain.swiftCompilerPath.pathString) result.append("-module-name") result.append(self.target.c99name) @@ -678,7 +697,7 @@ public final class SwiftTargetBuildDescription { result.append(try self.writeOutputFileMap().pathString) } - if self.destinationBuildParameters.useWholeModuleOptimization { + if self.defaultBuildParameters.useWholeModuleOptimization { result.append("-whole-module-optimization") result.append("-num-threads") result.append(String(ProcessInfo.processInfo.activeProcessorCount)) @@ -698,7 +717,7 @@ public final class SwiftTargetBuildDescription { /// Returns true if ObjC compatibility header should be emitted. private var shouldEmitObjCCompatibilityHeader: Bool { - self.destinationBuildParameters.triple.isDarwin() && self.target.type == .library + self.defaultBuildParameters.triple.isDarwin() && self.target.type == .library } func writeOutputFileMap() throws -> AbsolutePath { @@ -712,7 +731,7 @@ public final class SwiftTargetBuildDescription { """# - if self.destinationBuildParameters.useWholeModuleOptimization { + if self.defaultBuildParameters.useWholeModuleOptimization { let moduleName = self.target.c99name content += #""" @@ -743,7 +762,7 @@ public final class SwiftTargetBuildDescription { // Write out the entries for each source file. let sources = self.sources let objects = try self.objects - let ltoEnabled = self.destinationBuildParameters.linkingParameters.linkTimeOptimizationMode != nil + let ltoEnabled = self.defaultBuildParameters.linkingParameters.linkTimeOptimizationMode != nil let objectKey = ltoEnabled ? "llvm-bc" : "object" for idx in 0.. [String] { - let scope = self.destinationBuildParameters.createScope(for: self.target) + let scope = self.defaultBuildParameters.createScope(for: self.target) var flags: [String] = [] // Swift defines. @@ -846,7 +865,7 @@ public final class SwiftTargetBuildDescription { // Include path for the toolchain's copy of SwiftSyntax. #if BUILD_MACROS_AS_DYLIBS if target.type == .macro { - flags += try ["-I", self.destinationBuildParameters.toolchain.hostLibDir.pathString] + flags += try ["-I", self.defaultBuildParameters.toolchain.hostLibDir.pathString] } #endif @@ -857,7 +876,7 @@ public final class SwiftTargetBuildDescription { private var activeCompilationConditions: [String] { var compilationConditions = ["-DSWIFT_PACKAGE"] - switch self.destinationBuildParameters.configuration { + switch self.defaultBuildParameters.configuration { case .debug: compilationConditions += ["-DDEBUG"] case .release: @@ -869,7 +888,7 @@ public final class SwiftTargetBuildDescription { /// Optimization arguments according to the build configuration. private var optimizationArguments: [String] { - switch self.destinationBuildParameters.configuration { + switch self.defaultBuildParameters.configuration { case .debug: return ["-Onone"] case .release: @@ -883,7 +902,7 @@ public final class SwiftTargetBuildDescription { // test targets must be built with -enable-testing // since its required for test discovery (the non objective-c reflection kind) return ["-enable-testing"] - } else if self.destinationBuildParameters.testingParameters.enableTestability { + } else if self.defaultBuildParameters.testingParameters.enableTestability { return ["-enable-testing"] } else { return [] @@ -893,20 +912,20 @@ public final class SwiftTargetBuildDescription { /// Module cache arguments. private var moduleCacheArgs: [String] { get throws { - ["-module-cache-path", try self.destinationBuildParameters.moduleCache.pathString] + ["-module-cache-path", try self.defaultBuildParameters.moduleCache.pathString] } } private var stdlibArguments: [String] { var arguments: [String] = [] - let isLinkingStaticStdlib = self.destinationBuildParameters.linkingParameters.shouldLinkStaticSwiftStdlib - && self.destinationBuildParameters.triple.isSupportingStaticStdlib + let isLinkingStaticStdlib = self.defaultBuildParameters.linkingParameters.shouldLinkStaticSwiftStdlib + && self.defaultBuildParameters.triple.isSupportingStaticStdlib if isLinkingStaticStdlib { arguments += ["-static-stdlib"] } - if let resourcesPath = self.destinationBuildParameters.toolchain.swiftResourcesPath(isStatic: isLinkingStaticStdlib) { + if let resourcesPath = self.defaultBuildParameters.toolchain.swiftResourcesPath(isStatic: isLinkingStaticStdlib) { arguments += ["-resource-dir", "\(resourcesPath)"] } diff --git a/Sources/Build/BuildDescription/TargetBuildDescription.swift b/Sources/Build/BuildDescription/TargetBuildDescription.swift index e2c15d47697..ad9de913c2d 100644 --- a/Sources/Build/BuildDescription/TargetBuildDescription.swift +++ b/Sources/Build/BuildDescription/TargetBuildDescription.swift @@ -101,7 +101,7 @@ public enum TargetBuildDescription { var buildParameters: BuildParameters { switch self { case .swift(let swiftTargetBuildDescription): - return swiftTargetBuildDescription.destinationBuildParameters + return swiftTargetBuildDescription.defaultBuildParameters case .clang(let clangTargetBuildDescription): return clangTargetBuildDescription.buildParameters } diff --git a/Sources/Build/BuildManifest/LLBuildManifestBuilder+Swift.swift b/Sources/Build/BuildManifest/LLBuildManifestBuilder+Swift.swift index 040f195a01b..116467633e5 100644 --- a/Sources/Build/BuildManifest/LLBuildManifestBuilder+Swift.swift +++ b/Sources/Build/BuildManifest/LLBuildManifestBuilder+Swift.swift @@ -45,7 +45,7 @@ extension LLBuildManifestBuilder { let moduleNode = Node.file(target.moduleOutputPath) let cmdOutputs = objectNodes + [moduleNode] - if target.destinationBuildParameters.driverParameters.useIntegratedSwiftDriver { + if target.defaultBuildParameters.driverParameters.useIntegratedSwiftDriver { try self.addSwiftCmdsViaIntegratedDriver( target, inputs: inputs, @@ -68,7 +68,7 @@ extension LLBuildManifestBuilder { // jobs needed to build this Swift target. var commandLine = try target.emitCommandLine() commandLine.append("-driver-use-frontend-path") - commandLine.append(target.destinationBuildParameters.toolchain.swiftCompilerPath.pathString) + commandLine.append(target.defaultBuildParameters.toolchain.swiftCompilerPath.pathString) // FIXME: At some point SwiftPM should provide its own executor for // running jobs/launching processes during planning let resolver = try ArgsResolver(fileSystem: target.fileSystem) @@ -132,7 +132,7 @@ extension LLBuildManifestBuilder { // common intermediate dependency modules, such dependencies can lead // to cycles in the resulting manifest. var manifestNodeInputs: [Node] = [] - if targetDescription.destinationBuildParameters.driverParameters.useExplicitModuleBuild && !isMainModule(job) { + if targetDescription.defaultBuildParameters.driverParameters.useExplicitModuleBuild && !isMainModule(job) { manifestNodeInputs = jobInputs } else { manifestNodeInputs = (inputs + jobInputs).uniqued() @@ -287,7 +287,7 @@ extension LLBuildManifestBuilder { // jobs needed to build this Swift target. var commandLine = try targetDescription.emitCommandLine() commandLine.append("-driver-use-frontend-path") - commandLine.append(targetDescription.destinationBuildParameters.toolchain.swiftCompilerPath.pathString) + commandLine.append(targetDescription.defaultBuildParameters.toolchain.swiftCompilerPath.pathString) commandLine.append("-experimental-explicit-module-build") let resolver = try ArgsResolver(fileSystem: self.fileSystem) let executor = SPMSwiftDriverExecutor( @@ -378,14 +378,14 @@ extension LLBuildManifestBuilder { cmdOutputs: [Node] ) throws { let isLibrary = target.target.type == .library || target.target.type == .test - let cmdName = target.target.getCommandName(config: target.destinationBuildParameters.buildConfig) + let cmdName = target.target.getCommandName(config: target.defaultBuildParameters.buildConfig) self.manifest.addWriteSourcesFileListCommand(sources: target.sources, sourcesFileListPath: target.sourcesFileListPath) self.manifest.addSwiftCmd( name: cmdName, inputs: inputs + [Node.file(target.sourcesFileListPath)], outputs: cmdOutputs, - executable: target.destinationBuildParameters.toolchain.swiftCompilerPath, + executable: target.defaultBuildParameters.toolchain.swiftCompilerPath, moduleName: target.target.c99name, moduleAliases: target.target.moduleAliases, moduleOutputPath: target.moduleOutputPath, @@ -396,7 +396,7 @@ extension LLBuildManifestBuilder { sources: target.sources, fileList: target.sourcesFileListPath, isLibrary: isLibrary, - wholeModuleOptimization: target.destinationBuildParameters.configuration == .release, + wholeModuleOptimization: target.defaultBuildParameters.configuration == .release, outputFileMapPath: try target.writeOutputFileMap() // FIXME: Eliminate side effect. ) } @@ -406,7 +406,7 @@ extension LLBuildManifestBuilder { ) throws -> [Node] { var inputs = target.sources.map(Node.file) - let swiftVersionFilePath = addSwiftGetVersionCommand(buildParameters: target.destinationBuildParameters) + let swiftVersionFilePath = addSwiftGetVersionCommand(buildParameters: target.defaultBuildParameters) inputs.append(.file(swiftVersionFilePath)) // Add resources node as the input to the target. This isn't great because we @@ -452,7 +452,7 @@ extension LLBuildManifestBuilder { } } - for dependency in target.target.dependencies(satisfying: target.destinationBuildParameters.buildEnvironment) { + for dependency in target.target.dependencies(satisfying: target.defaultBuildParameters.buildEnvironment) { switch dependency { case .target(let target, _): try addStaticTargetInputs(target) @@ -479,7 +479,7 @@ extension LLBuildManifestBuilder { } for binaryPath in target.libraryBinaryPaths { - let path = target.destinationBuildParameters.destinationPath(forBinaryAt: binaryPath) + let path = target.defaultBuildParameters.destinationPath(forBinaryAt: binaryPath) if self.fileSystem.isDirectory(binaryPath) { inputs.append(directory: path) } else { @@ -491,7 +491,7 @@ extension LLBuildManifestBuilder { // Depend on any required macro product's output. try target.requiredMacroProducts.forEach { macro in - try inputs.append(.virtual(macro.getLLBuildTargetName(config: target.destinationBuildParameters.buildConfig))) + try inputs.append(.virtual(macro.getLLBuildTargetName(config: target.defaultBuildParameters.buildConfig))) } return inputs + additionalInputs @@ -500,7 +500,7 @@ extension LLBuildManifestBuilder { /// Adds a top-level phony command that builds the entire target. private func addTargetCmd(_ target: SwiftTargetBuildDescription, cmdOutputs: [Node]) { // Create a phony node to represent the entire target. - let targetName = target.target.getLLBuildTargetName(config: target.destinationBuildParameters.buildConfig) + let targetName = target.target.getLLBuildTargetName(config: target.defaultBuildParameters.buildConfig) let targetOutput: Node = .virtual(targetName) self.manifest.addNode(targetOutput, toTarget: targetName) @@ -509,7 +509,7 @@ extension LLBuildManifestBuilder { inputs: cmdOutputs, outputs: [targetOutput] ) - if self.plan.graph.isInRootPackages(target.target, satisfying: target.destinationBuildParameters.buildEnvironment) { + if self.plan.graph.isInRootPackages(target.target, satisfying: target.defaultBuildParameters.buildEnvironment) { if !target.isTestTarget { self.addNode(targetOutput, toTarget: .main) } @@ -519,13 +519,13 @@ extension LLBuildManifestBuilder { private func addModuleWrapCmd(_ target: SwiftTargetBuildDescription) throws { // Add commands to perform the module wrapping Swift modules when debugging strategy is `modulewrap`. - guard target.destinationBuildParameters.debuggingStrategy == .modulewrap else { return } + guard target.defaultBuildParameters.debuggingStrategy == .modulewrap else { return } var moduleWrapArgs = [ - target.destinationBuildParameters.toolchain.swiftCompilerPath.pathString, + target.defaultBuildParameters.toolchain.swiftCompilerPath.pathString, "-modulewrap", target.moduleOutputPath.pathString, "-o", target.wrappedModuleOutputPath.pathString, ] - moduleWrapArgs += try target.destinationBuildParameters.tripleArgs(for: target.target) + moduleWrapArgs += try target.defaultBuildParameters.tripleArgs(for: target.target) self.manifest.addShellCmd( name: target.wrappedModuleOutputPath.pathString, description: "Wrapping AST for \(target.target.name) for debugging", diff --git a/Sources/Build/BuildPlan/BuildPlan+Swift.swift b/Sources/Build/BuildPlan/BuildPlan+Swift.swift index dbddbe58ff6..058631598f2 100644 --- a/Sources/Build/BuildPlan/BuildPlan+Swift.swift +++ b/Sources/Build/BuildPlan/BuildPlan+Swift.swift @@ -19,7 +19,7 @@ extension BuildPlan { func plan(swiftTarget: SwiftTargetBuildDescription) throws { // We need to iterate recursive dependencies because Swift compiler needs to see all the targets a target // depends on. - let environment = swiftTarget.destinationBuildParameters.buildEnvironment + let environment = swiftTarget.defaultBuildParameters.buildEnvironment for case .target(let dependency, _) in try swiftTarget.target.recursiveDependencies(satisfying: environment) { switch dependency.underlying { case let underlyingTarget as ClangTarget where underlyingTarget.type == .library: @@ -40,7 +40,7 @@ extension BuildPlan { swiftTarget.additionalFlags += try pkgConfig(for: target).cFlags case let target as BinaryTarget: if case .xcframework = target.kind { - let libraries = try self.parseXCFramework(for: target, triple: swiftTarget.destinationBuildParameters.triple) + let libraries = try self.parseXCFramework(for: target, triple: swiftTarget.defaultBuildParameters.triple) for library in libraries { library.headersPaths.forEach { swiftTarget.additionalFlags += ["-I", $0.pathString, "-Xcc", "-I", "-Xcc", $0.pathString] diff --git a/Sources/Commands/Utilities/TestingSupport.swift b/Sources/Commands/Utilities/TestingSupport.swift index 9c3f0392600..751c85d7689 100644 --- a/Sources/Commands/Utilities/TestingSupport.swift +++ b/Sources/Commands/Utilities/TestingSupport.swift @@ -36,7 +36,9 @@ enum TestingSupport { func findXCTestHelper(swiftBuildPath: AbsolutePath) -> AbsolutePath? { // XCTestHelper tool is installed in libexec. - let maybePath = swiftBuildPath.parentDirectory.parentDirectory.appending(components: "libexec", "swift", "pm", "swiftpm-xctest-helper") + let maybePath = swiftBuildPath.parentDirectory.parentDirectory.appending( + components: "libexec", "swift", "pm", "swiftpm-xctest-helper" + ) if swiftTool.fileSystem.isFile(maybePath) { return maybePath } else { @@ -46,7 +48,10 @@ enum TestingSupport { } if let firstCLIArgument = CommandLine.arguments.first { - let runningSwiftBuildPath = try AbsolutePath(validating: firstCLIArgument, relativeTo: swiftTool.originalWorkingDirectory) + let runningSwiftBuildPath = try AbsolutePath( + validating: firstCLIArgument, + relativeTo: swiftTool.originalWorkingDirectory + ) if let xctestHelperPath = findXCTestHelper(swiftBuildPath: runningSwiftBuildPath) { return xctestHelperPath } @@ -54,7 +59,10 @@ enum TestingSupport { // This will be true during swiftpm development or when using swift.org toolchains. let xcodePath = try TSCBasic.Process.checkNonZeroExit(args: "/usr/bin/xcode-select", "--print-path").spm_chomp() - let installedSwiftBuildPath = try TSCBasic.Process.checkNonZeroExit(args: "/usr/bin/xcrun", "--find", "swift-build", environment: ["DEVELOPER_DIR": xcodePath]).spm_chomp() + let installedSwiftBuildPath = try TSCBasic.Process.checkNonZeroExit( + args: "/usr/bin/xcrun", "--find", "swift-build", + environment: ["DEVELOPER_DIR": xcodePath] + ).spm_chomp() if let xctestHelperPath = findXCTestHelper(swiftBuildPath: try AbsolutePath(validating: installedSwiftBuildPath)) { return xctestHelperPath } @@ -126,7 +134,7 @@ enum TestingSupport { #else let env = try Self.constructTestEnvironment( toolchain: try swiftTool.getTargetToolchain(), - destinationBuildParameters: swiftTool.buildParametersForTest( + defaultBuildParameters: swiftTool.buildParametersForTest( enableCodeCoverage: enableCodeCoverage, shouldSkipBuilding: shouldSkipBuilding, library: .xctest diff --git a/Sources/Commands/Utilities/XCTEvents.swift b/Sources/Commands/Utilities/XCTEvents.swift index a264b205e3a..0ceedfce77f 100644 --- a/Sources/Commands/Utilities/XCTEvents.swift +++ b/Sources/Commands/Utilities/XCTEvents.swift @@ -237,12 +237,12 @@ extension TestErrorInfo { extension TestIssue { init(_ issue: XCTIssue) { self.init( - type: .init(destinationBuildParameters: issue.type), + type: .init(defaultBuildParameters: issue.type), compactDescription: issue.compactDescription, detailedDescription: issue.detailedDescription, - associatedError: issue.associatedError.map { .init(destinationBuildParameters: $0) }, - sourceCodeContext: .init(destinationBuildParameters: issue.sourceCodeContext), - attachments: issue.attachments.map { .init(destinationBuildParameters: $0) } + associatedError: issue.associatedError.map { .init(defaultBuildParameters: $0) }, + sourceCodeContext: .init(defaultBuildParameters: issue.sourceCodeContext), + attachments: issue.attachments.map { .init(defaultBuildParameters: $0) } ) } } @@ -275,8 +275,8 @@ extension TestLocation { extension TestSourceCodeContext { init(_ context: XCTSourceCodeContext) { self.init( - callStack: context.callStack.map { .init(destinationBuildParameters: $0) }, - location: context.location.map { .init(destinationBuildParameters: $0) } + callStack: context.callStack.map { .init(defaultBuildParameters: $0) }, + location: context.location.map { .init(defaultBuildParameters: $0) } ) } } @@ -285,8 +285,8 @@ extension TestSourceCodeFrame { init(_ frame: XCTSourceCodeFrame) { self.init( address: frame.address, - symbolInfo: (try? frame.symbolInfo()).map { .init(destinationBuildParameters: $0) }, - symbolicationError: frame.symbolicationError.map { .init(destinationBuildParameters: $0) } + symbolInfo: (try? frame.symbolInfo()).map { .init(defaultBuildParameters: $0) }, + symbolicationError: frame.symbolicationError.map { .init(defaultBuildParameters: $0) } ) } } @@ -296,7 +296,7 @@ extension TestSourceCodeSymbolInfo { self.init( imageName: symbolInfo.imageName, symbolName: symbolInfo.symbolName, - location: symbolInfo.location.map { .init(destinationBuildParameters: $0) } + location: symbolInfo.location.map { .init(defaultBuildParameters: $0) } ) } } diff --git a/Tests/BuildTests/BuildPlanTests.swift b/Tests/BuildTests/BuildPlanTests.swift index 5ea4e286dac..6e48e9a3dc0 100644 --- a/Tests/BuildTests/BuildPlanTests.swift +++ b/Tests/BuildTests/BuildPlanTests.swift @@ -769,7 +769,7 @@ final class BuildPlanTests: XCTestCase { #if os(macOS) let linkArguments = [ - result.plan.destinationBuildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.defaultBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "exe").pathString, "-module-name", "exe", @@ -786,7 +786,7 @@ final class BuildPlanTests: XCTestCase { ] #elseif os(Windows) let linkArguments = [ - result.plan.destinationBuildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.defaultBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "exe.exe").pathString, "-module-name", "exe", @@ -798,7 +798,7 @@ final class BuildPlanTests: XCTestCase { ] #else let linkArguments = [ - result.plan.destinationBuildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.defaultBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "exe").pathString, "-module-name", "exe", @@ -1182,7 +1182,7 @@ final class BuildPlanTests: XCTestCase { #if os(macOS) XCTAssertEqual(try result.buildProduct(for: "exe").linkArguments(), [ - result.plan.destinationBuildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.defaultBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "exe").pathString, "-module-name", "exe", @@ -1196,7 +1196,7 @@ final class BuildPlanTests: XCTestCase { ]) #elseif os(Windows) XCTAssertEqual(try result.buildProduct(for: "exe").linkArguments(), [ - result.plan.destinationBuildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.defaultBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "exe.exe").pathString, "-module-name", "exe", @@ -1208,7 +1208,7 @@ final class BuildPlanTests: XCTestCase { ]) #else XCTAssertEqual(try result.buildProduct(for: "exe").linkArguments(), [ - result.plan.destinationBuildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.defaultBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "exe").pathString, "-module-name", "exe", @@ -1272,7 +1272,7 @@ final class BuildPlanTests: XCTestCase { #if os(macOS) XCTAssertEqual(try result.buildProduct(for: "exe").linkArguments(), [ - result.plan.destinationBuildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.defaultBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "exe").pathString, "-module-name", "exe", @@ -1285,7 +1285,7 @@ final class BuildPlanTests: XCTestCase { ]) #elseif os(Windows) XCTAssertEqual(try result.buildProduct(for: "exe").linkArguments(), [ - result.plan.destinationBuildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.defaultBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "exe.exe").pathString, "-module-name", "exe", @@ -1296,7 +1296,7 @@ final class BuildPlanTests: XCTestCase { ]) #else XCTAssertEqual(try result.buildProduct(for: "exe").linkArguments(), [ - result.plan.destinationBuildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.defaultBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "exe").pathString, "-module-name", "exe", @@ -1431,7 +1431,7 @@ final class BuildPlanTests: XCTestCase { #if os(macOS) XCTAssertEqual(try result.buildProduct(for: "exe").linkArguments(), [ - result.plan.destinationBuildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.defaultBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "exe").pathString, "-module-name", "exe", @@ -1444,7 +1444,7 @@ final class BuildPlanTests: XCTestCase { ]) #elseif os(Windows) XCTAssertEqual(try result.buildProduct(for: "exe").linkArguments(), [ - result.plan.destinationBuildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.defaultBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "exe.exe").pathString, "-module-name", "exe", @@ -1456,7 +1456,7 @@ final class BuildPlanTests: XCTestCase { ]) #else XCTAssertEqual(try result.buildProduct(for: "exe").linkArguments(), [ - result.plan.destinationBuildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.defaultBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "exe").pathString, "-module-name", "exe", @@ -1626,7 +1626,7 @@ final class BuildPlanTests: XCTestCase { #if os(macOS) XCTAssertEqual(try result.buildProduct(for: "exe").linkArguments(), [ - result.plan.destinationBuildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.defaultBuildParameters.toolchain.swiftCompilerPath.pathString, "-lc++", "-L", buildPath.pathString, "-o", buildPath.appending(components: "exe").pathString, @@ -1640,7 +1640,7 @@ final class BuildPlanTests: XCTestCase { ]) #elseif os(Windows) XCTAssertEqual(try result.buildProduct(for: "exe").linkArguments(), [ - result.plan.destinationBuildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.defaultBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "exe.exe").pathString, "-module-name", "exe", @@ -1652,7 +1652,7 @@ final class BuildPlanTests: XCTestCase { ]) #else XCTAssertEqual(try result.buildProduct(for: "exe").linkArguments(), [ - result.plan.destinationBuildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.defaultBuildParameters.toolchain.swiftCompilerPath.pathString, "-lstdc++", "-L", buildPath.pathString, "-o", buildPath.appending(components: "exe").pathString, @@ -1782,7 +1782,7 @@ final class BuildPlanTests: XCTestCase { #if os(macOS) XCTAssertEqual(try result.buildProduct(for: "exe").linkArguments(), [ - result.plan.destinationBuildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.defaultBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "exe").pathString, "-module-name", "exe", @@ -1796,7 +1796,7 @@ final class BuildPlanTests: XCTestCase { ]) #elseif os(Windows) XCTAssertEqual(try result.buildProduct(for: "exe").linkArguments(), [ - result.plan.destinationBuildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.defaultBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "exe.exe").pathString, "-module-name", "exe", @@ -1807,7 +1807,7 @@ final class BuildPlanTests: XCTestCase { ]) #else XCTAssertEqual(try result.buildProduct(for: "exe").linkArguments(), [ - result.plan.destinationBuildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.defaultBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "exe").pathString, "-module-name", "exe", @@ -2029,7 +2029,7 @@ final class BuildPlanTests: XCTestCase { XCTAssertEqual( try result.buildProduct(for: "PkgPackageTests").linkArguments(), [ - result.plan.destinationBuildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.defaultBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "PkgPackageTests.xctest", "Contents", "MacOS", "PkgPackageTests") @@ -2049,7 +2049,7 @@ final class BuildPlanTests: XCTestCase { ) #elseif os(Windows) XCTAssertEqual(try result.buildProduct(for: "PkgPackageTests").linkArguments(), [ - result.plan.destinationBuildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.defaultBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "PkgPackageTests.xctest").pathString, "-module-name", "PkgPackageTests", @@ -2060,7 +2060,7 @@ final class BuildPlanTests: XCTestCase { ]) #else XCTAssertEqual(try result.buildProduct(for: "PkgPackageTests").linkArguments(), [ - result.plan.destinationBuildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.defaultBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "PkgPackageTests.xctest").pathString, "-module-name", "PkgPackageTests", @@ -2129,7 +2129,7 @@ final class BuildPlanTests: XCTestCase { #if os(macOS) XCTAssertEqual(try result.buildProduct(for: "exe").linkArguments(), [ - result.plan.destinationBuildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.defaultBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "exe").pathString, "-module-name", "exe", @@ -2493,7 +2493,7 @@ final class BuildPlanTests: XCTestCase { #if os(macOS) XCTAssertEqual(try result.buildProduct(for: "exe").linkArguments(), [ - result.plan.destinationBuildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.defaultBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "exe").pathString, "-module-name", "exe", @@ -2508,7 +2508,7 @@ final class BuildPlanTests: XCTestCase { ]) #elseif os(Windows) XCTAssertEqual(try result.buildProduct(for: "exe").linkArguments(), [ - result.plan.destinationBuildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.defaultBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "exe.exe").pathString, "-module-name", "exe", @@ -2519,7 +2519,7 @@ final class BuildPlanTests: XCTestCase { ]) #else XCTAssertEqual(try result.buildProduct(for: "exe").linkArguments(), [ - result.plan.destinationBuildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.defaultBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "exe").pathString, "-module-name", "exe", @@ -2639,7 +2639,7 @@ final class BuildPlanTests: XCTestCase { #if os(macOS) XCTAssertEqual(fooLinkArgs, [ - result.plan.destinationBuildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.defaultBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "Foo").pathString, "-module-name", "Foo", @@ -2655,7 +2655,7 @@ final class BuildPlanTests: XCTestCase { ]) XCTAssertEqual(barLinkArgs, [ - result.plan.destinationBuildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.defaultBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "libBar-Baz.dylib").pathString, "-module-name", "Bar_Baz", @@ -2671,7 +2671,7 @@ final class BuildPlanTests: XCTestCase { ]) #elseif os(Windows) XCTAssertEqual(fooLinkArgs, [ - result.plan.destinationBuildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.defaultBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "Foo.exe").pathString, "-module-name", "Foo", @@ -2683,7 +2683,7 @@ final class BuildPlanTests: XCTestCase { ]) XCTAssertEqual(barLinkArgs, [ - result.plan.destinationBuildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.defaultBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "Bar-Baz.dll").pathString, "-module-name", "Bar_Baz", @@ -2694,7 +2694,7 @@ final class BuildPlanTests: XCTestCase { ]) #else XCTAssertEqual(fooLinkArgs, [ - result.plan.destinationBuildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.defaultBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "Foo").pathString, "-module-name", "Foo", @@ -2707,7 +2707,7 @@ final class BuildPlanTests: XCTestCase { ]) XCTAssertEqual(barLinkArgs, [ - result.plan.destinationBuildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.defaultBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "libBar-Baz.so").pathString, "-module-name", "Bar_Baz", @@ -2807,7 +2807,7 @@ final class BuildPlanTests: XCTestCase { #if os(macOS) let linkArguments = [ - result.plan.destinationBuildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.defaultBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "liblib.dylib").pathString, "-module-name", "lib", @@ -2823,7 +2823,7 @@ final class BuildPlanTests: XCTestCase { ] #elseif os(Windows) let linkArguments = [ - result.plan.destinationBuildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.defaultBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "lib.dll").pathString, "-module-name", "lib", @@ -2835,7 +2835,7 @@ final class BuildPlanTests: XCTestCase { ] #else let linkArguments = [ - result.plan.destinationBuildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.defaultBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "liblib.so").pathString, "-module-name", "lib", @@ -2945,7 +2945,7 @@ final class BuildPlanTests: XCTestCase { #if os(macOS) XCTAssertEqual(try result.buildProduct(for: "lib").linkArguments(), [ - result.plan.destinationBuildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.defaultBuildParameters.toolchain.swiftCompilerPath.pathString, "-lc++", "-L", buildPath.pathString, "-o", buildPath.appending(components: "liblib.dylib").pathString, @@ -2960,7 +2960,7 @@ final class BuildPlanTests: XCTestCase { ]) XCTAssertEqual(try result.buildProduct(for: "exe").linkArguments(), [ - result.plan.destinationBuildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.defaultBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "exe").pathString, "-module-name", "exe", @@ -2973,7 +2973,7 @@ final class BuildPlanTests: XCTestCase { ]) #elseif os(Windows) XCTAssertEqual(try result.buildProduct(for: "lib").linkArguments(), [ - result.plan.destinationBuildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.defaultBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "lib.dll").pathString, "-module-name", "lib", @@ -2985,7 +2985,7 @@ final class BuildPlanTests: XCTestCase { ]) XCTAssertEqual(try result.buildProduct(for: "exe").linkArguments(), [ - result.plan.destinationBuildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.defaultBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "exe.exe").pathString, "-module-name", "exe", @@ -2997,7 +2997,7 @@ final class BuildPlanTests: XCTestCase { ]) #else XCTAssertEqual(try result.buildProduct(for: "lib").linkArguments(), [ - result.plan.destinationBuildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.defaultBuildParameters.toolchain.swiftCompilerPath.pathString, "-lstdc++", "-L", buildPath.pathString, "-o", buildPath.appending(components: "liblib.so").pathString, @@ -3011,7 +3011,7 @@ final class BuildPlanTests: XCTestCase { ]) XCTAssertEqual(try result.buildProduct(for: "exe").linkArguments(), [ - result.plan.destinationBuildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.defaultBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "exe").pathString, "-module-name", "exe", @@ -6171,7 +6171,7 @@ final class BuildPlanTests: XCTestCase { #if os(macOS) let linkArguments = [ - result.plan.destinationBuildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.defaultBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "exe").pathString, "-module-name", "exe", @@ -6187,7 +6187,7 @@ final class BuildPlanTests: XCTestCase { ] #elseif os(Windows) let linkArguments = [ - result.plan.destinationBuildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.defaultBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "exe.exe").pathString, "-module-name", "exe", @@ -6198,7 +6198,7 @@ final class BuildPlanTests: XCTestCase { ] #else let linkArguments = [ - result.plan.destinationBuildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.defaultBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "exe").pathString, "-module-name", "exe", From 76dd8c44e116416d188a3cdba74226c3a30c7fdf Mon Sep 17 00:00:00 2001 From: Max Desiatov Date: Fri, 16 Feb 2024 20:39:15 +0000 Subject: [PATCH 28/33] Update `CHANGELOG.md` --- CHANGELOG.md | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fe5ed046fe5..1111c786de1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ Note: This is in reverse chronological order, so newer entries are added to the top. -Swift Next +Swift 6.0 ----------- * [#7202] @@ -8,11 +8,22 @@ Swift Next Package manifests can now access information about the Git repository the given package is in via the context object's `gitInformation` property. This allows to determine the current tag (if any), the current commit and whether or not there are uncommited changes. +* [#7201] + + `// swift-tools-version:` no longer has to be specified on the first line of `Package.swift`. + +* [#7118] + + Macros cross-compiled by SwiftPM with Swift SDKs are now correctly built, loaded, and evaluated for the host triple. + +Swift 5.10 +----------- + * [#7010] On macOS, `swift build` and `swift run` now produce binaries that allow backtraces in debug builds. Pass `SWIFT_BACKTRACE=enable=yes` environment variable to enable backtraces on such binaries when running them. -* [7101] +* [#7101] Binary artifacts are now cached along side repository checkouts so they do not need to be re-downloaded across projects. @@ -387,4 +398,8 @@ Swift 3.0 [#6276]: https://github.com/apple/swift-package-manager/pull/6276 [#6540]: https://github.com/apple/swift-package-manager/pull/6540 [#6663]: https://github.com/apple/swift-package-manager/pull/6663 +[#7010]: https://github.com/apple/swift-package-manager/pull/7010 [#7101]: https://github.com/apple/swift-package-manager/pull/7101 +[#7118]: https://github.com/apple/swift-package-manager/pull/7118 +[#7201]: https://github.com/apple/swift-package-manager/pull/7201 +[#7202]: https://github.com/apple/swift-package-manager/pull/7202 From 788c7af6386bde242513caf291ab57d4f1618304 Mon Sep 17 00:00:00 2001 From: Max Desiatov Date: Fri, 16 Feb 2024 20:46:42 +0000 Subject: [PATCH 29/33] Fix tests for `destinationBuildParameters` property renaming --- Tests/BuildTests/BuildPlanTests.swift | 86 +++++++++++++-------------- 1 file changed, 43 insertions(+), 43 deletions(-) diff --git a/Tests/BuildTests/BuildPlanTests.swift b/Tests/BuildTests/BuildPlanTests.swift index 6e48e9a3dc0..5ea4e286dac 100644 --- a/Tests/BuildTests/BuildPlanTests.swift +++ b/Tests/BuildTests/BuildPlanTests.swift @@ -769,7 +769,7 @@ final class BuildPlanTests: XCTestCase { #if os(macOS) let linkArguments = [ - result.plan.defaultBuildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.destinationBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "exe").pathString, "-module-name", "exe", @@ -786,7 +786,7 @@ final class BuildPlanTests: XCTestCase { ] #elseif os(Windows) let linkArguments = [ - result.plan.defaultBuildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.destinationBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "exe.exe").pathString, "-module-name", "exe", @@ -798,7 +798,7 @@ final class BuildPlanTests: XCTestCase { ] #else let linkArguments = [ - result.plan.defaultBuildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.destinationBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "exe").pathString, "-module-name", "exe", @@ -1182,7 +1182,7 @@ final class BuildPlanTests: XCTestCase { #if os(macOS) XCTAssertEqual(try result.buildProduct(for: "exe").linkArguments(), [ - result.plan.defaultBuildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.destinationBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "exe").pathString, "-module-name", "exe", @@ -1196,7 +1196,7 @@ final class BuildPlanTests: XCTestCase { ]) #elseif os(Windows) XCTAssertEqual(try result.buildProduct(for: "exe").linkArguments(), [ - result.plan.defaultBuildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.destinationBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "exe.exe").pathString, "-module-name", "exe", @@ -1208,7 +1208,7 @@ final class BuildPlanTests: XCTestCase { ]) #else XCTAssertEqual(try result.buildProduct(for: "exe").linkArguments(), [ - result.plan.defaultBuildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.destinationBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "exe").pathString, "-module-name", "exe", @@ -1272,7 +1272,7 @@ final class BuildPlanTests: XCTestCase { #if os(macOS) XCTAssertEqual(try result.buildProduct(for: "exe").linkArguments(), [ - result.plan.defaultBuildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.destinationBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "exe").pathString, "-module-name", "exe", @@ -1285,7 +1285,7 @@ final class BuildPlanTests: XCTestCase { ]) #elseif os(Windows) XCTAssertEqual(try result.buildProduct(for: "exe").linkArguments(), [ - result.plan.defaultBuildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.destinationBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "exe.exe").pathString, "-module-name", "exe", @@ -1296,7 +1296,7 @@ final class BuildPlanTests: XCTestCase { ]) #else XCTAssertEqual(try result.buildProduct(for: "exe").linkArguments(), [ - result.plan.defaultBuildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.destinationBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "exe").pathString, "-module-name", "exe", @@ -1431,7 +1431,7 @@ final class BuildPlanTests: XCTestCase { #if os(macOS) XCTAssertEqual(try result.buildProduct(for: "exe").linkArguments(), [ - result.plan.defaultBuildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.destinationBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "exe").pathString, "-module-name", "exe", @@ -1444,7 +1444,7 @@ final class BuildPlanTests: XCTestCase { ]) #elseif os(Windows) XCTAssertEqual(try result.buildProduct(for: "exe").linkArguments(), [ - result.plan.defaultBuildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.destinationBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "exe.exe").pathString, "-module-name", "exe", @@ -1456,7 +1456,7 @@ final class BuildPlanTests: XCTestCase { ]) #else XCTAssertEqual(try result.buildProduct(for: "exe").linkArguments(), [ - result.plan.defaultBuildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.destinationBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "exe").pathString, "-module-name", "exe", @@ -1626,7 +1626,7 @@ final class BuildPlanTests: XCTestCase { #if os(macOS) XCTAssertEqual(try result.buildProduct(for: "exe").linkArguments(), [ - result.plan.defaultBuildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.destinationBuildParameters.toolchain.swiftCompilerPath.pathString, "-lc++", "-L", buildPath.pathString, "-o", buildPath.appending(components: "exe").pathString, @@ -1640,7 +1640,7 @@ final class BuildPlanTests: XCTestCase { ]) #elseif os(Windows) XCTAssertEqual(try result.buildProduct(for: "exe").linkArguments(), [ - result.plan.defaultBuildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.destinationBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "exe.exe").pathString, "-module-name", "exe", @@ -1652,7 +1652,7 @@ final class BuildPlanTests: XCTestCase { ]) #else XCTAssertEqual(try result.buildProduct(for: "exe").linkArguments(), [ - result.plan.defaultBuildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.destinationBuildParameters.toolchain.swiftCompilerPath.pathString, "-lstdc++", "-L", buildPath.pathString, "-o", buildPath.appending(components: "exe").pathString, @@ -1782,7 +1782,7 @@ final class BuildPlanTests: XCTestCase { #if os(macOS) XCTAssertEqual(try result.buildProduct(for: "exe").linkArguments(), [ - result.plan.defaultBuildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.destinationBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "exe").pathString, "-module-name", "exe", @@ -1796,7 +1796,7 @@ final class BuildPlanTests: XCTestCase { ]) #elseif os(Windows) XCTAssertEqual(try result.buildProduct(for: "exe").linkArguments(), [ - result.plan.defaultBuildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.destinationBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "exe.exe").pathString, "-module-name", "exe", @@ -1807,7 +1807,7 @@ final class BuildPlanTests: XCTestCase { ]) #else XCTAssertEqual(try result.buildProduct(for: "exe").linkArguments(), [ - result.plan.defaultBuildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.destinationBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "exe").pathString, "-module-name", "exe", @@ -2029,7 +2029,7 @@ final class BuildPlanTests: XCTestCase { XCTAssertEqual( try result.buildProduct(for: "PkgPackageTests").linkArguments(), [ - result.plan.defaultBuildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.destinationBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "PkgPackageTests.xctest", "Contents", "MacOS", "PkgPackageTests") @@ -2049,7 +2049,7 @@ final class BuildPlanTests: XCTestCase { ) #elseif os(Windows) XCTAssertEqual(try result.buildProduct(for: "PkgPackageTests").linkArguments(), [ - result.plan.defaultBuildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.destinationBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "PkgPackageTests.xctest").pathString, "-module-name", "PkgPackageTests", @@ -2060,7 +2060,7 @@ final class BuildPlanTests: XCTestCase { ]) #else XCTAssertEqual(try result.buildProduct(for: "PkgPackageTests").linkArguments(), [ - result.plan.defaultBuildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.destinationBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "PkgPackageTests.xctest").pathString, "-module-name", "PkgPackageTests", @@ -2129,7 +2129,7 @@ final class BuildPlanTests: XCTestCase { #if os(macOS) XCTAssertEqual(try result.buildProduct(for: "exe").linkArguments(), [ - result.plan.defaultBuildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.destinationBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "exe").pathString, "-module-name", "exe", @@ -2493,7 +2493,7 @@ final class BuildPlanTests: XCTestCase { #if os(macOS) XCTAssertEqual(try result.buildProduct(for: "exe").linkArguments(), [ - result.plan.defaultBuildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.destinationBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "exe").pathString, "-module-name", "exe", @@ -2508,7 +2508,7 @@ final class BuildPlanTests: XCTestCase { ]) #elseif os(Windows) XCTAssertEqual(try result.buildProduct(for: "exe").linkArguments(), [ - result.plan.defaultBuildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.destinationBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "exe.exe").pathString, "-module-name", "exe", @@ -2519,7 +2519,7 @@ final class BuildPlanTests: XCTestCase { ]) #else XCTAssertEqual(try result.buildProduct(for: "exe").linkArguments(), [ - result.plan.defaultBuildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.destinationBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "exe").pathString, "-module-name", "exe", @@ -2639,7 +2639,7 @@ final class BuildPlanTests: XCTestCase { #if os(macOS) XCTAssertEqual(fooLinkArgs, [ - result.plan.defaultBuildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.destinationBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "Foo").pathString, "-module-name", "Foo", @@ -2655,7 +2655,7 @@ final class BuildPlanTests: XCTestCase { ]) XCTAssertEqual(barLinkArgs, [ - result.plan.defaultBuildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.destinationBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "libBar-Baz.dylib").pathString, "-module-name", "Bar_Baz", @@ -2671,7 +2671,7 @@ final class BuildPlanTests: XCTestCase { ]) #elseif os(Windows) XCTAssertEqual(fooLinkArgs, [ - result.plan.defaultBuildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.destinationBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "Foo.exe").pathString, "-module-name", "Foo", @@ -2683,7 +2683,7 @@ final class BuildPlanTests: XCTestCase { ]) XCTAssertEqual(barLinkArgs, [ - result.plan.defaultBuildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.destinationBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "Bar-Baz.dll").pathString, "-module-name", "Bar_Baz", @@ -2694,7 +2694,7 @@ final class BuildPlanTests: XCTestCase { ]) #else XCTAssertEqual(fooLinkArgs, [ - result.plan.defaultBuildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.destinationBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "Foo").pathString, "-module-name", "Foo", @@ -2707,7 +2707,7 @@ final class BuildPlanTests: XCTestCase { ]) XCTAssertEqual(barLinkArgs, [ - result.plan.defaultBuildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.destinationBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "libBar-Baz.so").pathString, "-module-name", "Bar_Baz", @@ -2807,7 +2807,7 @@ final class BuildPlanTests: XCTestCase { #if os(macOS) let linkArguments = [ - result.plan.defaultBuildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.destinationBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "liblib.dylib").pathString, "-module-name", "lib", @@ -2823,7 +2823,7 @@ final class BuildPlanTests: XCTestCase { ] #elseif os(Windows) let linkArguments = [ - result.plan.defaultBuildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.destinationBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "lib.dll").pathString, "-module-name", "lib", @@ -2835,7 +2835,7 @@ final class BuildPlanTests: XCTestCase { ] #else let linkArguments = [ - result.plan.defaultBuildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.destinationBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "liblib.so").pathString, "-module-name", "lib", @@ -2945,7 +2945,7 @@ final class BuildPlanTests: XCTestCase { #if os(macOS) XCTAssertEqual(try result.buildProduct(for: "lib").linkArguments(), [ - result.plan.defaultBuildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.destinationBuildParameters.toolchain.swiftCompilerPath.pathString, "-lc++", "-L", buildPath.pathString, "-o", buildPath.appending(components: "liblib.dylib").pathString, @@ -2960,7 +2960,7 @@ final class BuildPlanTests: XCTestCase { ]) XCTAssertEqual(try result.buildProduct(for: "exe").linkArguments(), [ - result.plan.defaultBuildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.destinationBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "exe").pathString, "-module-name", "exe", @@ -2973,7 +2973,7 @@ final class BuildPlanTests: XCTestCase { ]) #elseif os(Windows) XCTAssertEqual(try result.buildProduct(for: "lib").linkArguments(), [ - result.plan.defaultBuildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.destinationBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "lib.dll").pathString, "-module-name", "lib", @@ -2985,7 +2985,7 @@ final class BuildPlanTests: XCTestCase { ]) XCTAssertEqual(try result.buildProduct(for: "exe").linkArguments(), [ - result.plan.defaultBuildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.destinationBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "exe.exe").pathString, "-module-name", "exe", @@ -2997,7 +2997,7 @@ final class BuildPlanTests: XCTestCase { ]) #else XCTAssertEqual(try result.buildProduct(for: "lib").linkArguments(), [ - result.plan.defaultBuildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.destinationBuildParameters.toolchain.swiftCompilerPath.pathString, "-lstdc++", "-L", buildPath.pathString, "-o", buildPath.appending(components: "liblib.so").pathString, @@ -3011,7 +3011,7 @@ final class BuildPlanTests: XCTestCase { ]) XCTAssertEqual(try result.buildProduct(for: "exe").linkArguments(), [ - result.plan.defaultBuildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.destinationBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "exe").pathString, "-module-name", "exe", @@ -6171,7 +6171,7 @@ final class BuildPlanTests: XCTestCase { #if os(macOS) let linkArguments = [ - result.plan.defaultBuildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.destinationBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "exe").pathString, "-module-name", "exe", @@ -6187,7 +6187,7 @@ final class BuildPlanTests: XCTestCase { ] #elseif os(Windows) let linkArguments = [ - result.plan.defaultBuildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.destinationBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "exe.exe").pathString, "-module-name", "exe", @@ -6198,7 +6198,7 @@ final class BuildPlanTests: XCTestCase { ] #else let linkArguments = [ - result.plan.defaultBuildParameters.toolchain.swiftCompilerPath.pathString, + result.plan.destinationBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, "-o", buildPath.appending(components: "exe").pathString, "-module-name", "exe", From e858a4cedc7e6076bdc56269b63f65670a2f5709 Mon Sep 17 00:00:00 2001 From: Max Desiatov Date: Fri, 16 Feb 2024 21:07:25 +0000 Subject: [PATCH 30/33] Fix `destinationBuildParameters` renaming --- Sources/Commands/Utilities/TestingSupport.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/Commands/Utilities/TestingSupport.swift b/Sources/Commands/Utilities/TestingSupport.swift index 751c85d7689..7556a3e0c56 100644 --- a/Sources/Commands/Utilities/TestingSupport.swift +++ b/Sources/Commands/Utilities/TestingSupport.swift @@ -134,7 +134,7 @@ enum TestingSupport { #else let env = try Self.constructTestEnvironment( toolchain: try swiftTool.getTargetToolchain(), - defaultBuildParameters: swiftTool.buildParametersForTest( + destinationBuildParameters: swiftTool.buildParametersForTest( enableCodeCoverage: enableCodeCoverage, shouldSkipBuilding: shouldSkipBuilding, library: .xctest From 889acfdc7d58d9d0f2e455f944bb07d38bdbd71a Mon Sep 17 00:00:00 2001 From: Max Desiatov Date: Sun, 18 Feb 2024 16:46:21 +0000 Subject: [PATCH 31/33] Fix build directory path in `BuildOperationTests` --- Sources/Build/BuildOperation.swift | 6 ++++-- Tests/BuildTests/BuildOperationTests.swift | 8 +++++--- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/Sources/Build/BuildOperation.swift b/Sources/Build/BuildOperation.swift index ebc414d5cb2..d661ea9fdd5 100644 --- a/Sources/Build/BuildOperation.swift +++ b/Sources/Build/BuildOperation.swift @@ -272,7 +272,7 @@ public final class BuildOperation: PackageStructureDelegate, SPMBuildCore.BuildS } // TODO: Currently this function will only match frameworks. - internal func detectUnexpressedDependencies( + func detectUnexpressedDependencies( availableLibraries: [LibraryMetadata], targetDependencyMap: [String: [String]]? ) { @@ -298,7 +298,9 @@ public final class BuildOperation: PackageStructureDelegate, SPMBuildCore.BuildS } let usedSDKDependencies: [String] = Set(possibleTempsPaths).flatMap { possibleTempsPath in - guard let contents = try? self.fileSystem.readFileContents(possibleTempsPath.appending(component: "\(c99name).d")) else { + guard let contents = try? self.fileSystem.readFileContents( + possibleTempsPath.appending(component: "\(c99name).d") + ) else { return [String]() } diff --git a/Tests/BuildTests/BuildOperationTests.swift b/Tests/BuildTests/BuildOperationTests.swift index 3f196dd41fa..6a703ded853 100644 --- a/Tests/BuildTests/BuildOperationTests.swift +++ b/Tests/BuildTests/BuildOperationTests.swift @@ -22,14 +22,16 @@ import class TSCBasic.InMemoryFileSystem final class BuildOperationTests: XCTestCase { func testDetectUnexpressedDependencies() throws { + let buildParameters = mockBuildParameters(shouldDisableLocalRpath: false) + let fs = InMemoryFileSystem(files: [ - "/path/to/build/debug/Lunch.build/Lunch.d" : "/Best.framework" + "\(buildParameters.dataPath)/debug/Lunch.build/Lunch.d" : "/Best.framework" ]) let observability = ObservabilitySystem.makeForTesting() let buildOp = BuildOperation( - productsBuildParameters: mockBuildParameters(shouldDisableLocalRpath: false), - toolsBuildParameters: mockBuildParameters(shouldDisableLocalRpath: false), + productsBuildParameters: buildParameters, + toolsBuildParameters: buildParameters, cacheBuildManifest: false, packageGraphLoader: { fatalError() }, additionalFileRules: [], From cfc1b6575866824fb8e0608263b53dbd26247c7c Mon Sep 17 00:00:00 2001 From: Max Desiatov Date: Sun, 18 Feb 2024 16:52:17 +0000 Subject: [PATCH 32/33] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1111c786de1..bc97daa61f3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,7 @@ Swift 6.0 * [#7201] - `// swift-tools-version:` no longer has to be specified on the first line of `Package.swift`. + `// swift-tools-version:` can now be specified on subsequent lines of `Package.swift`, for example when first few lines are required to contain a copyright comment header. * [#7118] From 10d1aea84897366b04404f9058d6958e5ef96795 Mon Sep 17 00:00:00 2001 From: Max Desiatov Date: Sun, 18 Feb 2024 16:53:45 +0000 Subject: [PATCH 33/33] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bc97daa61f3..61f95911802 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,7 @@ Swift 6.0 * [#7201] - `// swift-tools-version:` can now be specified on subsequent lines of `Package.swift`, for example when first few lines are required to contain a copyright comment header. + `// swift-tools-version:` can now be specified on subsequent lines of `Package.swift`, for example when first few lines are required to contain a licensing comment header. * [#7118]