Skip to content

Compiling on Ubuntu 20.04 gcc 9 armhf

Steven A White edited this page Jun 2, 2022 · 1 revision

Warning

Due to the specification of the ARM embedded application binary interface (EABI). ARM is unable to allow an exported template specification to appear in more then one compilation unit. You can find more information at [1][2]

To work around this issue you will need to pass theadditional DEFINE of XSD_NO_EXPORT to all compilation units in the BioGears code base. We have patched BioGears to do this automatically if the value of CMAKE_SYSTEM_PROCESSOR is armv7-a. If you are targeting another arm processor format in your CMAKE_TOOLCHAIN_FILE you will need to set the value of CMAKE_C_FLAGS and CMAKE_CXX_FLAGS manually to ensure that XSD_NO_EXPORT is defined. or at the end of your compilation you will see a message like the following.

IntegerList.o:(.data.rel.ro+0x1c): multiple definition of `typeinfo for
xsd::cxx::tree::simple_type<char, xsd::cxx::tree::type>'
DoubleList.o:(.data.rel.ro+0x1c): first defined here
IntegerList.o:(.rodata+0x40): multiple definition of `typeinfo name for
xsd::cxx::tree::simple_type<char, xsd::cxx::tree::type>'
DoubleList.o:(.rodata+0x40): first defined here
collect2: error: ld returned 1 exit status
Makefile:32: recipe for target 'libbiogears_cdm.so' failed
make: *** [libbiogears_cdm.so] Error 1

System Dependencies

These instructions depend on having completed the x86_64 dependency list.

package
build-essential
g++-arm-linux-gnuabihf
  sudo apt-get install g++-arm-linux-gnueabihf

Cross compiling in CMake

Cross compiling in CMake is fairly simple. Most problems can be solved by making a short toolchain file which is handed to cmake on the first pass of configuration. If you forget this toolchain file you will need to delete the build directory and start from over. The contents of our example toolchain file are below

arm-linux-gnueabihf-gcc-9

# the name of the target operating system
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_GENERATOR "GNU Makefiles")
set(CMAKE_SYSTEM_PROCESSOR "armv7-a")
# which compilers to use for C and C++
set(CMAKE_C_COMPILER arm-linux-gnueabihf-gcc-9)
set(CMAKE_C_FLAGS "-march=armv7-a -mfpu=neon-vfpv4  --std=c11 -fPIC")
set(CMAKE_CXX_COMPILER arm-linux-gnueabihf-g++-7)
set(CMAKE_CXX_FLAGS "-march=armv7-a -mfpu=neon-vfpv4  --std=c++14 -fPIC")

set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)

Based on your arm target you may need to modify the march flags. Toolchains files are very specific to your exact development board, sysroot, and cross compilers. Feel free to adjust yours accordingly. This example targets a ARMv8-A bord like a Cortex-A57

for all examples bellow we will assume you have named your toolchain file arm-linux-gnueabihf-gcc-9 and placed in in /opt/biogears/toolchains/. You can however place this file anywhere you want named anything you prefer, you will simply need to adjust your cmake commands accordingly.

External Libraries

Each entry in this list is written as though you are starting from your home directory or a common development folder. for instance /opt/biogears/sources/

Building eigen

wget https://gitlab.com/libeigen/eigen/-/archive/3.3.4/eigen-3.3.4.tar.gz
tar -xf 3.3.4.tar.gz
cd eigen-eigen-5a0156e40feb
mkdir build-arm ; cd build-arm
cmake -G Ninja -DCMAKE_TOOLCHAIN_FILE=/opt/biogears/toolchains/arm-linux-gnueabihf-gcc-9 \
               -DCMAKE_INSTALL_PREFIX=/opt/biogears/external_arm \
                ..
ninja install

Building xerces-c

wget https://archive.apache.org/dist/xerces/c/3/sources/xerces-c-3.2.1.tar.bz2
tar -xf xerces-c-3.2.1.tar.gz
cd xerces-c-3.2.1
mkdir build-arm ; cd build-arm
cmake -G Ninja -DCMAKE_TOOLCHAIN_FILE=/opt/biogears/toolchains/arm-linux-gnueabihf-gcc-9 \
               -DCMAKE_INSTALL_PREFIX=/opt/biogears/external_arm \
               -DCMAKE_BUILD_TYPE=Release \
               ..
ninja install

installing xsd For XSD we need a xsd binary we can run on our host system and header files we can use on our target platform. For this reason you will install the bin dir of the xsd 4.0 build in /opt/biogears/external not /opt/biogears/external_arm. While the includes will go in the latter.

wget https://www.codesynthesis.com/download/xsd/4.0/linux-gnu/x86_64/xsd-4.0.0-x86_64-linux-gnu.tar.bz2
tar -xf xsd-4.0.0-x86_64-linux-nu.tar.bz2
cp -r bin /opt/biogears/external
cp -r libxsd/xsd /opt/biogears/external_arm/include/

Building Biogears Core

Cross Compiling Biogears is only slightly different then compiling biogears natively. Two variables control where CMake will search for deps. IN our guide for compiling natively to ubuntu 20.04 we assumed you installed your deps /opt/biogears/external so we will assume this is also where the xsd compiler is located for this build.

Variable Purpose
CMAKE_PREFIX_PATH Search for programs that can run on the host machine
CMAKE_FIND_ROOT_PATH Search for libraries and headers for the target machine
CMAKE_CXX_FLAGS Sets extra defines needed to build biogears XSD_NO_EXPORT

both variables can accept a simi-colon delimited list of locations so if you have a sysroot you need to reference for cross compilation add it to CMAKE_FIND_ROOT_PATH or if you have other host executables to find add those paths to CMAKE_PREFIX_PATH

cd /opt/biogears/
git clone https://github.com/BioGearsEngine/core.git core
cd core
mkdir build-arm; cd build-arm
cmake -G "Ninja" -DCMAKE_BUILD_TYPE=Release \
               -DCMAKE_TOOLCHAIN_FILE=/opt/biogears/toolchains/arm-linux-gnueabihf-gcc-9 \
               -DCMAKE_INSTALL_PREFIX=/opt/biogears/usr \
               -DCMAKE_PREFIX_PATH=/opt/biogears/external \
               -DCMAKE_FIND_ROOT_PATH=/opt/biogears/external_arm \
               -DCMAKE_BUILD_TYPE=Release \
               -DCMAKE_CXX_FLAGS=-DXSD_NO_EXPORT \
               -DBiogears_BUILD_HOWTOS=OFF \
               ..
cmake --build . --config Release --target bg-cli

*If you are targeting a different ARM processor besides armv7-a with the armeabi then remember to pass to avoid the previously mentioned linker errors

-DCMAKE_C_FLAGS=-DXSD_NO_EXPORT \
-DCMAKE_CXX_FLAGS=-DXSD_NO_EXPORT