Home > Software design >  Undefined reference in static library to global symbol included in an earlier included static librar
Undefined reference in static library to global symbol included in an earlier included static librar

Time:11-14

I am trying to build an application statically for RISC-V without standard includes and without a standard lib, and instead am trying to link in a statically built musl-libc using its libc.a and crt1.o files (Note, I built crt1.o into a static library libcrt1.a).

The following is my program:

#include <stdio.h>

int main()
{
    printf("Hello world!");
    return 0;
}

And here is my Makefile:

CC=/home/john/deps/install/opt/riscv/bin/riscv64-unknown-elf-gcc
CFLAGS=-Wall -g --static -static-libgcc -nostdinc -nostdlib -I/home/john/musl-1.1.23/install/include
LDFLAGS=-L/home/john/deps/install/opt/riscv/lib/gcc/riscv64-unknown-elf/8.1.0 -L/home/john/musl-1.1.23/install/lib -lc -lgcc -lcrt1

hello.elf: hello.c
        ${CC} ${CFLAGS} -o $@ $^ ${LDFLAGS}

clean:
        rm -f hello.elf

When I try to make this, I get the following error:

/home/john/musl-1.1.23/install/lib/libcrt1_weak.a(crt1.o): In function `_start_c':
/home/john/musl-1.1.23/crt/crt1.c:18: undefined reference to `__libc_start_main'
collect2: error: ld returned 1 exit status
Makefile:6: recipe for target 'hello.elf' failed

However, when I inspect the symbols of libc and libcrt1, I find that __libc_start_main is a GLOBAL symbol defined in libc:

File: libc.a(__libc_start_main.o)
     1: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS __libc_start_main.c
   323: 0000000000000000   112 FUNC    GLOBAL DEFAULT   14 __libc_start_main

(Here is the printout of the symbol in libcrt1 for clarity):

    88: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND __libc_start_main

Any help understanding why this global symbol is not being resolved would be greatly appreciated.

CodePudding user response:

Libraries have to at the end of the command line. ld is searching only one time for the symbols in the library.

LDFLAGS=-L/home/john/deps/install/opt/riscv/lib/gcc/riscv64-unknown-elf/8.1.0 -L/home/john/musl-1.1.23/install/lib -lcrt1 -lgcc -lc 

--library=archive Add archive file archive to the list of files to link. This option may be used any number of times. ld will search its path-list for occurrences of libarchive.a for every archive specified. On systems which support shared libraries, ld may also search for libraries with extensions other than .a. Specifically, on ELF and SunOS systems, ld will search a directory for a library with an extension of .so before searching for one with an extension of .a. By convention, a .so extension indicates a shared library. The linker will search an archive only once, at the location where it is specified on the command line. If the archive defines a symbol which was undefined in some object which appeared before the archive on the command line, the linker will include the appropriate file(s) from the archive. However, an undefined symbol in an object appearing later on the command line will not cause the linker to search the archive again. See the -( option for a way to force the linker to search archives multiple times. You may list the same archive multiple times on the command line. This type of archive searching is standard for Unix linkers. However, if you are using ld on AIX, note that it is different from the behaviour of the AIX linker.

  • Related