mercredi 13 avril 2022

Cross compile unit tests to arm-none-eabi and emulate in qemu

I've got code that is some what compiler dependent and I'd like to run the unit test written in gtest in qemu. I've found this tutorial that explains how to do it for arm-linux-gnueabihf all though it doesn't work any more I've made a docker container with a working version that I will show below. but when I try to compile a c++ hello world arm-none-eabi-g++ has undefiened references.

Dockerfile:

FROM ubuntu:20.04

RUN apt-get update -y --fix-missing


RUN DEBIAN_FRONTEND='noninteractive' apt-get install -y \
    libc6-armel-cross \
    libc6-dev-armel-cross \
    binutils-arm-linux-gnueabi \
    libncurses5-dev \
    build-essential \
    bison \
    flex \
    libssl-dev \
    bc \
    gcc-arm-linux-gnueabihf \
    g++-arm-linux-gnueabihf \
    qemu \
    qemu-user-static \
    qemu-system-arm

RUN apt-get install -y gcc-arm-none-eabi
RUN apt-get install -y binutils-arm-none-eabi
RUN apt-get install -y libnewlib-arm-none-eabi
RUN apt-get install -y libnewlib-nano-arm-none-eabi
RUN apt-get install -y libstdc++-arm-none-eabi-newlib

ADD ./helloArm.cpp /

helloArm.cpp:

#include <iostream>

int main()
{
    std::cout << "Hello Arm!" << std::endl;
}

To build and start the container make a folder and copy Dockerfile and helloArm.cpp.

Then goto the folder in the command line and run:

docker build -t arm-test .
docker run -it arm-test

This will bring up a bash prompt there you will have all the tools I've installed so far.

What I'd like is that arm-none-eabi will work the same as arm-linux-gnueabihf to run helloArm run the commands below in the docker container.

arm-linux-gnueabihf-g++ -o helloArm helloArm.cpp     
qemu-arm-static -L /usr/arm-linux-gnueabihf/ helloArm

Now when I try to build helloArm for arm-none-eabi with the command below

arm-none-eabi-g++ -o helloArm helloArm.cpp

I get these linking errors:

/usr/lib/gcc/arm-none-eabi/9.2.1/../../../arm-none-eabi/bin/ld: /usr/lib/gcc/arm-none-eabi/9.2.1/../../../arm-none-eabi/lib/libstdc++.a(cxx11-ios_failure.o): in function `(anonymous namespace)::__io_category_instance()':
/build/libstdc++-arm-none-eabi-7zwPZl/libstdc++-arm-none-eabi-12build2/build/libstdc++/src/c++11/../../../../src/libstdc++-v3/src/c++11/cxx11-ios_failure.cc:73: undefined reference to `__sync_synchronize'
/usr/lib/gcc/arm-none-eabi/9.2.1/../../../arm-none-eabi/bin/ld: /usr/lib/gcc/arm-none-eabi/9.2.1/../../../arm-none-eabi/lib/libstdc++.a(locale.o): in function `std::locale::_Impl::_M_install_cache(std::locale::facet const*, unsigned int)':
/build/libstdc++-arm-none-eabi-7zwPZl/libstdc++-arm-none-eabi-12build2/build/libstdc++/src/c++98/../../../../src/libstdc++-v3/src/c++98/locale.cc:36: undefined reference to `__sync_synchronize'
/usr/lib/gcc/arm-none-eabi/9.2.1/../../../arm-none-eabi/bin/ld: /usr/lib/gcc/arm-none-eabi/9.2.1/../../../arm-none-eabi/lib/libstdc++.a(locale_init.o): in function `(anonymous namespace)::get_locale_mutex()':
/build/libstdc++-arm-none-eabi-7zwPZl/libstdc++-arm-none-eabi-12build2/build/libstdc++/src/c++98/../../../../src/libstdc++-v3/src/c++98/locale_init.cc:66: undefined reference to `__sync_synchronize'
/usr/lib/gcc/arm-none-eabi/9.2.1/../../../arm-none-eabi/bin/ld: /usr/lib/gcc/arm-none-eabi/9.2.1/../../../arm-none-eabi/lib/libc.a(lib_a-abort.o): in function `abort':
/build/newlib-CVVEyx/newlib-3.3.0/build/arm-none-eabi/newlib/libc/stdlib/../../../../../newlib/libc/stdlib/abort.c:59: undefined reference to `_exit'
/usr/lib/gcc/arm-none-eabi/9.2.1/../../../arm-none-eabi/bin/ld: /usr/lib/gcc/arm-none-eabi/9.2.1/../../../arm-none-eabi/lib/libc.a(lib_a-exit.o): in function `exit':
/build/newlib-CVVEyx/newlib-3.3.0/build/arm-none-eabi/newlib/libc/stdlib/../../../../../newlib/libc/stdlib/exit.c:64: undefined reference to `_exit'
/usr/lib/gcc/arm-none-eabi/9.2.1/../../../arm-none-eabi/bin/ld: /usr/lib/gcc/arm-none-eabi/9.2.1/../../../arm-none-eabi/lib/libc.a(lib_a-fstatr.o): in function `_fstat_r':
/build/newlib-CVVEyx/newlib-3.3.0/build/arm-none-eabi/newlib/libc/reent/../../../../../newlib/libc/reent/fstatr.c:55: undefined reference to `_fstat'
/usr/lib/gcc/arm-none-eabi/9.2.1/../../../arm-none-eabi/bin/ld: /usr/lib/gcc/arm-none-eabi/9.2.1/../../../arm-none-eabi/lib/libc.a(lib_a-openr.o): in function `_open_r':
/build/newlib-CVVEyx/newlib-3.3.0/build/arm-none-eabi/newlib/libc/reent/../../../../../newlib/libc/reent/openr.c:50: undefined reference to `_open'
/usr/lib/gcc/arm-none-eabi/9.2.1/../../../arm-none-eabi/bin/ld: /usr/lib/gcc/arm-none-eabi/9.2.1/../../../arm-none-eabi/lib/libc.a(lib_a-sbrkr.o): in function `_sbrk_r':
/build/newlib-CVVEyx/newlib-3.3.0/build/arm-none-eabi/newlib/libc/reent/../../../../../newlib/libc/reent/sbrkr.c:51: undefined reference to `_sbrk'
/usr/lib/gcc/arm-none-eabi/9.2.1/../../../arm-none-eabi/bin/ld: /usr/lib/gcc/arm-none-eabi/9.2.1/../../../arm-none-eabi/lib/libc.a(lib_a-signalr.o): in function `_kill_r':
/build/newlib-CVVEyx/newlib-3.3.0/build/arm-none-eabi/newlib/libc/reent/../../../../../newlib/libc/reent/signalr.c:53: undefined reference to `_kill'
/usr/lib/gcc/arm-none-eabi/9.2.1/../../../arm-none-eabi/bin/ld: /usr/lib/gcc/arm-none-eabi/9.2.1/../../../arm-none-eabi/lib/libc.a(lib_a-signalr.o): in function `_getpid_r':
/build/newlib-CVVEyx/newlib-3.3.0/build/arm-none-eabi/newlib/libc/reent/../../../../../newlib/libc/reent/signalr.c:83: undefined reference to `_getpid'
/usr/lib/gcc/arm-none-eabi/9.2.1/../../../arm-none-eabi/bin/ld: /usr/lib/gcc/arm-none-eabi/9.2.1/../../../arm-none-eabi/lib/libc.a(lib_a-writer.o): in function `_write_r':
/build/newlib-CVVEyx/newlib-3.3.0/build/arm-none-eabi/newlib/libc/reent/../../../../../newlib/libc/reent/writer.c:49: undefined reference to `_write'
/usr/lib/gcc/arm-none-eabi/9.2.1/../../../arm-none-eabi/bin/ld: /usr/lib/gcc/arm-none-eabi/9.2.1/../../../arm-none-eabi/lib/libc.a(lib_a-closer.o): in function `_close_r':
/build/newlib-CVVEyx/newlib-3.3.0/build/arm-none-eabi/newlib/libc/reent/../../../../../newlib/libc/reent/closer.c:47: undefined reference to `_close'
/usr/lib/gcc/arm-none-eabi/9.2.1/../../../arm-none-eabi/bin/ld: /usr/lib/gcc/arm-none-eabi/9.2.1/../../../arm-none-eabi/lib/libc.a(lib_a-isattyr.o): in function `_isatty_r':
/build/newlib-CVVEyx/newlib-3.3.0/build/arm-none-eabi/newlib/libc/reent/../../../../../newlib/libc/reent/isattyr.c:52: undefined reference to `_isatty'
/usr/lib/gcc/arm-none-eabi/9.2.1/../../../arm-none-eabi/bin/ld: /usr/lib/gcc/arm-none-eabi/9.2.1/../../../arm-none-eabi/lib/libc.a(lib_a-lseekr.o): in function `_lseek_r':
/build/newlib-CVVEyx/newlib-3.3.0/build/arm-none-eabi/newlib/libc/reent/../../../../../newlib/libc/reent/lseekr.c:49: undefined reference to `_lseek'
/usr/lib/gcc/arm-none-eabi/9.2.1/../../../arm-none-eabi/bin/ld: /usr/lib/gcc/arm-none-eabi/9.2.1/../../../arm-none-eabi/lib/libc.a(lib_a-readr.o): in function `_read_r':
/build/newlib-CVVEyx/newlib-3.3.0/build/arm-none-eabi/newlib/libc/reent/../../../../../newlib/libc/reent/readr.c:49: undefined reference to `_read'
collect2: error: ld returned 1 exit status

I would guess that some library is missing or I forgot a flag.

I haven't been able to test if qemu works with arm-none-eabi but I think the syntax should be something like this

qemu-arm-static -L /usr/lib/arm-none-eabi/ helloArm

Aucun commentaire:

Enregistrer un commentaire