Skip to content

Commit 5a2b48e

Browse files
committed
Run build commands without declared outputs
It is possible to declare build commands without outputs and the expectation is that those would still run. Currently, that is not the case, since the only condition that makes llbuild run build commands is that there's a client for the output files (either compilation or copying of resources). This change adds a phony output to any command that has no declared outputs and declares these phony outputs as input for any targets that are asking for the plugin to be applied. This will lead to these commands running unconditionally, fixing the current silent failure to run these. rdar://100415491
1 parent b368b96 commit 5a2b48e

File tree

3 files changed

+21
-6
lines changed

3 files changed

+21
-6
lines changed

Sources/Build/BuildManifest/LLBuildManifestBuilder+Clang.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ extension LLBuildManifestBuilder {
8989
)
9090
}
9191

92-
try addBuildToolPlugins(.clang(target))
92+
let additionalInputs = try addBuildToolPlugins(.clang(target))
9393

9494
// Create a phony node to represent the entire target.
9595
let targetName = target.target.getLLBuildTargetName(config: target.buildParameters.buildConfig)
@@ -98,7 +98,7 @@ extension LLBuildManifestBuilder {
9898
self.manifest.addNode(output, toTarget: targetName)
9999
self.manifest.addPhonyCmd(
100100
name: output.name,
101-
inputs: objectFileNodes,
101+
inputs: objectFileNodes + additionalInputs,
102102
outputs: [output]
103103
)
104104

Sources/Build/BuildManifest/LLBuildManifestBuilder+Swift.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -484,14 +484,14 @@ extension LLBuildManifestBuilder {
484484
}
485485
}
486486

487-
try self.addBuildToolPlugins(.swift(target))
487+
let additionalInputs = try self.addBuildToolPlugins(.swift(target))
488488

489489
// Depend on any required macro product's output.
490490
try target.requiredMacroProducts.forEach { macro in
491491
try inputs.append(.virtual(macro.getLLBuildTargetName(config: target.buildParameters.buildConfig)))
492492
}
493493

494-
return inputs
494+
return inputs + additionalInputs
495495
}
496496

497497
/// Adds a top-level phony command that builds the entire target.

Sources/Build/BuildManifest/LLBuildManifestBuilder.swift

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,12 @@ extension LLBuildManifestBuilder {
194194
// MARK: - Compilation
195195

196196
extension LLBuildManifestBuilder {
197-
func addBuildToolPlugins(_ target: TargetBuildDescription) throws {
197+
func addBuildToolPlugins(_ target: TargetBuildDescription) throws -> [Node] {
198+
// For any build command that doesn't declare any outputs, we need to create a phony output to ensure they will still be run by the build system.
199+
var phonyOutputs = [Node]()
200+
// If we have multiple commands with no output files and no display name, this serves as a way to disambiguate the virtual nodes being created.
201+
var pluginNumber = 1
202+
198203
// Add any regular build commands created by plugins for the target.
199204
for result in target.buildToolPluginInvocationResults {
200205
// Only go through the regular build commands — prebuild commands are handled separately.
@@ -213,17 +218,27 @@ extension LLBuildManifestBuilder {
213218
writableDirectories: [result.pluginOutputDirectory]
214219
)
215220
}
221+
let additionalOutputs: [Node]
222+
if command.outputFiles.isEmpty {
223+
additionalOutputs = [.virtual("\(target.target.c99name)-\(command.configuration.displayName ?? "\(pluginNumber)")")]
224+
phonyOutputs += additionalOutputs
225+
pluginNumber += 1
226+
} else {
227+
additionalOutputs = []
228+
}
216229
self.manifest.addShellCmd(
217230
name: displayName + "-" + ByteString(encodingAsUTF8: uniquedName).sha256Checksum,
218231
description: displayName,
219232
inputs: command.inputFiles.map { .file($0) },
220-
outputs: command.outputFiles.map { .file($0) },
233+
outputs: command.outputFiles.map { .file($0) } + additionalOutputs,
221234
arguments: commandLine,
222235
environment: command.configuration.environment,
223236
workingDirectory: command.configuration.workingDirectory?.pathString
224237
)
225238
}
226239
}
240+
241+
return phonyOutputs
227242
}
228243
}
229244

0 commit comments

Comments
 (0)