Skip to content

Commit 736db53

Browse files
Merge pull request #302 from swiftwasm/yt/add-debug-info-format
PackageToJS: Add `--debug-info-format` option
2 parents 80077f5 + 2c515b5 commit 736db53

File tree

6 files changed

+621
-20
lines changed

6 files changed

+621
-20
lines changed

Diff for: Plugins/PackageToJS/Sources/PackageToJS.swift

+35-15
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,22 @@ struct PackageToJS {
1414
var enableCodeCoverage: Bool = false
1515
}
1616

17+
enum DebugInfoFormat: String, CaseIterable {
18+
/// No debug info
19+
case none
20+
/// The all DWARF sections and "name" section
21+
case dwarf
22+
/// Only "name" section
23+
case name
24+
}
25+
1726
struct BuildOptions {
1827
/// Product to build (default: executable target if there's only one)
1928
var product: String?
2029
/// Whether to apply wasm-opt optimizations in release mode (default: true)
2130
var noOptimize: Bool
31+
/// The format of debug info to keep in the final wasm file (default: none)
32+
var debugInfoFormat: DebugInfoFormat
2233
/// The options for packaging
2334
var packageOptions: PackageOptions
2435
}
@@ -388,7 +399,7 @@ struct PackagingPlanner {
388399
buildOptions: PackageToJS.BuildOptions
389400
) throws -> MiniMake.TaskKey {
390401
let (allTasks, _, _, _) = try planBuildInternal(
391-
make: &make, noOptimize: buildOptions.noOptimize
402+
make: &make, noOptimize: buildOptions.noOptimize, debugInfoFormat: buildOptions.debugInfoFormat
392403
)
393404
return make.addTask(
394405
inputTasks: allTasks, output: BuildPath(phony: "all"), attributes: [.phony, .silent]
@@ -397,7 +408,8 @@ struct PackagingPlanner {
397408

398409
private func planBuildInternal(
399410
make: inout MiniMake,
400-
noOptimize: Bool
411+
noOptimize: Bool,
412+
debugInfoFormat: PackageToJS.DebugInfoFormat
401413
) throws -> (
402414
allTasks: [MiniMake.TaskKey],
403415
outputDirTask: MiniMake.TaskKey,
@@ -432,24 +444,32 @@ struct PackagingPlanner {
432444
let finalWasmPath = outputDir.appending(path: wasmFilename)
433445

434446
if shouldOptimize {
435-
// Optimize the wasm in release mode
436-
let wasmWithoutDwarfPath = intermediatesDir.appending(path: wasmFilename + ".no-dwarf")
437-
438-
// First, strip DWARF sections as their existence enables DWARF preserving mode in wasm-opt
439-
let wasmWithoutDwarf = make.addTask(
440-
inputFiles: [selfPath, wasmProductArtifact], inputTasks: [outputDirTask, intermediatesDirTask],
441-
output: wasmWithoutDwarfPath
442-
) {
443-
print("Stripping DWARF debug info...")
444-
try system.wasmOpt(["--strip-dwarf", "--debuginfo"], input: $1.resolve(path: wasmProductArtifact).path, output: $1.resolve(path: $0.output).path)
447+
let wasmOptInputFile: BuildPath
448+
let wasmOptInputTask: MiniMake.TaskKey?
449+
switch debugInfoFormat {
450+
case .dwarf:
451+
// Keep the original wasm file
452+
wasmOptInputFile = wasmProductArtifact
453+
wasmOptInputTask = nil
454+
case .name, .none:
455+
// Optimize the wasm in release mode
456+
wasmOptInputFile = intermediatesDir.appending(path: wasmFilename + ".no-dwarf")
457+
// First, strip DWARF sections as their existence enables DWARF preserving mode in wasm-opt
458+
wasmOptInputTask = make.addTask(
459+
inputFiles: [selfPath, wasmProductArtifact], inputTasks: [outputDirTask, intermediatesDirTask],
460+
output: wasmOptInputFile
461+
) {
462+
print("Stripping DWARF debug info...")
463+
try system.wasmOpt(["--strip-dwarf", "--debuginfo"], input: $1.resolve(path: wasmProductArtifact).path, output: $1.resolve(path: $0.output).path)
464+
}
445465
}
446466
// Then, run wasm-opt with all optimizations
447467
wasm = make.addTask(
448-
inputFiles: [selfPath, wasmWithoutDwarfPath], inputTasks: [outputDirTask, wasmWithoutDwarf],
468+
inputFiles: [selfPath, wasmOptInputFile], inputTasks: [outputDirTask] + (wasmOptInputTask.map { [$0] } ?? []),
449469
output: finalWasmPath
450470
) {
451471
print("Optimizing the wasm file...")
452-
try system.wasmOpt(["-Os", "--debuginfo"], input: $1.resolve(path: wasmWithoutDwarfPath).path, output: $1.resolve(path: $0.output).path)
472+
try system.wasmOpt(["-Os"] + (debugInfoFormat != .none ? ["--debuginfo"] : []), input: $1.resolve(path: wasmOptInputFile).path, output: $1.resolve(path: $0.output).path)
453473
}
454474
} else {
455475
// Copy the wasm product artifact
@@ -518,7 +538,7 @@ struct PackagingPlanner {
518538
make: inout MiniMake
519539
) throws -> (rootTask: MiniMake.TaskKey, binDir: BuildPath) {
520540
var (allTasks, outputDirTask, intermediatesDirTask, packageJsonTask) = try planBuildInternal(
521-
make: &make, noOptimize: false
541+
make: &make, noOptimize: false, debugInfoFormat: .dwarf
522542
)
523543

524544
// Install npm dependencies used in the test harness

Diff for: Plugins/PackageToJS/Sources/PackageToJSPlugin.swift

+10-1
Original file line numberDiff line numberDiff line change
@@ -295,8 +295,16 @@ extension PackageToJS.BuildOptions {
295295
static func parse(from extractor: inout ArgumentExtractor) -> PackageToJS.BuildOptions {
296296
let product = extractor.extractOption(named: "product").last
297297
let noOptimize = extractor.extractFlag(named: "no-optimize")
298+
let rawDebugInfoFormat = extractor.extractOption(named: "debug-info-format").last
299+
var debugInfoFormat: PackageToJS.DebugInfoFormat = .none
300+
if let rawDebugInfoFormat = rawDebugInfoFormat {
301+
guard let format = PackageToJS.DebugInfoFormat(rawValue: rawDebugInfoFormat) else {
302+
fatalError("Invalid debug info format: \(rawDebugInfoFormat), expected one of \(PackageToJS.DebugInfoFormat.allCases.map(\.rawValue).joined(separator: ", "))")
303+
}
304+
debugInfoFormat = format
305+
}
298306
let packageOptions = PackageToJS.PackageOptions.parse(from: &extractor)
299-
return PackageToJS.BuildOptions(product: product, noOptimize: noOptimize != 0, packageOptions: packageOptions)
307+
return PackageToJS.BuildOptions(product: product, noOptimize: noOptimize != 0, debugInfoFormat: debugInfoFormat, packageOptions: packageOptions)
300308
}
301309

302310
static func help() -> String {
@@ -313,6 +321,7 @@ extension PackageToJS.BuildOptions {
313321
--no-optimize Whether to disable wasm-opt optimization (default: false)
314322
--use-cdn Whether to use CDN for dependency packages (default: false)
315323
--enable-code-coverage Whether to enable code coverage collection (default: false)
324+
--debug-info-format The format of debug info to keep in the final wasm file (values: none, dwarf, name; default: none)
316325
317326
SUBCOMMANDS:
318327
test Builds and runs tests

Diff for: Plugins/PackageToJS/Tests/ExampleTests.swift

+2
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,8 @@ extension Trait where Self == ConditionTrait {
139139
let swiftSDKID = try #require(Self.getSwiftSDKID())
140140
try withPackage(at: "Examples/Basic") { packageDir, runSwift in
141141
try runSwift(["package", "--swift-sdk", swiftSDKID, "js"], [:])
142+
try runSwift(["package", "--swift-sdk", swiftSDKID, "js", "--debug-info-format", "dwarf"], [:])
143+
try runSwift(["package", "--swift-sdk", swiftSDKID, "js", "--debug-info-format", "name"], [:])
142144
try runSwift(["package", "--swift-sdk", swiftSDKID, "-Xswiftc", "-DJAVASCRIPTKIT_WITHOUT_WEAKREFS", "js"], [:])
143145
}
144146
}

Diff for: Plugins/PackageToJS/Tests/PackagingPlannerTests.swift

+9-4
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,16 @@ import Testing
3434
)
3535
}
3636

37+
typealias DebugInfoFormat = PackageToJS.DebugInfoFormat
38+
3739
@Test(arguments: [
38-
(variant: "debug", configuration: "debug", noOptimize: false),
39-
(variant: "release", configuration: "release", noOptimize: false),
40-
(variant: "release_no_optimize", configuration: "release", noOptimize: true),
40+
(variant: "debug", configuration: "debug", noOptimize: false, debugInfoFormat: DebugInfoFormat.none),
41+
(variant: "release", configuration: "release", noOptimize: false, debugInfoFormat: DebugInfoFormat.none),
42+
(variant: "release_no_optimize", configuration: "release", noOptimize: true, debugInfoFormat: DebugInfoFormat.none),
43+
(variant: "release_dwarf", configuration: "release", noOptimize: false, debugInfoFormat: DebugInfoFormat.dwarf),
44+
(variant: "release_name", configuration: "release", noOptimize: false, debugInfoFormat: DebugInfoFormat.name),
4145
])
42-
func planBuild(variant: String, configuration: String, noOptimize: Bool) throws {
46+
func planBuild(variant: String, configuration: String, noOptimize: Bool, debugInfoFormat: PackageToJS.DebugInfoFormat) throws {
4347
let options = PackageToJS.PackageOptions()
4448
let system = TestPackagingSystem()
4549
let planner = PackagingPlanner(
@@ -60,6 +64,7 @@ import Testing
6064
buildOptions: PackageToJS.BuildOptions(
6165
product: "test",
6266
noOptimize: noOptimize,
67+
debugInfoFormat: debugInfoFormat,
6368
packageOptions: options
6469
)
6570
)

0 commit comments

Comments
 (0)