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

xiaoxiang781216 pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/nuttx-ntfc.git

commit 986238df3b1958a69c772806d39f745c3c656644
Author: raiden00pl <[email protected]>
AuthorDate: Tue Aug 4 17:29:44 2026 +0200

    builder.py: register app_bindir and exec_cwd for kernel-mode builds
    
    Kernel-mode CMake builds install applications to <build>/bin. On qemu
    arm/riscv the target mounts them over a semihosting hostfs relative to
    the spawned process working directory. When the generated .config
    selects CONFIG_BUILD_KERNEL=y, register app_bindir=<build>/bin and
    exec_cwd=<build>, keeping values set in YAML.
    
    Signed-off-by: raiden00pl <[email protected]>
    Assisted-by: Claude Code
---
 src/ntfc/builder.py   | 17 ++++++++++++++
 tests/test_builder.py | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 81 insertions(+)

diff --git a/src/ntfc/builder.py b/src/ntfc/builder.py
index 6e104f5..fa8887b 100644
--- a/src/ntfc/builder.py
+++ b/src/ntfc/builder.py
@@ -458,6 +458,23 @@ class NuttXBuilder:
             cores[core]["elf_path"] = nuttx_elf_path
             cores[core]["conf_path"] = nuttx_conf_path
 
+            if self._is_kernel_config(nuttx_conf_path):
+                # kernel-mode: applications are installed to <build>/bin
+                # and hostfs mounts resolve relative to the process cwd
+                cores[core].setdefault(
+                    "app_bindir", os.path.join(build_path, "bin")
+                )
+                cores[core].setdefault("exec_cwd", build_path)
+
+    @staticmethod
+    def _is_kernel_config(conf_path: str) -> bool:
+        """Check if a generated .config selects a kernel build."""
+        if not os.path.isfile(conf_path):
+            return False
+
+        with open(conf_path, "r", encoding="utf-8") as f:
+            return any(line.strip() == "CONFIG_BUILD_KERNEL=y" for line in f)
+
     def _reboot_core(
         self, core: str, cores: Dict[str, Any]
     ) -> None:  # pragma: no cover
diff --git a/tests/test_builder.py b/tests/test_builder.py
index 1fb4ab8..ab64223 100644
--- a/tests/test_builder.py
+++ b/tests/test_builder.py
@@ -79,6 +79,70 @@ def test_builder_init():
     )
 
 
+def test_builder_kernel_mode_core_config(tmp_path) -> None:
+    config = copy.deepcopy(conf_dir)
+    config["config"]["build_dir"] = str(tmp_path)
+    config["product"]["cores"]["core0"]["defconfig"] = "dummy/path"
+
+    build_path = tmp_path / "product-xxx-dummy"
+    build_path.mkdir()
+    (build_path / ".config").write_text("CONFIG_BUILD_KERNEL=y\n")
+
+    b = NuttXBuilder(config)
+    b._run_command = builder_run_command_dummy
+    b._make_dir = builder_make_dir_dummy
+    b.build_all()
+
+    core = b.new_conf()["product"]["cores"]["core0"]
+    assert core["app_bindir"] == str(build_path / "bin")
+    assert core["exec_cwd"] == str(build_path)
+
+
+def test_builder_kernel_mode_keeps_user_overrides(tmp_path) -> None:
+    config = copy.deepcopy(conf_dir)
+    config["config"]["build_dir"] = str(tmp_path)
+    config["product"]["cores"]["core0"]["defconfig"] = "dummy/path"
+    config["product"]["cores"]["core0"]["app_bindir"] = "/custom/bin"
+    config["product"]["cores"]["core0"]["exec_cwd"] = "/custom/cwd"
+
+    build_path = tmp_path / "product-xxx-dummy"
+    build_path.mkdir()
+    (build_path / ".config").write_text("CONFIG_BUILD_KERNEL=y\n")
+
+    b = NuttXBuilder(config)
+    b._run_command = builder_run_command_dummy
+    b._make_dir = builder_make_dir_dummy
+    b.build_all()
+
+    core = b.new_conf()["product"]["cores"]["core0"]
+    assert core["app_bindir"] == "/custom/bin"
+    assert core["exec_cwd"] == "/custom/cwd"
+
+
+def test_builder_flat_mode_no_kernel_keys(tmp_path) -> None:
+    config = copy.deepcopy(conf_dir)
+    config["config"]["build_dir"] = str(tmp_path)
+    config["product"]["cores"]["core0"]["defconfig"] = "dummy/path"
+
+    build_path = tmp_path / "product-xxx-dummy"
+    build_path.mkdir()
+    (build_path / ".config").write_text("CONFIG_BUILD_FLAT=y\n")
+
+    b = NuttXBuilder(config)
+    b._run_command = builder_run_command_dummy
+    b._make_dir = builder_make_dir_dummy
+    b.build_all()
+
+    core = b.new_conf()["product"]["cores"]["core0"]
+    assert "app_bindir" not in core
+    assert "exec_cwd" not in core
+
+    # missing .config (dummy build) is treated as a flat build
+    assert (
+        NuttXBuilder._is_kernel_config(str(tmp_path / "nonexistent")) is False
+    )
+
+
 def test_builder_passes_build_env() -> None:
     config = copy.deepcopy(conf_dir)
     config["config"]["build_env"] = {"CC": "gcc-13", "CXX": "g++-13"}

Reply via email to