3

I'm trying to compile a C++ application for a Raspberry Pi Zero using GCC 8.2.1.
I'm using this for a relatively large C++17 project that is being built using CMake, and I'm trying to cross-compile it on my x86-64 laptop.

Even with the simplest code possible, I'm not able to compile it for ARMv6:

int main() {}
$ arm-linux-gnueabihf-g++ test.cpp -static -march=armv6 -mfpu=vfp -mfloat-abi=hard

When running the file on the Pi, I get an Illegal instruction error, and readelf returns the following:

$ arm-linux-gnueabihf-readelf -A a.out
Attribute Section: aeabi
File Attributes
  Tag_CPU_name: "7-A"
  Tag_CPU_arch: v7
  Tag_CPU_arch_profile: Application
  Tag_ARM_ISA_use: Yes
  Tag_THUMB_ISA_use: Thumb-2
  Tag_FP_arch: VFPv3
  Tag_Advanced_SIMD_arch: NEONv1
  Tag_ABI_PCS_wchar_t: 4
  Tag_ABI_FP_rounding: Needed
  Tag_ABI_FP_denormal: Needed
  Tag_ABI_FP_exceptions: Needed
  Tag_ABI_FP_number_model: IEEE 754
  Tag_ABI_align_needed: 8-byte
  Tag_ABI_align_preserved: 8-byte, except leaf SP
  Tag_ABI_enum_size: int
  Tag_ABI_VFP_args: VFP registers
  Tag_CPU_unaligned_access: v6

GCC seems to ignore my architecture flags.

When simply compiling it into an object file, it seems to work just fine, but the linking stage always uses ARMv7:

$ arm-linux-gnueabihf-g++ test.cpp -static -march=armv6 -mfpu=vfp -mfloat-abi=hard -c
$ arm-linux-gnueabihf-readelf -A test.o
Attribute Section: aeabi
File Attributes
  Tag_CPU_name: "6"
  Tag_CPU_arch: v6
  Tag_ARM_ISA_use: Yes
  Tag_THUMB_ISA_use: Thumb-1
  Tag_FP_arch: VFPv2
  Tag_ABI_PCS_wchar_t: 4
  Tag_ABI_FP_denormal: Needed
  Tag_ABI_FP_exceptions: Needed
  Tag_ABI_FP_number_model: IEEE 754
  Tag_ABI_align_needed: 8-byte
  Tag_ABI_align_preserved: 8-byte, except leaf SP
  Tag_ABI_enum_size: int
  Tag_ABI_VFP_args: VFP registers
  Tag_ABI_optimization_goals: Aggressive Debug
  Tag_CPU_unaligned_access: v6

What am I doing wrong?

tttapa
  • 1,397
  • 12
  • 26

2 Answers2

2

I ended up compiling GCC from source, following this post. I didn't need all of the steps (I compiled everything using GCC 8 instead of compiling GCC 6.3 first, and I didn't edit any source files.)

I posted a Dockerfile with all build steps on GitHub.

The architecture of the executables produced is correct now, but I can't test it on target yet to check if it actually runs.

tttapa
  • 1,397
  • 12
  • 26
  • when execute: make ARCH=arm INSTALL_HDR_PATH=/opt/cross-pi-gcc/arm-linux-gnueabihf headers_install I got: /bin/sh: 1: rsync: not found Makefile:1212: recipe for target 'headers_install' failed make: *** [headers_install] Error 127 kindly advise – M.Hefny Dec 07 '20 at 19:07
  • uname -a Linux 50cf6719eda5 5.9.8-050908-generic #202011101634 SMP Wed Nov 11 00:51:04 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux – M.Hefny Dec 07 '20 at 19:07
  • 1
    @M.Hefny Sounds like you don't have rsync installed. I no longer use this approach, I use crosstool-ng, you can find all of my build scripts on GitHub: https://github.com/tttapa/RPi-Cpp-Toolchain – tttapa Dec 07 '20 at 19:11
  • yes many thanks.... I had to run apt install rsync regards – M.Hefny Dec 07 '20 at 20:33
1

By default, newer GCC versions do not create correct binaries for ARMv6. Even though you pass the correct -mcpu= flag to gcc, it will create startup code for the newer ARMv7 architecture. Running them on your RasPI Zero will cause an "Illegal Instruction" exception.

this info is mentioned here https://github.com/Pro/raspi-toolchain

M.Hefny
  • 2,677
  • 1
  • 26
  • 30