Page 1 of 1

Another linking error

Posted: Tue Jan 17, 2012 12:38 pm
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.

Re: Another linking error

Posted: Tue Jan 17, 2012 1:53 pm
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?

Re: Another linking error

Posted: Tue Jan 17, 2012 2:01 pm
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

Re: Another linking error

Posted: Tue Jan 17, 2012 3:52 pm
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. :(

Re: Another linking error

Posted: Wed Jan 18, 2012 3:14 am
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.

Re: Another linking error

Posted: Fri Jan 20, 2012 4:07 pm
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?

Re: Another linking error

Posted: Fri Jan 20, 2012 4:16 pm
by afritieefy
Well, I just tried compiling with LD, and the behavior is the same. :D