Build googletest for Baremetal targets (stm32)

googletest(gtest) is a test framework famous for its powerful assertions and easy setup. After switching from boost-test to gtest several years ago, I have been using gtest a lot at work and in personal projects. It is super easy to set up a new test and add test suites/cases.

To make the code unit-testable, when working on embedded software, usually the code is separated into the-code-that-runs-anywhere and the-code-that-runs-only-on-this-hardware. The portable part (usually command parsing, state machines that are hardware unrelated) is put into their own module and is tested by unit test on desktop. It then is linked together with the hardware-specific setup/drivers for the target which usually runs FreeRTOS even baremetal.

Fortunately istarc has created a template project which has gtest integrated for baremetal targets on stm32 processors. You can choose the easy way of using this template or do the hard way by integrating gtest into your existing makefile.

The Easy Way – Use istarc’s stm32 template project

If you do not mind the dependency on mbed, just go to https://github.com/istarc/stm32 and follow the instructions to get all the dependencies.

Then

# Create a folder outside stm32

mkdir stm32-gtest & cd stm32-gtest

# Create project

${ISTARC_STM32_DIR}/mbed-project-wizard/gen-stm32f407-GCC-project.sh mbed-none-shgtest

# Configure gtest

make test-deps

# Make unit test

make test

Easy, isn’t it?

Unfortunately, however, this template project has dependencies to mbed SDK. So if you already have a project setup, you probably just want to integrate gtest into the existing project instead of making a new one. Then you need to read on –

The Slightly Harder Way – Integrate Gtest into your own project

Patch gtest by one line

Firstly you need to patch googletest by ONE LINE to support baremetal platforms.

gtest-diff

(The patch can also be found at https://github.com/clarkli86/googletest/commit/b0d72ca81f4acf80be27f133e5eace346a7128d7)

Configure and build gtest

Usually people use the fused-src of gtest because it does not require building gtest. But to support baremetal targets, gtest really needs to be configured properly

autoreconf -fvi
# Change cpu and mpu setings to suit your platform
./configure --disable-shared --without-pthreads --disable-libtool-lock --prefix=/home/clark/googletest --exec-prefix=/home/clark/googletest --host=arm-none-eabi LDFLAGS="-mcpu=cortex-m4 -mthumb -mfloat-abi=soft -mthumb-interwork  --specs=nosys.specs " CFLAGS="-mcpu=cortex-m4 -mthumb -mfloat-abi=soft -mthumb-interwork -Iinc -DGTEST_HAS_POSIX_RE=0 -DGTEST_HAS_PTHREAD=0 -DGTEST_HAS_DEATH_TEST=0 -DGTEST_HAS_STREAM_REDIRECTION=0 -DGTEST_OS_NONE -std=c99 -Os" CXXFLAGS="-mcpu=cortex-m4 -mthumb -mfloat-abi=soft -mthumb-interwork -Iinc -DGTEST_HAS_POSIX_RE=0 -DGTEST_HAS_PTHREAD=0 -DGTEST_HAS_DEATH_TEST=0 -DGTEST_HAS_STREAM_REDIRECTION=0 -DGTEST_OS_NONE -std=gnu++11 -Os -D_POSIX_PATH_MAX=255"
make & make install-libLTLIBRARIES

After this, libgtest.la should have been installed at the location specified by PREFIX. Now just link to it in your main project!

Possible Issues

  • gtest does require stdlib, so make sure you do not have -nostdlib in your linker flags.

 

References

  1. https://istarc.wordpress.com/2015/01/06/stm32f4-unit-testing/

Leave a comment