1

I'm working on learning how to use a cross-platform compiler on my Windows machine with C++ and having a problem. I've tried all I could without any success. Any help will be greatly appreciated. I have installed CYGWIN64 and gcc-arm-none-eabi-10-2020-q4-major on my Windows machine.

My Code:

#include <iostream>
int main()
{
    std::cout << "Hello World!\n";
}

Error Message:

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

c:/cross gcc/gnu arm embedded toolchain/10 2020-q4-major/bin/../lib
/gcc/arm-none-eabi/10.2.1/../../../../arm-none-eabi/bin/ld.exe: c:/cross 
gcc/gnu arm embedded toolchain/10 2020-q4-major/bin/../lib/gcc/arm-none-
eabi/10.2.1/../../../../arm-none-eabi/lib\libc.a(lib_a-exit.o): in 
function `exit': exit.c:(.text.exit+0x2c): undefined reference to `_exit'
c:/cross gcc/gnu arm embedded toolchain/10 2020-q4-major/bin/../l 
/gcc/arm-none-eabi/10.2.1/../../../../arm-none-eabi/bin/ld.exe:
C:\cygwin64\tmp\cckThWXU.o: in function `m
ain': helloworld.cpp:(.text+0x34): undefined reference to 
`std::basic_ostream<char, std::char_traits<char> >& 
std::operator<<<std::char_traits<char> >(std::basic_ostream<char, 
std::char_traits<char> >&, char const*)'
c:/cross gcc/gnu arm embedded toolchain/10 2020-q4-major/bin/../lib
/gcc/arm-none-eabi/10.2.1/../../../../arm-none-eabi/bin/ld.exe:   
helloworld.cpp:(.text+0x50): undefined reference to `std::cout'
c:/cross gcc/gnu arm embedded toolchain/10 2020-q4-major/bin/../l/gcc
/arm-none-eabi/10.2.1/../../../../arm-none-eabi/bin/ld.exe: C:\cygwin64
\tmp\cckThWXU.o: in function 
`__static_initialization_and_destruction_0(int, int)': helloworld.cpp:
(.text+0x88): undefined reference to `std::ios_base::Init::Init()'
c:/cross gcc/gnu arm embedded toolchain/10 2020-q4-major/bin/../lib
/gcc/arm-none-eabi/10.2.1/../../../../arm-none-eabi/bin/ld.exe: 
helloworld.cpp:(.text+0xb8): undefined reference to 
`std::ios_base::Init::~Init()'
c:/cross gcc/gnu arm embedded toolchain/10 2020-q4-major/bin/../lib
/gcc/arm-none-eabi/10.2.1/../../../../arm-none-eabi/bin/ld.exe: c:/cross 
gcc/gnu arm embedded toolchain/10 2020-q4-major/bin/../lib/gcc/arm-none-
eabi/10.2.1/../../../../arm-none-eabi/lib\libc.a(lib_a-abort.o): in 
function `abort': abort.c:(.text.abort+0x10): undefined reference to 
`_exit'
c:/cross gcc/gnu arm embedded toolchain/10 2020-q4-major/bin/../lib
/gcc/arm-none-eabi/10.2.1/../../../../arm-none-eabi/bin/ld.exe: c:/cross 
gcc/gnu arm embedded toolchain/10 2020-q4-major/bin/../lib/gcc/arm-none-
eabi/10.2.1/../../../../arm-none-eabi/lib\libc.a(lib_a-signalr.o): in 
function `_kill_r': signalr.c:(.text._kill_r+0x1c): undefined reference 
to `_kill'
c:/cross gcc/gnu arm embedded toolchain/10 2020-q4-major/bin/../lib
/gcc/arm-none-eabi/10.2.1/../../../../arm-none-eabi/bin/ld.exe: c:/cross 
gcc/gnu arm embedded toolchain/10 2020-q4-major/bin/../lib/gcc/arm-none-
eabi/10.2.1/../../../../arm-none-eabi/lib\libc.a(lib_a-signalr.o): in 
function `_getpid_r': signalr.c:(.text._getpid_r+0x4): undefined 
reference to `_getpid'
c:/cross gcc/gnu arm embedded toolchain/10 2020-q4-major/bin/../lib
/gcc/arm-none-eabi/10.2.1/../../../../arm-none-eabi/bin/ld.exe: c:/cross 
gcc/gnu arm embedded toolchain/10 2020-q4-major/bin/../lib/gcc/arm-none-
eabi/10.2.1/../../../../arm-none-eabi/lib\libc.a(lib_a-sbrkr.o): in 
function `_sbrk_r': sbrkr.c:(.text._sbrk_r+0x18): undefined reference to 

`_sbrk' collect2.exe: error: ld returned 1 exit status

Error Message

Anton Krug
  • 1,555
  • 2
  • 19
  • 32
Toye
  • 11
  • 2
  • 1
    from where `gcc-arm-none-eabi-10-2020-q4-major` is coming for ? A link will be nice. It seems you are missing the C libraries for ARM. Please show the command line used to invoke the cross-compiler. – matzeri May 17 '21 at 04:53
  • I downloaded gcc-arm-none-eabi-10-2020-q4-major from this site: https://developer.arm.com/-/media/Files/downloads/gnu-rm/9-2020q2/gcc-arm-none-eabi-9-2020-q2-update-win32.exe?revision=50c95fb2-67ca-4df7-929b-55396266b4a1&la=en&hash=DE1CD6E7A15046FD1ADAF828EA4FA82228E682E2. Also, I type this command from CYGWIN64 installed on my windows machine: arm-none-eabi-g++ helloworld.cpp -o helloworld – Toye May 17 '21 at 21:27

1 Answers1

0

I don't think your problem is related to cygwin or windows. You would get the same error on Linux too. BTW if you have Windows 10 and don't mind Hyper-V then you could theoretically use Windows subsystem for Linux and use Linux toolchains on your project (even from within a window).

It's more about the embedded nature of the compilation, on x86 we assume that we have an operating system, which provided syscalls, has booted up and initialized memories and peripherals, which has a console/stdout available for applications. While things in bare-metal are very different, where you have to do a lot before your main function can execute code. You are using Arm compiler, it doesn't know what board you are using, what memory map it will have, what peripherals it will include. What cout is expected to do? Output on UART (what baud rate, and which UART, if there are multiple of them), output on LCD (what LCD, with what driver, how it's connected, SPI or other means, what are these settings for that LCD)... So that's why a lot of embedded projects do 'blinky' as their hello world as blinking some LED or toggle values on some GPIO port are in general easier to test, easier to implement and are specific, we expect some port or LED to go high and low, while with cout it could mean anything and some targets might not even have means to make cout work at all (no UART, no SPI to connect LCD, no semihosting).

With iostream and embedded devices it can mean a so many things and using it like that will never work. Vendors usually provide HAL for their devices usually bundled with their toolchain (or IDE) which has stubs to initialise the device and implement syscalls such as _open, _write, _close etc... which then calls like iostream can use to open the 'file' which in this case could be implemented to open UART and each 'printf' would use putc and that would use write, which their HAL implements.

I would recommend instead using some vendor IDE (depending what target boards you intend), I can think at least of a few of them, which bundle Arm toolchain and support Windows and Linux so your cross-platform works. I'm not going to name them as I want to stay unbiased (and I work for one vendor), but they are easy to google and doesn't matter if I name some when you probably want target something specific.

If you want make code that is transferable between targets, then I would recommend starting without that constrain and get going with one vendor and get used to what the HAL/startup code does. And maybe then I would wrappers and do some abstraction, and experiment with some other vendors to get the feel what their HAL will do.

And if having so generic code, then it will not work just like that out of the box. You would need some weakly linked implementations of function like putchar so then for each vendor they could implement that function just to call their HAL. In essence doing:

<some application> -> <your library> -> <generic HAL call> -> <vendor specific HAL call>

For more info here is a bit about weak: How to make weak linking work with GCC?

Look for example for this cross target printf implementation, each user has to implement the _putchar as he can't know what, how and where the printf will be used.

https://github.com/mpaland/printf

Probably you shouldn't be making a multi-target application, but a generic pluggable library, so users could add it to their applications instead of using yours. As yours will not work in one shape no matter how generic you try. Each vendor has its own startup code, HAL, linker scripts, and a way to organize the project to work in their ecosystem. There is no one system that would compatible with everybody, so if you want to be portable, you have to allow users to use whatever their vendor recommends and then invoke your library from within their application.

I would strongly recommend dropping the portability, make something first work on one host, one toolchain one target, get some experience and knowledge how things work and only then try to make stuff portable and generic.

Anton Krug
  • 1,555
  • 2
  • 19
  • 32