[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: library search test fails, please help

From: Duane Ellis
Subject: Re: library search test fails, please help
Date: Sun, 22 Feb 2009 20:53:21 -0500
User-agent: Thunderbird (Windows/20081209)

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.


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 =


reply via email to

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