[Top][All Lists]

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

Re: Simple "how-to" question, libtool

From: Brian Dessent
Subject: Re: Simple "how-to" question, libtool
Date: Thu, 12 Jun 2008 14:10:37 -0700

Mar Loh wrote:

> Q1: Every time I run ./configure from the topdir, the system checks
> (checking for BSD-compatible....) are re-run every time it gets to a new
> subdirectory, making the configure take a long time. How do I remove these
> checks when going to a new subdirectory (these are clearly redundant)?

This is the nature of a recursive build system.  The configure checks
may seem redundant but they're not, because in such a system each
directory with a configure script is a separate entity.  If the test was
not run again, the results would not be available in that dir.  The
traditional way in a recursive system that a higher level directory
communicates information to subdirectories is by passing arguments to
the subconfigure invocations, or invoking submakes with variable

There is another simpler way, however -- the config cache.  If you
"configure -C" at the top level, this will create a config.cache file
there that stores the results of configure tests, or in fact any
variable matching *_cv_* (for cached value.)  This will also cause
configure to add "--cache-file=../config.cache" when invoking
subconfigures.  This causes the subdirs to share the cache.

A properly written test will do (at least) two things: it will store its
result in a variable in this *_cv_* namespace, and it will check before
doing any expensive work whether this variable is already set, and
bypass the expensive work if so.  The result of this is that a properly
written test will only do the expensive work once, and any subsequent
invocations -- either later in that configure script or in a different
configure script that is sharing the cache -- will just use the cached
value, normally printing "(cached)" in the output.

The cache is also useful when configure needs to be re-run, either
explicitly through the user invoking it or "config.status --recheck", or
when some dependency gets updated that causes the Makefile to do as
such.  The second run will use all the cached values for tests that are
cacheable, usually making it a lot faster.  Of course this is a double
edged sword: if the user is rerunning configure with significantly
different options or if the generated configure script has changed
semantically (e.g. the developer has edited a m4 macro) then the results
may be intentionally different in which case it would be necessary to
delete the config.cache file.

There are some situations where the cache cannot be shared: for example
if there are two configures that perform a similar test but with
different options/semantics.  If they both store their result to the
same variable and are sharing a cache, one will be incorrect.  Also,
some tests aren't properly written and don't effectively cache their
result.  But in general I don't think you need to worry unless you're
doing something really broken in your own macros, as all the ones that
ship with the tools ought to be cache-friendly.

There is another, more radical solution: nonrecursive build.  This
doesn't mean that you have to put everything in one large dir, or even
that you can't have all the build logic split off into per-directory
files.  Using includes you can still structure your files as in the case
of the recursive build, but in this scenario there is only one configure
script and one large Makefile that handles building everything.

> Q2: I'd like all *.h files to end up in /topdir/include/, with depth (e.g.
> topdir/libsrcdir/libsrcsubdir1/header1.h -->
> topdir/include/libsrcsubdir1/header1.h). How do I accomplish this? I've
> tried some things using top_srcdir, but I think I have the recursion messed
> up such that the local makefiles think that top_srcdir is whatever directory
> it's presently in, if that makes sense.

What do you mean "end up"?  The result of "make install" should put them
at their eventual destination on the end user's system, not some
location in the build dir.  Are you saying that you want the build
system to create a bunch of symlinks inside the build dir before
building anything?  What problem are you trying to solve?

> Q3: I'd like all *.la libraries to end up in /topdir/lib/, without depth
> (e.g. topdir/lib/

This goal very much goes against the end-user-centric philosophy that
the autotools try to foster.  In that vein, the output location is
whatever the current directory was when the user ran configure.  Also
called VPATH-builds (after the make feature used to implement it), this
allows for configuring in a location that is not necessarily the same as
the source dir.

This allows for a great deal of flexibility for the end user, such as:

- For a single source tree, you can have multiple build trees each
configured with totally different options or even on completely
different host architectures.

- The source can reside on a read-only network directory/filesystem and
still remain buildable.

- With a build tree separate from the source tree it is easy to simply
delete everything and start over without having to unpack the source
again or rely on "make distclean" being usable (e.g. in cases where you
don't even have a generated Makefile in every dir yet due to configure

If the user has none of the above needs and simply runs configure in the
source dir, then the build tree is the same as the source tree as in the
traditional case.  But it's still important to conceptually think of the
build tree and the source tree as totally separate, and the resulting
libs/objects always go in the the build tree, whose location is
determined by the user.

I think you will get better help if you state what problem you're trying
to solve.  The "make install" step will take care of putting the
libraries where they need to go on the user's system, but that should
never be a location inside the source or build trees.  If you need to do
a simulated install for example to create a binary package, the right
method is "make install DESTDIR=/scratch/dir" which will populate
everything under /scratch/dir as if it were / of the user's system.  You
can then create a tarball of that whole tree which captures the
installed state of everything in your tree.

Note that automake does have the 'subdir-objects' option.  If you refer
in a to a source file in a subdirectory foo/bar.c, this
option tells whether the resulting object from that compilation goes
into foo/ or ./ in the build tree.  In a nonrecursive build system, this
allows to control whether you want to collapse the build tree into a
single flat dir or mirror the same structure as the source tree.  In a
recursive build system tends to only refer to source files
in that same dir so it has less of a meaning there.


reply via email to

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