diff --git a/Sources/SWBApplePlatform/AssetCatalogCompiler.swift b/Sources/SWBApplePlatform/AssetCatalogCompiler.swift index ac390469..7f9db7cb 100644 --- a/Sources/SWBApplePlatform/AssetCatalogCompiler.swift +++ b/Sources/SWBApplePlatform/AssetCatalogCompiler.swift @@ -55,7 +55,7 @@ public final class ActoolCompilerSpec : GenericCompilerSpec, SpecIdentifierType, } private func assetTagCombinations(catalogInputs inputs: [FileToBuild], _ cbc: CommandBuildContext, _ delegate: any TaskGenerationDelegate) async throws -> Set> { - return try await executeExternalTool(cbc, delegate, commandLine: [resolveExecutablePath(cbc, cbc.scope.actoolExecutablePath()).str, "--print-asset-tag-combinations", "--output-format", "xml1"] + inputs.map { $0.absolutePath.str }, workingDirectory: cbc.producer.defaultWorkingDirectory, environment: environmentFromSpec(cbc, delegate).bindingsDictionary, executionDescription: "Compute asset tag combinations") { output in + return try await executeExternalTool(cbc, delegate, commandLine: [resolveExecutablePath(cbc, cbc.scope.actoolExecutablePath(), delegate: delegate).str, "--print-asset-tag-combinations", "--output-format", "xml1"] + inputs.map { $0.absolutePath.str }, workingDirectory: cbc.producer.defaultWorkingDirectory, environment: environmentFromSpec(cbc, delegate).bindingsDictionary, executionDescription: "Compute asset tag combinations") { output in struct AssetCatalogToolOutput: Decodable { struct Diagnostic: Decodable { let description: String diff --git a/Sources/SWBApplePlatform/InterfaceBuilderCompiler.swift b/Sources/SWBApplePlatform/InterfaceBuilderCompiler.swift index c2d99b00..d9b86d09 100644 --- a/Sources/SWBApplePlatform/InterfaceBuilderCompiler.swift +++ b/Sources/SWBApplePlatform/InterfaceBuilderCompiler.swift @@ -171,8 +171,8 @@ public final class IbtoolCompilerSpecStoryboard: IbtoolCompilerSpec, SpecIdentif } } - override public func commandLineFromTemplate(_ cbc: CommandBuildContext, _ delegate: any TaskGenerationDelegate, optionContext: (any DiscoveredCommandLineToolSpecInfo)?, specialArgs: [String] = [], lookup: ((MacroDeclaration) -> MacroExpression?)? = nil) -> [CommandLineArgument] { - var commandLine = super.commandLineFromTemplate(cbc, delegate, optionContext: optionContext, specialArgs: specialArgs, lookup: lookup) + override public func commandLineFromTemplate(_ cbc: CommandBuildContext, _ delegate: any TaskGenerationDelegate, optionContext: (any DiscoveredCommandLineToolSpecInfo)?, specialArgs: [String] = [], lookup: ((MacroDeclaration) -> MacroExpression?)? = nil) async -> [CommandLineArgument] { + var commandLine = await super.commandLineFromTemplate(cbc, delegate, optionContext: optionContext, specialArgs: specialArgs, lookup: lookup) guard let primaryOutput = evaluatedOutputs(cbc, delegate)?.first else { delegate.error("Unable to determine primary output for storyboard compilation") return [] diff --git a/Sources/SWBApplePlatform/MiGCompiler.swift b/Sources/SWBApplePlatform/MiGCompiler.swift index 1f9c9ceb..7d36416d 100644 --- a/Sources/SWBApplePlatform/MiGCompiler.swift +++ b/Sources/SWBApplePlatform/MiGCompiler.swift @@ -38,7 +38,7 @@ public final class MigCompilerSpec : CompilerSpec, SpecIdentifierType, @unchecke return cbc.scope.migExecutablePath().str } - public override func resolveExecutablePath(_ cbc: CommandBuildContext, _ path: Path) -> Path { + public override func resolveExecutablePath(_ cbc: CommandBuildContext, _ path: Path, delegate: any CoreClientTargetDiagnosticProducingDelegate) async -> Path { return resolveExecutablePath(cbc.producer, Path(computeExecutablePath(cbc))) } diff --git a/Sources/SWBApplePlatform/OpenCLCompiler.swift b/Sources/SWBApplePlatform/OpenCLCompiler.swift index 6b81c761..00e3913b 100644 --- a/Sources/SWBApplePlatform/OpenCLCompiler.swift +++ b/Sources/SWBApplePlatform/OpenCLCompiler.swift @@ -69,7 +69,7 @@ final class OpenCLCompilerSpec : CompilerSpec, SpecIdentifierType, GCCCompatible let executionDescription = "Create \(arch) bitcode for \(filePath.basename)" - var commandLine = [resolveExecutablePath(cbc, Path(openclc)).str] + var commandLine = [await resolveExecutablePath(cbc, Path(openclc), delegate: delegate).str] commandLine += ["-x", "cl", compilerVersionFlag] optimizationLevelFlag.map{ commandLine.append($0) } commandLine += preprocessorDefinitionsFlags @@ -101,7 +101,7 @@ final class OpenCLCompilerSpec : CompilerSpec, SpecIdentifierType, GCCCompatible let ruleInfo = ["Compile", filePath.str] - var commandLine = [resolveExecutablePath(cbc, Path(openclc)).str] + var commandLine = [await resolveExecutablePath(cbc, Path(openclc), delegate: delegate).str] commandLine += ["-x", "cl", compilerVersionFlag] if scope.evaluate(BuiltinMacros.OPENCL_MAD_ENABLE) { commandLine.append("-cl-mad-enable") diff --git a/Sources/SWBApplePlatform/ResMergerLinkerSpec.swift b/Sources/SWBApplePlatform/ResMergerLinkerSpec.swift index 1380e2cd..931bc66c 100644 --- a/Sources/SWBApplePlatform/ResMergerLinkerSpec.swift +++ b/Sources/SWBApplePlatform/ResMergerLinkerSpec.swift @@ -24,7 +24,7 @@ public final class ResMergerLinkerSpec : GenericLinkerSpec, SpecIdentifierType, let environment: EnvironmentBindings = environmentFromSpec(cbc, delegate) do { - var commandLine = [resolveExecutablePath(cbc, Path("ResMerger")).str] + var commandLine = [await resolveExecutablePath(cbc, Path("ResMerger"), delegate: delegate).str] commandLine += BuiltinMacros.ifSet(BuiltinMacros.MACOS_TYPE, in: cbc.scope) { ["-fileType", $0] } commandLine += BuiltinMacros.ifSet(BuiltinMacros.MACOS_CREATOR, in: cbc.scope) { ["-fileCreator", $0] } @@ -64,7 +64,7 @@ public final class ResMergerLinkerSpec : GenericLinkerSpec, SpecIdentifierType, outputPath = outputPath.join(cbc.scope.evaluate(BuiltinMacros.PRODUCT_NAME) + ".rsrc") } - var commandLine = [resolveExecutablePath(cbc, Path("ResMerger")).str] + var commandLine = [await resolveExecutablePath(cbc, Path("ResMerger"), delegate: delegate).str] commandLine.append(tmpOutputPath.str) commandLine += BuiltinMacros.ifSet(BuiltinMacros.MACOS_TYPE, in: cbc.scope) { ["-fileType", $0] } diff --git a/Sources/SWBApplePlatform/XCStringsCompiler.swift b/Sources/SWBApplePlatform/XCStringsCompiler.swift index 0b527947..fd7b0d3d 100644 --- a/Sources/SWBApplePlatform/XCStringsCompiler.swift +++ b/Sources/SWBApplePlatform/XCStringsCompiler.swift @@ -49,7 +49,7 @@ public final class XCStringsCompilerSpec: GenericCompilerSpec, SpecIdentifierTyp } if shouldGenerateSymbols(cbc) { - constructSymbolGenerationTask(cbc, delegate) + await constructSymbolGenerationTask(cbc, delegate) } if shouldCompileCatalog(cbc) { @@ -138,10 +138,10 @@ public final class XCStringsCompilerSpec: GenericCompilerSpec, SpecIdentifierTyp } /// Generates a task for generating code symbols for strings. - private func constructSymbolGenerationTask(_ cbc: CommandBuildContext, _ delegate: any TaskGenerationDelegate) { + private func constructSymbolGenerationTask(_ cbc: CommandBuildContext, _ delegate: any TaskGenerationDelegate) async { // The template spec file contains fields suitable for the compilation step. // But here we construct a custom command line for symbol generation. - let execPath = resolveExecutablePath(cbc, Path("xcstringstool")) + let execPath = await resolveExecutablePath(cbc, Path("xcstringstool"), delegate: delegate) var commandLine = [execPath.str, "generate-symbols"] // For now shouldGenerateSymbols only returns true if there are Swift sources. diff --git a/Sources/SWBCore/PlannedTaskAction.swift b/Sources/SWBCore/PlannedTaskAction.swift index cd9d0de4..999660e5 100644 --- a/Sources/SWBCore/PlannedTaskAction.swift +++ b/Sources/SWBCore/PlannedTaskAction.swift @@ -264,8 +264,8 @@ public struct FileCopyTaskActionContext { extension FileCopyTaskActionContext { public init(_ cbc: CommandBuildContext) { let compilerPath = cbc.producer.clangSpec.resolveExecutablePath(cbc, forLanguageOfFileType: cbc.producer.lookupFileType(languageDialect: .c)) - let linkerPath = cbc.producer.ldLinkerSpec.resolveExecutablePath(cbc, Path(cbc.producer.ldLinkerSpec.computeExecutablePath(cbc))) - let lipoPath = cbc.producer.lipoSpec.resolveExecutablePath(cbc, Path(cbc.producer.lipoSpec.computeExecutablePath(cbc))) + let linkerPath = cbc.producer.ldLinkerSpec.resolveExecutablePath(cbc.producer, Path(cbc.producer.ldLinkerSpec.computeExecutablePath(cbc))) + let lipoPath = cbc.producer.lipoSpec.resolveExecutablePath(cbc.producer, Path(cbc.producer.lipoSpec.computeExecutablePath(cbc))) // If we couldn't find clang, skip the special stub binary handling. We may be using an Open Source toolchain which only has Swift. Also skip it for installLoc builds. if compilerPath.isEmpty || !compilerPath.isAbsolute || cbc.scope.evaluate(BuiltinMacros.BUILD_COMPONENTS).contains("installLoc") { diff --git a/Sources/SWBCore/SpecImplementations/CommandLineToolSpec.swift b/Sources/SWBCore/SpecImplementations/CommandLineToolSpec.swift index f9798b10..b02c0c80 100644 --- a/Sources/SWBCore/SpecImplementations/CommandLineToolSpec.swift +++ b/Sources/SWBCore/SpecImplementations/CommandLineToolSpec.swift @@ -876,7 +876,13 @@ open class CommandLineToolSpec : PropertyDomainSpec, SpecType, TaskTypeDescripti let optionContext = await discoveredCommandLineToolSpecInfo(cbc.producer, cbc.scope, delegate) // Compute the command line arguments from the template. - let commandLine = commandLine ?? commandLineFromTemplate(cbc, delegate, optionContext: optionContext, specialArgs: specialArgs, lookup: lookup).map(\.asString) + let providedCommandLine = commandLine + let commandLine: [String] + if let providedCommandLine { + commandLine = providedCommandLine + } else { + commandLine = await commandLineFromTemplate(cbc, delegate, optionContext: optionContext, specialArgs: specialArgs, lookup: lookup).map(\.asString) + } // Compute the environment variables to set. var environment: [(String, String)] = environmentFromSpec(cbc, delegate, lookup: lookup) @@ -1152,7 +1158,7 @@ open class CommandLineToolSpec : PropertyDomainSpec, SpecType, TaskTypeDescripti } /// Resolve an executable path or name to an absolute path. - open func resolveExecutablePath(_ cbc: CommandBuildContext, _ path: Path) -> Path { + open func resolveExecutablePath(_ cbc: CommandBuildContext, _ path: Path, delegate: any CoreClientTargetDiagnosticProducingDelegate) async -> Path { return resolveExecutablePath(cbc.producer, path) } @@ -1185,14 +1191,14 @@ open class CommandLineToolSpec : PropertyDomainSpec, SpecType, TaskTypeDescripti return executionDescription } - open func commandLineFromTemplate(_ cbc: CommandBuildContext, _ delegate: any TaskGenerationDelegate, optionContext: (any DiscoveredCommandLineToolSpecInfo)?, specialArgs: [String] = [], lookup: ((MacroDeclaration) -> MacroExpression?)? = nil) -> [CommandLineArgument] { - return commandLineArgumentsFromTemplate(cbc, delegate, optionContext: optionContext, specialArgs: specialArgs, lookup: lookup) + open func commandLineFromTemplate(_ cbc: CommandBuildContext, _ delegate: any TaskGenerationDelegate, optionContext: (any DiscoveredCommandLineToolSpecInfo)?, specialArgs: [String] = [], lookup: ((MacroDeclaration) -> MacroExpression?)? = nil) async -> [CommandLineArgument] { + return await commandLineArgumentsFromTemplate(cbc, delegate, optionContext: optionContext, specialArgs: specialArgs, lookup: lookup) } /// Creates and returns the command line from the template provided by the specification. /// - parameter specialArgs: Used to replace the `special-args` placeholder in the command line template. /// - parameter lookup: An optional closure which functionally defined overriding values during build setting evaluation. - public func commandLineArgumentsFromTemplate(_ cbc: CommandBuildContext, _ delegate: any TaskGenerationDelegate, optionContext: (any DiscoveredCommandLineToolSpecInfo)?, specialArgs: [String] = [], lookup: ((MacroDeclaration) -> MacroExpression?)? = nil) -> [CommandLineArgument] { + public func commandLineArgumentsFromTemplate(_ cbc: CommandBuildContext, _ delegate: any TaskGenerationDelegate, optionContext: (any DiscoveredCommandLineToolSpecInfo)?, specialArgs: [String] = [], lookup: ((MacroDeclaration) -> MacroExpression?)? = nil) async -> [CommandLineArgument] { let commandLineTemplate = self.commandLineTemplate! let lookup = { self.lookup($0, cbc, delegate, lookup) } @@ -1239,13 +1245,13 @@ open class CommandLineToolSpec : PropertyDomainSpec, SpecType, TaskTypeDescripti // Resolve the executable path. // // FIXME: It would be nice to just move this to a specific handler for this first item in the template array (we could generalize the existing ExecPath key for this purpose). - args[0] = { path in + args[0] = await { path in if path.asString.hasPrefix("builtin-") || (path.asString.hasPrefix("<") && path.asString.hasSuffix(">")) { return path } // Otherwise, look up the path if necessary. - return .path(resolveExecutablePath(cbc, Path(path.asString))) + return .path(await resolveExecutablePath(cbc, Path(path.asString), delegate: delegate)) }(args[0]) return args diff --git a/Sources/SWBCore/SpecImplementations/Tools/CCompiler.swift b/Sources/SWBCore/SpecImplementations/Tools/CCompiler.swift index 152c391d..dcf46d85 100644 --- a/Sources/SWBCore/SpecImplementations/Tools/CCompiler.swift +++ b/Sources/SWBCore/SpecImplementations/Tools/CCompiler.swift @@ -1056,7 +1056,7 @@ public class ClangCompilerSpec : CompilerSpec, SpecIdentifierType, GCCCompatible // Start with the executable. let compilerExecPath = resolveExecutablePath(cbc, forLanguageOfFileType: resolvedInputFileType) - let launcher = resolveCompilerLauncher(cbc, compilerPath: compilerExecPath, delegate: delegate) + let launcher = await resolveCompilerLauncher(cbc, compilerPath: compilerExecPath, delegate: delegate) if let launcher { commandLine += [launcher.str] } @@ -1114,7 +1114,7 @@ public class ClangCompilerSpec : CompilerSpec, SpecIdentifierType, GCCCompatible } // Add the prefix header arguments, if used. - let prefixInfo = addPrefixHeaderArgs(cbc, delegate, inputFileType: resolvedInputFileType, perFileFlags: perFileFlags, inputDeps: &inputDeps, commandLine: &commandLine, clangInfo: clangInfo) + let prefixInfo = await addPrefixHeaderArgs(cbc, delegate, inputFileType: resolvedInputFileType, perFileFlags: perFileFlags, inputDeps: &inputDeps, commandLine: &commandLine, clangInfo: clangInfo) // Add dependencies on the SDK used. @@ -1426,7 +1426,7 @@ public class ClangCompilerSpec : CompilerSpec, SpecIdentifierType, GCCCompatible } /// Adds the arguments to use the prefix header, in the appropriate manner for the target. - private func addPrefixHeaderArgs(_ cbc: CommandBuildContext, _ delegate: any TaskGenerationDelegate, inputFileType: FileTypeSpec, perFileFlags: [String], inputDeps: inout [Path], commandLine: inout [String], clangInfo: DiscoveredClangToolSpecInfo?) -> ClangPrefixInfo? { + private func addPrefixHeaderArgs(_ cbc: CommandBuildContext, _ delegate: any TaskGenerationDelegate, inputFileType: FileTypeSpec, perFileFlags: [String], inputDeps: inout [Path], commandLine: inout [String], clangInfo: DiscoveredClangToolSpecInfo?) async -> ClangPrefixInfo? { // Don't use the prefix header if the input file opted out. guard cbc.inputs[0].shouldUsePrefixHeader else { return nil @@ -1824,11 +1824,11 @@ public class ClangCompilerSpec : CompilerSpec, SpecIdentifierType, GCCCompatible private func resolveCompilerLauncher(_ cbc: CommandBuildContext, compilerPath: Path, delegate: any TaskGenerationDelegate) -> Path? { let value = cbc.scope.evaluate(BuiltinMacros.C_COMPILER_LAUNCHER) if !value.isEmpty { - return resolveExecutablePath(cbc, Path(value)) + return resolveExecutablePath(cbc.producer, Path(value)) } if cbc.scope.evaluate(BuiltinMacros.CLANG_CACHE_ENABLE_LAUNCHER) { let name = Path("clang-cache") - let resolved = resolveExecutablePath(cbc, name) + let resolved = resolveExecutablePath(cbc.producer, name) // Only set it as launcher if it has been found and is next to the compiler. if resolved != name && resolved.dirname == compilerPath.dirname { return resolved diff --git a/Sources/SWBCore/SpecImplementations/Tools/CodeSign.swift b/Sources/SWBCore/SpecImplementations/Tools/CodeSign.swift index d8d7ead2..373b3e93 100644 --- a/Sources/SWBCore/SpecImplementations/Tools/CodeSign.swift +++ b/Sources/SWBCore/SpecImplementations/Tools/CodeSign.swift @@ -23,7 +23,7 @@ public final class CodesignToolSpec : CommandLineToolSpec, SpecIdentifierType, @ codesign = Path("/usr/bin/codesign") } if !codesign.isAbsolute { - codesign = resolveExecutablePath(cbc, codesign) + codesign = resolveExecutablePath(cbc.producer, codesign) } return codesign.str } diff --git a/Sources/SWBCore/SpecImplementations/Tools/CopyTool.swift b/Sources/SWBCore/SpecImplementations/Tools/CopyTool.swift index 9df6d6d5..e7053e61 100644 --- a/Sources/SWBCore/SpecImplementations/Tools/CopyTool.swift +++ b/Sources/SWBCore/SpecImplementations/Tools/CopyTool.swift @@ -129,7 +129,7 @@ public final class CopyToolSpec : CompilerSpec, SpecIdentifierType, @unchecked S // FIXME: The same comment above (w.r.t. how to bind this logic) applies here. if cbc.scope.evaluate(BuiltinMacros.PBXCP_STRIP_UNSIGNED_BINARIES, lookup: lookup) || !cbc.scope.evaluate(BuiltinMacros.PBXCP_STRIP_SUBPATHS, lookup: lookup).isEmpty { let insertIndex = commandLine.firstIndex(of: "-resolve-src-symlinks") ?? commandLine.endIndex - commandLine.replaceSubrange(insertIndex.. Path { - return resolveExecutablePath(cbc, Path(computeExecutablePath(cbc))) + return resolveExecutablePath(cbc.producer, Path(computeExecutablePath(cbc))) } public override func constructTasks(_ cbc: CommandBuildContext, _ delegate: any TaskGenerationDelegate) async { diff --git a/Sources/SWBCore/SpecImplementations/Tools/ModulesVerifierTool.swift b/Sources/SWBCore/SpecImplementations/Tools/ModulesVerifierTool.swift index bef83d2b..a584628e 100644 --- a/Sources/SWBCore/SpecImplementations/Tools/ModulesVerifierTool.swift +++ b/Sources/SWBCore/SpecImplementations/Tools/ModulesVerifierTool.swift @@ -24,7 +24,7 @@ public final class ModulesVerifierToolSpec : GenericCommandLineToolSpec, SpecIde let ruleInfo = defaultRuleInfo(cbc, delegate) let clangSpec = try! cbc.producer.getSpec() as ClangCompilerSpec - let clangPath = clangSpec.resolveExecutablePath(cbc, Path("clang")) + let clangPath = await clangSpec.resolveExecutablePath(cbc, Path("clang"), delegate: delegate) let specialArguments = ["--clang", clangPath.str, "--diagnostic-filename-map", fileNameMapPath.str] let commandLine = await commandLineFromTemplate(cbc, delegate, optionContext: discoveredCommandLineToolSpecInfo(cbc.producer, cbc.scope, delegate), specialArgs: specialArguments).map(\.asString) diff --git a/Sources/SWBCore/SpecImplementations/Tools/SwiftABICheckerTool.swift b/Sources/SWBCore/SpecImplementations/Tools/SwiftABICheckerTool.swift index d3eca2b1..b33ca677 100644 --- a/Sources/SWBCore/SpecImplementations/Tools/SwiftABICheckerTool.swift +++ b/Sources/SWBCore/SpecImplementations/Tools/SwiftABICheckerTool.swift @@ -25,6 +25,15 @@ public final class SwiftABICheckerToolSpec : GenericCommandLineToolSpec, SpecIde } } + override public func resolveExecutablePath(_ cbc: CommandBuildContext, _ path: Path, delegate: any CoreClientTargetDiagnosticProducingDelegate) async -> Path { + let swiftInfo = await cbc.producer.swiftCompilerSpec.discoveredCommandLineToolSpecInfo(cbc.producer, cbc.scope, delegate) + if let prospectivePath = swiftInfo?.toolPath.dirname.join(path), cbc.producer.executableSearchPaths.fs.exists(prospectivePath) { + return prospectivePath + } + + return await super.resolveExecutablePath(cbc, path, delegate: delegate) + } + override public func constructTasks(_ cbc: CommandBuildContext, _ delegate: any TaskGenerationDelegate) async { // FIXME: We should ensure this cannot happen. fatalError("unexpected direct invocation") diff --git a/Sources/SWBCore/SpecImplementations/Tools/SwiftABIGenerationTool.swift b/Sources/SWBCore/SpecImplementations/Tools/SwiftABIGenerationTool.swift index b407fe1b..4ad27dee 100644 --- a/Sources/SWBCore/SpecImplementations/Tools/SwiftABIGenerationTool.swift +++ b/Sources/SWBCore/SpecImplementations/Tools/SwiftABIGenerationTool.swift @@ -25,6 +25,15 @@ public final class SwiftABIGenerationToolSpec : GenericCommandLineToolSpec, Spec } } + override public func resolveExecutablePath(_ cbc: CommandBuildContext, _ path: Path, delegate: any CoreClientTargetDiagnosticProducingDelegate) async -> Path { + let swiftInfo = await cbc.producer.swiftCompilerSpec.discoveredCommandLineToolSpecInfo(cbc.producer, cbc.scope, delegate) + if let prospectivePath = swiftInfo?.toolPath.dirname.join(path), cbc.producer.executableSearchPaths.fs.exists(prospectivePath) { + return prospectivePath + } + + return await super.resolveExecutablePath(cbc, path, delegate: delegate) + } + override public func constructTasks(_ cbc: CommandBuildContext, _ delegate: any TaskGenerationDelegate) async { // FIXME: We should ensure this cannot happen. fatalError("unexpected direct invocation") diff --git a/Sources/SWBCore/SpecImplementations/Tools/SwiftCompiler.swift b/Sources/SWBCore/SpecImplementations/Tools/SwiftCompiler.swift index 3bed7c80..133a215b 100644 --- a/Sources/SWBCore/SpecImplementations/Tools/SwiftCompiler.swift +++ b/Sources/SWBCore/SpecImplementations/Tools/SwiftCompiler.swift @@ -2391,7 +2391,7 @@ public final class SwiftCompilerSpec : CompilerSpec, SpecIdentifierType, SwiftDi if cbc.scope.evaluate(BuiltinMacros.PLATFORM_REQUIRES_SWIFT_AUTOLINK_EXTRACT) { let toolName = cbc.producer.hostOperatingSystem.imageFormat.executableName(basename: "swift-autolink-extract") - let toolPath = resolveExecutablePath(cbc, toolSpecInfo.toolPath.dirname.join(toolName)) + let toolPath = await resolveExecutablePath(cbc, toolSpecInfo.toolPath.dirname.join(toolName), delegate: delegate) delegate.createTask( type: self, diff --git a/Sources/SWBCore/SpecImplementations/Tools/TAPITools.swift b/Sources/SWBCore/SpecImplementations/Tools/TAPITools.swift index 818147fb..fa384143 100644 --- a/Sources/SWBCore/SpecImplementations/Tools/TAPITools.swift +++ b/Sources/SWBCore/SpecImplementations/Tools/TAPITools.swift @@ -33,7 +33,7 @@ public final class TAPIToolSpec : GenericCommandLineToolSpec, GCCCompatibleCompi return cbc.scope.tapiExecutablePath() } - public override func resolveExecutablePath(_ cbc: CommandBuildContext, _ path: Path) -> Path { + public override func resolveExecutablePath(_ cbc: CommandBuildContext, _ path: Path, delegate: any CoreClientTargetDiagnosticProducingDelegate) async -> Path { // Ignore "tapi" from the spec and go through TAPI_EXEC // FIXME: We should go through the normal spec mechanisms... return resolveExecutablePath(cbc.producer, Path(computeExecutablePath(cbc))) @@ -104,7 +104,7 @@ public final class TAPIToolSpec : GenericCommandLineToolSpec, GCCCompatibleCompi let toolInfo = await discoveredCommandLineToolSpecInfo(cbc.producer, scope, delegate) // Compute the command line. - var commandLine: [String] = commandLineFromTemplate(cbc, delegate, optionContext: toolInfo, lookup: lookup).map(\.asString) + var commandLine: [String] = await commandLineFromTemplate(cbc, delegate, optionContext: toolInfo, lookup: lookup).map(\.asString) // Compute inputs. var inputs = cbc.inputs.map({ delegate.createNode($0.absolutePath) }) as [PlannedPathNode] diff --git a/Sources/SWBCore/SpecImplementations/Tools/UnifdefTool.swift b/Sources/SWBCore/SpecImplementations/Tools/UnifdefTool.swift index 08091d21..99b2517b 100644 --- a/Sources/SWBCore/SpecImplementations/Tools/UnifdefTool.swift +++ b/Sources/SWBCore/SpecImplementations/Tools/UnifdefTool.swift @@ -35,7 +35,7 @@ public final class UnifdefToolSpec : CommandLineToolSpec, SpecIdentifierType, @u // Set the exit status mode to 2, which is "exit status is 0 on success". (The default is 0 if nothing // changed and 1 if something changed.) - var args = [resolveExecutablePath(cbc, Path("unifdef")).str, "-x", "2"] + var args = [resolveExecutablePath(cbc.producer, Path("unifdef")).str, "-x", "2"] args += extraFlags if cbc.scope.evaluate(BuiltinMacros.IS_UNOPTIMIZED_BUILD) && !extraFlags.contains("-B") { // Add empty lines for any removed lines so that the source locations still match and thus we can go to diff --git a/Sources/SWBCore/SpecImplementations/Tools/ValidateEmbeddedBinaryTool.swift b/Sources/SWBCore/SpecImplementations/Tools/ValidateEmbeddedBinaryTool.swift index 886484e3..cfbdb57a 100644 --- a/Sources/SWBCore/SpecImplementations/Tools/ValidateEmbeddedBinaryTool.swift +++ b/Sources/SWBCore/SpecImplementations/Tools/ValidateEmbeddedBinaryTool.swift @@ -21,7 +21,7 @@ public final class ValidateEmbeddedBinaryToolSpec: GenericCommandLineToolSpec, S let outputPath = input.absolutePath var commandLine = await commandLineFromTemplate(cbc, delegate, optionContext: discoveredCommandLineToolSpecInfo(cbc.producer, cbc.scope, delegate), lookup: lookup).map(\.asString) - commandLine[0] = resolveExecutablePath(cbc, Path("embeddedBinaryValidationUtility")).str + commandLine[0] = resolveExecutablePath(cbc.producer, Path("embeddedBinaryValidationUtility")).str let inputs: [any PlannedNode] = [delegate.createNode(input.absolutePath)] + cbc.commandOrderingInputs let outputs: [any PlannedNode] = [delegate.createNode(outputPath)] + (cbc.commandOrderingOutputs.isEmpty ? [delegate.createVirtualNode("ValidateEmbeddedBinary \(outputPath.str)")] : cbc.commandOrderingOutputs) diff --git a/Sources/SWBUniversalPlatform/LexCompiler.swift b/Sources/SWBUniversalPlatform/LexCompiler.swift index 2c1cb199..36f441e7 100644 --- a/Sources/SWBUniversalPlatform/LexCompiler.swift +++ b/Sources/SWBUniversalPlatform/LexCompiler.swift @@ -42,7 +42,7 @@ final class LexCompilerSpec : CompilerSpec, SpecIdentifierType, @unchecked Senda let lexFlags = cbc.scope.evaluate(BuiltinMacros.LEXFLAGS) // Compute the command line arguments. - var commandLine = [resolveExecutablePath(cbc, cbc.scope.evaluate(BuiltinMacros.LEX)).str] + var commandLine = [await resolveExecutablePath(cbc, cbc.scope.evaluate(BuiltinMacros.LEX), delegate: delegate).str] commandLine += await commandLineFromOptions(cbc, delegate, optionContext: discoveredCommandLineToolSpecInfo(cbc.producer, cbc.scope, delegate)).map(\.asString) commandLine += lexFlags if let perFileArgs = input.additionalArgs { diff --git a/Sources/SWBUniversalPlatform/TestEntryPointGenerationTool.swift b/Sources/SWBUniversalPlatform/TestEntryPointGenerationTool.swift index 5ee78857..e8e97f25 100644 --- a/Sources/SWBUniversalPlatform/TestEntryPointGenerationTool.swift +++ b/Sources/SWBUniversalPlatform/TestEntryPointGenerationTool.swift @@ -17,8 +17,8 @@ import SWBCore final class TestEntryPointGenerationToolSpec: GenericCommandLineToolSpec, SpecIdentifierType, @unchecked Sendable { static let identifier = "org.swift.test-entry-point-generator" - override func commandLineFromTemplate(_ cbc: CommandBuildContext, _ delegate: any TaskGenerationDelegate, optionContext: (any DiscoveredCommandLineToolSpecInfo)?, specialArgs: [String] = [], lookup: ((MacroDeclaration) -> MacroExpression?)? = nil) -> [CommandLineArgument] { - var args = super.commandLineFromTemplate(cbc, delegate, optionContext: optionContext, specialArgs: specialArgs, lookup: lookup) + override func commandLineFromTemplate(_ cbc: CommandBuildContext, _ delegate: any TaskGenerationDelegate, optionContext: (any DiscoveredCommandLineToolSpecInfo)?, specialArgs: [String] = [], lookup: ((MacroDeclaration) -> MacroExpression?)? = nil) async -> [CommandLineArgument] { + var args = await super.commandLineFromTemplate(cbc, delegate, optionContext: optionContext, specialArgs: specialArgs, lookup: lookup) for (toolchainPath, toolchainLibrarySearchPath) in cbc.producer.toolchains.map({ ($0.path, $0.librarySearchPaths) }) { if let path = toolchainLibrarySearchPath.findLibrary(operatingSystem: cbc.producer.hostOperatingSystem, basename: "IndexStore") { args.append(contentsOf: ["--index-store-library-path", .path(path)]) @@ -41,7 +41,7 @@ final class TestEntryPointGenerationToolSpec: GenericCommandLineToolSpec, SpecId } public func constructTasks(_ cbc: CommandBuildContext, _ delegate: any TaskGenerationDelegate, indexStorePaths: [Path], indexUnitBasePaths: [Path]) async { - var commandLine = commandLineFromTemplate(cbc, delegate, optionContext: nil) + var commandLine = await commandLineFromTemplate(cbc, delegate, optionContext: nil) for indexStorePath in indexStorePaths { commandLine.append(contentsOf: ["--index-store", .path(indexStorePath)]) diff --git a/Sources/SWBUniversalPlatform/YaccCompiler.swift b/Sources/SWBUniversalPlatform/YaccCompiler.swift index 82a0641e..004a744d 100644 --- a/Sources/SWBUniversalPlatform/YaccCompiler.swift +++ b/Sources/SWBUniversalPlatform/YaccCompiler.swift @@ -64,7 +64,7 @@ final class YaccCompilerSpec : CompilerSpec, SpecIdentifierType, @unchecked Send delegate.declareGeneratedSourceFile(outputHeaderPath) // Compute the command arguments. - var args = [resolveExecutablePath(cbc, cbc.scope.evaluate(BuiltinMacros.YACC)).str] + var args = [await resolveExecutablePath(cbc, cbc.scope.evaluate(BuiltinMacros.YACC), delegate: delegate).str] // FIXME: Add the auto-generated options. args += cbc.scope.evaluate(BuiltinMacros.YACCFLAGS) if let perFileArgs = input.additionalArgs {