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"}
