Add a new `-weak' flag to tell libtool when not to propogate

dependency libraries from dlpreopened modules to libraries:

* config/ltmain.in: Support new -weak link mode option.  Adjust
help message.
* libltdl/Makefile.am (libltdlc_la_LDFLAGS): Use it.
* doc/libtool.texi (Linking with dlopened modules): Document it.
(Link mode): Mention -weak.
* NEWS: Updated.
This commit is contained in:
Gary V. Vaughan 2004-08-29 16:05:34 +00:00
parent e84c803d1b
commit 0158428875
5 changed files with 207 additions and 55 deletions

View File

@ -1,3 +1,15 @@
2004-08-29 Gary V. Vaughan <gary@gnu.org>
Add a new `-weak' flag to tell libtool when not to propogate
dependency libraries from dlpreopened modules to libraries:
* config/ltmain.in: Support new -weak link mode option. Adjust
help message.
* libltdl/Makefile.am (libltdlc_la_LDFLAGS): Use it.
* doc/libtool.texi (Linking with dlopened modules): Document it.
(Link mode): Mention -weak.
* NEWS: Updated.
2004-08-29 Gary V. Vaughan <gary@gnu.org>
* config/ltmain.in (opt_help): Defer showing help messages until
@ -65,6 +77,8 @@
* doc/libtool.texi (Cheap tricks): Escape the `@' for texinfo.
2004-08-27 Gary V. Vaughan <gary@gnu.org>
* doc/libtool.texi (Cheap tricks): Fix the instructions for making
a ltmain.in wrapping libtool in light of recent changes to the
version checking code.

2
NEWS
View File

@ -31,6 +31,8 @@ New in 1.5b: 2004-??-??; CVS version 1.5a, Libtool team:
* If you configure libtool with --disable-shared (or if libtool does not
support shared libraries on your platform) trying to build a library using
`-shared' is a fatal error.
* New link mode option `-weak' tells libtool when not to propogate dependency
libraries from dlpreopened modules.
* libtoolize installs libtool.m4, (ltdl.m4 if used,) and various supporting
m4 definitions to AC_CONFIG_MACRO_DIR.
* Mode inferrence removed, shorthand for choosing modes added.

View File

@ -517,6 +517,7 @@ The following components of LINK-COMMAND are treated specially:
-static do not do any dynamic linking of libtool libraries
-version-info CURRENT[:REVISION[:AGE]]
specify library version info [each variable defaults to 0]
-weak LIBNAME declare that the target provides the LIBNAME interface
All other options (arguments beginning with \`-') are ignored.
@ -2343,6 +2344,7 @@ func_mode_link ()
thread_safe=no
vinfo=
vinfo_number=no
weak_libs=
func_infer_tag $base_compile
@ -2457,21 +2459,24 @@ func_mode_link ()
prev=
continue
;;
framework)
case $host in
*-*-darwin*)
case "$deplibs " in
*" $qarg.ltframework "*) ;;
*) deplibs="$deplibs $qarg.ltframework" # this is fixed later
;;
esac
;;
esac
prev=
continue
;;
inst_prefix)
inst_prefix_dir="$arg"
prev=
continue
;;
precious_regex)
precious_files_regex="$arg"
prev=
continue
;;
release)
release="-$arg"
prev=
continue
;;
objectlist)
if test -f "$arg"; then
save_arg=$arg
@ -2576,6 +2581,16 @@ func_mode_link ()
prev=
continue
;;
precious_regex)
precious_files_regex="$arg"
prev=
continue
;;
release)
release="-$arg"
prev=
continue
;;
rpath | xrpath)
# We need an absolute path.
case $arg in
@ -2598,6 +2613,24 @@ func_mode_link ()
prev=
continue
;;
shrext)
shrext_cmds="$arg"
prev=
continue
;;
weak)
weak_libs="$weak_libs $arg"
prev=
continue
;;
xcclinker)
linker_flags="$linker_flags $qarg"
compiler_flags="$compiler_flags $qarg"
prev=
compile_command="$compile_command $qarg"
finalize_command="$finalize_command $qarg"
continue
;;
xcompiler)
compiler_flags="$compiler_flags $qarg"
prev=
@ -2613,32 +2646,6 @@ func_mode_link ()
finalize_command="$finalize_command $wl$qarg"
continue
;;
xcclinker)
linker_flags="$linker_flags $qarg"
compiler_flags="$compiler_flags $qarg"
prev=
compile_command="$compile_command $qarg"
finalize_command="$finalize_command $qarg"
continue
;;
framework)
case $host in
*-*-darwin*)
case "$deplibs " in
*" $qarg.ltframework "*) ;;
*) deplibs="$deplibs $qarg.ltframework" # this is fixed later
;;
esac
;;
esac
prev=
continue
;;
shrext)
shrext_cmds="$arg"
prev=
continue
;;
*)
eval "$prev=\"\$arg\""
prev=
@ -2692,6 +2699,11 @@ func_mode_link ()
continue
;;
-framework)
prev=framework
continue
;;
-inst-prefix-dir)
prev=inst_prefix
continue
@ -2804,11 +2816,6 @@ func_mode_link ()
continue
;;
-shrext)
prev=shrext
continue
;;
-no-fast-install)
fast_install=no
continue
@ -2881,6 +2888,11 @@ func_mode_link ()
continue
;;
-shrext)
prev=shrext
continue
;;
-static)
# The effects of -static are defined in a previous loop.
# We used to do the same as -all-static on platforms that
@ -2899,12 +2911,18 @@ func_mode_link ()
prev=vinfo
continue
;;
-version-number)
prev=vinfo
vinfo_number=yes
continue
;;
-weak)
prev=weak
continue
;;
-Wc,*)
args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wc,//'`
arg=
@ -2957,11 +2975,6 @@ func_mode_link ()
continue
;;
-framework)
prev=framework
continue
;;
# Some other compiler flag.
-* | +*)
# Unknown arguments in both finalize_command and compile_command need
@ -3244,16 +3257,21 @@ func_mode_link ()
# Collect and forward deplibs of preopened libtool libs
for lib in $dlprefiles; do
# Ignore non-libtool-libs
dependency_libs=
case $lib in
*/*.la | *\\*.la)
. $lib
deplibs="$deplibs $dependency_libs"
;;
*.la)
. ./$lib
deplibs="$deplibs $dependency_libs"
;;
*[\\/]*.la) . $lib ;;
*.la) . ./$lib ;;
esac
# Collect preopened libtool deplibs, except any this library
# has declared as weak libs
for deplib in $dependency_libs; do
deplib_base=`echo "$deplib" |$SED "$basename"`
case " $weak_libs " in
*" $deplib_base "*) ;;
*) deplibs="$deplibs $deplib" ;;
esac
done
done
libs="$dlprefiles"
fi
@ -6547,6 +6565,9 @@ inherited_linker_flags='$inherited_linker_flags'
# Libraries that this one depends upon.
dependency_libs='$dependency_libs'
# Names of additional weak libraries provided by this library
weak_library_names='$weak_libs'
# Version information for $libname.
current=$current
age=$age

View File

@ -166,6 +166,7 @@ Dlopened modules
* Building modules:: Creating dlopenable objects and libraries.
* Dlpreopening:: Dlopening that works on static platforms.
* Linking with dlopened modules:: Using dlopenable modules in libraries.
* Finding the dlname:: Choosing the right file to @code{dlopen}.
* Dlopen issues:: Unresolved problems that need your attention.
@ -1427,6 +1428,13 @@ existing projects where identical version numbers are already used across
operating systems. New projects should use the @samp{-version-info} flag
instead.
@item -weak @var{libname}
if @var{output-file} is a libtool library, declare that it provides a
weak @var{libname} interface. This is a hint to libtool that there is
no need to append @var{libname} to the list of dependency libraries of
@var{output-file}, because linking against @var{output-file} already
supplies the same interface (@pxref{Linking with dlopened modules}).
@item -Wl,@var{flag}
@itemx -Xlinker @var{flag}
Pass a linker specific flag directly to the linker.
@ -2884,6 +2892,7 @@ use libtool to generate dlopen-accessible modules.
@menu
* Building modules:: Creating dlopenable objects and libraries.
* Dlpreopening:: Dlopening that works on static platforms.
* Linking with dlopened modules:: Using dlopenable modules in libraries.
* Finding the dlname:: Choosing the right file to @code{dlopen}.
* Dlopen issues:: Unresolved problems that need your attention.
@end menu
@ -3071,6 +3080,112 @@ symbols preloaded into @samp{libhell}, you must prefix
@end deftypefun
@node Linking with dlopened modules
@section Linking with dlopened modules
@cindex linking, dlopen
@cindex linking, dlpreopen
When, say, an interpreter application uses dlopened modules to extend
the list of methods it provides, an obvious abstraction for the
maintainers of the interpreter is to have all methods (including the
built in ones supplied with the interpreter) accessed through
dlopen. For one thing, the dlopening functionality will be tested
even during routine invocations. For another, only one subsystem has
to be written for getting methods into the interpreter.
The downside of this abstraction is, of course, that environments that
provide only static linkage can't even load the intrinsic interpreter
methods. Not so! We can statically link those methods by
@strong{dlpreopening} them.
Unfortunately, since platforms such as @sc{aix} and cygwin require
that all library symbols must be resolved at compile time, the
interpreter maintainers will need to provide a library to both its own
dlpreopened modules, and third-party modules loaded by dlopen. In
itself, that is not so bad, except that the interpreter too must
provide those same symbols otherwise it will be impossible to resolve
all the symbols required by the modules as they are loaded. Things
are even worse if the code that loads the modules for the interpreter
is itself in a library -- and that is usually the case for any
non-trivial application. Modern platforms take care of this by
automatically loading all of a module's dependency libraries as the
module is loaded (libltdl can do this even on platforms that can't do
it by themselves). In the end, this leads to problems with duplicated
symbols and prevents modules from loading, and prevents the
application from compiling when modules are preloaded.
@example
,-------------. ,------------------. ,-----------------.
| Interpreter |----> Module------------> Third-party |
`-------------' | Loader | |Dlopened Modules |
| | | `-----------------'
|,-------v--------.| |
|| Dlpreopened || |
|| Modules || |
|`----------------'| |
| | | |
|,-------v--------.| ,--------v--------.
||Module Interface|| |Module Interface |
|| Library || | Library |
|`----------------'| `-----------------'
`------------------'
@end example
Libtool has the concept of @dfn{weak library interfaces} to circumvent
this problem. Recall that the code that dlopens method-provider
modules for the interpreter application resides in a library: All of
the modules and the dlopener library itself should be linked against
the common library that resolves the module symbols at compile time.
To guard against duplicate symbol definitions, and for dlpreopened
modules to work at all in this scenario, the dlopener library must
declare that it provides a weak library interface to the common
symbols in the library it shares with the modules. That way, when
@command{libtool} links the @strong{Module Loader} library with some
@strong{Dlpreopened Modules} that were in turn linked against the
@strong{Module Interface Library}, it knows that the @strong{Module
Loader} provides an already loaded @strong{Module Interface Library}
to resolve symbols for the @strong{Dlpreopened Modules}, and doesn't
ask the compiler driver to link an identical @strong{Module Interface
Library} dependency library too.
In conjunction with Automake, the @file{Makefile.am} for the
@strong{Module Loader} might look like this:
@example
lib_LTLIBRARIES = libinterface.la libloader.la
libinterface_la_SOURCES = interface.c interface.h
libinterface_la_LDFLAGS = -version-info 3:2:1
libloader_la_SOURCES = loader.c
libloader_la_LDFLAGS = -weak libinterface.la \
-version-info 3:2:1 \
-dlpreopen ../modules/intrinsics.la
libloader_la_LIBADD = $(libinterface_la_OBJECTS)
@end example
And the @file{Makefile.am} for the @file{intrinsics.la} module in a
sibling @file{modules} directory might look like this:
@example
AM_CPPFLAGS = -I$(srcdir)/../libloader
AM_LDFLAGS = -no-undefined -module -avoid-version \
-export-dynamic
noinst_LTLIBRARIES = intrinsics.la
intrinsics_la_LIBADD = ../libloader/libinterface.la
../libloader/libinterface.la:
cd ../libloader; $(MAKE) $(AM_MAKEFLAGS) libinterface.la
@end example
@cindex -weak option
For a more complex example, see the sources of @file{libltdl} in the
Libtool distribution, which is built with the help of the @samp{-weak}
option.
@node Finding the dlname
@section Finding the correct name to dlopen
@cindex names of dynamic modules

View File

@ -62,7 +62,7 @@ libltdl_la_LIBADD = libdlloader.la
libltdlc_la_SOURCES = $(libltdl_la_SOURCES)
libltdlc_la_CPPFLAGS = -DLTDLOPEN=libltdlc $(AM_CPPFLAGS)
libltdlc_la_LDFLAGS = $(LT_DLPREOPEN)
libltdlc_la_LDFLAGS = -weak libdlloader.la $(LT_DLPREOPEN)
libltdlc_la_LIBADD = $(libdlloader_la_OBJECTS) $(libdlloader_la_LIBADD)
## These are installed as a subdirectory of pkgdatadir so that