Page 1 of 1

Compiling in Static Libraries

Posted: Sat Nov 05, 2005 7:45 pm
by TheChuckster
I would like to provide a C library to my users. I have a set of common functions like printf and functions like putch that call that kernel via system calls. How would I go about compiling and linking them in such a way that my user programs can link them in? I use the GCC compiler.

My user apps are ELF binaries. For now I am going to stick with static libraries because I need to figure out the basics first. I suppose some how I need to provide a unified object file of the library that the user program some how links in. I just don't know how to go about doing both of these tasks (compiling the library and linking it into user apps) with GCC and LD.

Re:Compiling in Static Libraries

Posted: Sat Nov 05, 2005 10:26 pm
by AR
To create a shared library: i586-elf-ld -shared -o bin/libTestLib.so TestLib.o TestLibData.o

To link it dynamically to a program: i586-elf-ld TestCore.o -lTestLib -o bin/TestCore.elf -L./bin
(-L adds a new library path, -l finds the library with lib<NAME>.so)

To create a static library: i586-elf-ar -rcs bin/libTestLib.a TestLib.o TestLibData.o
To link it statically to a program: i586-elf-ld TestCore.o -lTestLib -o bin/TestCore.elf -L./bin
(Note: *.so takes precedence over *.a, to change this behaviour use "-Bstatic" [ie. "-Bstatic -lTestLib1 -lTestLib2"])

Re:Compiling in Static Libraries

Posted: Sun Nov 06, 2005 8:31 am
by TheChuckster
Thanks. That was very helpful. I think I'm making a dumb mistake though. I have the .a file produced just fine and I'm linking in the library with my user app, but I still get undefined reference errors from ld when I try to link my user app. The compiliation itself goes without errors just fine and it seems to be able to FIND my library just not use it.

My user app compiliation script:

Code: Select all

gcc -Wall -nostdinc -fno-builtin -I../include -c -o main.o main.c
ld -T link.ld -lmain -L../bin -o test2.bin main.o
My library compiliation script:

Code: Select all

gcc -Wall -nostdinc -fno-builtin -I../include -c -o libmain.o libmain.c
ar -rcs ../bin/libmain.a libmain.o
The linker errors I'm getting:

Code: Select all

main.o(.text+0x24): In function `main':
: undefined reference to `PrintString'
main.o(.text+0x30): In function `main':
: undefined reference to `PrintString'
main.o(.text+0x44): In function `main':
: undefined reference to `Gets'
main.o(.text+0x50): In function `main':
: undefined reference to `PrintString'
Here's an objdump of the library:

Code: Select all

In archive libmain.a:

libmain.o:     file format elf32-i386

SYMBOL TABLE:
00000000 l    df *ABS*  00000000 libmain.c
00000000 l    d  .text  00000000 
00000000 l    d  .data  00000000 
00000000 l    d  .bss   00000000 
00000000 l    d  .note.GNU-stack        00000000 
00000000 l    d  .comment       00000000 
00000000 g     F .text  00000042 PrintInString
00000042 g     F .text  00000024 StringLength
000000bf g     F .text  0000002a PrintChar
00000066 g     F .text  00000037 PrintString
0000009d g     F .text  00000022 Gets
000000e9 g     F .text  0000001a Exec
00000103 g     F .text  0000001a Sleep
0000011d g     F .text  00000017 Exit
It must be painfully obvious what I'm doing wrong, but I haven't a clue.

Re:Compiling in Static Libraries

Posted: Sun Nov 06, 2005 9:31 am
by Candy
Move the -lmain to the end of the line, or before the file you want to link (but in any case, after the -L../bin). That should solve it.

There's a thing with library loading that makes it required to be either in front of or after those loading symbols from it. There doesn't appear to be any real logic (or I don't care enough to find out what it is) so just move them about the command line or duplicate them (which doesn't include them twice, so it's no real baddie, but it's ugly nonetheless) until it works.