On Thu, 24 Sep 2020, Oleg Smolsky wrote:
Libtool convenience libraries are not "real" static libraries.
Instead they are object files stored in an archive file. Prior to use
(when linking using libtool) the objects are extracted and passed to
the linker directly (perhaps with renaming to assure there are no
over-writes during the extraction).
Well, AFAIK any well-formed .a file (an archive) is a static lib. And these can be passed to the linker. Are you saying that libtool extracts the individual .o files instead passing -lfoo (for libfoo.a)?
While libtool convenience
libraries are certainly "convenient" they can dramatically slow down
the build. It takes time to do the operations associated with the ar
files, but most importantly it prohibits parallelism in the build.
Yes, this is certainly a concern. I've noticed stalls in my non-recursive build. I'm guessing that is due to repackaging the libs.
> So, I am not sure what can be done here. Could you clarify the following
> - Does the aforementioned renaming bloat the executable?
Bloating of the executable depends on the object files linked with it.
Linkers may vary as to how smart they are at ignoring supplied objects
where no symbols have been used.
> - How is the linker able to resolve mutiply-defined symbols for the
> duplicated nodes in the DAG?
The convenience library does not do anything regarding mutiply-defined
symbols (at the C language level) while linking. If there is a
conflict then the linker should normally fail.
I find the situation puzzling. My project has just over a hundred of these LT convenience libraries and there are several places where collisions result in renaming. Yet nowhere do I see multiply defined symbols.
If libtool/automake scripts do not do dedup... I can only guess that the linker sees .o files inside multiple .a archives (or multiple .o files coming from distinct directories via the command line) and performs dedup. Is that getting closer to the truth?
> - Is there an alternative way to express inter-lib dependencies with
Using a non-recursive build and using Automake macros to express what
is currently expressed as convenence libraries (using original object
files in place rather than storing in 'ar' format and extracting over
and over) will tremendously decrease build times. Automake supports
an include syntax which allows distributing build information in the
project (e.g. putting it in subdirectories next to source files) yet
incorporating in single build. If everything is ruled by one
non-recursive 'make', and the dependencies are properly cascading,
then using Automake's non-recursive build capability will provide a
huge boost to build performance, and particulary on modern multicore
My setup is a large, non-recursive thing with "include" statements. On the top of that I am trying to understand the issues and costs imposed by the convenience libraries. My primary ask is transitive dependencies between the libs as I have more than 100 of them (and several dozen apps and hundreds of tests).
Thanks in advance!