[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Getting 'undefined reference' errors during linking but I think I in
From: |
Eric Siegerman |
Subject: |
Re: Getting 'undefined reference' errors during linking but I think I included all libraries?!? |
Date: |
Fri, 2 May 2003 15:06:23 -0400 |
User-agent: |
Mutt/1.2.5i |
On Fri, May 02, 2003 at 10:46:42AM -0700, address@hidden wrote:
> I was having a conversation with a C guru and he told me that ANSI C standard
> doesn't /require/ C compiler to do multiple passes when linking.
Indeed, only one pass is how things is how things were
traditionally done. Some compilers (apparently, from what you're
saying) do multiple passes, but depending on such a thing is far
from portable.
UNIX Seventh Edition (from which all else in UNIX and C ultimately flows) has
this to say in its ld(1) man page:
| If any argument is a library, it is searched exactly once at the point
| it is encountered in the argument list. Only those routines defining
| an unresolved external reference are loaded. If a routine from a
| library references another routine in the library, and the library has
| not been processed by ranlib(1), the referenced routine must appear
| after the referencing routine in the library. Thus the order of pro-
| grams within libraries may be important. If the first member of a
| library is named `__.SYMDEF', then it is understood to be a dictionary
| for the library such as produced by ranlib; the dictionary is searched
| iteratively to satisfy as many references as possible.
| [...]
| -lx This option is an abbreviation for the library name
| `/lib/libx.a', where x is a string. If that does not exist, ld
| tries `/usr/lib/libx.a'. A library is searched when its name is
| encountered, so the placement of a -l is significant.
> (Why they can't look ahead in order to let you put -L's AFTER -l's as well
> is beyond me.)
I presume, because it's sometimes desirable to specify different
-L search paths for different libraries; and collecting all the
-L's together into one big list before starting to do the linking
would make that impossible.
But you can't depend on this behaviour; ld(1) from SunOS 4.1.3 says:
| In general, options should appear ahead of the list of files to pro-
| cess. Unless otherwise specified, the effect of an option covers all
| of ld operations, independent of that option's placement on the command
| line. Exceptions to this rule include some of the binding control
| options specified by `-B' and the abbreviated library-names specified
| by `-l'. [But not -L] These may appear anywhere, and their influence
| is dependent upon their location
> In summary, if one was *Really* obsessed with *portability across various
> C compilers*, I wonder if one should get in habit of putting -l's after
> object filesand main().... because there may be a C compiler out there that
> _requires_
> it.
Just so. To be portable, you should:
- put all the -L's before any of the .o files or -l's
- order .o files and -l options as though the linker were going
to do only one pass over them all
Unless I miss my guess, the first of these requirements is the
reason that Automake has both xxx_LDFLAGS and xxx_LDADD options
in the first place!
--
| | /\
|-_|/ > Eric Siegerman, Toronto, Ont. address@hidden
| | /
My Wine works. However it crashes about half the time on startup.
Apparently their simulation of windoze API is getting too accurate. :)
- Kyle Sallee