Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 10 May 2002 18:38:35 -0400
From:      Mikhail Teterin <mi+mx@aldan.algebra.com>
To:        Terry Lambert <tlambert2@mindspring.com>
Cc:        Mikhail Teterin <mi@corbulon.video-collage.com>, current@FreeBSD.org
Subject:   Re: does the order of .a files matter?
Message-ID:  <200205101838.35989.mi%2Bmx@aldan.algebra.com>
In-Reply-To: <3CDC2F2C.2CB9C818@mindspring.com>
References:  <200205101233.g4ACXctb041093@corbulon.video-collage.com> <200205101343.01636.mi%2Bmx@aldan.algebra.com> <3CDC2F2C.2CB9C818@mindspring.com>

next in thread | previous in thread | raw e-mail | index | archive | help
On Friday 10 May 2002 04:35 pm, Terry Lambert wrote:
= Mikhail Teterin wrote:
= > = For my information:  Why didn't you take John De Bowsky's advice to:
= > =
= > =       ld $objlist `lorder $liblist | tsort -q`
= >
= > I tried that before I asked on the mailing list the first time. It
= > did reduce the number of the undefined symbols, but not to zero.
=
= It's possible that the symbols are truly undefined (e.g. "stat64"),
= but I think that is unlikely.

= > It would probably be quite beneficial if you dropped this paternalistic
= > attitude. "Pain high enough"... Please...
=
= If I sounded paternalistic in my answer, it's because the question
= being asked is really a "newby" question about how linkers work, and
= really doesn't belong on the -current list.

It looked (and still looks) to me like a bug or an incompleteness. That's
why I involved -current into it. The -stable is unlikely to make the changes
neccessary, but with -current I had hope.

= Here is a more comprehensive answer, which does not leave the solution
= as "an exercise for the student":
=
= Most linkers don't do what you want, which is make up for programmer
= incompetence by doing an automatic topological sort on all symbol
= dependencies, regardless of where or in what type of file the symbol
= is defined, because most linkers treat archives and libraries very
= differently than lists of object files.
=
= This is the technically correct thing for them to do.

Doing what you explain by incompetence is no different from listing the
object files (.o) on the linker's command line in an arbitrary order --
say, alphabetically, as done by most of the FreeBSD's own Makefiles. Not
out of incompetence, but rather for neatness sake. The fact, that the
linker has no problems in this case shows the existing inconsitency.

= This only works intra-archive, not inter-archive. For inter-archive,
= you are expected to order the archives in the proper order, and the

This expectation is not even documented anywhere...

= > Tsort is ALREADY incorporated into ld in some shape, because object
= > files on command line or within one .a CAN be misordered.
             ************

= Within one .a, they are only permitted to be misordered if "ranlib"
= has been run on the archive (see the quotation of the ranlib manual
= page, above).

Your attempt to dodge explaining the other case -- that of misordered
object files _on command line_ has been logged.

= Within multiple .a's, they are handled differently, because linking
= against a .a file does not necessarily pull in all of the object files
= in the archive. *This is intentional; it is by design*.

Design of what? Of linker? If so, the design is inconsistent (broken?),
for it handles the same entities (object files) differently depending on
how they are given to it (in a single .a, on command line, in multiple
.a files).

= It's my understanding that you are making libraries in the first place
= in order to get around command line length limitations, and have
= settled upon archives, rather than incremental linking using "ld -r -o
= A.o ${A_OBJS}".

Not quite. The software's original build is broken up into dozens of
interdependent libraries. They had no problems linking together on
neither Solaris, nor AIX, nor HP-UX, nor NT.

= If this is the case, it would probably be a good idea to choose
= which objects go into which library carefully, to avoid ending
= up with undefined symbols.

I'm not (yet) developing this software. I'm just trying to port it!

= Alternately, if you insist on using ".a" files directly, as if they
= were normal object files, someone has already posted that you should
= probably use the "--whole-archive" argument, so that the archive
= contents aren't pulled in *only* if they define symbols which are in
= the current undefined symbol list, but to pull them in unconditionally
= (i.e. "treat them as a list of object files instead of an archive").

That suggestion I missed. But it looks like --whole-archive will suck in
everything, including the really unneeded objects.

Perhaps, the linkers on the commercial OSes I listed do use some smarter
equivalent of ``--whole-archive'' by default. IMO, it makes sense, since
those, who know, THEIR libraries are organized properly, and care for
the speed of linking can always add --no-whole-archive (or equivalent)
to THEIR makefiles -- speeding up their ``build world''.

= In the end, you will have to have already been told to solve it, in
= this thread, and which I have laid out, in no uncertain terms, in this
= email.

I think, the terms I used to say, that I already solved my problem,
were no less uncertain. My immediate problem that is.

I'm now readying my horse and armor for the trip to figure out, why is
this sort of gymnastics only needed with the OSF toolchain (actually, I
may be wrong here, since I did not _personally_ verify this thing links
on the other systems without the hoop-jumping).

= > This, BTW, shows how inconsistent the current situation is -- the
= > linker does not mind misordered object files, but is very picky
= > about the order of static libraries (shared ones can be misordered
= > too, AFAIK). I don't see how one can sincerely defend its lack of
= > what still appears to be a missing feature.
=
=Libraries are not object files, and they are not lists of object files.

The documentation suggests otherwise. From ar(1):

	The GNU ar program creates, modifies,  and  extracts  from
	archives.   An  archive is a single file holding a collec-
	tion of other files in a structure that makes it  possible
	to  retrieve the original individual files (called members
	of the archive).

In fact, Debian's .deb files are compressed ar-balls, just like
FreeBSD's .tgz packages are compressed tar-balls (less confusingly
named, though).

= You can create a list of object files by:
=
= 	ld -r -o list_x.o ${X_OBJS}
=
= and then linking:
=
= 	cc -o foo ${OBJS} list_x.o
=
= Instead of:
=
= 	cc -o foo ${OBJS} list_x.a

This is very useful. Thank you!

= A true library implies that you have done the dependency ordering
= necessary to avoid the problems you are seeing because you are using
= libraries and *have not done that*.

I wish, you could point me to some documentation on that.

= In other words, *do not use "--whole-archive", please*

It seems, --whole-archive is likely to bloat the executable with
the stuff, that is genuinly unneeded, so, no, I'm not going to use
that.

	-mi


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-current" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200205101838.35989.mi%2Bmx>