zephyr: CONFIG_PICOLIBC + sparse = zephyr/posix/sys/stat.h:40:11: error: unable to open 'sys/_timespec.h'
Describe the bug
CONFIG_PICOLIBC is currently incompatible with sparse due to some .h files complexities.
EDIT October 2nd with newer, simpler, SOF-free reproduction
# Compiles and provides all sparse warnings
west build -b intel_adsp_cavs25 samples/hello_world -p -- \
-DCONFIG_MINIMAL_LIBC=y -DZEPHYR_SCA_VARIANT=sparse
# Does not compile and can't provide some sparse warnings
west build -b intel_adsp_cavs25 samples/hello_world -p -- \
-DCONFIG_PICOLIBC=y -DZEPHYR_SCA_VARIANT=sparse
Slower, -j1 version that does not bury the relevant error:
west build -b intel_adsp_cavs25 samples/hello_world -p -- \
-DCONFIG_PICOLIBC=y -DZEPHYR_SCA_VARIANT=sparse
ninja -j1 -C build
Building C object zephyr/lib/libc/picolibc/CMakeFiles/lib__libc__picolibc.dir/libc-hooks.c.obj
zephyr/lib/libc/picolibc/libc-hooks.c: note: in included file:
zephyr/include/zephyr/posix/sys/stat.h:40:11: error: unable to open 'sys/_timespec.h'
OLDER, initial and more complex reproduction that requires SOF. Kept here for completeness, you can probably skip it.
Commit f0daf904bb0202c9247 switched CONFIG_PICOLIBC on by default. This broke the “sparse” analyzer used in the SOF project:
https://github.com/thesofproject/sof/actions/runs/6247162197/job/16959223474?pr=8235
/zep_workspace/zephyr/lib/os/printk.c:123:33: error: undefined identifier 'FDEV_SETUP_STREAM'
/zep_workspace/zephyr/lib/os/printk.c:144:32: error: undefined identifier 'FDEV_SETUP_STREAM'
/zep_workspace/zephyr/lib/os/printk.c:144:49: error: invalid initializer
/zep_workspace/zephyr/include/zephyr/posix/sys/stat.h:40:11: error: unable to open 'sys/_timespec.h'
Note this is not just a sparse warning or false positive: compilation with sparse actually FAILS, it cannot even complete.
To Reproduce
Detailed steps at
Expected behavior
Sparse can still sparse.
Impact
Broken SOF CI
Logs and console output
Environment (please complete the following information):
Github runner Ubuntu 22.04 LTS
Zephyr CI image with Zephyr SDK + https://github.com/marc-hb/sparse/commit/3848a76ba49f336
zephyr commit 341590545ac8 and SOF commit 75337b41eb51)
Additional context
These two workarounds were tested successfully:
-
git revert f0daf904bb0202c9247
-
CONFIG_MINIMAL_LIBC=y as in
~/SOF/sof/scripts/xtensa-build-zephyr.py -p mtl --cmake-args=-DZEPHYR_SCA_VARIANT=sparse --cmake-args=-DCONFIG_LOG_USE_VLA=n --cmake-args=-DCONFIG_MINIMAL_LIBC=y
About this issue
- Original URL
- State: closed
- Created 9 months ago
- Comments: 18
Commits related to this issue
- app/prj.conf: disable PICOLIBC with CONFIG_MINIMAL_LIBC=y Starting from Zephyr commit f0daf904bb02, CONFIG_PICOLIBC is on by default. PICOLIBC does not seem compatible with sparse yet: https://githu... — committed to marc-hb/sof by marc-hb 9 months ago
- app/prj.conf: disable PICOLIBC with CONFIG_MINIMAL_LIBC=y Starting from Zephyr commit f0daf904bb02, CONFIG_PICOLIBC is on by default. PICOLIBC does not seem compatible with sparse yet: https://githu... — committed to thesofproject/sof by marc-hb 9 months ago
- .github/sparse-zephyr: add -DCONFIG_MINIMAL_LIBC to avoid picolibc Add a sparse-specific workaround for the incompatibility with picolibc (the new Zephyr default) https://github.com/zephyrproject-rto... — committed to marc-hb/sof by marc-hb 9 months ago
- .github/sparse-zephyr: add -DCONFIG_MINIMAL_LIBC to avoid picolibc Add a sparse-specific workaround for the incompatibility with picolibc (the new Zephyr default) https://github.com/zephyrproject-rto... — committed to thesofproject/sof by marc-hb 9 months ago
It works with newlib nano because newlib nano uses almost identical headers, so sparse ends up using the regular newlib headers. With picolibc, we really need the picolibc headers instead. When using sparse and the Zephyr SDK, we could probably compute the required include path:
Great, then it sounds like there is hope. Will be on my todo list to be looked at after collab-hwm work.
I don’t think this should be closed, as it does seem to be something we should fix. Though I wonder what makes picolibc so different from newlib nano that sets
-specs=nano.specsand still works with SOF.Yup, if sparse isn’t parsing the .specs file to pull in the picolibc header path, it’s not going to work very well. If you know you’re using the Zephyr SDK, you can probably hard-code the picolibc header path for sparse to use. Otherwise, figuring out where the headers are will require digging through whatever toolchain is in use.