[UEFI bare bones/x-compiler config] - LD not finding libgcc

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
User avatar
Schol-R-LEA
Member
Member
Posts: 1925
Joined: Fri Oct 27, 2006 9:42 am
Location: Athens, GA, USA

[UEFI bare bones/x-compiler config] - LD not finding libgcc

Post by Schol-R-LEA »

Warning: long post, with a fair amount of code.

Following the 'Recoding' thread, I decided to go ahead and write a more conventional kernel as practice for my more ambitious plans. To this end, I was trying out the UEFI bare bones tutorial to see how to boot on a modern system.

I followed the tutorial example for compiling with GCC - mostly blindly, in part to see what faults I might find - and after making symoblic links to the data.c and efi.h files, I compiled the code successfully as follows:

Code: Select all

x86_64-w64-mingw32-gcc -ffreestanding -I ~/Deployments/cross-dev-utils/gnu-efi-code/inc/ -I ~/Deployments/cross-dev-utils/gnu-efi-code/inc/x86_64/ -I ~/Deployments/cross-dev-utils/gnu-efi-code/inc/protocol/ -c -o hello.o boot.c

x86_64-w64-mingw32-gcc -ffreestanding -I ~/Deployments/cross-dev-utils/gnu-efi-code/inc/ -I ~/Deployments/cross-dev-utils/gnu-efi-code/inc/x86_64/ -I ~/Deployments/cross-dev-utils/gnu-efi-code/inc/protocol/ -c -o data.o data.c 
However, the linking phase went as follows:

Code: Select all

x86_64-w64-mingw32-gcc -nostdlib -Wl,-dll -shared -Wl,--subsystem,10 -e efi_main -o BOOTX64.EFI hello.o data.o -lgcc
and got the error message
/home/schol-r-lea/opt/cross/lib/gcc/x86_64-w64-mingw32/11.0.0/../../../../x86_64-w64-mingw32/bin/ld: cannot find -lgcc
collect2: error: ld returned 1 exit status


I tried adding the library path as recommended here,

Code: Select all

x86_64-w64-mingw32-gcc -nostdlib -Wl,-dll -shared -Wl,--subsystem,10 -e efi_main -L /home/schol-r-lea/opt/cross/lib/gcc/x86_64-w64-mingw32/11.0.0/../../../../x86_64-w64-mingw32/lib/ -lgcc -o BOOTX64.EFI hello.o data.o
But this got the same error message back.

I suspect the problem is either with my cross-compiler setup, or with the library path I am adding. To get the path and other relevant details, I used the following command:

Code: Select all

$ x86_64-w64-mingw32-gcc -xc -E -v -lgcc
which yielded

Code: Select all

Using built-in specs.
COLLECT_GCC=x86_64-w64-mingw32-gcc
Target: x86_64-w64-mingw32
Configured with: /home/schol-r-lea/Deployments/cross-dev-utils/gcc/configure --target=x86_64-w64-mingw32 --prefix=/home/schol-r-lea/opt/cross --disable-nls --enable-languages=ada --without-headers
Thread model: win32
Supported LTO compression algorithms: zlib zstd
gcc version 11.0.0 20201231 (experimental) (GCC) 
COMPILER_PATH=/home/schol-r-lea/opt/cross/libexec/gcc/x86_64-w64-mingw32/11.0.0/:/home/schol-r-lea/opt/cross/libexec/gcc/x86_64-w64-mingw32/11.0.0/:/home/schol-r-lea/opt/cross/libexec/gcc/x86_64-w64-mingw32/:/home/schol-r-lea/opt/cross/lib/gcc/x86_64-w64-mingw32/11.0.0/:/home/schol-r-lea/opt/cross/lib/gcc/x86_64-w64-mingw32/:/home/schol-r-lea/opt/cross/lib/gcc/x86_64-w64-mingw32/11.0.0/../../../../x86_64-w64-mingw32/bin/
LIBRARY_PATH=/home/schol-r-lea/opt/cross/lib/gcc/x86_64-w64-mingw32/11.0.0/:/home/schol-r-lea/opt/cross/lib/gcc/x86_64-w64-mingw32/11.0.0/../../../../x86_64-w64-mingw32/lib/../lib/:/home/schol-r-lea/opt/cross/lib/gcc/x86_64-w64-mingw32/11.0.0/../../../../x86_64-w64-mingw32/lib/
COLLECT_GCC_OPTIONS='-E' '-v' '-mtune=generic' '-march=x86-64'
To install and update my cross-compilers for various targets, I use a pair of shell scripts, one to update binutils, and the other for updating gcc. These are:

Code: Select all

#!/bin/bash

HOME_DIR="/home/schol-r-lea"
BINUTILS_SRC="$HOME_DIR/Deployments/cross-dev-utils/binutils-gdb"
BINUTILS_BUILD="$BINUTILS_SRC/build"
DEST="$HOME_DIR/opt/cross"

cd $BINUTILS_SRC
git pull origin master

cd $BINUTILS_BUILD
for TARGET in "i686-elf" "x86_64-elf" \
"x86_64-w64-mingw32" \
"arm-none-eabi" "aarch64-none-elf" \
"arm-linux-gnueabihf"  "aarch64-linux-gnu" \
"riscv32-unknown-elf" "riscv64-unknown-elf" \
"mipsel-unknown-elf" "mips64el-unknown-elf" 
do
  TARGET_DIR="$BINUTILS_BUILD/$TARGET"
  if [ ! -d $TARGET_DIR ]; then
     mkdir -p $TARGET_DIR
  fi
  make distclean
  
  cd $TARGET_DIR
  $BINUTILS_SRC/configure --target=$TARGET --prefix=$DEST --with-sysroot --disable-nls --disable-werror
  make
  make install
done
and

Code: Select all

#!/bin/bash

GCC_SRC="/home/schol-r-lea/Deployments/cross-dev-utils/gcc"
GCC_BUILD="$GCC_SRC/build"
DEST="/home/schol-r-lea/opt/cross"

cd $GCC_SRC
git pull origin master

cd $GCC_BUILD
for TARGET in "i686-elf" "x86_64-elf" \
"x86_64-w64-mingw32" \
"arm-none-eabi" "aarch64-none-elf" \
"arm-linux-gnueabihf" "aarch64-linux-gnu"   \
"riscv32-unknown-elf" "riscv64-unknown-elf" \
 "mipsel-unknown-elf" "mips64el-unknown-elf"
do
  TARGET_DIR="$GCC_BUILD/$TARGET"
  if [ ! -d $TARGET_DIR ]; then
     mkdir -p $TARGET_DIR
  fi

  cd $TARGET_DIR
  $GCC_SRC/configure --target=$TARGET --prefix=$DEST --disable-nls \
                     --enable-languages=objc,c,d,c++,go,ada \
                     --without-headers
  make all-gcc
  make all-target-libgcc
  make install-gcc
  make install-target-libgcc
done
While this is undoubtedly overkill, it does give me plenty of options for both source and target.

One thing I did note was the absence of a linker script in the tutorial. LD scripts are something I sadly have ignored for the most part up until now, and I will definitely need help with writing one here.
Rev. First Speaker Schol-R-LEA;2 LCF ELF JAM POEE KoR KCO PPWMTF
Ordo OS Project
Lisp programmers tend to seem very odd to outsiders, just like anyone else who has had a religious experience they can't quite explain to others.
Doctor5555
Posts: 14
Joined: Sat Oct 10, 2020 4:05 pm

Re: [UEFI bare bones/x-compiler config] - LD not finding li

Post by Doctor5555 »

When you tried adding the library path as explained in the link, I believe the library path you needed was

Code: Select all

/home/schol-r-lea/opt/cross/lib/gcc/x86_64-w64-mingw32/11.0.0/
If you actually follow the directories, at least in my installation (which is 10.2.0 and x86_64-elf only), the libgcc is in the equivalent path and only an ldscripts folder at the one you used.
You can see both folders reported under "LIBRARY_PATH" in the "x86_64-w64-mingw32-gcc -xc -E -v -lgcc" result.
kzinti
Member
Member
Posts: 898
Joined: Mon Feb 02, 2015 7:11 pm

Re: [UEFI bare bones/x-compiler config] - LD not finding li

Post by kzinti »

You can simply ask GCC where libgcc is:

Code: Select all

x86_64-w64-mingw32-gcc $(CFLAGS) -print-file-name=libgcc.a
Or in a makefile:

Code: Select all

LIBGCC = $(shell x86_64-w64-mingw32-gcc $(CFLAGS) -print-file-name=libgcc.a)
If this fails, it means there is a problem with your cross compiler build / installation.

Once you have the location of libgcc, you can use it for linking:

Code: Select all

x86_64-w64-mingw32-ld $(LDFLAGS) $(OBJECTS) $(LIBGCC) -o $@
User avatar
Schol-R-LEA
Member
Member
Posts: 1925
Joined: Fri Oct 27, 2006 9:42 am
Location: Athens, GA, USA

Re: [UEFI bare bones/x-compiler config] - LD not finding li

Post by Schol-R-LEA »

kzinti wrote:You can simply ask GCC where libgcc is:

Code: Select all

x86_64-w64-mingw32-gcc $(CFLAGS) -print-file-name=libgcc.a
Unfortunately, all this gives is the file name, not the path to it.

Also, I apparently overlooked something important, though not directly related to the problem: I didn't build libgcc.a with -noredzone set. This means I probably need to completely rebuild my cross-compiler anyway.
Rev. First Speaker Schol-R-LEA;2 LCF ELF JAM POEE KoR KCO PPWMTF
Ordo OS Project
Lisp programmers tend to seem very odd to outsiders, just like anyone else who has had a religious experience they can't quite explain to others.
kzinti
Member
Member
Posts: 898
Joined: Mon Feb 02, 2015 7:11 pm

Re: [UEFI bare bones/x-compiler config] - LD not finding li

Post by kzinti »

Schol-R-LEA wrote:Unfortunately, all this gives is the file name, not the path to it.
This means there is a problem with your setup: GCC cannot find libgcc on its search path.

It sounds to me that your cross-compiler was not built or installed properly.
Schol-R-LEA wrote:Also, I apparently overlooked something important, though not directly related to the problem: I didn't build libgcc.a with -noredzone set. This means I probably need to completely rebuild my cross-compiler anyway.
Mingw uses the MS ABI which doesn't have red zones. So that's probably not the issue. But it doesn't hurt to be explicit and add "-mno-red-zone" just to be safe.
Octocontrabass
Member
Member
Posts: 5568
Joined: Mon Mar 25, 2013 7:01 pm

Re: [UEFI bare bones/x-compiler config] - LD not finding li

Post by Octocontrabass »

Schol-R-LEA wrote:To install and update my cross-compilers for various targets, I use a pair of shell scripts, one to update binutils, and the other for updating gcc.
Are there prebuilt MinGW-w64 packages available for your OS? You might have better luck with those.
kzinti
Member
Member
Posts: 898
Joined: Mon Feb 02, 2015 7:11 pm

Re: [UEFI bare bones/x-compiler config] - LD not finding li

Post by kzinti »

Octocontrabass wrote:Are there prebuilt MinGW-w64 packages available for your OS? You might have better luck with those.
+1. When I played with mingw 32/64 on Linux, I simply downloaded the pre-built packages and installed them. I was able to compile and run my UEFI bootloader successfully using them.
User avatar
Schol-R-LEA
Member
Member
Posts: 1925
Joined: Fri Oct 27, 2006 9:42 am
Location: Athens, GA, USA

Re: [UEFI bare bones/x-compiler config] - LD not finding li

Post by Schol-R-LEA »

kzinti wrote:
Schol-R-LEA wrote:Unfortunately, all this gives is the file name, not the path to it.
This means there is a problem with your setup: GCC cannot find libgcc on its search path.

It sounds to me that your cross-compiler was not built or installed properly.
OK, then. I'll look over my install script again, and see if there is anything I am missing. If anyone could look at it for me (as given in the first post of the thread) and see if anything pops out as clearly incorrect, I would appreciate it.
Rev. First Speaker Schol-R-LEA;2 LCF ELF JAM POEE KoR KCO PPWMTF
Ordo OS Project
Lisp programmers tend to seem very odd to outsiders, just like anyone else who has had a religious experience they can't quite explain to others.
nullplan
Member
Member
Posts: 1790
Joined: Wed Aug 30, 2017 8:24 am

Re: [UEFI bare bones/x-compiler config] - LD not finding li

Post by nullplan »

Schol-R-LEA wrote:OK, then. I'll look over my install script again, and see if there is anything I am missing. If anyone could look at it for me (as given in the first post of the thread) and see if anything pops out as clearly incorrect, I would appreciate it.
In the GCC script, there is no "set -e" anywhere, and -e is not part of the Shebang line. There is also no explicit exit out of the loop if any of the make commands fail. Therefore, how do you know the GCC build for MinGW succeeded? Unless you like watching your terminal screen four hours with scrolling text, and catching the short instance of something failing before the build moves on to MIPS or something, you don't. Is it possible the build failed and you didn't notice?
Carpe diem!
User avatar
Schol-R-LEA
Member
Member
Posts: 1925
Joined: Fri Oct 27, 2006 9:42 am
Location: Athens, GA, USA

Re: [UEFI bare bones/x-compiler config] - LD not finding li

Post by Schol-R-LEA »

I will try running it again with the '-e' option in the shebang and find out.
Rev. First Speaker Schol-R-LEA;2 LCF ELF JAM POEE KoR KCO PPWMTF
Ordo OS Project
Lisp programmers tend to seem very odd to outsiders, just like anyone else who has had a religious experience they can't quite explain to others.
User avatar
Schol-R-LEA
Member
Member
Posts: 1925
Joined: Fri Oct 27, 2006 9:42 am
Location: Athens, GA, USA

Re: [UEFI bare bones/x-compiler config] - LD not finding li

Post by Schol-R-LEA »

OK, so running the script with the '-e' (stop on error?) option did come up with a problem when trying to compile with the 'Ada' option; there also was an issue in the Binutils script with the 'make distclean' invocation. Removing those causes them both to run to completion, but the result of trying to get the Libgcc path from GCC still returns only the file name. I'll review the installation process to make sure I didn't overlook any steps or perform them incorrectly.
Rev. First Speaker Schol-R-LEA;2 LCF ELF JAM POEE KoR KCO PPWMTF
Ordo OS Project
Lisp programmers tend to seem very odd to outsiders, just like anyone else who has had a religious experience they can't quite explain to others.
kzinti
Member
Member
Posts: 898
Joined: Mon Feb 02, 2015 7:11 pm

Re: [UEFI bare bones/x-compiler config] - LD not finding li

Post by kzinti »

I've taken a 4th look at your scripts. They look fine. I am not sure what is going on here.

I do recall trying to compile mingw a long time ago and giving up, but I don't remember what problems I ran into.
nexos
Member
Member
Posts: 1081
Joined: Tue Feb 18, 2020 3:29 pm
Libera.chat IRC: nexos

Re: [UEFI bare bones/x-compiler config] - LD not finding li

Post by nexos »

Do the other targets you compiled look alright?
"How did you do this?"
"It's very simple — you read the protocol and write the code." - Bill Joy
Projects: NexNix | libnex | nnpkg
User avatar
xenos
Member
Member
Posts: 1121
Joined: Thu Aug 11, 2005 11:00 pm
Libera.chat IRC: xenos1984
Location: Tartu, Estonia
Contact:

Re: [UEFI bare bones/x-compiler config] - LD not finding li

Post by xenos »

This might be a suggestion which you tried first already, as it is so simple, but since I saw it nowhere mentioned above, let me still state it:

Have you checked that libgcc is actually built successfully and installed in the path where ld is looking for it?
Programmers' Hardware Database // GitHub user: xenos1984; OS project: NOS
User avatar
Schol-R-LEA
Member
Member
Posts: 1925
Joined: Fri Oct 27, 2006 9:42 am
Location: Athens, GA, USA

Re: [UEFI bare bones/x-compiler config] - LD not finding li

Post by Schol-R-LEA »

I've checked the expected paths where libgcc.a ought to be for each target triplet (~/opt/cross/lib/gcc/<triplet>/11.0.0/) and the only ones where it is missing x86_64-w64-mingw32, aarch64-linux-gnu, and arm-linux-gnueabihf . I can only assume that there is some additional step (or omitted one) specific to those triplets.

Or perhaps the ones with specific OS targets simply don't build libgcc.a by default. Not sure.
Rev. First Speaker Schol-R-LEA;2 LCF ELF JAM POEE KoR KCO PPWMTF
Ordo OS Project
Lisp programmers tend to seem very odd to outsiders, just like anyone else who has had a religious experience they can't quite explain to others.
Post Reply