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