[comp.unix.questions] help needed in cc library search order

jwp@larry.sal.wisc.edu (Jeffrey W Percival) (05/06/89)

I am working with Ultrix 2.2 and the C compiler, and I just got real
confused about linking a main program with several subroutine libraries
that contain identically named routines.  Here's the big picture:
suppose I have a main program that calls a "mid-level" routine mid(),
which in turn calls a "low-level" routine low().  I want to link to
different versions of low(), depending on which version of main() I
am building.

Here's the calling tree:

	main()
	    mid()
		low()

I have 2 libraries: lib1 has mid() and low() in it,
lib2 has a different low() (same name, different code).
Let's call the first version of low "low1()" and the other "low2()",
even though their real names are identical.

Case 1:	cc main.o lib1.a
does just as I'd suspect.  I get main, mid, and low1().

Case 2: cc main.o lib2.a lib1.a

The mystery:  I would have thought that I would get low2() always,
because lib2 preceeds lib1.  HOWEVER,  I get low1() unless I
make a call to low2() in main().  In other words, the linker
chooses differently depending on whether main() makes a call to low().

Can someone help me understand this?
-- 
Jeff Percival (jwp@larry.sal.wisc.edu)

chris@mimsy.UUCP (Chris Torek) (05/06/89)

In article <176@larry.sal.wisc.edu> jwp@larry.sal.wisc.edu
(Jeffrey W Percival) writes:
>... Case 2: cc main.o lib2.a lib1.a

>The mystery:  I would have thought that I would get low2() always,
>because lib2 preceeds lib1.  HOWEVER,  I get low1() unless I
>make a call to low2() in main().  In other words, the linker
>chooses differently depending on whether main() makes a call to low().

The linker acts differently when reading a library than when reading
a `.o' file.  If you say

	ld /lib/crt0.o main.o low.o lib1.a	# or `cc' instead of `ld'

you will get your second version of low().  But when you say

	ld /lib/crt0.o main.o lib2.a lib1.a

you are telling ld `read main.o, then *scan* lib2.a, then scan lib1.a'
---so ld scans it, looking for any symbols it happens to need just then,
and finds none.  It closes lib2 and goes on to lib1, where it finds
mid() and *now* discovers it needs low().  It does *not* stop, back
up to lib2, look again, and find the low() there; ld *never* `backs
up'.  If there were no low() in lib1, it would complain `_low undefined'.

What you need to do, then, is convince ld to pull low() out of lib2
anyway, whether it really needs it or not.  There is a simple way
to do this:

	ld -u _low /lib/crt0.o main.o lib2.a lib1.a

The `-u' flag tells ld `make this an undefined symbol'.  Thus, when it
comes across low() in lib2, it will take it immediately.

`cc' might accept -u, or might not; if not, you will have to run
ld directly (and append -lc to tell it to search the C library).
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris@mimsy.umd.edu	Path:	uunet!mimsy!chris