This is the mail archive of the automake@gnu.org mailing list for the automake project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Getting 'undefined reference' errors during linking but I thinkI included all libraries?!?


On Fri, May 02, 2003 at 10:46:42AM -0700, cs@gnumatica.com 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.        erics@telepres.com
|  |  /
My Wine works.  However it crashes about half the time on startup.
Apparently their simulation of windoze API is getting too accurate.  :)
	- Kyle Sallee




Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]