Recently I’ve had to cross-compile GNU Radio for an ARM embedded system. I have decided to use Buildroot to build GNU Radio and its dependencies, since I’m fairly familiar with using Buildroot to generate embedded Linux images. Earlier this year, Jean-Michel Friedt and
Gwenhaël Goavec-Merou presented in FOSDEM their work about adding a GNU Radio package in buildroot. They gave a talk called “Never compile on the target!“.
Unfortunately, the version they used was GNU Radio 3.8, and the package hasn’t been updated to GNU Radio 3.9 yet. I wanted to use GNU Radio 3.9, so I decided to try to update the Buildroot package. After some assorted problems, I have managed to get GNU Radio 3.9 running on my ARM target. The fixes I’ve done are really horrible, so I’ve been quite tempted not to share my changes. I’ve finally decide to share this even though it’s far from perfect, because it might save someone from having to replicate this work, and because if anyone wants to do this properly and update the upstream package, this could be useful as a starting point.
The changes to the Buildroot tree are in the gr39 branch of my Github fork of Buildroot. This patch applies against the current stable release, which is the 2021.08 tag, but it could possibly apply cleanly to other versions.
These are the difficulties I’ve had to solve. First, the detection of NumPy with CMake didn’t work, even though NumPy was correctly installed to the
TARGET directories, and in fact it was possible to
import numpy in the target. I am not totally sure how this works, but from glancing at
GrPython.cmake, it seems to me that this runs the host Python and tries to import NumPy. This seems bound to give problems, because NumPy has been built for the target, and might not be present in the host. To get around this problem, I have simply modified the
CMakeLists.txt so that not finding NumPy doesn’t cause a fatal error.
A related problem is that, during the build, some
.h header files from NumPy could not be found, because the correct include path wasn’t passed to
g++. I tried without success to use
-DNUMPY_INCLUDE_DIR when running
cmake (inspired by this). Finally, I’ve decided not to spend more time and set this by hand in
After getting GNU Radio to build, I found a real oddity. The library
libgnuradio-digital.so had an undefined symbol:
gr::digital::map_bb_impl::s_map_size. This is a
static constexpr that is only used in a few places in
g++ would create a symbol for this instead of just replacing the constant value in the generated code escapes me. I’ve tried to search for some clues and understand the subtleties of
constexpr, but after finding some references to ODR-used and remembering this joke, I decided to replace the
static constexpr by a
Finally, the dynamic libraries generated by pybind11 are missing the
.so extension in the target directory. This will give import errors in Python. They need to be renamed to add the
.so extension. I haven’t included this in the patch in my gr39 branch, because I renamed them by hand. These libraries are found in
usr/lib/python3.9/site-packages/pmt in the target directory and have names ending in
_python, such as
blocks/blocks_python. They should be renamed to
blocks/blocks_python.so, etc. I haven’t investigated why this happens.
And this is it. Hopefully someone will find this post useful eventually.