From 10c67125ddef749c6d37247e63797990d1ff2403 Mon Sep 17 00:00:00 2001 From: Emmanuel Jacquier Date: Mon, 9 Mar 2026 13:27:22 -0400 Subject: [PATCH] Wasm debug symbols by default for simulator --- cmd/common/compile.go | 23 +++++++++++++++++------ cmd/common/compile_test.go | 16 ++++++++-------- cmd/workflow/deploy/compile.go | 2 +- cmd/workflow/deploy/compile_test.go | 2 +- cmd/workflow/simulate/simulate.go | 2 +- 5 files changed, 28 insertions(+), 17 deletions(-) diff --git a/cmd/common/compile.go b/cmd/common/compile.go index 4e844708..5bca20d1 100644 --- a/cmd/common/compile.go +++ b/cmd/common/compile.go @@ -16,7 +16,8 @@ const makefileName = "Makefile" var defaultWasmOutput = filepath.Join("wasm", "workflow.wasm") // getBuildCmd returns a single step that builds the workflow and returns the WASM bytes. -func getBuildCmd(workflowRootFolder, mainFile, language string) (func() ([]byte, error), error) { +// If stripSymbols is true, debug symbols are stripped from the binary to reduce size. +func getBuildCmd(workflowRootFolder, mainFile, language string, stripSymbols bool) (func() ([]byte, error), error) { tmpPath := filepath.Join(workflowRootFolder, ".cre_build_tmp.wasm") switch language { case constants.WorkflowLanguageTypeScript: @@ -33,11 +34,15 @@ func getBuildCmd(workflowRootFolder, mainFile, language string) (func() ([]byte, }, nil case constants.WorkflowLanguageGolang: // Build the package (.) so all .go files (main.go, workflow.go, etc.) are compiled together + ldflags := "-buildid=" + if stripSymbols { + ldflags = "-buildid= -w -s" + } cmd := exec.Command( "go", "build", "-o", tmpPath, "-trimpath", - "-ldflags=-buildid= -w -s", + "-ldflags="+ldflags, ".", ) cmd.Dir = workflowRootFolder @@ -68,11 +73,15 @@ func getBuildCmd(workflowRootFolder, mainFile, language string) (func() ([]byte, }, nil default: // Build the package (.) so all .go files are compiled together + ldflags := "-buildid=" + if stripSymbols { + ldflags = "-buildid= -w -s" + } cmd := exec.Command( "go", "build", "-o", tmpPath, "-trimpath", - "-ldflags=-buildid= -w -s", + "-ldflags="+ldflags, ".", ) cmd.Dir = workflowRootFolder @@ -90,8 +99,10 @@ func getBuildCmd(workflowRootFolder, mainFile, language string) (func() ([]byte, } // CompileWorkflowToWasm compiles the workflow at workflowPath and returns the WASM binary. -// It runs the sequence of commands from getBuildCmds (make build + copy for WASM, or single build for Go/TS), then reads the temp WASM file. -func CompileWorkflowToWasm(workflowPath string) ([]byte, error) { +// If stripSymbols is true, debug symbols are stripped to reduce binary size (used for deploy). +// If false, debug symbols are kept for better error messages (used for simulate). +// For custom builds (WASM language with Makefile), stripSymbols has no effect. +func CompileWorkflowToWasm(workflowPath string, stripSymbols bool) ([]byte, error) { workflowRootFolder, workflowMainFile, err := WorkflowPathRootAndMain(workflowPath) if err != nil { return nil, fmt.Errorf("workflow path: %w", err) @@ -122,7 +133,7 @@ func CompileWorkflowToWasm(workflowPath string) ([]byte, error) { return nil, fmt.Errorf("unsupported workflow language for file %s", workflowMainFile) } - buildStep, err := getBuildCmd(workflowRootFolder, workflowMainFile, language) + buildStep, err := getBuildCmd(workflowRootFolder, workflowMainFile, language, stripSymbols) if err != nil { return nil, err } diff --git a/cmd/common/compile_test.go b/cmd/common/compile_test.go index aec71b63..0280c9f1 100644 --- a/cmd/common/compile_test.go +++ b/cmd/common/compile_test.go @@ -40,21 +40,21 @@ func TestFindMakefileRoot(t *testing.T) { func TestCompileWorkflowToWasm_Go_Success(t *testing.T) { t.Run("basic_workflow", func(t *testing.T) { path := deployTestdataPath("basic_workflow", "main.go") - wasm, err := CompileWorkflowToWasm(path) + wasm, err := CompileWorkflowToWasm(path, true) require.NoError(t, err) assert.NotEmpty(t, wasm) }) t.Run("configless_workflow", func(t *testing.T) { path := deployTestdataPath("configless_workflow", "main.go") - wasm, err := CompileWorkflowToWasm(path) + wasm, err := CompileWorkflowToWasm(path, true) require.NoError(t, err) assert.NotEmpty(t, wasm) }) t.Run("missing_go_mod", func(t *testing.T) { path := deployTestdataPath("missing_go_mod", "main.go") - wasm, err := CompileWorkflowToWasm(path) + wasm, err := CompileWorkflowToWasm(path, true) require.NoError(t, err) assert.NotEmpty(t, wasm) }) @@ -62,7 +62,7 @@ func TestCompileWorkflowToWasm_Go_Success(t *testing.T) { func TestCompileWorkflowToWasm_Go_Malformed_Fails(t *testing.T) { path := deployTestdataPath("malformed_workflow", "main.go") - _, err := CompileWorkflowToWasm(path) + _, err := CompileWorkflowToWasm(path, true) require.Error(t, err) assert.Contains(t, err.Error(), "failed to compile workflow") assert.Contains(t, err.Error(), "undefined: sdk.RemovedFunctionThatFailsCompilation") @@ -73,7 +73,7 @@ func TestCompileWorkflowToWasm_Wasm_Success(t *testing.T) { _ = os.Remove(wasmPath) t.Cleanup(func() { _ = os.Remove(wasmPath) }) - wasm, err := CompileWorkflowToWasm(wasmPath) + wasm, err := CompileWorkflowToWasm(wasmPath, true) require.NoError(t, err) assert.NotEmpty(t, wasm) @@ -89,14 +89,14 @@ func TestCompileWorkflowToWasm_Wasm_Fails(t *testing.T) { wasmPath := filepath.Join(wasmDir, "workflow.wasm") require.NoError(t, os.WriteFile(wasmPath, []byte("not really wasm"), 0600)) - _, err := CompileWorkflowToWasm(wasmPath) + _, err := CompileWorkflowToWasm(wasmPath, true) require.Error(t, err) assert.Contains(t, err.Error(), "no Makefile found") }) t.Run("make_build_fails", func(t *testing.T) { path := deployTestdataPath("wasm_make_fails", "wasm", "workflow.wasm") - _, err := CompileWorkflowToWasm(path) + _, err := CompileWorkflowToWasm(path, true) require.Error(t, err) assert.Contains(t, err.Error(), "failed to compile workflow") assert.Contains(t, err.Error(), "build output:") @@ -120,7 +120,7 @@ func TestCompileWorkflowToWasm_TS_Success(t *testing.T) { if err := install.Run(); err != nil { t.Skipf("bun install failed (network or cre-sdk): %v", err) } - wasm, err := CompileWorkflowToWasm(mainPath) + wasm, err := CompileWorkflowToWasm(mainPath, true) if err != nil { t.Skipf("TS compile failed (published cre-sdk may lack full layout): %v", err) } diff --git a/cmd/workflow/deploy/compile.go b/cmd/workflow/deploy/compile.go index 4349319b..e9a64ebe 100644 --- a/cmd/workflow/deploy/compile.go +++ b/cmd/workflow/deploy/compile.go @@ -48,7 +48,7 @@ func (h *handler) Compile() error { h.runtimeContext.Workflow.Language = cmdcommon.GetWorkflowLanguage(workflowMainFile) } - wasmFile, err := cmdcommon.CompileWorkflowToWasm(resolvedWorkflowPath) + wasmFile, err := cmdcommon.CompileWorkflowToWasm(resolvedWorkflowPath, true) if err != nil { ui.Error("Build failed:") return fmt.Errorf("failed to compile workflow: %w", err) diff --git a/cmd/workflow/deploy/compile_test.go b/cmd/workflow/deploy/compile_test.go index c0cc0d79..5bb6410f 100644 --- a/cmd/workflow/deploy/compile_test.go +++ b/cmd/workflow/deploy/compile_test.go @@ -303,7 +303,7 @@ func outputPathWithExtensions(path string) string { // file content equals CompileWorkflowToWasm(workflowPath) + brotli + base64. func assertCompileOutputMatchesUnderlying(t *testing.T, simulatedEnvironment *chainsim.SimulatedEnvironment, inputs Inputs, ownerType string) { t.Helper() - wasm, err := cmdcommon.CompileWorkflowToWasm(inputs.WorkflowPath) + wasm, err := cmdcommon.CompileWorkflowToWasm(inputs.WorkflowPath, true) require.NoError(t, err) compressed, err := applyBrotliCompressionV2(&wasm) require.NoError(t, err) diff --git a/cmd/workflow/simulate/simulate.go b/cmd/workflow/simulate/simulate.go index 6e953dc2..08f721be 100644 --- a/cmd/workflow/simulate/simulate.go +++ b/cmd/workflow/simulate/simulate.go @@ -276,7 +276,7 @@ func (h *handler) Execute(inputs Inputs) error { spinner := ui.NewSpinner() spinner.Start("Compiling workflow...") - wasmFileBinary, err := cmdcommon.CompileWorkflowToWasm(resolvedWorkflowPath) + wasmFileBinary, err := cmdcommon.CompileWorkflowToWasm(resolvedWorkflowPath, false) spinner.Stop() if err != nil { ui.Error("Build failed:")