Skip to main content

Fixing Zephyr SDK in Debian Bullseye

On micro-controllers not capable to run a real Linux kernel, there is still the need for a comparable community effort to abstract away the different platforms. One project I find very promising is the Zephyr project which is a Linux Foundation project. Currently I am especially interested in the support for the NXP i.MXRT cross over micro-controllers.

Zephyr Logo

The project delivers cross compilation tool chains for all of the supported architectures (aarch64, arc, arm, mips, nios2, riscv64, sparc, x86_64, xtensa) which are easy to install and use. Since v0.11.3 of ths SDK there is a hidden dependency in the cross-debugger which require python. Those binaries are linked explicitly against python3.8 but Debian Bullseye only offers python3.7 or python3.9. The problem can be seen in this example trying to debug an example Zephyr application in Debian Bullseye:

dzu@krikkit:/opt/src/git/zephyrproject/zephyr (master)$ west debug -d build/lvgl -r pyocd
-- west debug: rebuilding
[0/1] cd /opt/src/git/zephyrproject/zephyr/build/lvgl/zephyr/cmake/flash && /usr/bin/cmake -E echo

-- west debug: using runner pyocd
-- runners.pyocd: pyOCD GDB server running on port 3333
/opt/zephyr-sdk-0.12.2/arm-zephyr-eabi/bin/arm-zephyr-eabi-gdb: error while loading shared libraries: libpython3.8.so.1.0: cannot open shared object file: No such file or directory
FATAL ERROR: command exited with status 127: /opt/zephyr-sdk-0.12.2/arm-zephyr-eabi/bin/arm-zephyr-eabi-gdb build/lvgl/zephyr/zephyr.elf -ex 'target remote :3333' -ex 'monitor halt' -ex 'monitor reset' -ex load
dzu@krikkit:/opt/src/git/zephyrproject/zephyr (master)$

bullseye-backports

So in order to fix this, we need the python3.8 Debian packages, but the packages are clearly not in the standard repositories:

dzu@krikkit:~$ apt search python3.8
Sorting... Done
Full Text Search... Done
dzu@krikkit:~$

Usually such things should eventually show up in the Debian Bullseye-backports repository:

dzu@krikkit:~$ cat /etc/apt/sources.list.d/bullseye-backports.list
deb http://deb.debian.org/debian bullseye-backports main contrib non-free
dzu@krikkit:~$

But as of today (2021-01-31) they did not turn up there yet.

Building your own backports

Searching for a solution I came across a nice project that encapsulates the build process in a docker container. Just clone the git repository, change to the directory and build the container like this:

dzu@krikkit:/opt/src/git/python3.8-backport (master)$ docker build \
 --target native --build-arg DEV=yes -t p3.8-bpo .

This will build the Debian packages and took me around 2 hours on my 4 core AMD Ryzen.

Copy them out of the container

When the build was successful, we can simply copy out the packages from the container. To use docker cp we need to create a container from the result of the previous step:

dzu@krikkit:/opt/src/git/python3.8-backport (master)$ CID=$(docker create p3.8-bpo)
dzu@krikkit:/opt/src/git/python3.8-backport (master)$ docker cp ${CID}:/usr/local/src/python-source/debs /tmp
dzu@krikkit:/opt/src/git/python3.8-backport (master)$ ls /tmp/debs/
idle-python3.8_3.8.7-1~bpo10+1_all.deb          python3.8_3.8.7-1~bpo10+1_amd64.deb
libpython3.8_3.8.7-1~bpo10+1_amd64.deb          python3.8-dbg_3.8.7-1~bpo10+1_amd64.deb
libpython3.8-dbg_3.8.7-1~bpo10+1_amd64.deb      python3.8-dev_3.8.7-1~bpo10+1_amd64.deb
libpython3.8-dev_3.8.7-1~bpo10+1_amd64.deb      python3.8-doc_3.8.7-1~bpo10+1_all.deb
libpython3.8-minimal_3.8.7-1~bpo10+1_amd64.deb  python3.8-examples_3.8.7-1~bpo10+1_all.deb
libpython3.8-stdlib_3.8.7-1~bpo10+1_amd64.deb   python3.8-minimal_3.8.7-1~bpo10+1_amd64.deb
libpython3.8-testsuite_3.8.7-1~bpo10+1_all.deb  python3.8-venv_3.8.7-1~bpo10+1_amd64.deb
dzu@krikkit:/opt/src/git/python3.8-backport (master)$ docker rm ${CID}
1e306ab790409f0c3bde41277815f2092641c3ed128f08ef4fa472a28e3ea0dd
dzu@krikkit:/opt/src/git/python3.8-backport (master)$

It is then enough to install these three packages from the output directory:

dzu@krikkit:~$ cd /tmp/debs/
dzu@krikkit:/tmp/debs$ sudo dpkg -i \
  libpython3.8_3.8.7-1~bpo10+1_amd64.deb \
  libpython3.8-minimal_3.8.7-1~bpo10+1_amd64.deb \
  libpython3.8-stdlib_3.8.7-1~bpo10+1_amd64.deb
Selecting previously unselected package libpython3.8:amd64.
(Reading database ... 382515 files and directories currently installed.)
Preparing to unpack libpython3.8_3.8.7-1~bpo10+1_amd64.deb ...
Unpacking libpython3.8:amd64 (3.8.7-1~bpo10+1) ...
Selecting previously unselected package libpython3.8-minimal:amd64.
Preparing to unpack libpython3.8-minimal_3.8.7-1~bpo10+1_amd64.deb ...
Unpacking libpython3.8-minimal:amd64 (3.8.7-1~bpo10+1) ...
Selecting previously unselected package libpython3.8-stdlib:amd64.
Preparing to unpack libpython3.8-stdlib_3.8.7-1~bpo10+1_amd64.deb ...
Unpacking libpython3.8-stdlib:amd64 (3.8.7-1~bpo10+1) ...
Setting up libpython3.8-minimal:amd64 (3.8.7-1~bpo10+1) ...
Setting up libpython3.8-stdlib:amd64 (3.8.7-1~bpo10+1) ...
Setting up libpython3.8:amd64 (3.8.7-1~bpo10+1) ...
Processing triggers for libc-bin (2.31-9) ...

dzu@krikkit:/tmp/debs$
Zephyr SDK fixed!

With these packages in place, the cross gdb now also runs correctly and with the text user interface enabled (tui mode) this is a screenshot of a debug session:

cross gdb
2021-02-01 Update

Switched the section on copying out the results to docker cp once I figured out how to make it work.

2021-02-16 Update

Added information that the Python 3.8 dependency was added in v0.11.3 of the SDK.

2022-10-21 Update

Zephyr SDK 0.15.0 added a separate gdb executable gdb-py linked against Python 3.8. The gdb binary is the binary previously available as gdb-no-py without Python support and thus does not need any libpython3.8 libraries from the host.

This means that you can probably work around the whole problem by simply using gdb-no-py instead of gdb on older Zephyr SDK installations. Unless you need Python support in gdb, of course.

To select a specific binary, add --gdb <path> to the west debug invocation.

Inside gdb you can check if Python support is enabled by executing show configuration. This is the output from the debugger launched by default in v0.15.1:

(gdb) show configuration
This GDB was configured as follows:
   configure --host=x86_64-build_pc-linux-gnu --target=arm-zephyr-eabi
             --with-auto-load-dir=$debugdir:$datadir/auto-load
             --with-auto-load-safe-path=$debugdir:$datadir/auto-load
             --with-expat
             --with-gdb-datadir=/__w/_temp/workspace/output/arm-zephyr-eabi/share/gdb (relocatable)
             --with-jit-reader-dir=/__w/_temp/workspace/output/arm-zephyr-eabi/lib/gdb (relocatable)
             --without-libunwind-ia64
             --without-lzma
             --without-babeltrace
             --without-intel-pt
             --with-mpfr
             --without-xxhash
             --without-python
             --without-python-libdir
             --without-debuginfod
             --without-guile
             --disable-source-highlight
             --with-separate-debug-dir=/__w/_temp/workspace/output/arm-zephyr-eabi/lib/debug (relocatable)
             --with-sysroot=/__w/_temp/workspace/output/arm-zephyr-eabi/arm-zephyr-eabi (relocatable)

("Relocatable" means the directory can be moved with the GDB installation
tree, and GDB will still find it.)
(gdb)

Comments

Comments powered by Disqus