Subject: Re: Pkgsrc zlib vs. base zlib, NetBSD
To: None <pkgsrc-users@netbsd.org>
From: James K. Lowden <jklowden@schemamania.org>
List: pkgsrc-users
Date: 06/06/2007 21:37:11
Gary Thorpe wrote:
> Thank you, this works partially (configure detects the right version)
> but it now fails in the final link stage:
> [...]
> -R/usr/pkg/lib -Wl,-rpath,/usr/pkg/lib -L/usr/local/lib -L/usr/lib -lz
> -L/usr/local/lib -Wl,-rpath,/usr/local/lib -lSDL -lpthread -lcurses
> initc.o(.text+0x15f0): In function `SplitSetup':
> : undefined reference to `gzdirect'
> initc.o(.text+0x18e3): In function `SplitSetup':
> : undefined reference to `gzdirect'
> initc.o(.text+0x1b64): In function `SplitSupport':
> : undefined reference to `gzdirect'
> initc.o(.text+0x23e6): In function `loadROM':
> : undefined reference to `gzdirect'
> initc.o(.text+0x6094): In function `loadGZipFile':
> : undefined reference to `gzdirect'
>
> These symbols are found in the pkgsrc version but not in the /usr/lib
> version. Should I try moving the -lz around so it comes before
> -L/usr/lib?
"All `-L' options apply to all `-l' options,
regardless of the order in which the options appear."
You may wish to spend a little more time with "info ld".
1. Put your -L directories in the order you want the linker i.e. ld(1) to
search for libraries.
2. Put your -rpath directories in the order you want the runtime linker
i.e. ld.so(1) to search for libraries.
3. Put your -l libraries in the order you want them resolved: if libA
needs libB, then -lA -lB is right. "[A]n undefined symbol in an object
appearing later on the command line will not cause the linker to search
the archive again."
On a stock NetBSD system, lists (1) and (2) are the same list in the same
order. You might imagine, though, that the build environment may differ
from the runtime environment. For example, a package that includes a
library and a utility that uses it might build the library, then link the
utility to it (-L path/to/build/directory), but set the RPATH to where the
library will eventually be installed (-rpath /usr/pkg/lib).
Approximately, ld(1) ensures that all symbols referred to be the
executable are present in the libraries you indicated. It starts with a
list of unresolved symbols mentioned in the executable. For each -l
library you mention (left to right, in order), it scans the -L path you
provide, looking for the library. The library supplies some symbols and
requires some; the linker updates its unresolved list and goes to the next
-l library, and so on, ending with the default libraries e.g. libc.
The runtime linker takes advantage of some of what ld(1) learned, but
normally relies on the RPATH for its directory search.
Quoth Matthias Scheler:
> Build a package for it. That takes less time than fighting with
> "configure" manually.
Not for everyone, certainly not for me. In any case, learning how to pass
arguments to the linker is valuable. Any pkgsrc user who ever "steps out
of bounds" and tries to build something "from source" -- even his own
stuff -- has to learn how to tell the linker and runtime linker where to
look for things (as well as what to look for, of course). I can't imagine
creating a package without a clear understanding of what the generated
command-line *should* look like.
HTH.
--jkl