0

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
Gian Laager
  • 474
  • 4
  • 14
  • 1
    qemu-arm-static is for running Arm Linux binaries. To build those, you should use a toolchain targeting Arm Linux, ie arm-linux-gnueabihf. The arm-none-eabi toolchain builds binaries for "bare metal", which (a) are more complicated to build because you often have to provide implementations of some basic stuff that Linux would provide for you and (b) won't necessarily run under qemu-arm-static, depending on what your choices in (a) were. – Peter Maydell Apr 13 '22 at 12:40
  • Ok I thought this would be a problem, so if I'd want to emulate it I would have to provide my own implementation for the functions that have an undefined reference. – Gian Laager Apr 13 '22 at 13:09
  • I also tried to compile a main function that adds two numbers with no output and and `_exit` was missing – Gian Laager Apr 13 '22 at 13:41
  • Well, yeah, it's bare-metal: what does "exit" do ? (There are answers to that, but not necessarily any obvious default.) I'm not sure why you're not just using the right toolchain for the task. – Peter Maydell Apr 13 '22 at 19:03
  • The problem is that I'm using [this implementation](https://stackoverflow.com/a/58200261/11885927) of a constexpr counter which basically abuses the compiler to get the job done. And I'm afraid that the 'right tool chain' might behave differently then the bare metal one. – Gian Laager Apr 14 '22 at 06:55
  • 1
    None of that C++ level stuff is going to be different for arm-linux-gnueabihf vs arm-none-eabi. And if it is non-portable at that level, then you should not be using it at all in the first place, because it's going to come back to bite you really quickly. – Peter Maydell Apr 14 '22 at 10:14

0 Answers0