Commit graph zephyr/cmake
Author SHA1 Message Date
Benjamin Cabé
2fa0c977b3 cmake: west: read the topdir through west's Python API
Running 'west topdir' pays for west's whole CLI import chain - argparse
setup, command discovery, west.app.main - only to print one path. Call
west.util.west_topdir() directly instead, which saves around 100 ms per
configure.

The output is unchanged: west's own CLI computes it the same way, and
PurePath().as_posix() reproduces the formatting it applies before
printing. The two failure paths are also untouched - a west version
import failure stays fatal, while a missing topdir stays tolerated so a
tree without a west workspace still configures.

'west build' already passes -DWEST_TOPDIR, so this helps plain cmake
invocations and twister, which configure without it.

Assisted-by: Claude Code:claude-opus-5
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
2026-08-28 15:28:56 -04:00
Benjamin Cabé
00867e136c cmake: armclang: use the target CPU for compiler capability probes
CMake stopped adding -mcpu itself once CMP0123 became NEW, and Zephyr
only passes it through TOOLCHAIN_C_FLAGS, which does not reach
try_compile. Compiler capability probes were therefore evaluated
against armclang's default CPU rather than the one being built for.

Add -mcpu to CMAKE_REQUIRED_FLAGS so probe results match the target.

Assisted-by: Claude:opus-5
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
2026-08-27 22:11:45 -04:00
Benjamin Cabé
159ab1c09f cmake: flash: remove deprecated flash/debug/attach/rtt targets
The CMake build system targets `flash`, `debug`, `debugserver`, `attach`
and `rtt` were deprecated in Zephyr 4.3 and are removed here as part of
the 4.5 deprecation removal cycle. They were thin wrappers that shelled
out to the corresponding west command, so users must now call `west
flash`, `west debug`, `west debugserver`, `west attach` and `west rtt`
directly. Note that `west build -t <target>` and `ninja <target>` are the
same mechanism, so both spellings are affected.

The generator loop was the only consumer of the `WEST_DIR` lookup and of
cmake/flash/check_runner_dependencies.cmake, so both are removed as well.
The runners.yaml generation in cmake/flash/CMakeLists.txt is kept: it is
what the west commands read, and it is also included directly by the
Nordic UICR helper projects.

The `run`, `run_<emulator>` and emulation `debugserver` targets are
provided by cmake/emu and are not affected.

Documentation that told users to run `ninja flash`, `ninja debug` or
`ninja attach` is updated to the equivalent west command, and the
zephyr-app-commands directive now rejects the removed goals when the
cmake tool is selected, so the docs cannot regress.

The now-unused RUNNERS_DEPS variable and the
check_runner_dependencies.cmake helper, which only existed to serve those
targets, are removed as well.

Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
Assisted-by: Claude:opus-5
2026-08-27 21:23:56 +01:00
Benjamin Cabé
89ac2d181b cmake: sca: don't set iwyu and C-STAT tool variables in the cache
CMAKE_<LANG>_INCLUDE_WHAT_YOU_USE and CMAKE_<LANG>_ICSTAT are set the
same way the compiler launchers used to be. Nothing sets a normal
variable of those names today so they are not shadowed, but there is no
reason to keep them in the cache either, where they would also survive a
change of ZEPHYR_SCA_VARIANT.

Assisted-by: Claude:claude-opus-5
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
2026-08-27 07:25:17 -07:00
Benjamin Cabé
94301e6acb cmake: sca: dtdoctor: keep existing compiler launchers in the chain
The dtdoctor wrapper runs the compiler or linker command unmodified and
only annotates its output, so it can share the launcher chain with
ccache instead of displacing it. Keep whatever launcher was already
configured at the end of the chain, giving '<wrapper> -- ccache <cc>'.

This is deliberately left to each tool: an SCA tool that intercepts the
compiler, such as sparse, ECLAIR or Coverity, cannot be combined with
ccache and must keep replacing it.

Assisted-by: Claude:claude-opus-5
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
2026-08-27 07:25:17 -07:00
Benjamin Cabé
477eaebbb7 cmake: sca: set compiler and linker launchers as normal variables
SCA tools installed their launchers as cache entries, but since CMP0126
a cache entry no longer removes a normal variable of the same name, so
they ended up shadowed by the launchers FindTargetTools sets for ccache
and the tool silently never ran. This started with a119dbf957, which
bumped the minimum CMake version to 3.28.0 and thereby turned the policy
to NEW.

There is no reason for these to be cache variables: they are INTERNAL
and sca.cmake is re-included on every configure. Setting them as normal
variables in the scope where FindTargetTools sets the ccache ones makes
the SCA launcher take effect again regardless of the policy, and stops
stale entries from surviving a change of ZEPHYR_SCA_VARIANT in an
existing build directory.

Assisted-by: Claude:claude-opus-5
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
2026-08-27 07:25:17 -07:00
Benjamin Cabé
77c6b14c4b cmake: doc: Add CMake build system reference documentation
Document the CMake modules, variables and target properties exposed by
the Zephyr build system, using the upstream CMake Sphinx domain so that
entities can be cross-referenced from the rest of the documentation
rather than looked up by reading the .cmake sources.

Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
2026-08-26 12:54:22 -04:00
Benjamin Cabé
d4ce3e76c3 cmake: extensions: write linker snippet files only when they change
zephyr_linker_sources() re-read and rewrote a snippet file on every call.
Rewriting a file updates its mtime even when the content is identical,
which dirties every ninja edge depending on it: all 14 snippets-*.ld
files were rewritten on every re-configure with byte-identical content.

Accumulate the lines in global properties instead and write each file
once, from a flush deferred to the end of the configure stage.
file(GENERATE) leaves a file untouched when its content is unchanged, so
a re-configure no longer perturbs the build graph.

The dirtied edges are otherwise masked by the syscalls trigger file being
touched at configure time. With that fixed as well, the rebuild after a
no-change re-configure drops from 0.44 s to 0.04 s for hello_world and
from 0.69 s to 0.05 s for echo_server.

Calling zephyr_linker_sources() after the flush cannot take effect and is
now a fatal error rather than a silently dropped snippet.

Assisted-by: Claude Code:claude-opus-5
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
2026-08-25 13:18:14 +02:00
Benjamin Cabé
dd6efdf715 cmake: kconfig: skip the Kconfig checksum recalculation when it is unused
The loop that recalculates the checksum after kconfig.py runs is only
consumed inside if(CREATE_NEW_DOTCONFIG). On any configure that does not
regenerate .config its result is discarded, so hashing all 5001 parsed
Kconfig sources is pure waste, measured in isolation at 168 ms.

Move the loop into the block that consumes it. The file(STRINGS) read
above stays where it is, as it also feeds the CMAKE_CONFIGURE_DEPENDS
registration, which must keep running unconditionally.

Assisted-by: Claude Code:claude-opus-5
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
2026-08-25 11:23:29 +02:00
Benjamin Cabé
8a2f52be7a cmake: kconfig: tidy up the Kconfig checksum accumulation
Accumulate the per-file MD5 checksums with string(APPEND) rather than
set(var "${var}${checksum}"), and register the configure dependencies
in a single set_property() call instead of one call per parsed Kconfig
file, of which there are 5001 for a hello_world build.

This is primarily a readability change; it may also be marginally
faster depending on the CMake version and host.

Assisted-by: Claude Code:claude-opus-5
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
2026-08-25 11:23:29 +02:00
Benjamin Cabé
0a22328a73 scripts: gen_relocate_app: drop deprecated pattern expansion
Stop glob-expanding the entries of a zephyr_code_relocate(FILES ...)
list. Expanding a pattern to several files has been deprecated since
Zephyr 4.2; the supported way is to expand it in CMake with
file(GLOB ...) and pass the resulting file names.

A pattern is now rejected with a named error instead of being silently
accepted, so the failure cannot go unnoticed. Entries without pattern
characters keep their current behaviour, including the "Not found"
warning for a missing file. All in-tree callers already pass explicit
file names.

Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
Assisted-by: Claude:opus-5
2026-08-24 18:43:22 +02:00
Benjamin Cabé
cfd2d6d5c1 cmake: kconfig: drop deprecated <board>_<rev>.conf fallback
Remove the fallback that pulled a board revision Kconfig fragment from
${BOARD_DIR}/<board>_<qualifiers>_<revision>.conf, deprecated since
Zephyr 4.2. Board revision configuration must be placed in
<board>_<revision>_defconfig, which is picked up by the regular
zephyr_file(CONF_FILES ... DEFCONFIG) lookup.

No in-tree board matched the fallback. The two files
boards/olimex/lora_stm32wl_devkit/olimex_lora_stm32wl_devkit_[CD].conf
are named after it but were never loaded: the fallback only ever matched
the fully qualified <board>_<soc>_<revision>.conf name, and these lack
the stm32wle5xx qualifier. They are deleted as dead files, which leaves
the build output unchanged. A board maintainer who does want
CONFIG_REGULATOR=y on that board should add
olimex_lora_stm32wl_devkit_C_defconfig instead; doing it here would be a
behaviour change rather than a deprecation removal.

BOARD_REVISION_CONFIG itself is kept: sysbuild still sets it, and it is
still merged into the final configuration.

Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
Assisted-by: Claude:opus-5
2026-08-24 18:43:22 +02:00
Benjamin Cabé
28e363fc69 cmake: remove deprecated app/boilerplate.cmake
Delete cmake/app/boilerplate.cmake, the backward-compatibility shim for
the pre-2.x "include(.../boilerplate.cmake NO_POLICY_SCOPE)" idiom. It
has warned on every direct inclusion since long before Zephyr 4.2 and
does nothing but forward to find_package(Zephyr).

Applications must use find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
as their first CMakeLists.txt statement. Nothing in-tree referenced the
file.

Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
Assisted-by: Claude:opus-5
2026-08-24 18:43:22 +02:00
Benjamin Cabé
f28028e730 arch: arm: remove deprecated CONFIG_PLATFORM_SPECIFIC_INIT
Remove CONFIG_PLATFORM_SPECIFIC_INIT and its z_arm_platform_init() hook,
deprecated in favour of CONFIG_SOC_RESET_HOOK / soc_reset_hook() well
before Zephyr 4.2 and therefore due for removal in 4.5.

The option had no reader left: neither cortex_m/reset.S nor
cortex_a_r/reset.S tests it, both only branch to soc_reset_hook(). Its
single in-tree selector, soc/renode/cortex_r8_virtual, is migrated to
select SOC_RESET_HOOK and its hook renamed to soc_reset_hook(); the body
is unchanged. Note that this re-activates the SCTLR.V clear on that SoC,
which had silently been dead code since the reset paths stopped calling
z_arm_platform_init() - the SoC now again selects the low exception
vector base as originally intended. It runs slightly later in the reset
sequence, after the per-mode stack pointers are set up. This should be
smoke-tested under Renode.

The stale z_arm_platform_init mention in the IAR linker script helper
comment is updated to soc_reset_hook.

Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
Assisted-by: Claude:opus-5
2026-08-21 14:23:38 +02:00
Benjamin Cabé
39065c6ee6 cmake: gcc: drop -gdwarf-4 pyelftools workaround
GCC 11+ defaults to DWARF v5, and -gdwarf-4 was forced only because
older pyelftools could not parse it. pyelftools has supported DWARF v5
since 0.27, and Zephyr now requires pyelftools>=0.29 (with CI pinned to
0.33), so the workaround is no longer needed. Remove the forced
-gdwarf-4 from both the compiler and linker flags to let GCC emit its
default DWARF version.

Assisted-by: Claude:opus-4.8
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
2026-08-20 10:56:47 +02:00
Paul Würtz
27ef837fc9 cmake: targets: Allow adding additional arguments to puncover
This allows i.e. non-interactive use and generating JSON reports of given
list of functions with an associated max stack sizes and flexibility to
add any other options.

Relates to #112163

Signed-off-by: Paul Würtz <paulwuertz@posteo.de>
2026-08-20 10:50:50 +02:00
Nicolas Pitre
6484418a3a kernel: move the sleep API declarations to their own header
k_sleep(), k_msleep() and k_usleep() are declared in kernel.h today.
Later commits grow that API with a tick based primitive plus inline unit
conversions, which is more than kernel.h ought to carry for a single
service.

Move the three declarations verbatim into a new include/zephyr/sleep.h
and have kernel.h include it, so existing users need no change. The new
header has to be registered with zephyr_syscall_header(), otherwise the
marshalling stubs for k_sleep() and k_usleep() stop being generated and
CONFIG_USERSPACE builds fail to find k_sleep_mrsh.c.

The unit_testing platform fabricates empty stand ins for the generated
syscall headers rather than running the generator, so sleep.h has to be
added to that list too.  Without it any unit test reaching kernel.h fails
to find zephyr/syscalls/sleep.h.

The sleep syscalls also have to be excluded from the automatic syscall
tracing in gen_syscalls.py, as kernel.h already is.  They carry hand
written trace points in kernel/sleep.c, and without the exclusion the
generated wrapper would wrap every call in a second set.

No functional change. A test application built for nucleo_f030r8 comes
out byte identical, at 10952 bytes of FLASH before and after.

Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
2026-08-20 08:52:31 +02:00
Tony Han
6f882517f9 arch: arm: core: add Cortex-A5 support to Kconfig and gcc-m-cpu.cmake
Add 'config CPU_CORTEX_A5' to arch/arm/core/cortex_a_r/Kconfig file.
Set 'GCC_M_CPU' to 'cortex-a5' in cmake/gcc-m-cpu.cmake for the
compiler.

Signed-off-by: Tony Han <tony.han@microchip.com>
2026-08-18 17:20:08 -04:00
Fin Maaß
a8649affcc riscv: select RISCV_ISA_EXT_ZBKB
select RISCV_ISA_EXT_ZBKB on extensions that
include it.

Signed-off-by: Fin Maaß <info@finmaass.de>
2026-08-17 16:27:42 -04:00
Josh DeWitt
f494cc3aed linker: Add a BSS linker location option
Allow applications to add special named sections to BSS or add linker
symbols around certain BSS objects without having to define their own
BSS area in RAM_SECTIONS that has to be memset separate of the rest of
BSS.

Signed-off-by: Josh DeWitt <josh.dewitt@garmin.com>
2026-08-13 16:21:54 -07:00
Torsten Rasmussen
437cd2641e cmake: restrict APPLICATION_CONFIG_DIR to zephyr_get(... LOCAL)
Application config dir is for the main application when using sysbuild.

Therefore restrict `zephyr_get(APPLICATION_CONFIG_DIR SYSBUILD_LOCAL)`
to ensure that other images does not pickup configuration files intended
for the main application.

APPLICATION_CONFIG_DIR can still be defined by the user for other images
using `<image>_APPLICATION_CONFIG_DIR=<path>`.

Signed-off-by: Torsten Rasmussen <Torsten.Rasmussen@nordicsemi.no>
2026-08-13 13:12:59 -04:00
Fin Maaß
e9fd4d3118 cmake: clang: add -Wno-parentheses-equality
add -Wno-parentheses-equality, so
clang doesn't complain about redundant
parenthesis, like it does when K_TIMEOUT_EQ()
is directly used in a if.

Signed-off-by: Fin Maaß <f.maass@vogl-electronic.com>
2026-08-12 13:10:49 -04:00
Mike J. Chen
bc5a686851 linker/xt-ld: pass C_FLAGS when processing the linker_script
When invoking the C compiler to preprocess the linker script, also pass the
C_FLAGS so that the xtensa-core is specified. Otherwise, if the toolchain
has multiple cores registered, the toolchain will use a default core when
one isn't specified and it could be incorrect for the build target.

Signed-off-by: Mike J. Chen <mjchen@google.com>
2026-08-12 13:08:37 -04:00
Tobias Aguiar
c456d2b127 arch: arm: cortex_m: linker: preserve input section alignment for ITCM
Replace SUBALIGN with ALIGN on the ITCM output section. This mirrors the
DTCM fix in commit de3deb75d4 ("fix: DTCM section alignment for DMA TCD
pool", upstream #107114, issue #107058).

SUBALIGN does not just align the start of the output section. It also
forces every input section assigned to that output section to a 4-byte
alignment boundary. This overrides any stricter or different alignment
requirements specified by the input sections themselves.

Use ALIGN instead so the ITCM output sections still start on a
4-byte boundary while preserving the original alignment requirements of
their input sections.

Signed-off-by: Tobias Aguiar <tobias.aguiarsilvadealmeida@nxp.com>
2026-08-12 12:58:29 -04:00
Anas Nashif
23fe4a52a0 cmake: sca: eclair: deviate Rule 10.3 for likely() and unlikely()
likely() and unlikely() hand a truth value to __builtin_expect(),
whose parameters GCC declares as long.  The resulting conversion from
an essentially Boolean expression to an essentially signed one is what
MISRA C:2012 Rule 10.3 objects to, and because the macros are used
throughout the kernel this single pair of definitions accounts for
2261 of the 6595 Rule 10.3 reports in the ECLAIR scan of qemu_x86.

The conversion is value-preserving and the result is immediately
compared against 0, so nothing is lost and the intent of the rule is
met.  Rewriting the macros to select a signed value explicitly does
silence the reports, but it perturbs the most heavily used
branch-hint macro in the tree for no reduction in risk, so record a
deviation instead.  These macros already carry a deliberate Directive
4.9 deviation in zephyr_common_config.ecl, and Rule 8.8 is already
deviated for generated syscall declarations on the same reasoning:
the construct is imposed by a mechanism outside the coding standard's
model.

The selector follows the existing Rule 11.6 deviation for
__LOG_ARG_CAST.

Assisted-by: Claude:claude-opus-5
Signed-off-by: Anas Nashif <anas.nashif@intel.com>
2026-08-11 13:50:43 -04:00
Josh DeWitt
9591012d9e cmake: kconfig: Ensure .config is regenerated when devicetree changes
Kconfig values can be derived from devicetree via $(dt...) functions
which means the .config file must be regenerated whenever devicetree
changes.

Signed-off-by: Josh DeWitt <josh.dewitt@garmin.com>
2026-08-11 13:42:08 -04:00
Nam Nguyen
c994c79021 arch: arm64: Add support for ARM Cortex-A720 CPU
Add ARMv9-A Cortex-A70 CPU support.

Signed-off-by: Nam Nguyen <nam.nguyen.xn@renesas.com>
2026-08-10 16:31:01 -04:00
Jamie McCrae
9722a5d516 cmake: modules: soc: Deprecate SOC_NAME, SOC_SERIES, SOC_FAMILY...
These variables are duplicates of Kconfig values and they do not
need to exist, therefore deprecated them, including SOC_V2_DIR

Signed-off-by: Jamie McCrae <jamie.mccrae@nordicsemi.no>
2026-08-08 16:33:24 -04:00
Hongquan Li
ce8d42d874 boards: qemu: add virtio-blk disk support
Create a raw disk image for QEMU virtio-blk tests.
Attach it through PCI or MMIO depending on the board.

Signed-off-by: Hongquan Li <hongquan.li@processmission.com>
2026-08-07 16:28:47 -04:00
Martin Meyer
d988cabdef cmake: ccache: fetch USE_CCACHE via zephyr_get for sysbuild
Add a `zephyr_get(USE_CCACHE)` call before the `USE_CCACHE` check so
that the variable is properly propagated from the sysbuild context,
allowing ccache to be enabled or disabled consistently across all
images in a sysbuild configuration.

Signed-off-by: Martin Meyer <meyer.m90@gmail.com>
2026-08-07 11:18:52 -04:00
Ederson de Souza
2cb53feca1 llext-edk: Properly get topdir when --sysbuild is used
When sysbuild is used with west (west build --sysbuild), west TOPDIR
variable is not saved to application build_info.yml, but to upper level
build_info.yml. Get topdir from there, otherwise during the EDK build
all paths relative to wesddt TOPDIR (such as modules) are handled as
absolute paths during EDK build.

Fixes: #110728

Signed-off-by: Ederson de Souza <ederson.desouza@intel.com>
2026-08-07 11:17:44 -04:00
Pieter De Gendt
1309640202 cmake: honor an explicitly selected Zephyr SDK
When ZEPHYR_SDK_INSTALL_DIR is set, the Zephyr SDK is looked up with
find_package() using HINTS. Since HINTS does not prevent the other
default search locations from being used, an explicitly selected but
incompatible SDK was silently ignored: find_package() fell through to
another SDK found elsewhere (for example in the CMake package
registry), while ZEPHYR_SDK_INSTALL_DIR kept pointing at the selected
directory. This produced confusing output such as a version being
reported that did not match the selected directory.

Restrict the lookup to ZEPHYR_SDK_INSTALL_DIR with NO_DEFAULT_PATH so
that an explicitly selected SDK is used exactly, and an incompatible
one results in a clear error instead of a silent fallback. Pointing
ZEPHYR_SDK_INSTALL_DIR at a directory containing multiple SDKs keeps
working, as HINTS still selects the best compatible SDK below it.

Assisted-by: Claude Code:claude-opus-4.8
Signed-off-by: Pieter De Gendt <pieter.degendt@basalte.be>
2026-08-06 14:33:07 +02:00
Anas Nashif
575ef58acd cmake: emu: qemu: restore the pflash drives on the command line
The CONFIG_FLASH_INTEL_PFLASH_CFI01 block still contributed its two
-drive options by appending to the QEMU_EXTRA_FLAGS variable. Since
the qemu_append_*() API was introduced, qemu.cmake reads that variable
exactly once, near the top of the file, to seed the EXTRA slot with
what boards left behind. The block runs after that seeding, so its
options never reached the command line.

Signed-off-by: Anas Nashif <anas.nashif@intel.com>
2026-08-05 18:36:55 +01:00
Adarsha Regmi
8925ae2806 toolchain: llvm: add ELD (ld.eld) linker support
ELD (“Embedded Linker”) is Qualcomm's open source, LLVM-based,
GNU-compatible linker designed for the needs of embedded systems. It can be
selected as an alternative to LLD when building Zephyr with the LLVM
toolchain.

This change adds a CONFIG_LLVM_USE_ELD Kconfig option and the required
CMake integration to locate ld.eld and use it during linking. A minimum ELD
version is enforced (22.0+) to ensure required linker-script features are
available.

ELD was discussed in several Zephyr Toolchain WG meetings from February
through June 2026. The meeting notes include links to recordings and
presentation slides covering key features such as linker plugins, LTO with
linker scripts, section budgeting, and rich diagnostics for facilitating
debugging.

Meeting notes: https://docs.google.com/document/d/1nFKhdhbxKhECvcVhwHQNytov3TbcN_eDUvPwPXlmXEM/edit#heading=h.8l0u6j5vo01p
Recording: https://zoom.us/rec/share/ztjugOyQ_zZcOf9zrZpomk2zxxE6aWeyvVJIUP2L-enc_wFubVJARkhOGlpzIEV2.nzAOoV97lPNrm_EB
Slides: https://riscv.atlassian.net/wiki/download/attachments/159286264/Invited%20Talk%20-Qualcomm%20Embedded%20Linker%20%E2%80%93%20Open%20sourcing.pdf?api=v2

ELD repository: https://github.com/qualcomm/eld
ELD docs: https://qualcomm.github.io/eld/

Prebuilt ELD binaries can be found on eld's github releases page:
https://github.com/qualcomm/eld/releases

Signed-off-by: Adarsha Regmi <aregmi@qti.qualcomm.com>
2026-08-05 18:36:15 +01:00
Anas Nashif
bcc6847d3a cmake: qemu: no need to check for CONFIG_QEMU_TARGET
CONFIG_QEMU_TARGET is assumed to always be set, no need for the check.

Signed-off-by: Anas Nashif <anas.nashif@intel.com>
2026-08-05 13:54:30 +01:00
Anas Nashif
c03e2bce23 cmake: emu: qemu: apply -no-reboot consistently from CONFIG_REBOOT
QEMU restarts the guest when the machine resets. An application built
without reboot support has no reason to reset, so a reset means it
misbehaved, and restarting it hides that behind a boot loop instead of
letting an automated run finish.

qemu_x86 already reasoned this way, emitting -no-reboot when
CONFIG_REBOOT was not set. qemu_arc emitted it unconditionally, so an
arc application with CONFIG_REBOOT=y had reboot silently disabled
anyway. Every other QEMU board never emitted it at all, and would spin
in a boot loop on an unexpected reset.

Move the decision into a fragment keyed on CONFIG_REBOOT, so all boards
behave the way qemu_x86 already did, and delete the two board copies.
This is the same failure mode as the leon3 -icount flag fixed earlier: a
board level flag that did not track the Kconfig it was meant to follow.

Of the 36 configurations in the matrix, 32 now emit -no-reboot; the four
that do not (qemu_cortex_a9, qemu_cortex_r5, mps2, mps3) are exactly the
ones with CONFIG_REBOOT=y. On qemu_x86 and qemu_arc the flag only
changes position on the command line, which QEMU does not care about.

No qemu targeted test relies on the machine resetting and continuing.

Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Anas Nashif <anas.nashif@intel.com>
2026-08-05 13:54:30 +01:00
Anas Nashif
575000192c cmake: emu: qemu: add a qemu_dumpdtb target
The arm and riscv "virt" machines generate a devicetree describing what
QEMU actually models, while Zephyr describes the same machines with a
hand written devicetree. There was no way to see the former, so keeping
the two in step meant reading QEMU's source.

Add a qemu_dumpdtb target that runs the emulator with -machine dumpdtb,
writing qemu.dtb into the build directory:

  west build -b qemu_riscv64 -t qemu_dumpdtb

QEMU exits as soon as the file is written without running the image, so
the target does not depend on the Zephyr binary. The board's -machine
argument merges with this one, since QEMU folds repeated -machine options
into a single option group.

Verified: qemu_riscv64 dumps a 4694 byte riscv-virtio devicetree and
qemu_cortex_a53 a linux,dummy-virt one. On a machine with no devicetree,
qemu_x86, QEMU declines with "This machine doesn't have an FDT" and the
target fails with that message rather than something obscure. The
run_qemu command line is unchanged on every board.

Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Anas Nashif <anas.nashif@intel.com>
2026-08-05 13:54:30 +01:00
Anas Nashif
9b10a456b3 cmake: emu: qemu: expose QEMU's diagnostic log via QEMU_LOG
QEMU can report when the guest does something invalid, such as touching
an unassigned physical address, and when the guest reaches emulation
QEMU has not implemented. Zephyr never asked for either, so both are
silent: the guest just misbehaves and the developer is left guessing.

Add QEMU_LOG, a comma separated list of QEMU -d log items, and
QEMU_LOG_FILE, which defaults to qemu.log in the build directory and
accepts "-" for stderr:

  west build -b qemu_cortex_m3 -- -DQEMU_LOG=guest_errors,unimp

Both are read with zephyr_get() so they also work under sysbuild.

Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Anas Nashif <anas.nashif@intel.com>
2026-08-05 13:54:30 +01:00
Anas Nashif
2667510656 cmake: emu: qemu: capture ethernet traffic with QEMU's filter-dump
PCAP=<file> only did anything for the serial transports, where
net_serial.cmake creates FIFOs and starts net-tools/monitor_15_4, an
out-of-tree binary the user has to build first. The block is POSIX only:
it shells out to mkfifo, stty and pkill. The ethernet transports,
CONFIG_NET_QEMU_ETHERNET and CONFIG_NET_QEMU_USER, had no capture at all.

QEMU can write the pcap itself. Attach a filter-dump object to the
netdev that net_nic.cmake already creates, so PCAP now works for the
ethernet transports with no FIFOs, no external capture process and no
POSIX-only tooling.

NET_QEMU_NETWORKING is a Kconfig choice, so at most one transport is
active in a build and PCAP stays unambiguous.

Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Anas Nashif <anas.nashif@intel.com>
2026-08-05 13:54:30 +01:00
Anas Nashif
728c89b14a cmake: emu: qemu: rename QEMU_FLAGS_${ARCH} to QEMU_BOARD_FLAGS
Like QEMU_CPU_TYPE_${ARCH}, this was indexed by an architecture that is
fixed for any one build, so the suffix distinguished nothing. The name
also said nothing about who owns the variable, even though its whole
purpose is to hold what the board contributes: the machine, the CPU, the
memory size, and whatever board specific devices come with them.

Rename it to QEMU_BOARD_FLAGS, which reads as the counterpart of the
existing QEMU_EXTRA_FLAGS, and reject the old name at configure time. An
out-of-tree board left on the old spelling would otherwise lose its
-machine argument silently.

Update the icount guard added earlier to match, and verify it still
rejects a board that appends -icount to the renamed variable.

Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Anas Nashif <anas.nashif@intel.com>
2026-08-05 13:54:30 +01:00
Anas Nashif
1018d71928 cmake: emu: qemu: drop the vestigial ARCH suffix from QEMU_CPU_TYPE
QEMU_CPU_TYPE_${ARCH} was indexed by architecture, but a build has
exactly one board and therefore exactly one ARCH, so the suffix
distinguished nothing. It only forced every board and the run target's
progress message to spell the same interpolation.

Rename it to QEMU_CPU_TYPE, and reject the old name at configure time so
an out-of-tree board does not silently end up with an empty progress
message.

Also record what the variable is for. Seven boards (cortex_a72,
cortex_a9, cortex_r5, leon3, malta, or1k, riscv32_xip) set it and never
pass -cpu, because their -machine already implies the CPU. It is not a
QEMU argument: the emulator code only reports it. Boards that do want a
-cpu argument reference it when composing QEMU_FLAGS_${ARCH}. That is
worth stating, since the name suggests it is what gets passed.

Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Anas Nashif <anas.nashif@intel.com>
2026-08-05 13:54:30 +01:00
Anas Nashif
267747440f cmake: emu: qemu: unify QEMU_ARCH and QEMU_binary_suffix
Boards had two ways to say the same thing. QEMU_ARCH's only consumer
was binary.cmake, which did nothing with it but feed it to
set_ifndef(QEMU_binary_suffix ...), so the two variables named one
concept: the suffix of the qemu-system-* binary to run. Five boards
used one spelling and four the other.

Keep the name that describes what the value is, fix its casing to match
the rest of the tree, and drop the alias. Boards that set QEMU_ARCH now
set QEMU_BINARY_SUFFIX directly.

Because an out-of-tree board setting a now-ignored variable would
silently get the wrong emulator rather than a build failure, reject
both old names at configure time with a message naming the replacement.

Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Anas Nashif <anas.nashif@intel.com>
2026-08-05 13:54:30 +01:00
Anas Nashif
eeecc4e2b0 cmake: emu: qemu: reject board -icount, drop dead flag on leon3
qemu_leon3 passed "-icount auto" in QEMU_FLAGS_${ARCH}, and icount.cmake
then appended "-icount shift=${CONFIG_QEMU_ICOUNT_SHIFT},...". QEMU
merges repeated -icount options into a single option group in which the
last shift= wins, so the board's value was silently discarded. Verified
against qemu-system-sparc: "-icount auto -icount shift=100" is rejected
for the invalid shift, while "-icount shift=100 -icount auto" is not.

Honouring the board's request instead turns out to break it: with
"-icount auto" actually applied, tests/kernel/timer/timer_api and
tests/kernel/sched/schedule_api on qemu_leon3 go from 170/170 passing
to 11 failed and 8 blocked. The derived shift is the value this board
wants, so the flag is dropped rather than migrated.

To keep the next board from losing an -icount flag the same silent way,
add QEMU_ICOUNT_OVERRIDE for boards that genuinely need a different
argument, and fail at configure time if a board puts -icount in
QEMU_FLAGS_${ARCH}, where it cannot take effect.

Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Anas Nashif <anas.nashif@intel.com>
2026-08-05 13:54:30 +01:00
Anas Nashif
e94b6d46c5 cmake: emu: qemu: add an API for contributing to the command line
The QEMU command line was assembled by appending to a handful of
specifically named variables: QEMU_FLAGS, QEMU_EXTRA_FLAGS,
MORE_FLAGS_FOR_<target>, PRE_QEMU_COMMANDS_FOR_<target> and its POST
counterpart, plus QEMU_TARGET_DEPENDS. Which of them a contributor
should use, and what the resulting argument order would be, was
documented nowhere and had to be inferred from the layout of the file.

Replace the raw variables with qemu_append_flags(),
qemu_append_extra_flags(), qemu_append_target_flags(),
qemu_add_run_targets(), qemu_add_pre_commands(),
qemu_add_post_commands() and qemu_add_target_depends(), and name the
two ordered slots the flags land in. State is kept in global properties
rather than directory variables, so a contribution no longer has to
come from a file that happens to be include()d into qemu.cmake.

The two slots are kept distinct rather than merged because boards seed
FLAGS_EXTRA before this file runs, and because QEMU numbers -serial
ports in the order they appear on the command line, which makes the
order within a slot significant.

The board-facing contract is unchanged: boards still set
QEMU_FLAGS_${ARCH}, QEMU_EXTRA_FLAGS, QEMU_KERNEL_FILE and
QEMU_KERNEL_OPTION as before.

Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Anas Nashif <anas.nashif@intel.com>
2026-08-05 13:54:30 +01:00
Anas Nashif
38d4a52a4f cmake: emu: qemu: split qemu.cmake into per-concern fragments
qemu.cmake had grown to 534 lines, most of which were per-subsystem
blocks (console, display, icount, Bluetooth, networking, CAN, ivshmem,
NVMe, the x86_64 image split) with no separation between them. Move
each block into its own fragment under cmake/emu/qemu/ and leave
qemu.cmake as a 120-line orchestrator that sets up the shared flag
lists, includes the fragments and emits the run targets.

The command line is assembled from two interleaved lists, QEMU_FLAGS
and QEMU_EXTRA_FLAGS, so the include order of the fragments fixes the
order of the resulting arguments. The fragments are therefore included
in exactly the order their blocks appeared in. This is also why QEMU
networking is split in two: the serial transports (SLIP, PPP, pipe
stack) contribute to QEMU_FLAGS early, while the ethernet NIC model
contributes to QEMU_EXTRA_FLAGS late, and the original file already
had them as two separate sections a hundred lines apart.

Document the flag lists and the ordering contract at the top of
qemu.cmake, which was previously implicit in the layout of the file.

Pure code motion, no functional change: the generated qemu-system-*
command lines and run-target dependency edges were captured for 36
board/app combinations covering the x86 locore, SLIP/PPP/pipe-stack
networking, CAN, ivshmem, Bluetooth, semihosting, NVMe, icount and SMP
paths, and are byte-identical before and after.

Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Anas Nashif <anas.nashif@intel.com>
2026-08-05 13:54:30 +01:00
Anas Nashif
c399622ef3 cmake: emu: qemu: fix NVMe disk dependency and drop dead code
The qemu_nvme_disk target, which creates the backing image for the
-drive flag added under CONFIG_NVME, was only wired as a dependency of
the run targets when QEMU_KERNEL_FILE happened to be defined. That
variable is only ever set by the CONFIG_X86_64 block in this same file,
so on any other board CONFIG_NVME appended "-drive file=nvme_disk.img"
while nothing ever created the image. Accumulate run-target
dependencies in QEMU_TARGET_DEPENDS instead, so the NVMe image and the
x86_64 kernel image each register their own, and drop the empty
qemu_nvme_disk stub that existed only to satisfy the fused guard.

While here, remove PRE_QEMU_COMMANDS, which is dereferenced when
building the run targets but is set nowhere in the tree, and hoist the
three open-coded copies of the "escape QEMU_INSTANCE for the Makefiles
generator" conditional into a single qemu_instance variable.

Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Anas Nashif <anas.nashif@intel.com>
2026-08-05 13:54:30 +01:00
Anas Nashif
73214f0516 cmake: sca: eclair: add deviation for directive 4.8 and explanation
Add deviation for directive 4.8, clarifying its advisory nature
and the rationale behind not adopting it in the project. This change
ensures that public headers define types consistently while
acknowledging the limitations of unit properties for shared headers.

Signed-off-by: Anas Nashif <anas.nashif@intel.com>
2026-08-05 13:54:03 +01:00
Anas Nashif
ac5f4ad157 cmake: sca: eclair: deviate Directive 4.13 for va_start/va_end
Directive 4.13 (call resource operations in an appropriate sequence) flags
the va_start()/va_end() pairing used by the variadic assertion and print
helpers. By the definition of <stdarg.h> these are always used as a
correctly nested pair within a single function and the language guarantees
the sequence, so deviate them as deliberate and safe.

Assisted-by: GitHub Copilot:claude-sonnet-4.6
Signed-off-by: Anas Nashif <anas.nashif@intel.com>
2026-08-05 13:54:03 +01:00
Anas Nashif
5bd7f28c56 cmake: sca: eclair: disapply advisory Rule 12.1
Rule 12.1 (make operator precedence explicit) is advisory and is not
adopted by the project. The reports are dominated by the universally
understood precedence between the equality/comparison operators and the
logical && / || operators (e.g. "a && b == c"), where adding parentheses
brings no clarity and would only churn the code base.

The genuinely error-prone precedence cases - a bitwise operator mixed with
a comparison, or an assignment used as a controlling expression - are
already diagnosed by the compiler via -Wparentheses, which is fatal under
-Werror. Disapplying Rule 12.1 therefore does not lose coverage of the
dangerous cases, consistent with the handling of other impractical advisory
guidelines (Directive 4.6 and 4.8).

Assisted-by: GitHub Copilot:claude-sonnet-4.6
Signed-off-by: Anas Nashif <anas.nashif@intel.com>
2026-08-05 13:54:03 +01:00
Anas Nashif
a9bec7d63d cmake: sca: eclair: disapply advisory Directive 4.6
Directive 4.6 (use width-and-signedness typedefs instead of the basic
numerical types) is advisory and is not adopted by the project:

  - The basic numerical types are used throughout the tree where a specific
    width is not required (return codes, counters, line numbers, indices),
    and many of these appear in public APIs where churning int into int32_t
    has no safety benefit.

  - The directive cannot be satisfied at all for the basic floating types
    (float, double, long double), which make up a large fraction of the
    reports; the C standard provides no width-and-signedness typedefs for
    them.

Disapply the directive, consistent with the handling of other impractical
advisory guidelines (e.g. Rule 2.2, 13.5 and 14.2).

Assisted-by: GitHub Copilot:claude-sonnet-4.6
Signed-off-by: Anas Nashif <anas.nashif@intel.com>
2026-08-05 13:54:03 +01:00