aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org>2019-12-09 08:46:56 +0200
committerSergey Poznyakoff <gray@gnu.org.ua>2019-12-14 12:49:41 +0200
commit7b871d62b657f1711c9355854f7e06e4ac04ad55 (patch)
tree1b029857b51f6fa13a3d6f12a4b67bf0ebabfeac
downloadltbug-master.tar.gz
ltbug-master.tar.bz2
Initial revisionHEADmaster
-rw-r--r--.gitignore19
-rw-r--r--Makefile32
-rw-r--r--README102
-rw-r--r--doc/.gitignore1
-rw-r--r--doc/Makefile11
-rw-r--r--doc/html.init55
-rw-r--r--doc/ltb1.texi160
-rw-r--r--doc/ltb2.texi167
-rw-r--r--doc/ltbug.texi108
-rw-r--r--doc/style.css49
-rw-r--r--ltb1/.gitignore1
-rw-r--r--ltb1/Makefile.am4
-rw-r--r--ltb1/configure.ac28
-rw-r--r--ltb1/lib/Makefile.am3
-rw-r--r--ltb1/lib/libltb1.c8
-rw-r--r--ltb1/ltb1.h2
-rw-r--r--ltb1/src/.gitignore1
-rw-r--r--ltb1/src/Makefile.am6
-rw-r--r--ltb1/src/main.c9
-rw-r--r--ltb1/test.sh162
-rw-r--r--ltb2/Makefile28
-rw-r--r--ltb2/ltb2/.gitignore1
-rw-r--r--ltb2/ltb2/Makefile.am4
-rw-r--r--ltb2/ltb2/configure.ac26
-rw-r--r--ltb2/ltb2/liba/Makefile.am3
-rw-r--r--ltb2/ltb2/liba/libltb2a.c8
-rw-r--r--ltb2/ltb2/libb/Makefile.am3
-rw-r--r--ltb2/ltb2/libb/libltb2b.c8
-rw-r--r--ltb2/ltb2/ltb2.h2
-rw-r--r--ltb2/ltb2/src/Makefile.am5
-rw-r--r--ltb2/ltb2/src/main.c10
-rw-r--r--ltb2/ltb2dep/.gitignore1
-rw-r--r--ltb2/ltb2dep/Makefile.am2
-rw-r--r--ltb2/ltb2dep/configure.ac26
-rw-r--r--ltb2/ltb2dep/main.c7
-rw-r--r--ltb2/test.sh171
-rw-r--r--patches/0001-ltmain.in-append-rpath-option-arguments-to-finalize_.patch50
-rw-r--r--patches/0001-ltmain.in-ensure-that-local-source-tree-directories-.patch71
-rw-r--r--patches/0002-ltmain.in-ensure-that-local-source-tree-directories-.patch69
-rw-r--r--patches/Makefile13
-rw-r--r--patches/libtool-2.4.6-ltb1-2.patch83
41 files changed, 1519 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..4710001
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,19 @@
+.emacs*
+*~
+*.l[oa]
+*.[oa]
+.deps
+.libs
+Makefile.in
+libtool
+m4
+COPYING
+INSTALL
+aclocal.m4
+autom4te.cache
+build-aux
+config.log
+config.status
+configure
+*.tar.gz
+.makevars
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..2144e0c
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,32 @@
+all: ltbug-1.tar.gz ltbug-2.tar.gz
+
+ltbug-1.tar.gz: ltb1-autoconf
+ rm -rf _build
+ mkdir _build
+ (cd _build && \
+ ../ltb1/configure && \
+ make dist)
+ mv _build/ltbug-1.tar.gz .
+ rm -rf _build
+
+ltb1-autoconf:
+ cd ltb1 && autoreconf -i -s
+
+ltbug-2.tar.gz: ltb2-autoconf
+ make -C ltb2 dist
+ mv ltb2/ltbug-2.tar.gz .
+
+ltb2-autoconf:
+ cd ltb2/ltb2dep && autoreconf -i -s
+ cd ltb2/ltb2 && autoreconf -i -s
+
+ifneq (,$(wildcard .makevars))
+ include .makevars
+else
+ $(error Required file .makevars does not exist)
+endif
+
+publish: all
+ $(MAKE) -C doc publish
+ $(MAKE) -C patches publish
+ scp ltbug-1.tar.gz ltbug-2.tar.gz $(DISTLOC)
diff --git a/README b/README
new file mode 100644
index 0000000..ba64de4
--- /dev/null
+++ b/README
@@ -0,0 +1,102 @@
+* Overview
+
+This is a testcase for what seems to be a bug in the libtool.
+
+* Synopsis
+
+Imagine a project consististing of at least one installable shared
+library and installable binary program, which is linked with that
+library. The problem manifests itself on systems where relink_command
+is set in the resulting wrapper script for the binary, such as
+GNU/Linux, if one or more -Wl,-rpath linker options appear in the
+_LDFLAGS variable of the Makefile.am responsible for building the
+binary. When this happens, directories supplied with these options
+take precedence over locations in the build tree. If a previous
+version of the library is already installed on the system and one of
+the -Wl,-rpath options points to its location, the local version of
+the binary (.libs/lt-name) will be linked with the installed library,
+instead of its local copy. This leads to undesirable consequences,
+e.g. if the package provides a test suite, it will likely fail, since
+it will be using old library version.
+
+* Real-life case
+
+The present testcase has been derived from a real life case I
+encountered in GNU mailutils [1]. The package can optionally be built
+with MIT Kerberos [2]. The configure script uses the krb5-config tool
+to obtain the linker options needed for linking with the library. The
+tool is invoked as "krb5-config --libs" and its output is then added
+to the *_LDADD variable of several Makefile.am's via the substitution
+variable [3]. However, it happens that the output in question
+contains the -Wl,-rpath linker option, e.g.:
+
+ $ krb5-config --libs
+ -L/usr/lib64 -Wl,--enable-new-dtags -Wl,-rpath -Wl,/usr/lib64 -lkrb5 -lk5crypto -lcom_err
+
+When this option makes its way to the *_LDADD variable, the local (not
+yet installed) version of the mailutils programs uses old libraries if
+a prior version of mailutils is already installed.
+
+* The test case
+
+I attempted to create a minimal testcase. It consists of:
+
+ - lib/libltb1.la
+ A library providing a single test function ltb_version(), which
+ prints on stdout an identifier string defined at compile time.
+ - src/ltr1
+ A binary linked with libltb1.la and invoking ltb_version().
+ The ltb1_LDFLAGS variable contains the expansion of the variable
+ CF_LIB_FLAGS, defined in configure.ac and containing -Wl.-rpath
+ -Wl,/usr/local/lib
+
+* Testing
+
+Follow these steps:
+
+1. Configure the package with a prominent identifier string:
+
+ ./configure LTBUG_ID='installed'
+
+2. Make and install it to /usr/local:
+
+ make
+ make install # obviously, as root
+
+3. Clean up the source tree:
+
+ make distclean
+
+4. Configure the package with another identifier and build it again:
+
+ ./configure LTBUG_ID='local'
+ make
+
+6. Run src/lbt1. It will display
+
+ ltbug: installed
+
+instead of the expected
+
+ ltbug: local
+
+Inspecting the src/lt-lbt1 binary with ldd shows that it is linked
+against installed version of libltb1.so
+
+* Proposed solution
+
+So far, mailutils filters out all '-Wl,' options from the output of
+the external config tool, before assigning it to the substitution
+variable. However, that does not seem to be a right solution. The
+proposed patch to ltmain.in ensures that any arguments to -Wl,-rpath
+options are appended to the end of the linker command line, after any
+eventual local directories [4]. The patch is built for the commit
+b9b44533fbf7c7752ffd255c3d09cc360e24183b of libtool.
+
+* References
+
+[1] https://mailutils.org
+[2] http://web.mit.edu/kerberos/
+[3] http://git.savannah.gnu.org/cgit/mailutils.git/tree/am/gssapi.m4
+ (mirror at http://git.gnu.org.ua/cgit/mailutils.git/tree/am/gssapi.m4)
+[4] 0001-ltmain.in-append-rpath-option-arguments-to-finalize_.patch
diff --git a/doc/.gitignore b/doc/.gitignore
new file mode 100644
index 0000000..2d19fc7
--- /dev/null
+++ b/doc/.gitignore
@@ -0,0 +1 @@
+*.html
diff --git a/doc/Makefile b/doc/Makefile
new file mode 100644
index 0000000..b27cf48
--- /dev/null
+++ b/doc/Makefile
@@ -0,0 +1,11 @@
+ifneq (,$(wildcard ../.makevars))
+ include ../.makevars
+else
+ $(error Required file ../.makevars does not exist)
+endif
+
+ltbug.html: ltbug.texi ltb1.texi ltb2.texi html.init
+ makeinfo --html --no-headers --no-split --init-file=html.init ltbug.texi
+
+publish: ltbug.html
+ scp ltbug.html $(DISTLOC)/index.html
diff --git a/doc/html.init b/doc/html.init
new file mode 100644
index 0000000..8b29bd8
--- /dev/null
+++ b/doc/html.init
@@ -0,0 +1,55 @@
+# Texi2any configuration for ltbug1 documentation. -*- perl -*-
+# Copyright (C) 2009-2019 Sergey Poznyakoff
+use strict;
+
+# Show TOC in place of the @contents directive.
+set_from_init_file('INLINE_CONTENTS', 1);
+# Do not show Texinfo menus.
+set_from_init_file('SHOW_MENU', 0);
+# Inhibit output of CSS lines in page headers.
+set_from_init_file('CSS_LINES', '');
+
+set_from_init_file('BODYTEXT', "");
+
+set_from_init_file('EXTRA_HEAD', "\
+ <link rev=\"made\" href=\"mailto:gray\@gnu.org.ua\">\
+ <link rel=\"stylesheet\" type=\"text/css\" href=\"style.css\">");
+
+sub gray_end_file($)
+{
+ my $self = shift;
+ my $program_text = '';
+ if ($self->get_conf('PROGRAM_NAME_IN_FOOTER')) {
+ my $program_string = &{$self->{'format_program_string'}}($self);
+ $program_text = "<p>
+ $program_string
+</p>";
+ }
+ my $pre_body_close = $self->get_conf('PRE_BODY_CLOSE');
+ $pre_body_close = '' if (!defined($pre_body_close));
+ return "
+<div class=\"copyright\">
+$program_text
+
+$pre_body_close
+</div>
+</body>
+</html>
+";
+}
+
+texinfo_register_formatting_function('end_file', \&gray_end_file);
+
+set_from_init_file('PRE_BODY_CLOSE',
+'<p>Copyright (C) 2019 <a href="mailto:gray@gnu.org">Sergey Poznyakoff</a></p>
+<p>
+Content is available under <a href="http://www.gnu.org/copyleft/fdl.html">GNU Free Documentation License 1.3</a>.
+</p>');
+
+# Print generating program name at the bottom of a page.
+set_from_init_file('PROGRAM_NAME_IN_FOOTER',1);
+
+# Disable horizontal bars
+set_from_init_file('DEFAULT_RULE', '');
+set_from_init_file('BIG_RULE', '');
+
diff --git a/doc/ltb1.texi b/doc/ltb1.texi
new file mode 100644
index 0000000..745eeba
--- /dev/null
+++ b/doc/ltb1.texi
@@ -0,0 +1,160 @@
+@node Synopsis
+@unnumbered Synopsis
+
+Imagine a project consisting of at least one installable shared
+library (@file{libltb1}) and an installable binary program
+(@file{ltb1}), which is linked with that library. If the
+@samp{ltb1_LDFLAGS} variable contains one or more @option{-Wl,-rpath}
+linker options, the created wrapper script will prefer directories
+listed in them over locations in the build tree. If a previous
+version of the @file{libltb1} library is already installed in one of
+these directories, the @file{ltb1} wrapper will use the installed
+version of the library, instead of the one from the source tree.
+This leads to undesirable consequences, e.g. if the package provides a
+test suite, it will likely fail, since it will be using old library
+version.
+
+@node Background
+@unnumbered Background
+
+The issue was observed when building @uref{https://mailutils.org,GNU
+mailutils} with @uref{http://web.mit.edu/kerberos/,MIT Kerberos}. The
+Mailutils configure script uses the @file{krb5-config} tool to obtain
+the linker options needed for linking with the library. The tool is
+invoked as @samp{krb5-config --libs} and its output is then added to the
+@samp{*_LDADD} variable of several Makefile.am's via the
+@uref{http://git.savannah.gnu.org/cgit/mailutils.git/tree/am/gssapi.m4,
+substitution variable}. The output in question looks like:
+
+@example
+ $ krb5-config --libs
+ -L/usr/lib64 -Wl,--enable-new-dtags -Wl,-rpath -Wl,/usr/lib64 -lkrb5 -lk5crypto -lcom_err
+@end example
+
+When the @option{-Wl,-rpath} option makes its way to the
+@samp{*_LDADD} variable, the wrapper scripts created for mailutils
+programs use libraries from the prior version of mailutils (installed
+in @file{/usr/lib64}).
+
+The problem is attested on GNU/Linux and FreeBSD systems
+(@pxref{affected systems}).
+
+@node The test case
+@unnumbered The test case
+
+The problem is illustrated by a testcase available for download from
+@uref{ltbug-1.tar.gz}. It consists of the following principal parts:
+
+@itemize @bullet
+@item @file{lib/libltb1.la}
+
+A library providing a single test function @samp{ltb_version()}, which
+prints on stdout an identifier string defined at compile time.
+
+@item @file{src/ltb1}
+
+A binary linked with @file{libltb1.la} and invoking @samp{ltb_version()}.
+The @code{ltb1_LDFLAGS} variable contains the expansion of the variable
+@code{CF_LIB_FLAGS}, defined in configure.ac and containing
+@option{-Wl.-rpath -Wl,$(libdir)}.
+
+@item Build framework created by autotools with @command{libtool} 2.4.6.
+@end itemize
+
+@unnumbered Testing
+
+Unpack @file{ltbug-1.tar.gz} and run @command{sh
+ltbug-1/test.sh}. This test script does the following:
+
+@enumerate 1
+@item Creates workspace and installation directory.
+
+Workspace directory @file{ltb-test1} is created in the current working
+directory. The installation directory with the same name is created in
+@file{/tmp}.
+
+@item Configures the package with a prominent identifier string.
+
+The identifier string @samp{installed} will be printed by the
+@code{ltb_version} function if called from the installed version of
+the library.
+
+@item Installs it to the installation directory.
+
+@item Configures the package with another identifier and builds it.
+
+The identifier string @samp{local} will be printed by the
+@code{ltb_version} function if the library from the local source tree
+is used.
+
+@item Runs @command{src/lbt1}.
+@end enumerate
+
+The test produces the following output:
+
+@example
+Building and installing project
+Building local copy of the project
+Running test program
+Test failed:
+--- expout 2019-12-13 11:46:13.489649518 +0200
++++ stdout 2019-12-13 11:46:13.517649520 +0200
+@@ -1 +1 @@
+-ltbug: local
++ltbug: installed
+Keeping the directories in place. When no longer needed, run:
+rm -rf /tmp/ltb-test1
+rm -rf ltb-test1
+@end example
+
+This shows that the installed copy of the library is used when the
+local wrapper @file{src/ltb1} is run.
+
+The test script leaves two directories for examination:
+the installation prefix directory @file{/tmp/ltb-test1}, and working
+directory @file{ltb-test1}. The latter contains the following files
+and directories:
+
+@table @file
+@item build_inst
+A directory where the installed version of the package was built.
+
+@item build_local
+Local build directory. The test runs @command{build_local/src/ltb1}.
+
+@item expout
+Expected standard output.
+
+@item stdout
+Obtained standard output.
+
+@item ltb2.out
+Standard output generated by the build process.
+
+@item ltb2.err
+Standard output generated by the build process.
+@end table
+
+The test script can be used with the following command line options:
+
+@table @option
+@item -p @var{dir}
+@itemx --prefix=@var{dir}
+Set root directory for the installation prefix. The prefix directory
+is @file{@var{dir}/ltb-test1}.
+
+@item -C @var{dir}
+@itemx --directory=@var{dir}
+Set test working directory root. Default is current working
+directory. The test directory name is constructed as
+@file{@var{dir}/ltb-test1}.
+
+@item --keep
+Keep test and installation directories for inspection. This is the
+default if the test fails.
+
+@item --help
+Display short usage summary.
+@end table
+
+
diff --git a/doc/ltb2.texi b/doc/ltb2.texi
new file mode 100644
index 0000000..ade5b41
--- /dev/null
+++ b/doc/ltb2.texi
@@ -0,0 +1,167 @@
+@unnumbered Synopsis
+
+Let a project consist of two installable libraries and a binary
+(@file{ltb2}) linked to both of them. One of the libraries depends on
+an external library, which has a libtool archive installed along with
+the shared library. The figure below illustrates this scheme:
+
+@example
+@group
+ ltb2 <---+-- liba <==== @file{@var{libdir}}/libdep.la
+ |
+ +-- libb
+@end group
+@end example
+
+Then, for GNU/Linux systems the wrapper script would issue the relink
+command that ends with the following options (split along multiple
+lines for readability):
+
+@example
+-Wl,-rpath -Wl,@var{srcdir}/liba/.libs
+-Wl,-rpath -Wl,@var{libdir}
+-Wl,-rpath -Wl,@var{srcdir}/libb/.libs
+-Wl,-rpath -Wl,@var{libdir}
+@end example
+
+For FreeBSD, the @env{LD_LIBRARY_PATH} used by the wrapper will look
+like:
+
+@example
+@var{srcdir}/liba/.libs:@var{libdir}:@var{srcdir}/libb/.libs:$LD_LIBRARY_PATH
+@end example
+
+In both cases, the @file{@var{libdir}} directory appearing before
+@file{libb} will cause the @file{libb} library to be searched in
+@file{@var{libdir}} first. If a prior version of the project is
+installed in the same prefix as the @file{libdep} library, then the
+@command{ltb2} wrapper will use the version of @file{liba} from the
+local source tree, but the version of @file{libb} installed on the
+system.
+
+@unnumbered Background
+
+The issue was initially discovered when building @uref{https://mailutils.org,GNU
+mailutils} on FreeBSD with support for OpenLDAP enabled. The latter
+incurred dependency on @file{libldap}, which was installed (along with
+@file{libldap.la}) in @file{/usr/local/lib}.
+
+The package built in these conditions failed most tests because it was
+using mailutils libraries from prior version, installed in
+@file{/usr/local/lib}.
+
+The issue has been confirmed to exist on GNU/Linux as well
+(@pxref{affected systems}).
+
+@unnumbered The test case
+
+A minimal testcase is available for download from
+@uref{ltbug-2.tar.gz}. It consists of two subpackages:
+@file{ltb2dep} implementing the dependency library, and the main
+test package @file{ltb2}. The latter builds and installs two libraries:
+@file{liba} and @file{libb}, and a test program @command{ltb2}, linked
+with both of these. The @file{liba} library provides the function
+@samp{ltb2a_version}. The @file{libb} library implements a similar
+function @samp{ltb2b_version}. Both functions print on the standard
+output the value of the @samp{LTBUG_ID} macro defined at the compile
+time. The @command{ltb2} program calls both functions in order.
+
+The test script first builds and installs the dependency library
+@file{ltb2dep}. Then, it builds the package with
+@code{LTBUG_ID="installed"} and installs it. When run, the installed
+@command{ltb2} program will output
+
+@example
+ltb2a: installed
+ltb2b: installed
+@end example
+
+Finally, the test rebuilds the package with @code{LTBUG_ID="local"}
+and runs the @command{ltb2} program from the source tree. The program
+then outputs:
+
+@example
+ltb2a: local
+ltb2b: installed
+@end example
+
+@noindent
+This shows that the command uses @file{libltb2a} from the local source
+tree and @file{libltb2b} previously installed on the system.
+
+Follow these steps to run the test:
+
+@enumerate 1
+@item Unpack the archive
+
+@example
+tar xf ltbug-2.tar.gz
+@end example
+
+@item Run
+
+@example
+sh ltbug-2/test.sh
+@end example
+
+@noindent
+or
+
+@example
+make -C ltbug-2 check
+@end example
+
+@end enumerate
+
+If the bug is present, you will see the following output:
+
+@example
+Building dependency library
+Building and installing project
+Building local copy of the project
+Running test program
+Test failed:
+--- expout 2019-12-12 13:45:53.193782824 +0200
++++ stdout 2019-12-12 13:45:53.222782826 +0200
+@@ -1,2 +1,2 @@
+ ltb2a: local
+-ltb2b: local
++ltb2b: installed
+Keeping the directories in place. When no longer needed, run:
+rm -rf /tmp/ltb-test2
+rm -rf ltb-test2
+make: *** [check] Error 1
+@end example
+
+The directory @file{ltb-test2} will be left on disk for examination.
+It will contain:
+
+@table @file
+@item build_dep
+Build directory for the dependency library @file{libltb2dep}.
+
+@item build_inst
+A directory where the installed version of the package was built.
+
+@item build_local
+Local build directory. The test runs @command{build_local/src/ltb2}.
+
+@item expout
+Expected standard output.
+
+@item stdout
+Obtained standard output.
+
+@item ltb2.out
+Standard output generated by the build process.
+
+@item ltb2.err
+Standard output generated by the build process.
+@end table
+
+The test script takes the same command line options as described above
+for the @file{ltb1} test.
+
+
+
+
diff --git a/doc/ltbug.texi b/doc/ltbug.texi
new file mode 100644
index 0000000..9f6f983
--- /dev/null
+++ b/doc/ltbug.texi
@@ -0,0 +1,108 @@
+\input texinfo @c -*-texinfo-*-
+@c %**start of header
+@settitle Two libtool issues
+
+@node Abstract
+@unnumbered Abstract
+
+@uref{https://www.gnu.org/software/libtool,GNU libtool} is a generic
+library support script used by many software packages as a portable
+interface for creating shared libraries. In contrast to the
+conventional approach where the build process results in binary
+programs and libraries being created, libtool produces, along with
+each binary, a @dfn{wrapper script} which is used to invoke that
+binary from the source tree. The wrapper invokes the binary in such
+way as to guarantee that shared objects from the local source tree are
+preferred over those already installed on the systems.
+
+It has been discovered that under certain conditions @command{libtool}
+creates wrappers that prefer installed versions of the shared objects
+over those built in the source tree. This makes results of any tests
+run in the source tree unreliable.
+
+This article describes two such cases. Minimal test suites are
+provided. Patches for libtool are proposed, both for the current
+stable version and the recent commit in the repository.
+
+@node ltb1
+@unnumbered Issue 1 (LTB1)
+@lowersections
+@include ltb1.texi
+@raisesections
+
+@node ltb2
+@unnumbered Issue 2 (LTB2)
+@lowersections
+@include ltb2.texi
+@raisesections
+
+@node affected systems
+@unnumbered Affected Systems
+The following systems are known to be affected:
+
+@itemize @bullet
+@item GNU/Linux
+@example
+host-triplet: x86_64-pc-linux-gnu
+shell: /bin/sh
+compiler: gcc
+compiler flags: -g -O2
+linker: /usr/x86_64-slackware-linux/bin/ld -m elf_x86_64 (gnu? yes)
+version: libtool (GNU libtool) 2.4.6
+automake: automake (GNU automake) 1.15
+autoconf: autoconf (GNU Autoconf) 2.69
+@end example
+
+@item GNU/Linux with libtool from repository
+@example
+host-triplet: x86_64-pc-linux-gnu
+shell: /bin/sh
+compiler: gcc
+compiler flags: -g -O2
+linker: /usr/x86_64-slackware-linux/bin/ld -m elf_x86_64 (gnu? yes)
+version: libtool (GNU libtool) 2.4.6.44-b9b4
+automake: automake (GNU automake) 1.15
+autoconf: autoconf (GNU Autoconf) 2.69
+@end example
+
+@item FreeBSD
+@example
+host-triplet: amd64-portbld-freebsd12.0
+shell: /bin/sh
+compiler: cc
+compiler flags: -O2 -pipe -fstack-protector-strong -fno-strict-aliasing
+linker: /usr/bin/ld (gnu? yes)
+version: libtool (GNU libtool) 2.4.6
+automake: automake (GNU automake) 1.16.1
+autoconf: autoconf (GNU Autoconf) 2.69
+@end example
+@end itemize
+
+@node patches
+@unnumbered Proposed Fixes
+
+Patches are available both for the current stable and for the
+repository version of GNU libtool. Both patched versions successfully
+pass libtool tests as well as the ltb1 and ltb2 tests.
+
+@unnumberedsec Patches for libtool git HEAD
+
+These patches were built over
+@uref{http://git.savannah.gnu.org/cgit/libtool.git/commit/?id=b9b44533fbf7c7752ffd255c3d09cc360e24183b,
+commit b9b44533fbf7c7752ffd255c3d09cc360e24183b}:
+
+@enumerate 1
+@item
+@uref{0001-ltmain.in-append-rpath-option-arguments-to-finalize_.patch}
+@item
+@uref{0002-ltmain.in-ensure-that-local-source-tree-directories-.patch}
+@end enumerate
+
+The patches should be applied in order.
+
+@unnumberedsec Patch for libtool version 2.4.6
+
+Cumulative patch: @uref{libtool-2.4.6-ltb1-2.patch}.
+
+@bye
+
diff --git a/doc/style.css b/doc/style.css
new file mode 100644
index 0000000..f1450ee
--- /dev/null
+++ b/doc/style.css
@@ -0,0 +1,49 @@
+/* Basic settings */
+body {
+ font-family: serif;
+ font-size: 120%;
+ color: #333;
+ background: white;
+ padding: 4px;
+ margin-top: 0;
+ margin-bottom: 2em;
+ margin-left: 5%;
+ margin-right: 5%;
+}
+
+a {
+ color: blue;
+ text-decoration: none;
+}
+
+a:hover {
+ text-decoration: underline;
+}
+
+img {
+ border: none 0;
+ vertical-align: top;
+}
+
+table {
+ border-collapse: collapse;
+}
+
+.right {
+ text-align: right;
+}
+
+dt {
+ font-weight: bold;
+}
+
+/* Copyright section */
+div.copyright {
+ font-size: 80%;
+ padding: 4px;
+ border-top: solid 2px black;
+}
+
+div.header {
+ border-bottom: solid 2px black;
+}
diff --git a/ltb1/.gitignore b/ltb1/.gitignore
new file mode 100644
index 0000000..f3c7a7c
--- /dev/null
+++ b/ltb1/.gitignore
@@ -0,0 +1 @@
+Makefile
diff --git a/ltb1/Makefile.am b/ltb1/Makefile.am
new file mode 100644
index 0000000..b8ff110
--- /dev/null
+++ b/ltb1/Makefile.am
@@ -0,0 +1,4 @@
+ACLOCAL_AMFLAGS = -I m4
+SUBDIRS = lib src
+noinst_HEADERS = ltb1.h
+EXTRA_DIST = test.sh
diff --git a/ltb1/configure.ac b/ltb1/configure.ac
new file mode 100644
index 0000000..690edc3
--- /dev/null
+++ b/ltb1/configure.ac
@@ -0,0 +1,28 @@
+# -*- Autoconf -*-
+# Process this file with autoconf to produce a configure script.
+
+AC_PREREQ([2.69])
+AC_INIT([ltbug], [1], [gray@gnu.org])
+AC_CONFIG_SRCDIR([src/main.c])
+AC_CONFIG_AUX_DIR([build-aux])
+AC_CONFIG_MACRO_DIR([m4])
+
+AM_INIT_AUTOMAKE([1.15 foreign])
+
+# Checks for programs.
+AC_PROG_CC
+LT_PREREQ([2.4.6])
+LT_INIT
+
+AC_ARG_VAR([LTBUG_ID],[Identifier of the bug case])
+if test -z "$LTBUG_ID"; then
+ LTBUG_ID="local"
+fi
+AC_DEFINE_UNQUOTED([LTBUG_ID],["$LTBUG_ID"],
+ [Text string identifying the library])
+
+AC_SUBST([CF_LIB_FLAGS],['-L$(libdir) -Wl,-rpath -Wl,$(libdir)'])
+
+AC_CONFIG_FILES([Makefile lib/Makefile src/Makefile])
+
+AC_OUTPUT
diff --git a/ltb1/lib/Makefile.am b/ltb1/lib/Makefile.am
new file mode 100644
index 0000000..88289f3
--- /dev/null
+++ b/ltb1/lib/Makefile.am
@@ -0,0 +1,3 @@
+lib_LTLIBRARIES = libltb1.la
+libltb1_la_SOURCES = libltb1.c
+libltb1_la_CPPFLAGS=-I$(top_srcdir)
diff --git a/ltb1/lib/libltb1.c b/ltb1/lib/libltb1.c
new file mode 100644
index 0000000..a81df69
--- /dev/null
+++ b/ltb1/lib/libltb1.c
@@ -0,0 +1,8 @@
+#include <stdio.h>
+
+void
+ltb_version (void)
+{
+ printf ("ltbug: %s\n", LTBUG_ID);
+}
+
diff --git a/ltb1/ltb1.h b/ltb1/ltb1.h
new file mode 100644
index 0000000..4350c74
--- /dev/null
+++ b/ltb1/ltb1.h
@@ -0,0 +1,2 @@
+extern void ltb_version (void);
+extern void ltb2_version (void);
diff --git a/ltb1/src/.gitignore b/ltb1/src/.gitignore
new file mode 100644
index 0000000..6a17948
--- /dev/null
+++ b/ltb1/src/.gitignore
@@ -0,0 +1 @@
+ltb1
diff --git a/ltb1/src/Makefile.am b/ltb1/src/Makefile.am
new file mode 100644
index 0000000..e6644fd
--- /dev/null
+++ b/ltb1/src/Makefile.am
@@ -0,0 +1,6 @@
+bin_PROGRAMS = ltb1
+ltb1_SOURCES = main.c
+ltb1_LDFLAGS = $(CF_LIB_FLAGS)
+ltb1_LDADD = ../lib/libltb1.la
+AM_CPPFLAGS = -I$(top_srcdir)
+
diff --git a/ltb1/src/main.c b/ltb1/src/main.c
new file mode 100644
index 0000000..d894b54
--- /dev/null
+++ b/ltb1/src/main.c
@@ -0,0 +1,9 @@
+#include <ltb1.h>
+
+int
+main (int argc, char **argv)
+{
+ ltb_version ();
+ return 0;
+}
+
diff --git a/ltb1/test.sh b/ltb1/test.sh
new file mode 100644
index 0000000..c8bd165
--- /dev/null
+++ b/ltb1/test.sh
@@ -0,0 +1,162 @@
+#! /bin/sh
+
+set -e
+
+cwdir=$(pwd)
+topdir=$(dirname $0)
+abs_topdir=$(cd $topdir; pwd)
+
+testdir=$cwdir
+prefix=${TMP:-/tmp}
+keep=no
+keep_testdir=no
+
+help() {
+ cat <<EOF
+usage: $0 [OPTIONS]
+Runs LTB1 t