Another linking error

Programming, for all ages and all languages.
Post Reply
afritieefy
Posts: 12
Joined: Fri Dec 02, 2011 6:13 am

Another linking error

Post by afritieefy »

Hi!

I have a strange problem when linking my user applications. When I link directly against my C library object files, no problems occur:

Code: Select all

tcc -o shell.exe -I$(INCDIR) $(LIBDIR)/crt0.o  $(LIBDIR)/_syscall.o $(LIBDIR)/errno.o $(LIBDIR)/stdio.o $(LIBDIR)/stdlib.o $(LIBDIR)/string.o shell.c
Unfortunately, when I create a static library libc.a, like this:

Code: Select all

tiny_libmaker.exe libc.a _syscall.o errno.o stdio.o stdlib.o string.o
Compiling & linking like this results in undefined references:

Code: Select all

tcc -c -o shell.o -I$(INCDIR) shell.c
tcc -o shell.exe -L$(LIBDIR) -lc $(LIBDIR)/crt0.o shell.o

tcc: undefined symbol 'stderr'
tcc: undefined symbol 'fprintf'
tcc: undefined symbol 'strcmp'
tcc: undefined symbol 'memset'
tcc: undefined symbol 'memmove'
tcc: undefined symbol 'printf'
It seems like my libc.a-file isn't used, because this file really contains these symbols

Code: Select all

objdump -t libc.a
In archive libc.a:

_syscall.o:     file format elf32-i386

SYMBOL TABLE:
00000000 l    df *ABS*  00000000 _syscall.c
00000000 g     F .text  00000029 _sys_exit
00000029 g     F .text  0000002f _sys_write
..............

stdio.o:     file format elf32-i386

SYMBOL TABLE:
00000000 l    df *ABS*  00000000 stdio.c
00000000 l     O .bss   00000400 _stdinbuf
00000400 l     O .bss   00000400 _stdoutbu
00000800 l     O .bss   00000400 _stderrbu
00000000 l     O .data  00000010 _stdin
00000010 l     O .data  00000010 _stdout
00000020 l     O .data  00000010 _stderr
0000003c l     O .data  00000011 L.1
00000030 g     O .data  00000004 stdin
00000034 g     O .data  00000004 stdout
00000038 g     O .data  00000004 stderr        <==
00000000 g     F .text  0000002d gets_s
00000000       F *UND*  00000000 _sys_read
0000002d g     F .text  0000005b printf        <==
000000e0 g     F .text  0000054e vsprintf
00000000       F *UND*  00000000 _sys_write
00000088 g     F .text  00000058 fprintf        <==
..............
Note: Although I'm using tiny_libmaker.exe as archiver and tcc.exe as linker here, the same problem occurs when using ar.exe and ld.exe.
DLBuunk
Member
Member
Posts: 39
Joined: Sun May 18, 2008 9:36 am
Location: The Netherlands

Re: Another linking error

Post by DLBuunk »

Conclusion: your archiver is only putting the first object file into the archive. Read up on the documentation of the archiver, so that you know how to tell it to put in all object files.

Oh, and why is is this in OS Design & Theory?
User avatar
bluemoon
Member
Member
Posts: 1761
Joined: Wed Dec 01, 2010 3:41 am
Location: Hong Kong

Re: Another linking error

Post by bluemoon »

Is there any warning? your linker probably cannot find -lc for any reason.
Try this:

Code: Select all

tcc -o shell.exe $(LIBDIR)/crt0.o shell.o $(LIBDIR)/libc.a
afritieefy
Posts: 12
Joined: Fri Dec 02, 2011 6:13 am

Re: Another linking error

Post by afritieefy »

bluemoon wrote:Is there any warning? your linker probably cannot find -lc for any reason.
Try this:

Code: Select all

tcc -o shell.exe $(LIBDIR)/crt0.o shell.o $(LIBDIR)/libc.a
There are no warnings. Changing "c" in "-lc" to something else gives a file-not-found error (as does deleting/renaming libc.a). I also tried that way, it doesn't make any difference.
DLBuunk wrote:Conclusion: your archiver is only putting the first object file into the archive. Read up on the documentation of the archiver, so that you know how to tell it to put in all object files.
objdump shows all files, as does viewing the library in 7zip.
DLBuunk wrote:Oh, and why is is this in OS Design & Theory?
Sorry, my bad :oops: Unfortunately, I don't think I can move this thing. :(
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re: Another linking error

Post by Solar »

First, try passing the *.a file directly in the list of object files:

Code: Select all

tcc -o shell.exe $(LIBDIR)/crt0.o $(LIBDIR)/libc.a shell.o
If this solves the problem, TCC disagrees with you on what constitutes a library, or the search path, or somesuch.

If this does not solve the problem, experiment with -fleading-underscore, because tiny_libmaker and TCC apparently disagree on them.
Every good solution is obvious once you've found it.
afritieefy
Posts: 12
Joined: Fri Dec 02, 2011 6:13 am

Re: Another linking error

Post by afritieefy »

Hi

After a lot of experimenting, I finally found a way to make my linker happy:
tcc -o shell.exe -L$(LIBDIR) -lc $(LIBDIR)/crt0.o shell.o
instead of:
tcc -o shell.exe -L$(LIBDIR) $(LIBDIR)/crt0.o shell.o -lc
Anyone knows why the order of the libraries/objectfiles matters?
afritieefy
Posts: 12
Joined: Fri Dec 02, 2011 6:13 am

Re: Another linking error

Post by afritieefy »

Well, I just tried compiling with LD, and the behavior is the same. :D
Post Reply