This is an automated email from the ASF dual-hosted git repository.

sjanc pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-newt.git

commit 26d44628c291fdbe7cb6e58c39f83a38f0ef447c
Author: Szymon Janc <[email protected]>
AuthorDate: Mon Oct 19 17:53:11 2026 +0200

    newt/toolchain: Fix compiler warnings ending up in dependency files
    
    GenDepsForFile wrote the combined stdout and stderr of the compiler
    to the .d file. Any warning printed while generating dependencies was
    parsed as a dependency list, so the real dependencies were ignored or
    nonexistent "dependencies" made every build recompile the file, or
    parsing failed with "line missing ':'".
    
    Only use the standard output for the dependency file. Standard error
    is shown in verbose mode, or used as the error text if the command
    fails.
    
    Assisted-by: Claude:claude-opus-5-5
---
 newt/toolchain/compiler.go  | 34 +++++++++++++++++++++++++++++++++-
 newt/toolchain/deps_test.go | 38 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 71 insertions(+), 1 deletion(-)

diff --git a/newt/toolchain/compiler.go b/newt/toolchain/compiler.go
index e8bc2df5..b8bf733d 100644
--- a/newt/toolchain/compiler.go
+++ b/newt/toolchain/compiler.go
@@ -20,6 +20,7 @@
 package toolchain
 
 import (
+       "bytes"
        "fmt"
        "io/ioutil"
        "mynewt.apache.org/newt/newt/cfgv"
@@ -678,7 +679,7 @@ func (c *Compiler) GenDepsForFile(file string, compilerType 
int) error {
        cmd = append(cmd, c.includesStrings()...)
        cmd = append(cmd, []string{"-MM", "-MG", srcPath}...)
 
-       o, err := util.ShellCommandLimitDbgOutput(cmd, nil, true, 0)
+       o, err := depsCommandOutput(cmd)
        if err != nil {
                return err
        }
@@ -703,6 +704,37 @@ func (c *Compiler) GenDepsForFile(file string, 
compilerType int) error {
        return nil
 }
 
+// depsCommandOutput executes the specified dependency generation command and
+// returns its standard output.  Standard error (e.g., compiler warnings) is
+// not part of the dependency list; it is only displayed in verbose mode or
+// returned as the error text if the command fails.
+func depsCommandOutput(cmdStrs []string) ([]byte, error) {
+       cmd, err := util.ShellCommandInit(cmdStrs, nil)
+       if err != nil {
+               return nil, err
+       }
+
+       util.LogShellCmd(cmdStrs, nil)
+
+       var stderr bytes.Buffer
+       cmd.Stderr = &stderr
+
+       o, err := cmd.Output()
+       if err != nil {
+               nerr := util.ChildNewtError(err)
+               if stderr.Len() > 0 {
+                       nerr.Text = stderr.String()
+               }
+               return nil, nerr
+       }
+
+       if stderr.Len() > 0 {
+               util.StatusMessage(util.VERBOSITY_VERBOSE, "%s", 
stderr.String())
+       }
+
+       return o, nil
+}
+
 func serializeCommand(cmd []string) []byte {
        // Use a newline as the separator rather than a space to disambiguate 
cases
        // where arguments contain spaces.
diff --git a/newt/toolchain/deps_test.go b/newt/toolchain/deps_test.go
index 585fcda5..eafc10b1 100644
--- a/newt/toolchain/deps_test.go
+++ b/newt/toolchain/deps_test.go
@@ -23,6 +23,8 @@ import (
        "fmt"
        "os"
        "path/filepath"
+       "runtime"
+       "slices"
        "sync"
        "testing"
        "time"
@@ -77,3 +79,39 @@ func TestCompilerConcurrentUpdates(t *testing.T) {
                t.Errorf("expected %d compile commands, got %d", n, got)
        }
 }
+
+// Compiler warnings on stderr must not end up in the dependency file.
+func TestGenDepsForFileIgnoresStderr(t *testing.T) {
+       if runtime.GOOS == "windows" {
+               t.Skip("uses a shell script as a fake compiler")
+       }
+
+       dir := t.TempDir()
+       cc := filepath.Join(dir, "fake-cc")
+       script := "#!/bin/sh\n" +
+               "echo 'warning: something odd' >&2\n" +
+               "echo 'src/a.o: src/a.c src/a.h'\n"
+       if err := os.WriteFile(cc, []byte(script), 0755); err != nil {
+               t.Fatal(err)
+       }
+
+       c := newTestCompiler()
+       c.ccPath = cc
+       c.baseDir = dir
+       c.dstDir = dir + "/bin"
+       src := dir + "/src/a.c"
+
+       if err := c.GenDepsForFile(src, COMPILER_TYPE_C); err != nil {
+               t.Fatal(err)
+       }
+
+       deps, err := ParseDepsFile(c.dstFilePath(src) + ".d")
+       if err != nil {
+               t.Fatal(err)
+       }
+
+       exp := []string{"src/a.c", "src/a.h"}
+       if !slices.Equal(deps, exp) {
+               t.Errorf("unexpected dependencies: expected %q, got %q", exp, 
deps)
+       }
+}

Reply via email to