This image provides an easy-to-use container environment for building, testing, and running GNU Radio out-of-tree (OOT) modules. There are many ways in which you can use this image. For example, you can use it as the base of your OOT's dedicated container image. Alternatively, you can use it to switch easily between GNU Radio versions and development environments. Furthermore, this image is adequate for usage in continuous integration (CI) engines (e.g., Github workflows), VSCode development containers, and more. Please refer to the examples below.
The following Dockerfile illustrates how the gnuradio-oot-dev
image can serve as the base for building a dedicated image with your OOT module.
ARG tag=3.10.3-ubuntu-focal
FROM igorfreire/gnuradio-oot-dev:$tag
# List of dependencies for your GR OOT module.
ARG deps
# OOT repository URL and name:
ARG oot_url
ARG oot_name
# Install dependencies
RUN apt-get install -y $deps
# Install the OOT module
RUN git clone --recursive $oot_url && \
cd $oot_name && mkdir build && cd build/ && \
cmake .. && \
cmake --build . && \
cmake --install . && \
ldconfig && \
cd ../../ && rm -r $oot_name
Suppose the above Dockerfile is saved on a file named oot.dockerfile
. In this case, for example, to build the gr-dvbs2rx project, run:
docker build -f oot.dockerfile -t gr-dvbs2rx \
--build-arg tag=3.9.4-ubuntu-focal \
--build-arg deps="libusb-1.0-0-dev libosmosdr-dev libsndfile1-dev" \
--build-arg oot_url=https://github.com/igorauad/gr-dvbs2rx/ \
--build-arg oot_name=gr-dvbs2rx \
.
After that, you can run your OOT inside the container while accessing an SDR interface directly from the container. Just make sure to use the correct options to access the SDR interface:
- USB interfaces: use option
--privileged -v /dev/bus/usb:/dev/bus/usb
. - Network-connected interfaces: use option
--network host
.
For example, the gr-dvbs2rx
image built earlier could be executed as follows:
docker run --rm -it --privileged -v /dev/bus/usb:/dev/bus/usb --network host dvbs2rx
Besides, the above Dockerfile is just a starting point. You can modify it easily to include other dependencies and tools. For a more advanced use case, refer to the actual Dockerfile used on the gr-dvbs2rx project.
The gnuradio-oot-dev
image can be a convenient solution to run multiple GNU Radio versions in parallel on reproducible environments.
To include the GUI, you can define aliases like so:
Linux
alias docker-gui='docker run --env="DISPLAY" -v $HOME/.Xauthority:/root/.Xauthority --network=host'
OSX
alias docker-gui='docker run --env="DISPLAY=host.docker.internal:0"'
In the case of OSX, you also need to authorize the container to access the host's X server:
xhost + localhost
After that, you can launch multiple containers with different GNU Radio versions. For example, run the GR 3.8, 3.9, and 3.10 containers as follows:
docker-gui --rm -it --name gr3.8 igorfreire/gnuradio-oot-dev:3.8.2-ubuntu-bionic
docker-gui --rm -it --name gr3.9 igorfreire/gnuradio-oot-dev:3.9.4-ubuntu-focal
docker-gui --rm -it --name gr3.10 igorfreire/gnuradio-oot-dev:3.10.3-ubuntu-focal
Then, for example, launch gnuradio-companion
from each container.
It is often useful to keep the OOT sources on the host while developing, building, and installing binaries inside the container. To do so, you can extend the commands explained in the previous section by adding a bind mount option. For example, suppose you have the OOT sources in your host at $HOME/src/my-oot/
. In this case, you can run the container as follows:
docker run --rm -it \
-v $HOME/src/my-oot/:/src/my-oot/ \
igorfreire/gnuradio-oot-dev:3.10.3-ubuntu-focal
Option -v $HOME/src/my-oot/:/src/my-oot/
creates a bind-mount at /src/my-oot/
inside the container, which you can use to access the OOT files. Any changes made in this directory are automatically reflected back to the host. For example, inside the container, build the OOT as follows:
cd /src/my-oot/
mkdir -p build/
cmake ..
make
The following snippet shows an example workflow configuration for an OOT module:
name: Test
on: [push, pull_request]
env:
BUILD_TYPE: Release
jobs:
build:
runs-on: ubuntu-latest
container:
image: igorfreire/gnuradio-oot-dev:3.10.3-ubuntu-focal
env:
PYTHONPATH: ${{github.workspace}}/build/python/bindings
steps:
- uses: actions/checkout@v2
- name: Configure CMake
run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}}
- name: Build
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}}
- name: Test
run: cd ${{github.workspace}}/build && ctest -C ${{env.BUILD_TYPE}} -VV
For example, refer to the workflow used on gr-dvbs2rx.
Development inside containers is greatly simplified on VSCode by using the Remote - Containers extension. All you need to do is install the extension, create a .devcontainer/devcontainer.json
file in your project, and reopen the workspace inside the container. The devcontainer.json
file should specify the image, as follows:
{
"image": "igorfreire/gnuradio-oot-dev:tag"
}
where tag
should be replaced by one of the available tags.
Furthermore, if you would like to run GUI applications (e.g., gnuradio-companion) directly from the VSCode terminal, you can append the following to your devcontainer.json
file:
Linux
{
...
"runArgs": [
"-v $HOME/.Xauthority:/root/.Xauthority",
"--network=host"
],
"containerEnv": {
"DISPLAY": "$DISPLAY"
}
}
OSX
{
...
"containerEnv": {
"DISPLAY": "host.docker.internal:0"
}
}