Qemu - Meson
Now its time to marry qemu and meson.build
Example project
Of course I did an examplem project for this:
STM32-L0-qemu-example
I did this with the B-L072Z-LRWAN1 development board from ST. But it will also work with the STM32F3Discovery board.

folder structure
├── STM32-ldscripts      # uC dependend linker files
|   ├──...
├── STM32-startup        # uC dependend startup files
|   ├──...
├── STM32Cube-F0-meson   # official ST HAL / CMIS Driver
|   ├──...
├── tests                # qemu test files
|   ├──...
├── lib                  # arm_semihosting files
|   ├──...
├── .gdbinit             # init file for gdb
├── .gitignore
├── .gitmodules
├── meson.build          # meson configuration file
├── cross_file.build     # meson cross-compilation configuration file
├── main.c
├── main.h
├── LICENSE
├── README.md
we now have a lib folder with the arm_semihosting files inside. there is also a meson.build file inside which get called by the root meson.build file to import the arm_semihosting sources.
Also we have a tests folder which contains the qemu test files. And also e meson.build file
we can configure meson to call the tests automatically.
ninja test
firstly we have to add a new line to the cross_file.build file
cross_file.build
exe_wrapper = 'qemu-system-arm'
but that will fail. I will explain that later.
after that we can define test executables in the meson.build file
tests/meson.build
#==============================================================================#
# define tests : minimal test that has to be succesfull
test1 = executable(
          'test1.elf',
          [qemu_startupfile, 'helloWorld.c',  stm32cube_srcs, srcs] ,
          c_args              : [c_args],
          link_args           : [qemu_linkargs, '-Wl,--gc-sections'],
          dependencies        : link_deps,
          include_directories : [incdirs, stm32cube_incdirs])
test(  'helloWorld',
       test1,
       args : qemu_args,
       timeout: 2)
The executable is defined the same as the main.elf executable.
We have to add a different startup file, because the qemu machine defines another memory-layout as the STM chips.
thats why we have to define a specific qemu_startupfile and qemu_linksargs.
For more information look at this link tests/meson.build
And more interestingly we take a look to the test function:
We have to define a name, an executable and the arguments which are getting called with the exe_wrapper defined application.
then we can just type ninja tests in the build directory and meson-build will compile the normal executable and all test executables.
After that it will run each test and shows a short summary (how much passed, how much failed)
problems
This example will not work…
Because meson will first call the exe_wrapper concat the executable file name and after that the qemu_args.
But we need to define the -kernel flag before the executable file name. Otherwise it will not work!
Thats why we need a bash-script, which calls the -kernel parameter before the exe-filename.
meson_exe_wrapper.sh
#!/bin/sh
if [ $# = 1 ]; then
  qemu-system-arm -version #at meson startup it makes a testrun with exact 1 parameter
  exit $?
else
  qemu-system-arm -kernel "$@"
  exit $?
fi
this bash script need to be stored in a class path where meson-build can find it and call it.
A meson specialty : At meson build creation it will check all tools if there are found. It calls every tool and if this call failes, the tool is not found and probably force a crash.
When we call qemu-system-arm call the wrong way it will return a false and lead meson to fail also…
thats why we need ther first qemu-system-arm -version line.
and the second call qemu-system-arm -kernel "$@" does what we intended to do.
Thats why we actualy do not call qemu-system-arm directly in the cross_file.build file.
But instead call the bash script
cross_file.build
exe_wrapper = 'meson_exe_wrapper.sh'
integration
We can now integrate the tests folder in the main build project.
We have to write a tests/meson.build file inside the tests folder and call it in the root meson.build file:
meson.build
# add tests
subdir('tests')
with ninja tests we now can use meson to build our tests, run them and creates a summary to the results.
