OE PyBOMBS

From GNU Radio
Jump to navigation Jump to search

OpenEmbedded and PyBOMBS

WIP: This page is a work-in-progress to provide details on using PyBOMBS to build and install projects using the OE SDKs.

Introduction

The goal of this work is to build ARM packages on an x86 machine in a cross-compiled environment. The results of the build on the x86 machine can be transferred to the desired ARM platform, thereby eliminating slow and sometimes impossible build tasks. The software development cycle is improved If server-grade x86 machines can offload compile tasks from the ARM targets, which are (by design) less powerful, have less RAM, and have less capable processing abilities.

Open Embedded is a tool that provides a framework that can cross compile a complete Linux file system on a "host" machine for other CPU architectures, or "targets". In this case, a pre-made Open Embedded "SDK" or "rootfs" is provided that contains the necessary packages, including GNU Radio. The rootfs is delivered in the format of a single self-extracting shell scipt (.sh). When executed, the script produces a directory structure that contains all of the compiled resources along with an environment setup file. The environment setup file is used to direct gcc away from the binaries and other files located on the host system, which are not binary compatible, and refers it to the contents of the SDK. Using the SDK and the environment setup file, the process of building new packages for an ARM platform on the x86 host is virtually the same as a native build.

Pybombs is a tool that provides a streamlined way of fetching, building, and installing packages. Pybombs can conveniently install packages and their dependencies in a single install directory structure, enhancing the ease of deployment to other platforms. Pybombs is similar to Open Embedded in that it uses recipe files that contain a dependency list, source locations, user credentials to fetch code, and a framework to include package-specific build details. Pybombs utilizes templates for packages that have similar build processes, i.e. packages that use "autotools" or "cmake". The template provides the framework, while the recipe provides a specific list of dependencies and source locations, and a means to provide special compile flags, build directory names, and other minor details that aren't necessarily common to other packages that use the template.

Open Embedded + Pybombs

If Pybombs can utilize the Open Embedded SDK, the simplicity and convenience of pybombs can be utilized when building packages for ARM platforms. Packaging the self-extracting shell script produced by Open Embedded's "bitbake", a rootfs can be deployed and built against in the same way any other package is.

Packaging the Open Embedded "SDK"

There are 3 items that need to be packaged together in order to easily assimilate the SDK into pybombs as a package. First, the self-extracting shell script, which contains the compiled sources makes up the main component of the package. Since the shell script may have an arbitrary name, decided by the Open Embedded bitbake procedure, a symlink should be created that points to the main shell script. The symlink allows the script to be executed using "oecore.sh", which points to the actual shell script file. The final component is the "toolchain" file that comes with GNU Radio, oe-sdk_cross.cmake. This file has been created to configure cmake for cross compilation.

here's how to package an OE SDK for pybombs

mkdir oecore-pkg
cp /path/to/oecore-x86_64-really-long-filename-toolchain-nodistro.sh oecore-pkg/
cp /path/to/gnuradio/cmake/Toolchains/oe-sdk_cross.make oecore-pkg/cross.cmake
cd oecore-pkg
ln -s oecore-x86_64-really-long-filename-toolchain-nodistro.sh oecore.sh
cd ..
tar -czpvf oecore-pkg.tar.gz oecore-pkg

Pybombs wants to fetch git, debian, rpm packages, or tarballs. During the fetch procedure, the oecore-pkg.tar.gz is downloaded and extracted to the `pybombs/src` directory. From here, the self-extracting shell script is executed and deployed into the target directory, where pybombs installs everything else.

Installing the OE SDK using pybombs

We want to use PyBOMBS now to install the SDK for us. The OE SDK shell script we tar'd up in the last step takes a few command-line options that we will set in the recipe file to automate things for us and reduce required user interaction. We first use the -d argument to set the directory where we will be installing the SDK, and we'll make use of the PyBOMBS $prefix variable, and we also want to use the "-y" option to say yes to any questions. When this is done, the SDK will be installed into $prefix/oecore-x86_64.

These instructions assume that you have the OE SDK shell script. You've either built it yourself using bitbake or downloaded one of the SDK's provided by GNU Radio. See our Embedded page for details of both of these methods of getting the SDK.

In addition to the SDK system's sysroot filesystem, the SDK comes with an environment setup file that has a similar name format as the oecore shell script. The recipe we show below creates for us a symlink to a standard file name that we can more easily use in any following PyBOMBS recipes. Finally, the cross.cmake file is copied from the source to the install directory. The following example PyBOMBS recipe performs all of the actions we've described here.

category: common
depends:
source: file:///home/username/open-embedded/oecore-pkg.tar.gz
inherit: empty

configure {
}

make {
  ./oecore.sh -d $prefix/oecore-x86_64/ -y
  ./patch.sh $prefix
  cp cross.cmake $prefix/oecore-x86_64/
  cd $prefix/oecore-x86_64/
  ln -s $(ls environment*) oecore-environment
}

install {
}

uninstall {
  rm -rf $prefix/oecore-x86_64/
}

Making a Template File for "arm-cmake"

A few modifications are made to the standard cmake template in order to cross-compile against the OE SDK. The main differences are the symlinks created in the install directory, sourcing the environment file in oecore-x86_64, and providing the toolchain file path in the "-DCMAKE_TOOLCHAIN_FILE" variable. The uninstall process includes the removal of the symlink.

The symlink must be created in order to allow recipes for packages to build with both regular cmake and oe-cmake. The install and source directories both have their names derived from the recipe file for each package. To illustrate the importance of this step, we'll use UHD as an example. If the uhd.lwr recipe file exists in the PyBOMBS recipes directory and refers to the cmake template, building it will install everything into the $prefix/uhd directory and place its source in src/uhd. Since the OE build process requires the oe-cmake.lwt template to build against the OE SDK, a separate recipe file must be made, i.e. oe-uhd.lwr, which inherits oe-cmake instead of cmake. During the build, PyBOMBS fetches source into src/oe-uhd and installs everything into $prefix/oe-uhd. However, when another package tries to build against uhd, it may expect to find it in $prefix/uhd. To solve this, a symlink is created to provide seamless compatibility with other build processes. There is no requirement for other build systems to inspect the contents of their referred dependency directories. The addition of the symlinks presents the most compatible known solution.

While we can build both uhd and oe-uhd, we'll have a problem with the installation into $prefix. It's best, then, if we have PyBOMBS work in a prefix that's completely separate from our non-OE-based installations. This is easily done by editing the config.dat file and changing the "prefix" line to point to your OE-based build directory.

What follows is the OE template example, oe-arm.lwt, that we would put into the templates directory in PyBOMBS.

configuredir: build
makedir: build
installdir: build
depends: cmake

var config_opt = ""

configure {
  BUILD_DIR=`pwd`
  cd $BUILD_DIR/../../
  ln -s arm-$basename $basename
  cd $BUILD_DIR
  source $prefix/oecore-x86_64/environment
  cmake .. -DCMAKE_INSTALL_PREFIX=$prefix -DCMAKE_BUILD_TYPE=$cmakebuildtype -DBUILD_RPATH=TRUE \
    -DCMAKE_CXX_FLAGS=-fpermissive -DCMAKE_TOOLCHAIN_FILE=$prefix/oecore-x86_64/cross.cmake \
    $config_opt
}
make {
    make -j $makewidth -l $makewidth
}

install {
    make install
}

uninstall {
        make uninstall
        unlink ../../$basename
}

Recipe Files

With the oe-cmake template, creating a new recipe is very simple. Below is a demonstration of a recipe for a dummy program "program", oe-program.lwr, which depends on oe-dep1 and oe-dep2. `python pybombs install program` will build oe-dep1 and oe-dep2 according to their recipes, install them, checkout program from the specified git repository, switch to the arm branch, build program, install it to "$prefix/arm-program" and insert a symlink "$prefix/program -> $prefix/arm-program" for compatibility with other build systems.

depends: arm-dep1 arm-dep2
category: common
source: git://$gitbase1:/program.git
gitbranch: arm
inherit: oe-cmake

var basename = "program"

Packages Already Provided by GNU Radio's OE Distributions

When using the OE distros provided by GNU Radio, many of the standard dependencies are already part of the system, both in the rootfs and the SDK. There is no need to duplicate all of these as OE recipes in Python, so we can remove them as dependencies when building our oe-<package>.lwr.

Just a quick, short list inspired by the UHD and GNU Radio recipes. This means that we can create oe-uhd.lwr and oe-gnuradio.lwr that require no PyBOMBS dependencies. We can make oe-gnuradio depend on oe-uhd, though, to make sure both are always tracking.

  • git
  • cmake
  • make
  • gcc
  • swig
  • python
  • boost
  • gsl
  • fftw
  • cppunit
  • libusb
  • cheetah
  • numpy
  • alsa
  • wxpython
  • lxml
  • pygtk
  • pycairo
  • pyqt4
  • pyqwt5
  • uhd
  • ice

Conclusion

With the new oe-cmake template, oecore-sdk.lwr recipe, and oesdk-pkg, a PyBOMBS user can build ARM packages in a cross-compile environment. Cross-compilation for ARM enables streamlined software development by avoiding the native build process on memory and CPU resource-constrained ARM devices. The PyBOMBS user can also perform builds without having to know about the underlying structure of the build processes, and can use the familiar PyBOMBS commands and procedures to build packages. In essence, the cross-compilation aspect has been abstracted by the combination of PyBOMBS and the OE SDK.