]> git.ipfire.org Git - thirdparty/libtool.git/commitdiff
Add a new `-weak' flag to tell libtool when not to propogate
authorGary V. Vaughan <gary@gnu.org>
Sun, 29 Aug 2004 16:05:34 +0000 (16:05 +0000)
committerGary V. Vaughan <gary@gnu.org>
Sun, 29 Aug 2004 16:05:34 +0000 (16:05 +0000)
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.

ChangeLog
NEWS
config/ltmain.in
doc/libtool.texi
libltdl/Makefile.am

index d3d485f61b7e8436d819b8a910b1513695c361ef..90ba1412a06e03ce5d4cef6e165d95bcdfc62cd3 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -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.
diff --git a/NEWS b/NEWS
index 3e3ea5a7ffcd3c520ffd5ef205cb0f73ef26ef66..926e220207f43e71f98a101fa7257f249443d300 100644 (file)
--- 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.
index 844b68abbc80d080f0d445cf1b7691db0b1bac83..70afb390a7cac16a4487668f21969424f620a1f3 100644 (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,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
index f94ac755a80010bc9e1097ef9d35b0a74fc4916a..1fc1402a3f5353bef51fe699c9c386f8744a964b 100644 (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
index 18314af71b7d120511612262d10fd28cc71489b1..c7303880f6ac23c5417ca65cd1f919cbd9747409 100644 (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