1
\$\begingroup\$

I am trying to port some simple c++ code to armv7e-m. I have experience compiling c++ for arm but this is my first time setting up the toolchain from scratch. Initially, I was having the following error:

enter image description here

This despite having the containing folder of cc1plus in my PATH:

~/arm-gnu-toolchain-12.2.rel1-x86_64-arm-none-eabi/bin/:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/snap/bin:~/arm-gnu-toolchain-12.2.rel1-x86_64-arm-none-eabi/libexec/gcc/arm-none-eabi/12.2.1

It's in the last one, under libexec/gcc/... I feel that I should not have had to add this path manually anyway. In any case, that didn't work... except when I ran it in gdb???

gdb --args arm-none-eabi-g++ -march=armv7e-m -w -c tetris.cpp

start

c

normal exit

arm-none-eabi-size tetris.o

tetris.o: ELF 32-bit LSB relocatable, ARM, EABI5 version 1 (SYSV), not stripped

My suspicion is that there's some environment variable shenanigans going on here. That doesn't make much sense though, since execvp is not the version that overwrites environ, that would be execve?

My compiler is arm-none-eabi-g++ (Arm GNU Toolchain 12.2.Rel1 (Build arm-12.24)) 12.2.1 20221205 which I got already built for Linux off of Arm's website. I'm running Ubuntu 22.04.2.

EDIT: I have narrowed down what's going on.

The following works:

~/arm-gnu-toolchain-12.2.rel1-x86_64-arm-none-eabi/bin/arm-none-eabi-g++ -c -g3 -Og -ffunction-sections -march=armv7e-m -mcpu=cortex-m4 -o tetris.o src/tetris.cpp

This does not:

arm-none-eabi-g++ -c -g3 -Og -ffunction-sections -march=armv7e-m -mcpu=cortex-m4 -o tetris.o src/tetris.cpp

PATH is set in both cases to point to both g++ and cc1plus. I have made sure there is no other arm-none-eabi-g++ on my system. Curiously, which arm-none-eabi-g++ shows nothing. Is it possible something's gone extremely wrong with my linux install?

\$\endgroup\$

1 Answer 1

2
\$\begingroup\$

No, compiler backends are not supposed to be on the path, because their names are not unique, and the frontend is not supposed to use the path for this.

Instead, the frontend is supposed to find the backends. It uses two ways for that: its own path, which it knows only from the command line, and a compiled-in value that is derived from the --prefix parameter the compiler was configured with.

The former is why using the full path works: the backend can be found relative to ~/arm-gnu-toolchain-12.2.rel1-x86_64-arm-none-eabi/bin/arm-none-eabi-g++.

If you do a "traditional" installation, you'd use the default --prefix setting of /usr/local for the compiler, then either use DESTDIR (more reliable) or override prefix during installation (works with most GNU packages) to redirect it to a subtree, and then use a symlink farming tool like stow to make the compiler available system-wide.

To install into a directory below your home like you want, you'd need to pass --prefix=~/arm-gnu-toolchain-12.2.rel1-x86_64-arm-none-eabi when configuring the compiler.

\$\endgroup\$
2
  • \$\begingroup\$ Could it working when run from gdb be explained by gdb calling it with a full path internally? \$\endgroup\$ Mar 11, 2023 at 20:55
  • 1
    \$\begingroup\$ Yes, that is precisely what happens. I just checked with another program, and argv[0] has the full path when run under gdb. \$\endgroup\$ Mar 11, 2023 at 20:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.