gcc linker problem

G

Georg

Hello,

I must be doing something wrong, but I don't get it:

- compile
gcc -c -O -Iinc src/hello.c -o obj/hello.o
gcc -c -O -Iinc src/msg_1.c -o obj/msg_1.o
gcc -c -O -Iinc src/msg_2.c -o obj/msg_2.o

- make library
ar -cru lib/libhello.a obj/msg_1.o obj/msg_2.o
ranlib lib/libhello.a

- link
ld -o exe/hello.x -t -Llib -lhello -lc obj/hello.o

ld: mode elf_i386
/lib/libc.so.6
obj/hello.o

?Why is ./lib/libhello.a missing here?

ld: warning: cannot find entry symbol start; defaulting to 0000000008048184

?What does that mean? How can I prevent it?

obj/hello.o(.text+0x17): In function `main':
: undefined reference to `msg_1'
obj/hello.o(.text+0x1c): In function `main':
: undefined reference to `msg_2'
ld: link errors found, deleting executable `exe/hello.x'

Check ./lib/libhello.a:

nm -s lib/libhello.a

Archive index:
msg_1 in msg_1.o
msg_2 in msg_2.o

msg_1.o:
00000000 T msg_1
U puts

msg_2.o:
00000000 T msg_2
U puts

There functions are in the archive. So why does the linker not find them?
Does anyone see my mistake?
I am working with SuSE Linux.
Bye,

Georg
 
R

Richard Bos

Georg said:
There functions are in the archive. So why does the linker not find them?
Does anyone see my mistake?

No idea; ask in a gcc group. Try, for example, gnu.gcc.help.

But you could have the decency to read their FAQ first.

Richard
 
B

Bryan Bullard

georg-

looks like a problem with your linker configuration. possibly, the object
file that contains the *true* entry point is not getting linked. it is part
of the c run time and for suse this is the "_start" symbol. possibly your
default linker script has been overridden. see the default link script for
details.

-bryan
 
D

Dan Pop

In said:
I must be doing something wrong, but I don't get it:

- compile
gcc -c -O -Iinc src/hello.c -o obj/hello.o
gcc -c -O -Iinc src/msg_1.c -o obj/msg_1.o
gcc -c -O -Iinc src/msg_2.c -o obj/msg_2.o

- make library
ar -cru lib/libhello.a obj/msg_1.o obj/msg_2.o
ranlib lib/libhello.a

- link
ld -o exe/hello.x -t -Llib -lhello -lc obj/hello.o

The thing you're doing wrong is using ld yourself. The ld command is for
super-gurus ONLY, the rest of the mortals are supposed to invoke it
through the compiler interface, gcc in your case.

Let's have a look at what gcc does for the most trivial linking job:

fangorn:~/tmp 1670> gcc -v test.o
Reading specs from /products/gnu/gcc2/v2.95.3/lib/gcc-lib/i686-pc-linux-gnu/2.95.3/specs
gcc version 2.95.3 20010315 (release)
/products/gnu/gcc2/v2.95.3/lib/gcc-lib/i686-pc-linux-gnu/2.95.3/collect2 -m elf_i386 -dynamic-linker /lib/ld-linux.so.2 /usr/lib/crt1.o /usr/lib/crti.o /products/gnu/gcc2/v2.95.3/lib/gcc-lib/i686-pc-linux-gnu/2.95.3/crtbegin.o -L/products/gnu/gcc2/v2.95.3/lib/gcc-lib/i686-pc-linux-gnu/2.95.3 -L/products/gnu/gcc2/v2.95.3/lib test.o -lgcc -lc -lgcc /products/gnu/gcc2/v2.95.3/lib/gcc-lib/i686-pc-linux-gnu/2.95.3/crtend.o /usr/lib/crtn.o

That's quite a bit more complex than your simple minded ld command, isn't
it? A number of "mysterious" object files (crt1.o, crti.o, crtbegin.o,
crtend.o, crtn.o) get linked behind my back, in a well defined
order WRT the rest of the files and libraries, to get a *working*
executable file. As a mere mortal, I'm quite happy that I don't have
to learn to type such ld commands myself. Especially considering that
the paths involved differ from one installation to another.
ld: mode elf_i386
/lib/libc.so.6
obj/hello.o

?Why is ./lib/libhello.a missing here?

Most likely because you put -lhello *before* obj/hello.o on the
command line. By the time ld processed the -lhello option, it found
nothing interesting in it, so it discarded it. The golden rule is that
each library must follow the object files/libraries that contain
references to it. In the case when two libraries contain crossed
references, mention one of them twice: -lfoo -lbar -lfoo.

So, you may have better success with the following command:

gcc -o exe/hello.x -Wl,-t obj/hello.o -Llib -lhello

No need for -lc, it's linked by default, and -Wl,-t is the canonical
way of passing the -t option to the linker. Because gcc itself has no
-t option, in this particular case a plain -t would have worked, as well.
But the -Wl option works even in the case of a conflict between gcc
options and ld options and it's faster to just use it than to check
whether such a conflict exists or not.
ld: warning: cannot find entry symbol start; defaulting to 0000000008048184

?What does that mean? How can I prevent it?

It means that you didn't include the mysterious object files mentioned
above into the ld argument list. The gcc command will do it for you.

Dan
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,768
Messages
2,569,575
Members
45,054
Latest member
LucyCarper

Latest Threads

Top