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 a35cdb660972c872d0c564c629260f44def0f89c
Author: Szymon Janc <[email protected]>
AuthorDate: Mon Oct 19 17:49:17 2026 +0200

    newt/toolchain: Report compiler tools missing in compiler.yml
    
    If a tool path is not set in compiler.yml for the host OS (e.g.,
    compiler.path.cc is defined only under an OS condition), running the
    tool failed with "exec: no command". Check the path when the tool is
    about to be used and report the missing compiler.yml key instead.
    Tools that are not used by a command are still allowed to be unset.
    
    Assisted-by: Claude:claude-opus-5-5
---
 newt/error_reporting_test.go                       | 18 ++++++
 newt/testdata/error_reporting/apps/app/pkg.yml     | 24 ++++++++
 newt/testdata/error_reporting/project.yml          | 25 ++++++++
 .../repos/apache-mynewt-core/compiler/sim/pkg.yml  | 21 +++++++
 .../repos/apache-mynewt-core/hw/bsp/sim/bsp.yml    | 28 +++++++++
 .../repos/apache-mynewt-core/hw/bsp/sim/pkg.yml    | 21 +++++++
 .../repos/apache-mynewt-core/repository.yml        | 22 +++++++
 .../repos/apache-mynewt-core/sys/foo/pkg.yml       | 21 +++++++
 .../repos/apache-mynewt-core/sys/foo/syscfg.yml    | 23 ++++++++
 newt/testdata/error_reporting/targets/app/pkg.yml  | 21 +++++++
 .../error_reporting/targets/app/target.yml         | 22 +++++++
 newt/toolchain/compiler.go                         | 69 ++++++++++++++++++++++
 12 files changed, 315 insertions(+)

diff --git a/newt/error_reporting_test.go b/newt/error_reporting_test.go
index ea83b336..b95321e3 100644
--- a/newt/error_reporting_test.go
+++ b/newt/error_reporting_test.go
@@ -119,3 +119,21 @@ func TestErrorReportingUpgradePkgRepos(t *testing.T) {
                })
        }
 }
+
+var errorReportingProjDir = filepath.Join("testdata", "error_reporting")
+
+// A compiler tool whose path is not set in compiler.yml for the host OS must
+// be reported with the name of the missing setting.
+func TestErrorReportingEmptyToolPath(t *testing.T) {
+       dir := copyToTemp(t, errorReportingProjDir)
+       errorReportingWriteFiles(t, dir, map[string]string{
+               "repos/apache-mynewt-core/compiler/sim/compiler.yml": "" +
+                       "compiler.path.cc.NOSUCHOS: gcc\n" +
+                       "compiler.path.archive: ar\n" +
+                       "compiler.flags.default: -O1\n",
+               "apps/app/src/main.c": "int main(void) { return 0; }\n",
+       })
+
+       errorReportingExpectFail(t, dir,
+               []string{"compiler.path.cc is not set in"}, "build", "app")
+}
diff --git a/newt/testdata/error_reporting/apps/app/pkg.yml 
b/newt/testdata/error_reporting/apps/app/pkg.yml
new file mode 100644
index 00000000..55bf224b
--- /dev/null
+++ b/newt/testdata/error_reporting/apps/app/pkg.yml
@@ -0,0 +1,24 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+pkg.name: apps/app
+pkg.type: app
+
+pkg.deps:
+    - "@apache-mynewt-core/sys/foo"
diff --git a/newt/testdata/error_reporting/project.yml 
b/newt/testdata/error_reporting/project.yml
new file mode 100644
index 00000000..9bc050d3
--- /dev/null
+++ b/newt/testdata/error_reporting/project.yml
@@ -0,0 +1,25 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+project.name: "error_reporting"
+
+repository.apache-mynewt-core:
+    type: git
+    vers: 0.0.0
+    url: 'https://dummy.invalid/apache-mynewt-core.git'
diff --git 
a/newt/testdata/error_reporting/repos/apache-mynewt-core/compiler/sim/pkg.yml 
b/newt/testdata/error_reporting/repos/apache-mynewt-core/compiler/sim/pkg.yml
new file mode 100644
index 00000000..2f624582
--- /dev/null
+++ 
b/newt/testdata/error_reporting/repos/apache-mynewt-core/compiler/sim/pkg.yml
@@ -0,0 +1,21 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+pkg.name: compiler/sim
+pkg.type: compiler
diff --git 
a/newt/testdata/error_reporting/repos/apache-mynewt-core/hw/bsp/sim/bsp.yml 
b/newt/testdata/error_reporting/repos/apache-mynewt-core/hw/bsp/sim/bsp.yml
new file mode 100644
index 00000000..934c920b
--- /dev/null
+++ b/newt/testdata/error_reporting/repos/apache-mynewt-core/hw/bsp/sim/bsp.yml
@@ -0,0 +1,28 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+bsp.arch: sim
+bsp.compiler: "@apache-mynewt-core/compiler/sim"
+
+bsp.flash_map:
+    areas:
+        FLASH_AREA_IMAGE_0:
+            device: 0
+            offset: 0x00000000
+            size: 64kB
diff --git 
a/newt/testdata/error_reporting/repos/apache-mynewt-core/hw/bsp/sim/pkg.yml 
b/newt/testdata/error_reporting/repos/apache-mynewt-core/hw/bsp/sim/pkg.yml
new file mode 100644
index 00000000..7eee233c
--- /dev/null
+++ b/newt/testdata/error_reporting/repos/apache-mynewt-core/hw/bsp/sim/pkg.yml
@@ -0,0 +1,21 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+pkg.name: hw/bsp/sim
+pkg.type: bsp
diff --git 
a/newt/testdata/error_reporting/repos/apache-mynewt-core/repository.yml 
b/newt/testdata/error_reporting/repos/apache-mynewt-core/repository.yml
new file mode 100644
index 00000000..aabf9b4b
--- /dev/null
+++ b/newt/testdata/error_reporting/repos/apache-mynewt-core/repository.yml
@@ -0,0 +1,22 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+repo.name: apache-mynewt-core
+repo.versions:
+    "0.0.0": "master"
diff --git 
a/newt/testdata/error_reporting/repos/apache-mynewt-core/sys/foo/pkg.yml 
b/newt/testdata/error_reporting/repos/apache-mynewt-core/sys/foo/pkg.yml
new file mode 100644
index 00000000..b190d90c
--- /dev/null
+++ b/newt/testdata/error_reporting/repos/apache-mynewt-core/sys/foo/pkg.yml
@@ -0,0 +1,21 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+pkg.name: sys/foo
+pkg.type: lib
diff --git 
a/newt/testdata/error_reporting/repos/apache-mynewt-core/sys/foo/syscfg.yml 
b/newt/testdata/error_reporting/repos/apache-mynewt-core/sys/foo/syscfg.yml
new file mode 100644
index 00000000..8c36f704
--- /dev/null
+++ b/newt/testdata/error_reporting/repos/apache-mynewt-core/sys/foo/syscfg.yml
@@ -0,0 +1,23 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+syscfg.defs:
+    FOO:
+        description: Test setting.
+        value: 0
diff --git a/newt/testdata/error_reporting/targets/app/pkg.yml 
b/newt/testdata/error_reporting/targets/app/pkg.yml
new file mode 100644
index 00000000..2d1c2718
--- /dev/null
+++ b/newt/testdata/error_reporting/targets/app/pkg.yml
@@ -0,0 +1,21 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+pkg.name: targets/app
+pkg.type: target
diff --git a/newt/testdata/error_reporting/targets/app/target.yml 
b/newt/testdata/error_reporting/targets/app/target.yml
new file mode 100644
index 00000000..96001dcf
--- /dev/null
+++ b/newt/testdata/error_reporting/targets/app/target.yml
@@ -0,0 +1,22 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+target.app: apps/app
+target.bsp: "@apache-mynewt-core/hw/bsp/sim"
+target.build_profile: default
diff --git a/newt/toolchain/compiler.go b/newt/toolchain/compiler.go
index 067aee5f..7194713b 100644
--- a/newt/toolchain/compiler.go
+++ b/newt/toolchain/compiler.go
@@ -112,6 +112,9 @@ type Compiler struct {
        compileCommands []CompileCommand
 
        extraDeps []string
+
+       // Directory containing compiler.yml; used in error messages.
+       compilerDir string
 }
 
 func (c *Compiler) GetCompileCommands() []CompileCommand {
@@ -154,6 +157,18 @@ func (c *Compiler) GetAddr2linePath() string {
        return c.a2lPath
 }
 
+// checkToolPath returns an error if the path of a tool, read from the
+// specified compiler.yml key, is empty. A path can be empty, e.g., if it is
+// only set for some host OSes.
+func (c *Compiler) checkToolPath(path string, key string) error {
+       if path == "" {
+               return util.FmtNewtError("%s is not set in %s/%s", key,
+                       c.compilerDir, COMPILER_FILENAME)
+       }
+
+       return nil
+}
+
 // Returns path of binutils tool with given name that belongs to the same
 // toolchain as objdump, e.g. arm-none-eabi-objdump -> arm-none-eabi-nm.
 func siblingToolPath(odPath string, tool string) string {
@@ -287,6 +302,7 @@ func NewCompiler(compilerDir string, dstDir string,
                dstDir:          dstDir,
                extraDeps:       []string{},
                compileCommands: []CompileCommand{},
+               compilerDir:     compilerDir,
        }
 
        c.depTracker = NewDepTracker(c)
@@ -560,13 +576,16 @@ func (c *Compiler) CompileFileCmd(file string, 
compilerType int) (
        objPath := c.dstFilePath(file) + ".o"
 
        var cmdName string
+       var toolKey string
        var flags []string
        switch compilerType {
        case COMPILER_TYPE_C:
                cmdName = c.ccPath
+               toolKey = "compiler.path.cc"
                flags = c.cflagsStrings()
        case COMPILER_TYPE_ASM:
                cmdName = c.asPath
+               toolKey = "compiler.path.as"
 
                // Include both the compiler flags and the assembler flags.
                // XXX: This is not great.  We don't have a way of specifying 
compiler
@@ -574,10 +593,14 @@ func (c *Compiler) CompileFileCmd(file string, 
compilerType int) (
                flags = append(c.cflagsStrings(), c.aflagsStrings()...)
        case COMPILER_TYPE_CPP:
                cmdName = c.cppPath
+               toolKey = "compiler.path.cpp"
                flags = append(c.cflagsStrings(), c.cxxflagsStrings()...)
        default:
                return nil, util.NewNewtError("Unknown compiler type")
        }
+       if err := c.checkToolPath(cmdName, toolKey); err != nil {
+               return nil, err
+       }
 
        srcPath := strings.TrimPrefix(file, c.baseDir+"/")
        cmd := []string{cmdName}
@@ -604,13 +627,16 @@ func (c *Compiler) GenDepsForFile(file string, 
compilerType int) error {
        }
 
        var cmdName string
+       var toolKey string
        var flags []string
        switch compilerType {
        case COMPILER_TYPE_C:
                cmdName = c.ccPath
+               toolKey = "compiler.path.cc"
                flags = c.cflagsStrings()
        case COMPILER_TYPE_ASM:
                cmdName = c.asPath
+               toolKey = "compiler.path.as"
 
                // Include both the compiler flags and the assembler flags.
                // XXX: This is not great.  We don't have a way of specifying 
compiler
@@ -618,10 +644,14 @@ func (c *Compiler) GenDepsForFile(file string, 
compilerType int) error {
                flags = append(c.cflagsStrings(), c.aflagsStrings()...)
        case COMPILER_TYPE_CPP:
                cmdName = c.cppPath
+               toolKey = "compiler.path.cpp"
                flags = append(c.cflagsStrings(), c.cxxflagsStrings()...)
        default:
                return util.NewNewtError("Unknown compiler type")
        }
+       if err := c.checkToolPath(cmdName, toolKey); err != nil {
+               return err
+       }
 
        srcPath := strings.TrimPrefix(file, c.baseDir+"/")
        cmd := []string{cmdName}
@@ -1116,6 +1146,10 @@ func (c *Compiler) CompileBinary(dstFile string, options 
map[string]bool,
        // Make sure the compiler package info is added to the global set.
        c.ensureLclInfoAdded()
 
+       if err := c.checkToolPath(c.ccPath, "compiler.path.cc"); err != nil {
+               return err
+       }
+
        util.StatusMessage(util.VERBOSITY_DEFAULT, "Linking %s\n", dstFile)
 
        libList := c.getStaticLibs(util.UniqueStaticLib(staticLib))
@@ -1157,6 +1191,12 @@ func (c *Compiler) generateExtras(elfFilename string,
        options map[string]bool) error {
 
        if options["binFile"] {
+               if err := c.checkToolPath(c.ocPath,
+                       "compiler.path.objcopy"); err != nil {
+
+                       return err
+               }
+
                binFile := elfFilename + ".bin"
                cmd := []string{
                        c.ocPath,
@@ -1181,6 +1221,12 @@ func (c *Compiler) generateExtras(elfFilename string,
        }
 
        if options["listFile"] {
+               if err := c.checkToolPath(c.osPath,
+                       "compiler.path.objsize"); err != nil {
+
+                       return err
+               }
+
                listFile := elfFilename + ".lst"
                f, err := os.OpenFile(listFile, 
os.O_CREATE|os.O_WRONLY|os.O_TRUNC,
                        0666)
@@ -1239,6 +1285,10 @@ func (c *Compiler) generateExtras(elfFilename string,
 }
 
 func (c *Compiler) PrintSize(elfFilename string) (string, error) {
+       if err := c.checkToolPath(c.osPath, "compiler.path.objsize"); err != 
nil {
+               return "", err
+       }
+
        cmd := []string{
                c.osPath,
                elfFilename,
@@ -1485,6 +1535,10 @@ func (c *Compiler) CompileArchive(outputFile string, 
createList bool) error {
                return nil
        }
 
+       if err := c.checkToolPath(c.arPath, "compiler.path.archive"); err != 
nil {
+               return err
+       }
+
        fullCmd := c.CompileArchiveCmd(outputFile, objFiles)
 
        cmdSafe := c.CompileArchiveCmdSafe(outputFile, objFiles)
@@ -1575,6 +1629,9 @@ func ParseObjectLine(line string, r *regexp.Regexp) 
(error, *symbol.SymbolInfo)
 }
 
 func (c *Compiler) RenameSymbols(sm *symbol.SymbolMap, libraryFile string, ext 
string) error {
+       if err := c.checkToolPath(c.ocPath, "compiler.path.objcopy"); err != 
nil {
+               return err
+       }
 
        cmd := c.RenameSymbolsCmd(sm, libraryFile, ext)
 
@@ -1588,6 +1645,10 @@ func (c *Compiler) RenameSymbols(sm *symbol.SymbolMap, 
libraryFile string, ext s
 }
 
 func (c *Compiler) ParseLibrary(libraryFile string) (error, []byte) {
+       if err := c.checkToolPath(c.odPath, "compiler.path.objdump"); err != 
nil {
+               return err, nil
+       }
+
        cmd := c.ParseLibraryCmd(libraryFile)
 
        out, err := util.ShellCommand(cmd, nil)
@@ -1598,6 +1659,10 @@ func (c *Compiler) ParseLibrary(libraryFile string) 
(error, []byte) {
 }
 
 func (c *Compiler) CopySymbols(infile string, outfile string, sm 
*symbol.SymbolMap) error {
+       if err := c.checkToolPath(c.ocPath, "compiler.path.objcopy"); err != 
nil {
+               return err
+       }
+
        cmd := c.CopySymbolsCmd(infile, outfile, sm)
 
        _, err := util.ShellCommand(cmd, nil)
@@ -1608,6 +1673,10 @@ func (c *Compiler) CopySymbols(infile string, outfile 
string, sm *symbol.SymbolM
 }
 
 func (c *Compiler) ConvertBinToHex(inFile string, outFile string, baseAddr 
int) error {
+       if err := c.checkToolPath(c.ocPath, "compiler.path.objcopy"); err != 
nil {
+               return err
+       }
+
        cmd := []string{
                c.ocPath,
                "-I",

Reply via email to