From: Gary V. Vaughan Date: Sun, 29 Aug 2004 16:05:34 +0000 (+0000) Subject: Add a new `-weak' flag to tell libtool when not to propogate X-Git-Tag: release-1-9b~5 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=01584288757a4821d2c1a17ffaca8330381a3745;p=thirdparty%2Flibtool.git 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. --- diff --git a/ChangeLog b/ChangeLog index d3d485f61..90ba1412a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2004-08-29 Gary V. Vaughan + + 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 * 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 + * 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. diff --git a/NEWS b/NEWS index 3e3ea5a7f..926e22020 100644 --- a/NEWS +++ b/NEWS @@ -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. diff --git a/config/ltmain.in b/config/ltmain.in index 844b68abb..70afb390a 100644 --- a/config/ltmain.in +++ b/config/ltmain.in @@ -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,18 +2459,21 @@ func_mode_link () prev= continue ;; - inst_prefix) - inst_prefix_dir="$arg" - prev= - continue - ;; - precious_regex) - precious_files_regex="$arg" + framework) + case $host in + *-*-darwin*) + case "$deplibs " in + *" $qarg.ltframework "*) ;; + *) deplibs="$deplibs $qarg.ltframework" # this is fixed later + ;; + esac + ;; + esac prev= continue ;; - release) - release="-$arg" + inst_prefix) + inst_prefix_dir="$arg" prev= continue ;; @@ -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,19 +2613,14 @@ func_mode_link () prev= continue ;; - xcompiler) - compiler_flags="$compiler_flags $qarg" + shrext) + shrext_cmds="$arg" prev= - compile_command="$compile_command $qarg" - finalize_command="$finalize_command $qarg" continue ;; - xlinker) - linker_flags="$linker_flags $qarg" - compiler_flags="$compiler_flags $wl$qarg" + weak) + weak_libs="$weak_libs $arg" prev= - compile_command="$compile_command $wl$qarg" - finalize_command="$finalize_command $wl$qarg" continue ;; xcclinker) @@ -2621,22 +2631,19 @@ func_mode_link () 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 + xcompiler) + compiler_flags="$compiler_flags $qarg" prev= + compile_command="$compile_command $qarg" + finalize_command="$finalize_command $qarg" continue ;; - shrext) - shrext_cmds="$arg" + xlinker) + linker_flags="$linker_flags $qarg" + compiler_flags="$compiler_flags $wl$qarg" prev= + compile_command="$compile_command $wl$qarg" + finalize_command="$finalize_command $wl$qarg" continue ;; *) @@ -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 diff --git a/doc/libtool.texi b/doc/libtool.texi index f94ac755a..1fc1402a3 100644 --- a/doc/libtool.texi +++ b/doc/libtool.texi @@ -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 diff --git a/libltdl/Makefile.am b/libltdl/Makefile.am index 18314af71..c7303880f 100644 --- a/libltdl/Makefile.am +++ b/libltdl/Makefile.am @@ -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