From aaa865c23c0097c477550af43e9e4f635443f37e Mon Sep 17 00:00:00 2001 From: Owen Voorhees Date: Tue, 9 Sep 2025 13:23:32 -0700 Subject: [PATCH] Set PATH in the env when invoking dsymutil so it can find lipo in another toolchain --- .../Tools/DsymutilTool.swift | 11 +++++- .../DebugInformationTests.swift | 37 +++++++++++++++++++ 2 files changed, 46 insertions(+), 2 deletions(-) diff --git a/Sources/SWBCore/SpecImplementations/Tools/DsymutilTool.swift b/Sources/SWBCore/SpecImplementations/Tools/DsymutilTool.swift index 8bde552c..3fccd547 100644 --- a/Sources/SWBCore/SpecImplementations/Tools/DsymutilTool.swift +++ b/Sources/SWBCore/SpecImplementations/Tools/DsymutilTool.swift @@ -11,7 +11,7 @@ //===----------------------------------------------------------------------===// public import SWBUtil -import SWBMacro +public import SWBMacro public final class DsymutilToolSpec : GenericCommandLineToolSpec, SpecIdentifierType, @unchecked Sendable { public static let identifier = "com.apple.tools.dsymutil" @@ -21,6 +21,13 @@ public final class DsymutilToolSpec : GenericCommandLineToolSpec, SpecIdentifier fatalError("unexpected direct invocation") } + public override func environmentFromSpec(_ cbc: CommandBuildContext, _ delegate: any DiagnosticProducingDelegate, lookup: ((MacroDeclaration) -> MacroExpression?)? = nil) -> [(String, String)] { + var env: [(String, String)] = super.environmentFromSpec(cbc, delegate, lookup: lookup) + // dsymutil may need to lookup lipo, which is not necessarily in the same toolchain. + env.append(("PATH", cbc.producer.executableSearchPaths.environmentRepresentation)) + return env + } + /// Override construction to patch the inputs. public func constructTasks(_ cbc: CommandBuildContext, _ delegate: any TaskGenerationDelegate, dsymBundle: Path, buildVariant: String = "", dsymSearchPaths: [String] = [], quietOperation: Bool = false) async { let output = cbc.output @@ -51,6 +58,6 @@ public final class DsymutilToolSpec : GenericCommandLineToolSpec, SpecIdentifier let inputs: [any PlannedNode] = cbc.inputs.map({ delegate.createNode($0.absolutePath) }) + cbc.commandOrderingInputs let outputs: [any PlannedNode] = [delegate.createNode(output), orderingOutputNode] + cbc.commandOrderingOutputs - delegate.createTask(type: self, ruleInfo: ruleInfo, commandLine: commandLine, environment: EnvironmentBindings(), workingDirectory: cbc.producer.defaultWorkingDirectory, inputs: inputs, outputs: outputs, action: nil, execDescription: resolveExecutionDescription(templateBuildContext, delegate), enableSandboxing: enableSandboxing) + delegate.createTask(type: self, ruleInfo: ruleInfo, commandLine: commandLine, environment: environmentFromSpec(cbc, delegate), workingDirectory: cbc.producer.defaultWorkingDirectory, inputs: inputs, outputs: outputs, action: nil, execDescription: resolveExecutionDescription(templateBuildContext, delegate), enableSandboxing: enableSandboxing) } } diff --git a/Tests/SWBTaskConstructionTests/DebugInformationTests.swift b/Tests/SWBTaskConstructionTests/DebugInformationTests.swift index 41c745cc..802efa2c 100644 --- a/Tests/SWBTaskConstructionTests/DebugInformationTests.swift +++ b/Tests/SWBTaskConstructionTests/DebugInformationTests.swift @@ -329,4 +329,41 @@ fileprivate struct DebugInformationTests: CoreBasedTests { } } + @Test(.requireSDKs(.macOS)) + func dsymutilEnvironment() async throws { + let testProject = TestProject( + "aProject", + groupTree: TestGroup( + "SomeFiles", path: "Sources", + children: [ + TestFile("main.c"), + ]), + buildConfigurations: [ + TestBuildConfiguration( + "Debug", + buildSettings: [ + "GENERATE_INFOPLIST_FILE": "YES", + "PRODUCT_NAME": "$(TARGET_NAME)", + "ALWAYS_SEARCH_USER_PATHS": "NO", + "DEBUG_INFORMATION_FORMAT": "dwarf-with-dsym", + ]), + ], + targets: [ + TestStandardTarget( + "CoreFoo", type: .framework, + buildPhases: [ + TestSourcesBuildPhase(["main.c"])]), + ]) + let tester = try await TaskConstructionTester(getCore(), testProject) + + let buildParameters = BuildParameters(configuration: "Debug") + + await tester.checkBuild(buildParameters, runDestination: .macOS) { results in + results.checkTask(.matchRuleType("GenerateDSYMFile"), .matchRuleItemBasename("CoreFoo")) { task in + results.checkNoDiagnostics() + // Ensure PATH is set in the dsymutil environment. + task.checkEnvironment(["PATH": .any]) + } + } + } }