diff --git a/builder/build.go b/builder/build.go index 5c38433b..c1fd78e3 100644 --- a/builder/build.go +++ b/builder/build.go @@ -100,7 +100,7 @@ func Build(pkgName, outpath string, config *compileopts.Config, action func(Buil AutomaticStackSize: config.AutomaticStackSize(), DefaultStackSize: config.Target.DefaultStackSize, NeedsStackObjects: config.NeedsStackObjects(), - Debug: config.Debug(), + Debug: true, LLVMFeatures: config.LLVMFeatures(), } @@ -539,6 +539,39 @@ func Build(pkgName, outpath string, config *compileopts.Config, action func(Buil return fmt.Errorf("unknown libc: %s", config.Target.Libc) } + // Strip debug information with -no-debug. + if !config.Debug() { + for _, tag := range config.BuildTags() { + if tag == "baremetal" { + // Don't use -no-debug on baremetal targets. It makes no sense: + // the debug information isn't flashed to the device anyway. + return fmt.Errorf("stripping debug information is unnecessary for baremetal targets") + } + } + if config.Target.Linker == "wasm-ld" { + // Don't just strip debug information, also compress relocations + // while we're at it. Relocations can only be compressed when debug + // information is stripped. + ldflags = append(ldflags, "--strip-debug", "--compress-relocations") + } else { + switch config.GOOS() { + case "linux": + // Either real linux or an embedded system (like AVR) that + // pretends to be Linux. It's a ELF linker wrapped by GCC in any + // case. + ldflags = append(ldflags, "-Wl,--strip-debug") + case "darwin": + // MacOS (darwin) doesn't have a linker flag to strip debug + // information. Apple expects you to use the strip command + // instead. + return errors.New("cannot remove debug information: MacOS doesn't suppor this linker flag") + default: + // Other OSes may have different flags. + return errors.New("cannot remove debug information: unknown OS: " + config.GOOS()) + } + } + } + // Create a linker job, which links all object files together and does some // extra stuff that can only be done after linking. jobs = append(jobs, &compileJob{ diff --git a/compileopts/config.go b/compileopts/config.go index 36782506..f2ba2857 100644 --- a/compileopts/config.go +++ b/compileopts/config.go @@ -209,9 +209,8 @@ func (c *Config) CFlags() []string { cflags = append(cflags, "-nostdlibinc", "-Xclang", "-internal-isystem", "-Xclang", filepath.Join(root, "lib", "picolibc", "newlib", "libc", "include")) cflags = append(cflags, "-I"+filepath.Join(root, "lib/picolibc-include")) } - if c.Debug() { - cflags = append(cflags, "-g") - } + // Always emit debug information. It is optionally stripped at link time. + cflags = append(cflags, "-g") return cflags } @@ -250,8 +249,9 @@ func (c *Config) VerifyIR() bool { return c.Options.VerifyIR } -// Debug returns whether to add debug symbols to the IR, for debugging with GDB -// and similar. +// Debug returns whether debug (DWARF) information should be retained by the +// linker. By default, debug information is retained but it can be removed with +// the -no-debug flag. func (c *Config) Debug() bool { return c.Options.Debug } diff --git a/main.go b/main.go index 7c3ee96d..c9fd0c04 100644 --- a/main.go +++ b/main.go @@ -1019,7 +1019,7 @@ func main() { printStacks := flag.Bool("print-stacks", false, "print stack sizes of goroutines") printAllocsString := flag.String("print-allocs", "", "regular expression of functions for which heap allocations should be printed") printCommands := flag.Bool("x", false, "Print commands") - nodebug := flag.Bool("no-debug", false, "disable DWARF debug symbol generation") + nodebug := flag.Bool("no-debug", false, "strip debug information") ocdCommandsString := flag.String("ocd-commands", "", "OpenOCD commands, overriding target spec (can specify multiple separated by commas)") ocdOutput := flag.Bool("ocd-output", false, "print OCD daemon output during debug") port := flag.String("port", "", "flash port (can specify multiple candidates separated by commas)")