0

I am attempting to compile some C code targeting the armv7-m platform with the vfpv3-d16 FPU on Ubuntu 22.04 running in WSL2. I am able to compile a simple "hello, world" program with arm-linux-gnueabihf-gcc -march=armv7 -mfpu=vfpv3-d16 without problem; however, I need the armv7-m architecture specifically as the code I am looking to compile requires the primask register that appears to be unique to the ARM M platform. When I compile with -march=armv7-m, I receive a linker error:

/usr/lib/gcc-cross/arm-linux-gnueabihf/11/../../../../arm-linux-gnueabihf/bin/ld: error: test.o: conflicting architecture profiles M/A
/usr/lib/gcc-cross/arm-linux-gnueabihf/11/../../../../arm-linux-gnueabihf/bin/ld: failed to merge target specific data of file test.o
collect2: error: ld returned 1 exit status

I've tried the steps found in this blog and this stackoverflow post, but everything I've been able to find about cross-compiling for ARM has made no mention of armv7-m specifically. I've also found this stackoverflow post that mentions a similar error, but compiling with -nostdlib or -nodefaultlibs just results in runtime errors instead, things like undefined reference to __libc_start_main.

I've been trying to compile the following file:

#include <stdio.h>

int main()
{
    printf("hello, world\n");

    return 0;
}

I've tried arm-linux-gnueabihf-gcc -mcpu=cortex-m7 test.c -o test, but despite the CPU I'm targeting having a predefined profile I get the same error about conflicting profiles.

I've tried arm-linux-gnueabihf-gcc -march=armv7-m test.c -o test, but I get an error about the target lacking an FPU and no building is done. Setting -mfloat-abi=soft results in a further error regarding a missing header gnu/stubs-soft.h. Setting -mfpu=vfpv3-d16 results in the same error about conflicting profiles.

I've been at this for two days now, and would love any sort of direction.

compiler version information:

$ arm-linux-gnueabihf-gcc -v
Using built-in specs.
COLLECT_GCC=arm-linux-gnueabihf-gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc-cross/arm-linux-gnueabihf/11/lto-wrapper
Target: arm-linux-gnueabihf
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 11.3.0-1ubuntu1~22.04.1' --with-bugurl=file:///usr/share/doc/gcc-11/README.Bugs --enable-languages=c,ada,c++,go,d,fortran,objc,obj-c++,m2 --prefix=/usr --with-gcc-major-version-only --program-suffix=-11 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-libitm --disable-libquadmath --disable-libquadmath-support --enable-plugin --enable-default-pie --with-system-zlib --enable-libphobos-checking=release --without-target-system-zlib --enable-multiarch --disable-sjlj-exceptions --with-arch=armv7-a+fp --with-float=hard --with-mode=thumb --disable-werror --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=arm-linux-gnueabihf --program-prefix=arm-linux-gnueabihf- --includedir=/usr/arm-linux-gnueabihf/include --with-build-config=bootstrap-lto-lean --enable-link-serialization=2
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 11.3.0 (Ubuntu 11.3.0-1ubuntu1~22.04.1)
kelleyr
  • 11
  • The link error is most probably due to the architecture specified in the compilation of your object module and the architecture of the libc.o that you're trying to link to. You must use a compiled runtime lib for the architecture you require, or use a compiler with library source. You're using a compiler with linux ABI, you may want to use an embedded device compiler as arm-none-aebi-gcc (see this https://stackoverflow.com/questions/5961701/arm-gcc-toolchain-as-arm-elf-or-arm-none-eabi-what-is-the-difference). The tool can be downloaded from ARM site. – Frankie_C Jul 08 '23 at 13:28
  • The simpler is to use this, even if the link is defined obsolete, https://developer.arm.com/downloads/-/gnu-rm. In this case you have to write your syscall module to make functional the memory handling and I/O of libc. – Frankie_C Jul 08 '23 at 13:29
  • An alternate answer: Try `sudo apt-get install gcc-arm-none-eabi`. You need to implement `write()'. First a question. Is the **armv7-m platform** running Linux? If no, then the compiler I suggest is better. The suggested compiler uses 'newlib'. The Linux version will use *glibc*. The OS is as important as the CPU when selecting a compiler. – artless noise Jul 09 '23 at 15:10

1 Answers1

0

armv7-m is an architecture. cortex-m3, cortex-m4, cortex-m7 ... are the products, they are the actual things you run code on. (The chip vendor, not ARM, makes a chip and buys a core and compiles it with options they have chosen for that core, including floating point).

float fun0 ( float a, float b )
{
    return(a+b);
}

arm-none-eabi-gcc -O2 -c -mcpu=cortex-m7 -mfpu=fpv5-d16 -mfloat-abi=hard so.c -o so.o
arm-none-eabi-objdump -d so.o

so.o:     file format elf32-littlearm


Disassembly of section .text:

00000000 <fun0>:
   0:   ee30 0a20   vadd.f32    s0, s0, s1
   4:   4770        bx  lr
   6:   bf00        nop

arm-none-eabi-gcc -O2 -c -mcpu=cortex-m4 -mfpu=vfpv3-d16 -mfloat-abi=hard so.c -o so.o
arm-none-eabi-objdump -d so.o

so.o:     file format elf32-littlearm


Disassembly of section .text:

00000000 <fun0>:
   0:   ee30 0a20   vadd.f32    s0, s0, s1
   4:   4770        bx  lr
   6:   bf00        nop

arm-linux-gnueabi-gcc -O2 -c -mcpu=cortex-m4 -mfpu=vfpv3-d16 -mfloat-abi=hard so.c -o so.o

etc, etc. The arm-whatever-whatever-gcc should not matter so much, of course the version of gcc has to be new enough to have known about the cortex-m4 and this fpu.

Being an MCU, should you be using arm-none-eabi instead of what you are using? You running Linux on this thing?


You are getting a linker error because you are linking in files that were not built with the same settings.

Do a readelf (arm-whatever-whatever-readelf) of each object you are linking and look at the architecture. And work through those that do not match and the resolve building them to match, or finding the one that was built to match.

arm-none-eabi-readelf -a so.o
...
File Attributes
  Tag_CPU_name: "7E-M"
  Tag_CPU_arch: v7E-M
  Tag_CPU_arch_profile: Microcontroller
  Tag_THUMB_ISA_use: Thumb-2
  Tag_FP_arch: VFPv3-D16
  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: small
  Tag_ABI_VFP_args: VFP registers
  Tag_ABI_optimization_goals: Aggressive Speed
  Tag_CPU_unaligned_access: v6

Can possibly narrow in by starting over with the linker adding one object/library at a time, hopefully it will switch from missing/unresolved blah to wrong architecture or this uses fpu and that doesn't, etc.

Your problem does not appear to be a compiler thing you are probably building those objects properly (but of course ask readelf and see what it says).

halfer
  • 19,824
  • 17
  • 99
  • 186
old_timer
  • 69,149
  • 8
  • 89
  • 168
  • Now all the other stuff you build and link into this can cause issues with the linker. particularly gcclib and whatever C library if any (why would you use a C library on an mcu of course is the next natural question if you run into library problems). – old_timer Jul 07 '23 at 21:02
  • also remember to enable the coprocessor, otherwise it will hang on the float instructions. – old_timer Jul 07 '23 at 21:02
  • ubuntu has nothing to do with this, cant run ubuntu on one of these mcus. – old_timer Jul 08 '23 at 07:19
  • libc_start_main implies you are trying to link in libc. Are you and why? If so you need an operating system or at least something to resolve the system calls, etc, etc. Also indicates part of the problem. If you provide a complete example (1) it will become obvious to you (2) we can explain each problem in your project or build. – old_timer Jul 08 '23 at 07:21