Allan Caffee wrote:
AC_CHECK_LIB (AFAIK) is not intended to handle static libraries.
I don't know much about AC_CHECK_LIB..
> The reason for this is that compilers handle static libraries quite
differently than shared object libraries.
This I disagree with. To a developer, these are '99.9% functionally
identical', with a confusing twist.
> Compilers treat static libraries as a single big object file to be
included along with all the others.
NO. This is fundamentally wrong.
A static library is scanned - in order, each member of the library is
examined to determine if it is needed or not. If the member of a
*STATIC* library is *NOT* needed, it is *SKIPPED* and not included in
the result executable. What I don't know about is the "shared library"
case.
This example demonstrates what I mean:
Step 0: Setup.
The application has 2 undefined things: Father, and Mother, and two
libraries M- male, and F, female it links against, and it links in order
(M) then (F).
Each library has 2 modules (M1,M2) and (F1,F2)
Step 1:
Library M, is *linked* first. Library M has module M1, resolving symbol
"father"- and is needed by the application. M1 also requires symbol
"mother", which is undefined. Library M also has module M2, resolving
symbol "baby-boy" - not needed by the application, or by module M1(father).
In the static library case, module M2 is skipped, Shared library case: I
do not know. I think, you get everything, like it or not. I don't know.
If these where, as you described "a single big object file to be
included along with all the others" - then "M2(babyboy)" would be
automatic - that is not the case for static libraries.
Step 2:
Library BAR is *linked* second. It has module "F1", resolving the symbol
"mother". However, F1(mother) requires the symbol "babyboy", and perhaps
"babygirl" - currently undefined, and skipped earlier when M2 was
scanned. Module (F2) defines "babygirl", which is included because
"mother" required it.
UNIX style linkers are "one pass" - in this example "M(M1,M2) was
already processed (as a static library) and in this example only occurs
once on the command line, it will not be revisited and module M(M2)
which resolves babyboy will not be included, thus, an
"undefined(babyboy)" occurs.
NOTES
It is more understandable if you create two columns of symbols,
"defined" and "undefined" and mentally process each module, in order.
Or - create a defined/undefined dependency graph sorted by the order the
modules occur or are processed by the linker.
If you reversed the library order (F) before (M) - this problem would
not happen (Most wives would agree, females first :-)
This sort of problem is often the cause of 'multiply defined' symbols
from libraries that people don't understand or won't take the time to
understand.
With GCC (and other Unix style tools) one can specify "multiple library
scans", using special command line options (GCC does this today with
libgcc inside the "specs" file). Users commonly curse at the situation,
become bewildered and duplicate the libraries multiple times on the
command line.
In contrast, other tools automatically retry libraries until there is
nothing more that can be resolved, I know one that was pathologically N!
in the way it scanned.
Older "static libraries" required "ranlib" (and/or "tsort") to sort the
modules by symbol in reasonable ways so that the linker would find
everything [newer, ie: GNU tools do this automatically].
Note however that "ranlib-sort" only occurs within a single library, not
across multiple libraries - which is the exact scenario here.
= END =
-Duane.
_______________________________________________
Autoconf mailing list
Autoconf@xxxxxxx
http://lists.gnu.org/mailman/listinfo/autoconf