[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

reply via email to

[Prev in Thread] Current Thread [Next in Thread]