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 test.
+See http://gray.gnu.org.ua/public/ltbug#ltb1 for details.
+OPTIONS are:
+
+ -p, --prefix=DIR set installation prefix root
+ (default: $prefix)
+ -C, --directory=DIR set test directory
+ (default: $testdir)
+ --keep keep test and installation directories for inspection
+ (default if the test fails)
+ --help display this help list
+
+EOF
+}
+
+unset arg
+while [ $# -gt 0 ]
+do
+ if [ -n "$arg" ]; then
+ eval $arg="$1"
+ unset arg
+ else
+ case $1 in
+ --prefix)
+ arg=prefix
+ ;;
+ --prefix=*)
+ prefix=${1##--prefix=}
+ ;;
+ -h|--help)
+ help
+ exit 0
+ ;;
+ -C|--directory)
+ arg=testdir
+ ;;
+ -C*)
+ testdir=${1##-C}
+ ;;
+ --directory=*)
+ testdir=${1##--directory=}
+ ;;
+ --keep)
+ keep=yes
+ ;;
+ *)
+ help >&2
+ exit 2
+ esac
+ fi
+ shift
+done
+
+prefix=$(cd $prefix; pwd)/ltb-test1
+testdir=$(cd $testdir; pwd)/ltb-test1
+
+if [ $prefix = $testdir ]; then
+ echo >&2 "prefix and test directory must differ"
+ exit 2
+fi
+
+STDOUT=$testdir/ltb1.out
+STDERR=$testdir/ltb1.err
+
+if [ -d $testdir ]; then
+ keep_testdir=yes
+else
+ mkdir $testdir
+fi
+if [ ! -w $testdir ]; then
+ echo >&2 "$0: test directory ($testdir) must be writable"
+ exit 2
+fi
+if [ ! -d $prefix ]; then
+ mkdir $prefix
+fi
+if [ ! -w $prefix ]; then
+ echo >&2 "$0: prefix directory ($prefix) must be writable"
+ exit 2
+fi
+
+abend() {
+ echo >&2 "Failed!"
+ tail -n 5 $STDERR >&2
+ echo >&2 "Examine $STDOUT and $STDERR for details"
+ exit 2
+}
+
+cd $testdir
+
+rm -rf build_inst build_local
+mkdir build_inst build_local
+
+echo "Building and installing project"
+(
+ cd build_inst
+ $abs_topdir/configure --prefix=$prefix LTBUG_ID='installed'
+ make
+ make install
+) 2>>$STDERR >$STDOUT || abend
+
+echo "Building local copy of the project"
+(
+ cd build_local
+ $abs_topdir/configure --prefix=$prefix
+ make
+) 2>>$STDERR >$STDOUT || abend
+
+cat > expout <<EOF
+ltbug: local
+EOF
+
+echo "Running test program"
+
+build_local/src/ltb1 > stdout
+
+if cmp -s stdout expout; then
+ status=0
+else
+ keep=yes
+ echo >&2 "Test failed:"
+ diff -pu expout stdout || true
+ status=1
+fi
+
+cd $cwdir
+
+if [ "$keep" = "yes" ]; then
+ echo "Keeping the directories in place. When no longer needed, run:"
+ dry_run=echo
+else
+ echo "Uninstalling"
+ dry_run=
+fi
+
+$dry_run rm -rf $prefix
+
+if [ "$keep_testdir" = "yes" ]; then
+ $dry_run rm -rf $testdir/build_inst $testdir/build_local
+ $dry_run rm -f $STDERR $STDOUT
+else
+ $dry_run rm -rf $testdir
+fi
+
+exit $status
+
diff --git a/ltb2/Makefile b/ltb2/Makefile
new file mode 100644
index 0000000..fe3c721
--- /dev/null
+++ b/ltb2/Makefile
@@ -0,0 +1,28 @@
+PROJECT=ltbug
+VERSION=2
+
+all:
+ @echo "usage: make check # to check the libtool issue"
+ @echo " or: make dist # to create a distributable archive"
+
+check:
+ @/bin/sh test.sh
+
+DISTDIR=$(PROJECT)-$(VERSION)
+
+distdir:
+ rm -rf $(DISTDIR) _build
+ mkdir $(DISTDIR)
+ cp test.sh Makefile $(DISTDIR)
+ for dir in ltb2dep ltb2; do \
+ rm -rf _build; \
+ mkdir _build && \
+ (cd _build && \
+ ../$$dir/configure && \
+ make distdir distdir=../$(DISTDIR)/$$dir); \
+ done
+ rm -rf _build
+
+dist: distdir
+ tar zvcf $(DISTDIR).tar.gz $(DISTDIR)
+ rm -rf $(DISTDIR)
diff --git a/ltb2/ltb2/.gitignore b/ltb2/ltb2/.gitignore
new file mode 100644
index 0000000..f3c7a7c
--- /dev/null
+++ b/ltb2/ltb2/.gitignore
@@ -0,0 +1 @@
+Makefile
diff --git a/ltb2/ltb2/Makefile.am b/ltb2/ltb2/Makefile.am
new file mode 100644
index 0000000..5e15026
--- /dev/null
+++ b/ltb2/ltb2/Makefile.am
@@ -0,0 +1,4 @@
+ACLOCAL_AMFLAGS = -I m4
+SUBDIRS = liba libb src
+noinst_HEADERS = ltb2.h
+
diff --git a/ltb2/ltb2/configure.ac b/ltb2/ltb2/configure.ac
new file mode 100644
index 0000000..f829992
--- /dev/null
+++ b/ltb2/ltb2/configure.ac
@@ -0,0 +1,26 @@
+# -*- Autoconf -*-
+# Process this file with autoconf to produce a configure script.
+
+AC_PREREQ([2.69])
+AC_INIT([ltb2], [0.2], [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_CONFIG_FILES([Makefile liba/Makefile libb/Makefile src/Makefile])
+
+AC_OUTPUT
diff --git a/ltb2/ltb2/liba/Makefile.am b/ltb2/ltb2/liba/Makefile.am
new file mode 100644
index 0000000..512a82c
--- /dev/null
+++ b/ltb2/ltb2/liba/Makefile.am
@@ -0,0 +1,3 @@
+lib_LTLIBRARIES = libltb2a.la
+libltb2a_la_SOURCES = libltb2a.c
+libltb2a_la_LIBADD = -L$(libdir) -lltb2dep
diff --git a/ltb2/ltb2/liba/libltb2a.c b/ltb2/ltb2/liba/libltb2a.c
new file mode 100644
index 0000000..e9a97c0
--- /dev/null
+++ b/ltb2/ltb2/liba/libltb2a.c
@@ -0,0 +1,8 @@
+#include <stdio.h>
+
+void
+ltb2a_version (void)
+{
+ printf ("ltb2a: %s\n", LTBUG_ID);
+}
+
diff --git a/ltb2/ltb2/libb/Makefile.am b/ltb2/ltb2/libb/Makefile.am
new file mode 100644
index 0000000..8eb5681
--- /dev/null
+++ b/ltb2/ltb2/libb/Makefile.am
@@ -0,0 +1,3 @@
+lib_LTLIBRARIES = libltb2b.la
+libltb2b_la_SOURCES = libltb2b.c
+
diff --git a/ltb2/ltb2/libb/libltb2b.c b/ltb2/ltb2/libb/libltb2b.c
new file mode 100644
index 0000000..90c6569
--- /dev/null
+++ b/ltb2/ltb2/libb/libltb2b.c
@@ -0,0 +1,8 @@
+#include <stdio.h>
+
+void
+ltb2b_version (void)
+{
+ printf ("ltb2b: %s\n", LTBUG_ID);
+}
+
diff --git a/ltb2/ltb2/ltb2.h b/ltb2/ltb2/ltb2.h
new file mode 100644
index 0000000..959d2b8
--- /dev/null
+++ b/ltb2/ltb2/ltb2.h
@@ -0,0 +1,2 @@
+extern void ltb2a_version (void);
+extern void ltb2b_version (void);
diff --git a/ltb2/ltb2/src/Makefile.am b/ltb2/ltb2/src/Makefile.am
new file mode 100644
index 0000000..2eaeda0
--- /dev/null
+++ b/ltb2/ltb2/src/Makefile.am
@@ -0,0 +1,5 @@
+bin_PROGRAMS = ltb2
+ltb2_SOURCES = main.c
+ltb2_LDADD = ../liba/libltb2a.la ../libb/libltb2b.la
+AM_CPPFLAGS = -I$(top_srcdir)
+
diff --git a/ltb2/ltb2/src/main.c b/ltb2/ltb2/src/main.c
new file mode 100644
index 0000000..c80d050
--- /dev/null
+++ b/ltb2/ltb2/src/main.c
@@ -0,0 +1,10 @@
+#include <ltb2.h>
+
+int
+main (int argc, char **argv)
+{
+ ltb2a_version ();
+ ltb2b_version ();
+ return 0;
+}
+
diff --git a/ltb2/ltb2dep/.gitignore b/ltb2/ltb2dep/.gitignore
new file mode 100644
index 0000000..f3c7a7c
--- /dev/null
+++ b/ltb2/ltb2dep/.gitignore
@@ -0,0 +1 @@
+Makefile
diff --git a/ltb2/ltb2dep/Makefile.am b/ltb2/ltb2dep/Makefile.am
new file mode 100644
index 0000000..1f94049
--- /dev/null
+++ b/ltb2/ltb2dep/Makefile.am
@@ -0,0 +1,2 @@
+lib_LTLIBRARIES = libltb2dep.la
+libltb2dep_la_SOURCES = main.c
diff --git a/ltb2/ltb2dep/configure.ac b/ltb2/ltb2dep/configure.ac
new file mode 100644
index 0000000..d13f37b
--- /dev/null
+++ b/ltb2/ltb2dep/configure.ac
@@ -0,0 +1,26 @@
+# -*- Autoconf -*-
+# Process this file with autoconf to produce a configure script.
+
+AC_PREREQ([2.69])
+AC_INIT([libltb2dep], [0.2], [gray@gnu.org])
+AC_CONFIG_SRCDIR([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 version"
+fi
+AC_DEFINE_UNQUOTED([LTBUG_ID],["$LTBUG_ID"],
+ [Text string identifying the library])
+
+AC_CONFIG_FILES([Makefile])
+
+AC_OUTPUT
diff --git a/ltb2/ltb2dep/main.c b/ltb2/ltb2dep/main.c
new file mode 100644
index 0000000..c491894
--- /dev/null
+++ b/ltb2/ltb2dep/main.c
@@ -0,0 +1,7 @@
+#include <stdio.h>
+
+void
+dummy (void)
+{
+}
+
diff --git a/ltb2/test.sh b/ltb2/test.sh
new file mode 100644
index 0000000..41388cb
--- /dev/null
+++ b/ltb2/test.sh
@@ -0,0 +1,171 @@
+#! /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 LTB2 test.
+See http://gray.gnu.org.ua/public/ltbug#ltb2 for details.
+OPTIONS are:
+
+ -p, --prefix=DIR set installation prefix root
+ (default: $prefix)
+ -C, --directory=DIR set test directory
+ (default: $testdir)
+ --keep keep test and installation directories for inspection
+ (default if the test fails)
+ --help display this help list
+
+EOF
+}
+
+unset arg
+while [ $# -gt 0 ]
+do
+ if [ -n "$arg" ]; then
+ eval $arg="$1"
+ unset arg
+ else
+ case $1 in
+ --prefix)
+ arg=prefix
+ ;;
+ --prefix=*)
+ prefix=${1##--prefix=}
+ ;;
+ -h|--help)
+ help
+ exit 0
+ ;;
+ -C|--directory)
+ arg=testdir
+ ;;
+ -C*)
+ testdir=${1##-C}
+ ;;
+ --directory=*)
+ testdir=${1##--directory=}
+ ;;
+ --keep)
+ keep=yes
+ ;;
+ *)
+ help >&2
+ exit 2
+ esac
+ fi
+ shift
+done
+
+prefix=$(cd $prefix; pwd)/ltb-test2
+testdir=$(cd $testdir; pwd)/ltb-test2
+
+if [ $prefix = $testdir ]; then
+ echo >&2 "prefix and test directory must differ"
+ exit 2
+fi
+
+STDOUT=$testdir/ltb2.out
+STDERR=$testdir/ltb2.err
+
+if [ -d $testdir ]; then
+ keep_testdir=yes
+else
+ mkdir $testdir
+fi
+if [ ! -w $testdir ]; then
+ echo >&2 "$0: test directory ($testdir) must be writable"
+ exit 2
+fi
+if [ ! -d $prefix ]; then
+ mkdir $prefix
+fi
+if [ ! -w $prefix ]; then
+ echo >&2 "$0: prefix directory ($prefix) must be writable"
+ exit 2
+fi
+
+abend() {
+ echo >&2 "Failed!"
+ tail -n 5 $STDERR >&2
+ echo >&2 "Examine $STDOUT and $STDERR for details"
+ exit 2
+}
+
+cd $testdir
+
+rm -rf build_dep build_inst build_local
+mkdir build_dep build_inst build_local
+
+echo "Building dependency library"
+(
+ cd build_dep
+ $abs_topdir/ltb2dep/configure --prefix=$prefix
+ make
+ make install
+) 2>>$STDERR >$STDOUT || abend
+
+echo "Building and installing project"
+(
+ cd build_inst
+ $abs_topdir/ltb2/configure --prefix=$prefix LTBUG_ID='installed'
+ make
+ make install
+) 2>>$STDERR >$STDOUT || abend
+
+echo "Building local copy of the project"
+(
+ cd build_local
+ $abs_topdir/ltb2/configure --prefix=$prefix
+ make
+) 2>>$STDERR >$STDOUT || abend
+
+cat > expout <<EOF
+ltb2a: local
+ltb2b: local
+EOF
+
+echo "Running test program"
+
+export LD_LIBRARY_PATH_RPATH=y
+
+build_local/src/ltb2 > stdout
+
+if cmp -s stdout expout; then
+ status=0
+else
+ keep=yes
+ echo >&2 "Test failed:"
+ diff -pu expout stdout || /bin/true
+ status=1
+fi
+
+cd $cwdir
+
+if [ "$keep" = "yes" ]; then
+ echo "Keeping the directories in place. When no longer needed, run:"
+ dry_run=echo
+else
+ echo "Uninstalling"
+ dry_run=
+fi
+
+$dry_run rm -rf $prefix
+
+if [ "$keep_testdir" = "yes" ]; then
+ $dry_run rm -rf $testdir/build_dep $testdir/build_inst $testdir/build_local
+ $dry_run rm -f $STDERR $STDOUT
+else
+ $dry_run rm -rf $testdir
+fi
+
+exit $status
diff --git a/patches/0001-ltmain.in-append-rpath-option-arguments-to-finalize_.patch b/patches/0001-ltmain.in-append-rpath-option-arguments-to-finalize_.patch
new file mode 100644
index 0000000..7d96034
--- /dev/null
+++ b/patches/0001-ltmain.in-append-rpath-option-arguments-to-finalize_.patch
@@ -0,0 +1,50 @@
+From 3aa30817116c0d231e44b3fc8fa5e67bfb62dca8 Mon Sep 17 00:00:00 2001
+From: Sergey Poznyakoff <gray@gnu.org.ua>
+Date: Mon, 9 Dec 2019 14:22:35 +0200
+Subject: [PATCH 1/2] ltmain.in: append -rpath option arguments to
+ finalize_rpath
+
+This makes sure the right library is used during tests even if
+-Wl,-rpath options appear in _LDADD or _LDFLAGS option.
+---
+ build-aux/ltmain.in | 17 +++++++++++++++--
+ 1 file changed, 15 insertions(+), 2 deletions(-)
+
+diff --git a/build-aux/ltmain.in b/build-aux/ltmain.in
+index 96b37003..c27abd1f 100644
+--- a/build-aux/ltmain.in
++++ b/build-aux/ltmain.in
+@@ -4664,6 +4664,7 @@ func_mode_link ()
+ vinfo=
+ vinfo_number=no
+ weak_libs=
++ rpath_arg=
+ single_module=$wl-single_module
+ func_infer_tag $base_compile
+
+@@ -5541,8 +5542,20 @@ func_mode_link ()
+
+ # Now actually substitute the argument into the commands.
+ if test -n "$arg"; then
+- func_append compile_command " $arg"
+- func_append finalize_command " $arg"
++ if test -n "$rpath_arg"; then
++ func_append finalize_rpath " ${arg##*,}"
++ unset rpath_arg
++ else
++ case $arg in
++ -Wl,-rpath,*)
++ func_append finalize_rpath " ${arg##*,}";;
++ -Wl,-rpath)
++ rpath_arg=1;;
++ *)
++ func_append compile_command " $arg"
++ func_append finalize_command " $arg"
++ esac
++ fi
+ fi
+ done # argument parsing loop
+
+--
+2.14.5
+
diff --git a/patches/0001-ltmain.in-ensure-that-local-source-tree-directories-.patch b/patches/0001-ltmain.in-ensure-that-local-source-tree-directories-.patch
new file mode 100644
index 0000000..8f057de
--- /dev/null
+++ b/patches/0001-ltmain.in-ensure-that-local-source-tree-directories-.patch
@@ -0,0 +1,71 @@
+From 076339142cba4e0fb55396231c5284544f6ee622 Mon Sep 17 00:00:00 2001
+From: Sergey Poznyakoff <gray@gnu.org.ua>
+Date: Thu, 12 Dec 2019 15:55:19 +0200
+Subject: [PATCH] ltmain.in: ensure that local source tree directories precede
+ any other in compiler_flags
+
+This is necessary to ensure that the program run by a libtool wrapper
+links with the libraries from the source tree.
+---
+ build-aux/ltmain.in | 17 ++++++++++++++---
+ 1 file changed, 14 insertions(+), 3 deletions(-)
+
+diff --git a/build-aux/ltmain.in b/build-aux/ltmain.in
+index 96b37003..b21d82cc 100644
+--- a/build-aux/ltmain.in
++++ b/build-aux/ltmain.in
+@@ -4660,6 +4660,7 @@ func_mode_link ()
+ xrpath=
+ perm_rpath=
+ temp_rpath=
++ temp_rpath_tail=
+ thread_safe=no
+ vinfo=
+ vinfo_number=no
+@@ -6196,7 +6197,10 @@ func_mode_link ()
+ # Make sure the rpath contains only unique directories.
+ case $temp_rpath: in
+ *"$absdir:"*) ;;
+- *) func_append temp_rpath "$absdir:" ;;
++ *) case $absdir in
++ "$progdir/"*) func_append temp_rpath "$absdir:" ;;
++ *) func_append temp_rpath_tail "$absdir:" ;;
++ esac
+ esac
+ fi
+
+@@ -6208,7 +6212,9 @@ func_mode_link ()
+ *)
+ case "$compile_rpath " in
+ *" $absdir "*) ;;
+- *) func_append compile_rpath " $absdir" ;;
++ *) case $absdir in
++ "$progdir/"*) func_append compile_rpath " $absdir" ;;
++ esac
+ esac
+ ;;
+ esac
+@@ -6282,7 +6288,9 @@ func_mode_link ()
+ *)
+ case "$compile_rpath " in
+ *" $absdir "*) ;;
+- *) func_append compile_rpath " $absdir" ;;
++ *) case $absdir in
++ "$progdir/"*) func_append compile_rpath " $absdir" ;;
++ esac
+ esac
+ ;;
+ esac
+@@ -6646,6 +6654,9 @@ func_mode_link ()
+ fi # link_all_deplibs != no
+ fi # linkmode = lib
+ done # for deplib in $libs
++
++ func_append temp_rpath "$temp_rpath_tail"
++
+ if test link = "$pass"; then
+ if test prog = "$linkmode"; then
+ compile_deplibs="$new_inherited_linker_flags $compile_deplibs"
+--
+2.14.5
+
diff --git a/patches/0002-ltmain.in-ensure-that-local-source-tree-directories-.patch b/patches/0002-ltmain.in-ensure-that-local-source-tree-directories-.patch
new file mode 100644
index 0000000..34671db
--- /dev/null
+++ b/patches/0002-ltmain.in-ensure-that-local-source-tree-directories-.patch
@@ -0,0 +1,69 @@
+From 8f30846ca997a08442c70a64f7e3c8b389b9ebb8 Mon Sep 17 00:00:00 2001
+From: Sergey Poznyakoff <gray@gnu.org.ua>
+Date: Thu, 12 Dec 2019 15:55:19 +0200
+Subject: [PATCH 2/2] ltmain.in: ensure that local source tree directories
+ precede other ones in compiler_flags
+
+---
+ build-aux/ltmain.in | 17 ++++++++++++++---
+ 1 file changed, 14 insertions(+), 3 deletions(-)
+
+diff --git a/build-aux/ltmain.in b/build-aux/ltmain.in
+index c27abd1f..b839c12c 100644
+--- a/build-aux/ltmain.in
++++ b/build-aux/ltmain.in
+@@ -4660,6 +4660,7 @@ func_mode_link ()
+ xrpath=
+ perm_rpath=
+ temp_rpath=
++ temp_rpath_tail=
+ thread_safe=no
+ vinfo=
+ vinfo_number=no
+@@ -6209,7 +6210,10 @@ func_mode_link ()
+ # Make sure the rpath contains only unique directories.
+ case $temp_rpath: in
+ *"$absdir:"*) ;;
+- *) func_append temp_rpath "$absdir:" ;;
++ *) case $absdir in
++ "$progdir/"*) func_append temp_rpath "$absdir:" ;;
++ *) func_append temp_rpath_tail "$absdir:" ;;
++ esac
+ esac
+ fi
+
+@@ -6221,7 +6225,9 @@ func_mode_link ()
+ *)
+ case "$compile_rpath " in
+ *" $absdir "*) ;;
+- *) func_append compile_rpath " $absdir" ;;
++ *) case $absdir in
++ "$progdir/"*) func_append compile_rpath " $absdir" ;;
++ esac
+ esac
+ ;;
+ esac
+@@ -6295,7 +6301,9 @@ func_mode_link ()
+ *)
+ case "$compile_rpath " in
+ *" $absdir "*) ;;
+- *) func_append compile_rpath " $absdir" ;;
++ *) case $absdir in
++ "$progdir/"*) func_append compile_rpath " $absdir" ;;
++ esac
+ esac
+ ;;
+ esac
+@@ -6659,6 +6667,9 @@ func_mode_link ()
+ fi # link_all_deplibs != no
+ fi # linkmode = lib
+ done # for deplib in $libs
++
++ func_append temp_rpath "$temp_rpath_tail"
++
+ if test link = "$pass"; then
+ if test prog = "$linkmode"; then
+ compile_deplibs="$new_inherited_linker_flags $compile_deplibs"
+--
+2.14.5
+
diff --git a/patches/Makefile b/patches/Makefile
new file mode 100644
index 0000000..4f53d22
--- /dev/null
+++ b/patches/Makefile
@@ -0,0 +1,13 @@
+ifneq (,$(wildcard ../.makevars))
+ include ../.makevars
+else
+ $(error Required file ../.makevars does not exist)
+endif
+
+PATCHES=\
+ 0001-ltmain.in-append-rpath-option-arguments-to-finalize_.patch\
+ 0002-ltmain.in-ensure-that-local-source-tree-directories-.patch\
+ libtool-2.4.6-ltb1-2.patch
+
+publish:
+ scp $(PATCHES) $(DISTLOC)
diff --git a/patches/libtool-2.4.6-ltb1-2.patch b/patches/libtool-2.4.6-ltb1-2.patch
new file mode 100644
index 0000000..d27b315
--- /dev/null
+++ b/patches/libtool-2.4.6-ltb1-2.patch
@@ -0,0 +1,83 @@
+diff -pur libtool-2.4.6.orig/build-aux/ltmain.in libtool-2.4.6/build-aux/ltmain.in
+--- libtool-2.4.6.orig/build-aux/ltmain.in 2015-02-06 14:57:56.000000000 +0200
++++ libtool-2.4.6/build-aux/ltmain.in 2019-12-13 13:40:44.701071633 +0200
+@@ -4644,10 +4644,12 @@ func_mode_link ()
+ xrpath=
+ perm_rpath=
+ temp_rpath=
++ temp_rpath_tail=
+ thread_safe=no
+ vinfo=
+ vinfo_number=no
+ weak_libs=
++ rpath_arg=
+ single_module=$wl-single_module
+ func_infer_tag $base_compile
+
+@@ -5521,8 +5523,20 @@ func_mode_link ()
+
+ # Now actually substitute the argument into the commands.
+ if test -n "$arg"; then
+- func_append compile_command " $arg"
+- func_append finalize_command " $arg"
++ if test -n "$rpath_arg"; then
++ func_append finalize_rpath " ${arg##*,}"
++ unset rpath_arg
++ else
++ case $arg in
++ -Wl,-rpath,*)
++ func_append finalize_rpath " ${arg##*,}";;
++ -Wl,-rpath)
++ rpath_arg=1;;
++ *)
++ func_append compile_command " $arg"
++ func_append finalize_command " $arg"
++ esac
++ fi
+ fi
+ done # argument parsing loop
+
+@@ -6176,7 +6190,10 @@ func_mode_link ()
+ # Make sure the rpath contains only unique directories.
+ case $temp_rpath: in
+ *"$absdir:"*) ;;
+- *) func_append temp_rpath "$absdir:" ;;
++ *) case $absdir in
++ "$progdir/"*) func_append temp_rpath "$absdir:" ;;
++ *) func_append temp_rpath_tail "$absdir:" ;;
++ esac
+ esac
+ fi
+
+@@ -6188,7 +6205,9 @@ func_mode_link ()
+ *)
+ case "$compile_rpath " in
+ *" $absdir "*) ;;
+- *) func_append compile_rpath " $absdir" ;;
++ *) case $absdir in
++ "$progdir/"*) func_append compile_rpath " $absdir" ;;
++ esac
+ esac
+ ;;
+ esac
+@@ -6262,7 +6281,9 @@ func_mode_link ()
+ *)
+ case "$compile_rpath " in
+ *" $absdir "*) ;;
+- *) func_append compile_rpath " $absdir" ;;
++ *) case $absdir in
++ "$progdir/"*) func_append compile_rpath " $absdir" ;;
++ esac
+ esac
+ ;;
+ esac
+@@ -6626,6 +6647,9 @@ func_mode_link ()
+ fi # link_all_deplibs != no
+ fi # linkmode = lib
+ done # for deplib in $libs
++
++ func_append temp_rpath "$temp_rpath_tail"
++
+ if test link = "$pass"; then
+ if test prog = "$linkmode"; then
+ compile_deplibs="$new_inherited_linker_flags $compile_deplibs"

Return to:

Send suggestions and report system problems to the System administrator.