1

I am trying to compile for a gd32v chip using gcc(the riscv version on the arch community repo). Compiling seems to work fine, however when trying to link the objects into an elf file, I get the error:

Linking ELF target: main.elf
riscv64-linux-gnu-g++ @_linker_flags -o main.elf ../../bmptk-RISC-V/targets/risc_v/gd32v/gd32vf103xb_boot.o hwlib.o main.o ../../bmptk-RISC-V/targets/risc_v/GD32VF103_standard_peripheral/Source/gd32vf103_rcu.o ../../bmptk-RISC-V/targets/risc_v/GD32VF103_standard_peripheral/Source/gd32vf103_gpio.o ../../bmptk-RISC-V/targets/risc_v/GD32VF103_standard_peripheral/system_gd32vf103.o bmptk_heap_none.o bmptk_fixed_size_stack.o -Os          -Tmain.ld       
/usr/lib/gcc/riscv64-linux-gnu/10.2.0/../../../../riscv64-linux-gnu/bin/ld: /usr/lib/gcc/riscv64-linux-gnu/10.2.0/../../../../riscv64-linux-gnu/lib/libstdc++.so: error adding symbols: file in wrong format
collect2: error: ld returned 1 exit status
make: *** [../../bmptk-RISC-V/Makefile.inc:1498: main.elf] Error 1

In this make rule, I am using a file '_linker_flags' for my linker flags, to keep the terminal clean during compilation. The contents of this file are as follows:

-march=rv32imac -mabi=ilp32 -Os -fdata-sections -ffunction-sections -I../../bmptk-RISC-V/targets/risc_v/ -I../../bmptk-RISC-V/targets/risc_v/GD32VF103_standard_peripheral -I../../bmptk-RISC-V/targets/risc_v/GD32VF103_standard_peripheral/Include -I../../bmptk-RISC-V/targets/risc_v/RISCV/drivers -I../../bmptk-RISC-V/targets/risc_v -I/usr/include -I/usr/include -I../../hwlib-RISC-V/library -I../../Catch2/single_include -I../../Catch2/single_include/catch2 -I../../boost_1_69_0 -I../../bmptk-RISC-V -I../../bmptk-RISC-V/targets -I../../bmptk-RISC-V/targets/risc_v -I../../bmptk-RISC-V/targets/risc_v/RISCV -I../../bmptk-RISC-V/targets/risc_v/RISCV/drivers -DHWCPP_FAKE_OSTREAM -DBMPTK_TARGET=gd32vf103v -DBMPTK_TARGET_gd32vf103v -DHWLIB_TARGET_gd32vf103v -DHWCPP_TARGET_gd32vf103v -DGF_TARGET_gd32vf103v -DBMPTK_CHIP=gd32vf103v -DBMPTK_CHIP_gd32vf103v -DBMPTK_XTAL= -DBMPTK_BAUDRATE=38400 -DHWLIB_BAUDRATE=38400 -DGODAFOSS_BAUDRATE=38400 -DGF_BAUDRATE=38400 -DBMPTK_VERSION=V04_00_work_in_progress_2020_05_23 -DBMPTK_EMBEDDED -lgcc -Wl,-Map,main.map -Wl,--gc-sections -Wl,-fatal-warnings

I'm not familiar with this error, does anyone know what I would have to look into to fix this?

EDIT: I asked a teacher at school and they told me that the problem most likely arised from using a mismatching linker and compiler, or that some object files weren't cleaned when calling make. I made sure all objects were deleted before compiling and made sure the compiler and linker were the same.

They should be the same. I am running riscv64-linux-gnu-ld version 2.35 and riscv64-linux-gnu-g++ version 10.2.0. Both are from the arch community repository.

Vvamp
  • 414
  • 4
  • 12
  • gd32v ... so you should be compiling for 32 bit. But you seem to be invoking the 64-bit toolchain and linking a 64-bit version of the c++ library. The 32/64-bit clash is probably your problem. Not sure how your toolchain looks, but maybe `riscv64-linux-gnu-g++` is not the right compiler for you, do you have some other choices? –  Oct 07 '20 at 13:55
  • @dratenik Thanks for your response! I was thinking about that too, but the toolchain should be able to compile for 32-bit. The description is as follows "Cross compiler for 32-bit and 64-bit RISC-V". I am also able to specify the -march and -mabi flags without issues. – Vvamp Oct 07 '20 at 14:25
  • You can check what format the `libstdc++.so` file that's mentioned in the error message is by running `file` on it. If it's 64bit, then that's the problem. –  Oct 07 '20 at 14:36
  • @dratenik It *is* 64-bit, thank you! Never knew of that command, it's very useful. But I'm confused; did I compile that file, or is it a standard included library? – Vvamp Oct 07 '20 at 14:43
  • That is the standard library for C++, shipped with the compiler. g++ links it by default as it is needed for c++ stuff. Do you have the 32-bit version lying around in some neighboring directories? –  Oct 07 '20 at 14:52
  • @dratenik not from the same library. AFAIK there is no riscv32-linux-gnu in the repo's. There is a riscv32-elf though, but it seems their is no folder for that. There is another riscv folder that does contain one for my chip it seems. How would I go about telling gcc to use that file? It is a .a file instead of a .so file, though. I'm not sure what that does exactly – Vvamp Oct 07 '20 at 14:59
  • `.a` is a static library (will be linked into your binary) `.so` is a dynamic library (your binary would only contain references to it, resolved at runtime, like a windows .dll). Some discussion on statically linking stdc++ here https://stackoverflow.com/questions/13636513/linking-libstdc-statically-any-gotchas –  Oct 07 '20 at 15:07
  • If you can't persuade g++ to go to the right directory, you also have the option of linking using plain gcc, showing it the library directory using `-L` option and then asking for the library with something like `-lstdc++ -lm` (c++ also needs the math library for some reason). –  Oct 07 '20 at 15:10
  • Oh yeah, it should also be preceded by something like `-Wl,-Bstatic`, see https://stackoverflow.com/questions/51805994/why-does-adding-wl-static-lmy-static-lib-clobber-the-library-search-path Anyway, good luck :) –  Oct 07 '20 at 15:13
  • Thank you so much. I’m done for now, but I’ll take a look tonight, or tomorrow. Thank you so much for your help, I was stuck on this issue all day! :)) – Vvamp Oct 07 '20 at 15:31
  • @dratenik I tried tried the '-static-libstdc++' option, along with setting -L to the folder that contains the .a file for my chip. This seems to work, but I got the same error: "file in wrong format". This time it is for libgcc_s.so.1, though. I can't find a file called "libgcc_s" in my library. Any ideas for this? – Vvamp Oct 08 '20 at 10:35
  • That was not a -W1, but -Wl (lowercase L). You can try it with libgcc as well, sure. Those contortions should not normally be needed, but I have no idea how to get your toolchain to behave in a more sane way. –  Oct 08 '20 at 10:39

1 Answers1

1

To see exactly the mapping/switches of the libraries supported by your compiler you can use : riscv64-linux-gnu-g++ -print-multi-lib. If you compiler was compiled with multilib enabled you can choose an rv32 libs without hard float otherwise it will not link also since you are compiler for rv32imac.
If your compiler was build without the multlib option you have two option:
Compile with -nostdlib and provide the needed file to the linker crt, libc libgcc ... or you can get a compiler which was build with multilib enabled.

yflelion
  • 1,698
  • 2
  • 5
  • 16