changeset 8265:20006894dae4

Infrastructure for relocatable installation, from GNU gettext. See http://lists.gnu.org/archive/html/bug-gnulib/2003-03/msg00020.html
author Bruno Haible <bruno@clisp.org>
date Thu, 01 Mar 2007 01:15:40 +0000
parents 4dfb3310f018
children c38f0e90bab8
files ChangeLog build-aux/config.libpath build-aux/install-reloc build-aux/reloc-ldflags lib/relocatable.c lib/relocatable.h lib/relocwrapper.c m4/relocatable.m4
diffstat 8 files changed, 1251 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2007-02-28  Bruno Haible  <bruno@clisp.org>
+
+	Import --enable-relocatable infrastructure.
+	* build-aux/config.libpath: New file, from GNU gettext.
+	* build-aux/install-reloc: New file, from GNU gettext.
+	* build-aux/reloc-ldflags: New file, from GNU gettext.
+	* lib/relocatable.h: New file, from GNU gettext.
+	* lib/relocatable.c: New file, from GNU gettext.
+	* lib/relocwrapper.c: New file, from GNU gettext.
+	* m4/relocatable.m4: New file, from GNU gettext.
+
 2007-02-28  Bruno Haible  <bruno@clisp.org>
 
 	* MODULES.html.sh (File system functions): Add xreadlink-with-size.
new file mode 100755
--- /dev/null
+++ b/build-aux/config.libpath
@@ -0,0 +1,148 @@
+#! /bin/sh
+# Output a system dependent set of variables, describing how to set the
+# run time search path of shared libraries in an executable at run time.
+#
+#   Copyright 1996-2005 Free Software Foundation, Inc.
+#   Taken from GNU libtool, 2003
+#   Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+#
+#   This program is free software; you can redistribute it and/or modify
+#   it under the terms of the GNU General Public License as published by
+#   the Free Software Foundation; either version 2 of the License, or
+#   (at your option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#   General Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License
+#   along with this program; if not, write to the Free Software Foundation,
+#   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+#   As a special exception to the GNU General Public License, if you
+#   distribute this file as part of a program that contains a
+#   configuration script generated by Autoconf, you may include it under
+#   the same distribution terms that you use for the rest of that program.
+#
+# The first argument passed to this file is the canonical host specification,
+#    CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or
+#    CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# The environment variable LD should be set by the caller.
+#
+# The set of defined variables is at the end of this script.
+
+host="$1"
+host_cpu=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+
+shlibpath_var=
+case $host_os in
+  aix3*)
+    shlibpath_var=LIBPATH
+    ;;
+  aix4* | aix5*)
+    if test "$host_cpu" = ia64; then
+      # AIX 5 supports IA64
+      shlibpath_var=LD_LIBRARY_PATH
+    else
+      shlibpath_var=LIBPATH
+    fi
+    ;;
+  beos*)
+    shlibpath_var=LIBRARY_PATH
+    ;;
+  bsdi4*)
+    shlibpath_var=LD_LIBRARY_PATH
+    ;;
+  cygwin* | mingw* | pw32*)
+    # FIXME: first we should search . and the directory the executable is in
+    shlibpath_var=PATH
+    ;;
+  darwin* | rhapsody*)
+    shlibpath_var=DYLD_LIBRARY_PATH
+    ;;
+  freebsd1*)
+    ;;
+  kfreebsd*-gnu)
+    shlibpath_var=LD_LIBRARY_PATH
+    ;;
+  freebsd*)
+    shlibpath_var=LD_LIBRARY_PATH
+    ;;
+  gnu*)
+    shlibpath_var=LD_LIBRARY_PATH
+    ;;
+  hpux9* | hpux10* | hpux11*)
+    shlibpath_var=SHLIB_PATH
+    ;;
+  irix5* | irix6* | nonstopux*)
+    case $host_os in
+      irix5* | nonstopux*)
+        shlibsuff=
+        ;;
+      *)
+        case $LD in # libtool.m4 will add one of these switches to LD
+          *-32|*"-32 ") shlibsuff= ;;
+          *-n32|*"-n32 ") shlibsuff=N32 ;;
+          *-64|*"-64 ") shlibsuff=64 ;;
+          *) shlibsuff= ;;
+        esac
+        ;;
+    esac
+    shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+    ;;
+  linux-gnu*)
+    shlibpath_var=LD_LIBRARY_PATH
+    ;;
+  knetbsd*-gnu)
+    shlibpath_var=LD_LIBRARY_PATH
+    ;;
+  netbsd*)
+    shlibpath_var=LD_LIBRARY_PATH
+    ;;
+  newsos6)
+    shlibpath_var=LD_LIBRARY_PATH
+    ;;
+  openbsd*)
+    shlibpath_var=LD_LIBRARY_PATH
+    ;;
+  os2*)
+    shlibpath_var=LIBPATH
+    ;;
+  osf3* | osf4* | osf5*)
+    shlibpath_var=LD_LIBRARY_PATH
+    ;;
+  sco3.2v5*)
+    shlibpath_var=LD_LIBRARY_PATH
+    ;;
+  solaris*)
+    shlibpath_var=LD_LIBRARY_PATH
+    ;;
+  sunos4*)
+    shlibpath_var=LD_LIBRARY_PATH
+    ;;
+  sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+    shlibpath_var=LD_LIBRARY_PATH
+    ;;
+  uts4*)
+    shlibpath_var=LD_LIBRARY_PATH
+    ;;
+  dgux*)
+    shlibpath_var=LD_LIBRARY_PATH
+    ;;
+  sysv4*MP*)
+    if test -d /usr/nec ;then
+      shlibpath_var=LD_LIBRARY_PATH
+    fi
+    ;;
+esac
+
+LC_ALL=C sed -e 's/^\([a-zA-Z0-9_]*\)=/acl_cv_\1=/' <<EOF
+
+# This is the shared library path variable.
+shlibpath_var=$shlibpath_var
+
+EOF
new file mode 100755
--- /dev/null
+++ b/build-aux/install-reloc
@@ -0,0 +1,130 @@
+#!/bin/sh
+# install-reloc - install a program including a relocating wrapper
+# Copyright (C) 2003, 2005-2006 Free Software Foundation, Inc.
+# Written by Bruno Haible <bruno@clisp.org>, 2003.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+# Usage:
+#   install-reloc library_path_var library_path_value prefix compile_command srcdir config_h_dir exeext install_command... destprog
+# where
+#   - library_path_var is the platform dependent runtime library path variable
+#   - library_path_value is a colon separated list of directories that contain
+#     the libraries at installation time (use this instead of -rpath)
+#   - prefix is the base directory at installation time
+#   - compile_command is a C compiler compilation and linking command
+#   - srcdir is the directory where to find relocwrapper.c and its dependencies
+#   - builddir is the directory where to find built dependencies (namely,
+#     alloca.h and stdbool.h)
+#   - config_h_dir is the directory where to find config.h
+#   - exeext is platform dependent suffix of executables
+#   - install-command is the install command line, excluding the final destprog
+#   - destprog is the destination program name
+# install-reloc renames destprog to destprog.bin and installs a relocating
+# wrapper in the place of destprog.
+
+progname=$0
+
+if test $# -eq 2; then
+  # Get arguments from environment variables.
+  library_path_var=$RELOC_LIBRARY_PATH_VAR
+  library_path_value=$RELOC_LIBRARY_PATH_VALUE
+  prefix=$RELOC_PREFIX
+  compile_command=$RELOC_COMPILE_COMMAND
+  srcdir=$RELOC_SRCDIR
+  builddir=$RELOC_BUILDDIR
+  config_h_dir=$RELOC_CONFIG_H_DIR
+  exeext=$RELOC_EXEEXT
+  install_prog=$RELOC_INSTALL_PROG # including the "-c" option
+else
+  if test $# -ge 9; then
+    # Get fixed position arguments.
+    library_path_var=$1
+    library_path_value=$2
+    prefix=$3
+    compile_command=$4
+    srcdir=$5
+    builddir=$6
+    config_h_dir=$7
+    exeext=$8
+    install_prog=$9 # maybe not including the "-c" option
+    shift
+    shift
+    shift
+    shift
+    shift
+    shift
+    shift
+    shift
+    shift
+  else
+    echo "Usage: $0 library_path_var library_path_value prefix compile_command srcdir builddir config_h_dir exeext install_command... destprog" 1>&2
+    exit 1
+  fi
+fi
+
+# Get destprog, last argument.
+destprog=
+for arg
+do
+  destprog=$arg
+done
+# Remove trailing $exeext, if present.
+if test -n "$exeext"; then
+  sedexpr='s|'`echo "$exeext" | sed -e 's,\.,\\\.,g'`'$||'
+  destprog=`echo "$destprog" | sed -e "$sedexpr"`
+fi
+
+# Outputs a command and runs it.
+func_verbose ()
+{
+  echo "$@"
+  "$@"
+}
+
+# Run install_command.
+func_verbose $install_prog "$@" || exit $?
+
+# If the platform doesn't support LD_LIBRARY_PATH or similar, we cannot build
+# a wrapper.
+test -n "$library_path_var" || exit 0
+
+libdirs=
+save_IFS="$IFS"; IFS=":"
+for dir in $library_path_value; do
+  IFS="$save_IFS"
+  if test -n "$dir"; then
+    case "$libdirs" in
+      *"\"$dir\""*) ;; # remove duplicate
+      *) libdirs="$libdirs\"$dir\"," ;;
+    esac
+  fi
+done
+IFS="$save_IFS"
+# If there are no library directories to add at runtime, we don't need a
+# wrapper.
+test -n "$libdirs" || exit 0
+
+# Compile wrapper.
+installdir=`echo "$destprog" | sed -e 's,/[^/]*$,,'`
+func_verbose $compile_command -I"$builddir" -I"$srcdir" -I"$config_h_dir" -DHAVE_CONFIG_H -DIN_RELOCWRAPPER -DNO_XMALLOC -D"INSTALLPREFIX=\"$prefix\"" -D"INSTALLDIR=\"$installdir\"" -D"LIBPATHVAR=\"$library_path_var\"" -D"LIBDIRS=$libdirs" -D"EXEEXT=\"$exeext\"" "$srcdir"/relocwrapper.c "$srcdir"/progname.c "$srcdir"/progreloc.c "$srcdir"/xreadlink.c "$srcdir"/readlink.c "$srcdir"/canonicalize-lgpl.c "$srcdir"/allocsa.c "$srcdir"/relocatable.c "$srcdir"/setenv.c "$srcdir"/strerror.c -o "$destprog.wrapper$exeext" || exit $?
+
+# Rename $destprog.wrapper -> $destprog -> $destprog.bin.
+ln -f "$destprog$exeext" "$destprog.bin$exeext" \
+  || { rm -f "$destprog.bin$exeext" && cp -p "$destprog$exeext" "$destprog.bin$exeext"; } \
+  || exit 1
+mv "$destprog.wrapper$exeext" "$destprog$exeext" || exit 1
+
+exit 0
new file mode 100755
--- /dev/null
+++ b/build-aux/reloc-ldflags
@@ -0,0 +1,102 @@
+#! /bin/sh
+# Output a system dependent linker command for putting a relocatable library
+# search path into an executable.
+#
+#   Copyright 2003 Free Software Foundation, Inc.
+#   Written by Bruno Haible <bruno@clisp.org>, 2003.
+#
+#   This program is free software; you can redistribute it and/or modify
+#   it under the terms of the GNU General Public License as published by
+#   the Free Software Foundation; either version 2 of the License, or
+#   (at your option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#   General Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License
+#   along with this program; if not, write to the Free Software Foundation,
+#   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+#   As a special exception to the GNU General Public License, if you
+#   distribute this file as part of a program that contains a
+#   configuration script generated by Autoconf, you may include it under
+#   the same distribution terms that you use for the rest of that program.
+#
+# The first argument passed to this file is the canonical host specification,
+#    CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or
+#    CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# The environment variable LD should be set by the caller.
+#
+# The second argument is a colon separated list of directories that contain
+# the libraries at installation time.
+#
+# The third argument is the directory into which the executable is going to be
+# installed.
+
+host="$1"
+host_cpu=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+
+library_path_value=$2
+
+installdir=$3
+
+# Verify that installdir is absolute.
+case "$installdir" in
+  /*) ;;
+  *)
+    echo "installdir is not absolute: $installdir" 1>&2
+    exit 1
+    ;;
+esac
+
+case "$host_os" in
+  linux*) # Supported since Linux 2.1 and glibc 2.1.
+    rpath=
+    save_IFS="$IFS"; IFS=":"
+    for dir in $library_path_value; do
+      IFS="$save_IFS"
+      case "$dir" in
+        /*)
+          # Make dir relative to installdir. (Works only if dir is absolute.)
+          idir="$installdir"
+          while true; do
+            dfirst=`echo "$dir" | sed -n -e 's,^//*\([^/]*\).*$,/\1,p'`
+            ifirst=`echo "$idir" | sed -n -e 's,^//*\([^/]*\).*$,/\1,p'`
+            if test -z "$dfirst" || test -z "$ifirst"; then
+              break
+            fi
+            if test "$dfirst" != "$ifirst"; then
+              break
+            fi
+            dir=`echo "$dir" | sed -e 's,^//*[^/]*,,'`
+            idir=`echo "$idir" | sed -e 's,^//*[^/]*,,'`
+          done
+          dir="\$ORIGIN"`echo "$idir" | sed -e 's,//*[^/]*,/..,g'`"$dir"
+          # Add dir to rpath.
+          rpath="${rpath}${rpath:+ }$dir"
+          ;;
+        *)
+          if test -n "$dir"; then
+            echo "libdir is not absolute: $dir" 1>&2
+          fi
+          ;;
+      esac
+    done
+    IFS="$save_IFS"
+    # Output it.
+    if test -n "$rpath"; then
+      echo "-Wl,-rpath,$rpath"
+    fi
+    ;;
+  *)
+    echo "relocation via rpath not supported on this system: $host" 1>&2
+    exit 1
+    ;;
+esac
+
+exit 0
new file mode 100644
--- /dev/null
+++ b/lib/relocatable.c
@@ -0,0 +1,468 @@
+/* Provide relocatable packages.
+   Copyright (C) 2003-2006 Free Software Foundation, Inc.
+   Written by Bruno Haible <bruno@clisp.org>, 2003.
+
+   This program is free software; you can redistribute it and/or modify it
+   under the terms of the GNU Library General Public License as published
+   by the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+   USA.  */
+
+
+/* Tell glibc's <stdio.h> to provide a prototype for getline().
+   This must come before <config.h> because <config.h> may include
+   <features.h>, and once <features.h> has been included, it's too late.  */
+#ifndef _GNU_SOURCE
+# define _GNU_SOURCE	1
+#endif
+
+#include <config.h>
+
+/* Specification.  */
+#include "relocatable.h"
+
+#if ENABLE_RELOCATABLE
+
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef NO_XMALLOC
+# define xmalloc malloc
+#else
+# include "xalloc.h"
+#endif
+
+#if defined _WIN32 || defined __WIN32__ || defined __CYGWIN__
+# define WIN32_LEAN_AND_MEAN
+# include <windows.h>
+#endif
+
+#if DEPENDS_ON_LIBCHARSET
+# include <libcharset.h>
+#endif
+#if DEPENDS_ON_LIBICONV && HAVE_ICONV
+# include <iconv.h>
+#endif
+#if DEPENDS_ON_LIBINTL && ENABLE_NLS
+# include <libintl.h>
+#endif
+
+/* Faked cheap 'bool'.  */
+#undef bool
+#undef false
+#undef true
+#define bool int
+#define false 0
+#define true 1
+
+/* Pathname support.
+   ISSLASH(C)           tests whether C is a directory separator character.
+   IS_PATH_WITH_DIR(P)  tests whether P contains a directory specification.
+ */
+#if defined _WIN32 || defined __WIN32__ || defined __CYGWIN__ || defined __EMX__ || defined __DJGPP__
+  /* Win32, Cygwin, OS/2, DOS */
+# define ISSLASH(C) ((C) == '/' || (C) == '\\')
+# define HAS_DEVICE(P) \
+    ((((P)[0] >= 'A' && (P)[0] <= 'Z') || ((P)[0] >= 'a' && (P)[0] <= 'z')) \
+     && (P)[1] == ':')
+# define IS_PATH_WITH_DIR(P) \
+    (strchr (P, '/') != NULL || strchr (P, '\\') != NULL || HAS_DEVICE (P))
+# define FILE_SYSTEM_PREFIX_LEN(P) (HAS_DEVICE (P) ? 2 : 0)
+#else
+  /* Unix */
+# define ISSLASH(C) ((C) == '/')
+# define IS_PATH_WITH_DIR(P) (strchr (P, '/') != NULL)
+# define FILE_SYSTEM_PREFIX_LEN(P) 0
+#endif
+
+/* Original installation prefix.  */
+static char *orig_prefix;
+static size_t orig_prefix_len;
+/* Current installation prefix.  */
+static char *curr_prefix;
+static size_t curr_prefix_len;
+/* These prefixes do not end in a slash.  Anything that will be concatenated
+   to them must start with a slash.  */
+
+/* Sets the original and the current installation prefix of this module.
+   Relocation simply replaces a pathname starting with the original prefix
+   by the corresponding pathname with the current prefix instead.  Both
+   prefixes should be directory names without trailing slash (i.e. use ""
+   instead of "/").  */
+static void
+set_this_relocation_prefix (const char *orig_prefix_arg,
+			    const char *curr_prefix_arg)
+{
+  if (orig_prefix_arg != NULL && curr_prefix_arg != NULL
+      /* Optimization: if orig_prefix and curr_prefix are equal, the
+	 relocation is a nop.  */
+      && strcmp (orig_prefix_arg, curr_prefix_arg) != 0)
+    {
+      /* Duplicate the argument strings.  */
+      char *memory;
+
+      orig_prefix_len = strlen (orig_prefix_arg);
+      curr_prefix_len = strlen (curr_prefix_arg);
+      memory = (char *) xmalloc (orig_prefix_len + 1 + curr_prefix_len + 1);
+#ifdef NO_XMALLOC
+      if (memory != NULL)
+#endif
+	{
+	  memcpy (memory, orig_prefix_arg, orig_prefix_len + 1);
+	  orig_prefix = memory;
+	  memory += orig_prefix_len + 1;
+	  memcpy (memory, curr_prefix_arg, curr_prefix_len + 1);
+	  curr_prefix = memory;
+	  return;
+	}
+    }
+  orig_prefix = NULL;
+  curr_prefix = NULL;
+  /* Don't worry about wasted memory here - this function is usually only
+     called once.  */
+}
+
+/* Sets the original and the current installation prefix of the package.
+   Relocation simply replaces a pathname starting with the original prefix
+   by the corresponding pathname with the current prefix instead.  Both
+   prefixes should be directory names without trailing slash (i.e. use ""
+   instead of "/").  */
+void
+set_relocation_prefix (const char *orig_prefix_arg, const char *curr_prefix_arg)
+{
+  set_this_relocation_prefix (orig_prefix_arg, curr_prefix_arg);
+
+  /* Now notify all dependent libraries.  */
+#if DEPENDS_ON_LIBCHARSET
+  libcharset_set_relocation_prefix (orig_prefix_arg, curr_prefix_arg);
+#endif
+#if DEPENDS_ON_LIBICONV && HAVE_ICONV && _LIBICONV_VERSION >= 0x0109
+  libiconv_set_relocation_prefix (orig_prefix_arg, curr_prefix_arg);
+#endif
+#if DEPENDS_ON_LIBINTL && ENABLE_NLS && defined libintl_set_relocation_prefix
+  libintl_set_relocation_prefix (orig_prefix_arg, curr_prefix_arg);
+#endif
+}
+
+#if !defined IN_LIBRARY || (defined PIC && defined INSTALLDIR)
+
+/* Convenience function:
+   Computes the current installation prefix, based on the original
+   installation prefix, the original installation directory of a particular
+   file, and the current pathname of this file.  Returns NULL upon failure.  */
+#ifdef IN_LIBRARY
+#define compute_curr_prefix local_compute_curr_prefix
+static
+#endif
+const char *
+compute_curr_prefix (const char *orig_installprefix,
+		     const char *orig_installdir,
+		     const char *curr_pathname)
+{
+  const char *curr_installdir;
+  const char *rel_installdir;
+
+  if (curr_pathname == NULL)
+    return NULL;
+
+  /* Determine the relative installation directory, relative to the prefix.
+     This is simply the difference between orig_installprefix and
+     orig_installdir.  */
+  if (strncmp (orig_installprefix, orig_installdir, strlen (orig_installprefix))
+      != 0)
+    /* Shouldn't happen - nothing should be installed outside $(prefix).  */
+    return NULL;
+  rel_installdir = orig_installdir + strlen (orig_installprefix);
+
+  /* Determine the current installation directory.  */
+  {
+    const char *p_base = curr_pathname + FILE_SYSTEM_PREFIX_LEN (curr_pathname);
+    const char *p = curr_pathname + strlen (curr_pathname);
+    char *q;
+
+    while (p > p_base)
+      {
+	p--;
+	if (ISSLASH (*p))
+	  break;
+      }
+
+    q = (char *) xmalloc (p - curr_pathname + 1);
+#ifdef NO_XMALLOC
+    if (q == NULL)
+      return NULL;
+#endif
+    memcpy (q, curr_pathname, p - curr_pathname);
+    q[p - curr_pathname] = '\0';
+    curr_installdir = q;
+  }
+
+  /* Compute the current installation prefix by removing the trailing
+     rel_installdir from it.  */
+  {
+    const char *rp = rel_installdir + strlen (rel_installdir);
+    const char *cp = curr_installdir + strlen (curr_installdir);
+    const char *cp_base =
+      curr_installdir + FILE_SYSTEM_PREFIX_LEN (curr_installdir);
+
+    while (rp > rel_installdir && cp > cp_base)
+      {
+	bool same = false;
+	const char *rpi = rp;
+	const char *cpi = cp;
+
+	while (rpi > rel_installdir && cpi > cp_base)
+	  {
+	    rpi--;
+	    cpi--;
+	    if (ISSLASH (*rpi) || ISSLASH (*cpi))
+	      {
+		if (ISSLASH (*rpi) && ISSLASH (*cpi))
+		  same = true;
+		break;
+	      }
+	    /* Do case-insensitive comparison if the filesystem is always or
+	       often case-insensitive.  It's better to accept the comparison
+	       if the difference is only in case, rather than to fail.  */
+#if defined _WIN32 || defined __WIN32__ || defined __CYGWIN__ || defined __EMX__ || defined __DJGPP__
+	    /* Win32, Cygwin, OS/2, DOS - case insignificant filesystem */
+	    if ((*rpi >= 'a' && *rpi <= 'z' ? *rpi - 'a' + 'A' : *rpi)
+		!= (*cpi >= 'a' && *cpi <= 'z' ? *cpi - 'a' + 'A' : *cpi))
+	      break;
+#else
+	    if (*rpi != *cpi)
+	      break;
+#endif
+	  }
+	if (!same)
+	  break;
+	/* The last pathname component was the same.  opi and cpi now point
+	   to the slash before it.  */
+	rp = rpi;
+	cp = cpi;
+      }
+
+    if (rp > rel_installdir)
+      /* Unexpected: The curr_installdir does not end with rel_installdir.  */
+      return NULL;
+
+    {
+      size_t curr_prefix_len = cp - curr_installdir;
+      char *curr_prefix;
+
+      curr_prefix = (char *) xmalloc (curr_prefix_len + 1);
+#ifdef NO_XMALLOC
+      if (curr_prefix == NULL)
+	return NULL;
+#endif
+      memcpy (curr_prefix, curr_installdir, curr_prefix_len);
+      curr_prefix[curr_prefix_len] = '\0';
+
+      return curr_prefix;
+    }
+  }
+}
+
+#endif /* !IN_LIBRARY || PIC */
+
+#if defined PIC && defined INSTALLDIR
+
+/* Full pathname of shared library, or NULL.  */
+static char *shared_library_fullname;
+
+#if defined _WIN32 || defined __WIN32__ || defined __CYGWIN__
+
+/* Determine the full pathname of the shared library when it is loaded.  */
+
+BOOL WINAPI
+DllMain (HINSTANCE module_handle, DWORD event, LPVOID reserved)
+{
+  (void) reserved;
+
+  if (event == DLL_PROCESS_ATTACH)
+    {
+      /* The DLL is being loaded into an application's address range.  */
+      static char location[MAX_PATH];
+
+      if (!GetModuleFileName (module_handle, location, sizeof (location)))
+	/* Shouldn't happen.  */
+	return FALSE;
+
+      if (!IS_PATH_WITH_DIR (location))
+	/* Shouldn't happen.  */
+	return FALSE;
+
+      {
+#if defined __CYGWIN__
+	/* On Cygwin, we need to convert paths coming from Win32 system calls
+	   to the Unix-like slashified notation.  */
+	static char location_as_posix_path[2 * MAX_PATH];
+	/* There's no error return defined for cygwin_conv_to_posix_path.
+	   See cygwin-api/func-cygwin-conv-to-posix-path.html.
+	   Does it overflow the buffer of expected size MAX_PATH or does it
+	   truncate the path?  I don't know.  Let's catch both.  */
+	cygwin_conv_to_posix_path (location, location_as_posix_path);
+	location_as_posix_path[MAX_PATH - 1] = '\0';
+	if (strlen (location_as_posix_path) >= MAX_PATH - 1)
+	  /* A sign of buffer overflow or path truncation.  */
+	  return FALSE;
+	shared_library_fullname = strdup (location_as_posix_path);
+#else
+	shared_library_fullname = strdup (location);
+#endif
+      }
+    }
+
+  return TRUE;
+}
+
+#else /* Unix except Cygwin */
+
+static void
+find_shared_library_fullname ()
+{
+#if defined __linux__ && __GLIBC__ >= 2
+  /* Linux has /proc/self/maps. glibc 2 has the getline() function.  */
+  FILE *fp;
+
+  /* Open the current process' maps file.  It describes one VMA per line.  */
+  fp = fopen ("/proc/self/maps", "r");
+  if (fp)
+    {
+      unsigned long address = (unsigned long) &find_shared_library_fullname;
+      for (;;)
+	{
+	  unsigned long start, end;
+	  int c;
+
+	  if (fscanf (fp, "%lx-%lx", &start, &end) != 2)
+	    break;
+	  if (address >= start && address <= end - 1)
+	    {
+	      /* Found it.  Now see if this line contains a filename.  */
+	      while (c = getc (fp), c != EOF && c != '\n' && c != '/')
+		continue;
+	      if (c == '/')
+		{
+		  size_t size;
+		  int len;
+
+		  ungetc (c, fp);
+		  shared_library_fullname = NULL; size = 0;
+		  len = getline (&shared_library_fullname, &size, fp);
+		  if (len >= 0)
+		    {
+		      /* Success: filled shared_library_fullname.  */
+		      if (len > 0 && shared_library_fullname[len - 1] == '\n')
+			shared_library_fullname[len - 1] = '\0';
+		    }
+		}
+	      break;
+	    }
+	  while (c = getc (fp), c != EOF && c != '\n')
+	    continue;
+	}
+      fclose (fp);
+    }
+#endif
+}
+
+#endif /* (WIN32 or Cygwin) / (Unix except Cygwin) */
+
+/* Return the full pathname of the current shared library.
+   Return NULL if unknown.
+   Guaranteed to work only on Linux, Cygwin and Woe32.  */
+static char *
+get_shared_library_fullname ()
+{
+#if !(defined _WIN32 || defined __WIN32__ || defined __CYGWIN__)
+  static bool tried_find_shared_library_fullname;
+  if (!tried_find_shared_library_fullname)
+    {
+      find_shared_library_fullname ();
+      tried_find_shared_library_fullname = true;
+    }
+#endif
+  return shared_library_fullname;
+}
+
+#endif /* PIC */
+
+/* Returns the pathname, relocated according to the current installation
+   directory.  */
+const char *
+relocate (const char *pathname)
+{
+#if defined PIC && defined INSTALLDIR
+  static int initialized;
+
+  /* Initialization code for a shared library.  */
+  if (!initialized)
+    {
+      /* At this point, orig_prefix and curr_prefix likely have already been
+	 set through the main program's set_program_name_and_installdir
+	 function.  This is sufficient in the case that the library has
+	 initially been installed in the same orig_prefix.  But we can do
+	 better, to also cover the cases that 1. it has been installed
+	 in a different prefix before being moved to orig_prefix and (later)
+	 to curr_prefix, 2. unlike the program, it has not moved away from
+	 orig_prefix.  */
+      const char *orig_installprefix = INSTALLPREFIX;
+      const char *orig_installdir = INSTALLDIR;
+      const char *curr_prefix_better;
+
+      curr_prefix_better =
+	compute_curr_prefix (orig_installprefix, orig_installdir,
+			     get_shared_library_fullname ());
+      if (curr_prefix_better == NULL)
+	curr_prefix_better = curr_prefix;
+
+      set_relocation_prefix (orig_installprefix, curr_prefix_better);
+
+      initialized = 1;
+    }
+#endif
+
+  /* Note: It is not necessary to perform case insensitive comparison here,
+     even for DOS-like filesystems, because the pathname argument was
+     typically created from the same Makefile variable as orig_prefix came
+     from.  */
+  if (orig_prefix != NULL && curr_prefix != NULL
+      && strncmp (pathname, orig_prefix, orig_prefix_len) == 0)
+    {
+      if (pathname[orig_prefix_len] == '\0')
+	/* pathname equals orig_prefix.  */
+	return curr_prefix;
+      if (ISSLASH (pathname[orig_prefix_len]))
+	{
+	  /* pathname starts with orig_prefix.  */
+	  const char *pathname_tail = &pathname[orig_prefix_len];
+	  char *result =
+	    (char *) xmalloc (curr_prefix_len + strlen (pathname_tail) + 1);
+
+#ifdef NO_XMALLOC
+	  if (result != NULL)
+#endif
+	    {
+	      memcpy (result, curr_prefix, curr_prefix_len);
+	      strcpy (result + curr_prefix_len, pathname_tail);
+	      return result;
+	    }
+	}
+    }
+  /* Nothing to relocate.  */
+  return pathname;
+}
+
+#endif
new file mode 100644
--- /dev/null
+++ b/lib/relocatable.h
@@ -0,0 +1,79 @@
+/* Provide relocatable packages.
+   Copyright (C) 2003, 2005 Free Software Foundation, Inc.
+   Written by Bruno Haible <bruno@clisp.org>, 2003.
+
+   This program is free software; you can redistribute it and/or modify it
+   under the terms of the GNU Library General Public License as published
+   by the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+   USA.  */
+
+#ifndef _RELOCATABLE_H
+#define _RELOCATABLE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* This can be enabled through the configure --enable-relocatable option.  */
+#if ENABLE_RELOCATABLE
+
+/* When building a DLL, we must export some functions.  Note that because
+   this is a private .h file, we don't need to use __declspec(dllimport)
+   in any case.  */
+#if HAVE_VISIBILITY && BUILDING_DLL
+# define RELOCATABLE_DLL_EXPORTED __attribute__((__visibility__("default")))
+#elif defined _MSC_VER && BUILDING_DLL
+# define RELOCATABLE_DLL_EXPORTED __declspec(dllexport)
+#else
+# define RELOCATABLE_DLL_EXPORTED
+#endif
+
+/* Sets the original and the current installation prefix of the package.
+   Relocation simply replaces a pathname starting with the original prefix
+   by the corresponding pathname with the current prefix instead.  Both
+   prefixes should be directory names without trailing slash (i.e. use ""
+   instead of "/").  */
+extern RELOCATABLE_DLL_EXPORTED void
+       set_relocation_prefix (const char *orig_prefix,
+			      const char *curr_prefix);
+
+/* Returns the pathname, relocated according to the current installation
+   directory.  */
+extern const char * relocate (const char *pathname);
+
+/* Memory management: relocate() leaks memory, because it has to construct
+   a fresh pathname.  If this is a problem because your program calls
+   relocate() frequently, think about caching the result.  */
+
+/* Convenience function:
+   Computes the current installation prefix, based on the original
+   installation prefix, the original installation directory of a particular
+   file, and the current pathname of this file.  Returns NULL upon failure.  */
+extern const char * compute_curr_prefix (const char *orig_installprefix,
+					 const char *orig_installdir,
+					 const char *curr_pathname);
+
+#else
+
+/* By default, we use the hardwired pathnames.  */
+#define relocate(pathname) (pathname)
+
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RELOCATABLE_H */
new file mode 100644
--- /dev/null
+++ b/lib/relocwrapper.c
@@ -0,0 +1,194 @@
+/* Relocating wrapper program.
+   Copyright (C) 2003, 2005-2006 Free Software Foundation, Inc.
+   Written by Bruno Haible <bruno@clisp.org>, 2003.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
+
+/* Dependencies:
+   relocwrapper
+    -> progname
+    -> progreloc
+        -> xreadlink
+           -> readlink
+        -> canonicalize
+           -> allocsa
+    -> relocatable
+    -> setenv
+       -> allocsa
+    -> strerror
+
+   Macros that need to be set while compiling this file:
+     - ENABLE_RELOCATABLE 1
+     - INSTALLPREFIX the base installation directory
+     - INSTALLDIR the directory into which this program is installed
+     - LIBPATHVAR the platform dependent runtime library path variable
+     - LIBDIRS a comma-terminated list of strings representing the list of
+       directories that contain the libraries at installation time
+
+   We don't want to internationalize this wrapper because then it would
+   depend on libintl and therefore need relocation itself.  So use only
+   libc functions, no gettext(), no error(), no xmalloc(), no xsetenv().
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+#include <errno.h>
+
+#include "progname.h"
+#include "relocatable.h"
+#include "setenv.h"
+
+/* Return a copy of the filename, with an extra ".bin" at the end.
+   More generally, it replaces "${EXEEXT}" at the end with ".bin${EXEEXT}".  */
+static char *
+add_dotbin (const char *filename)
+{
+  size_t filename_len = strlen (filename);
+  char *result = (char *) malloc (filename_len + 4 + 1);
+
+  if (result != NULL)
+    {
+      if (sizeof (EXEEXT) > sizeof (""))
+	{
+	  /* EXEEXT handling.  */
+	  const size_t exeext_len = sizeof (EXEEXT) - sizeof ("");
+	  static const char exeext[] = EXEEXT;
+	  if (filename_len > exeext_len)
+	    {
+	      /* Compare using an inlined copy of c_strncasecmp(), because
+		 the filenames may have undergone a case conversion since
+		 they were packaged.  In other words, EXEEXT may be ".exe"
+		 on one system and ".EXE" on another.  */
+	      const char *s1 = filename + filename_len - exeext_len;
+	      const char *s2 = exeext;
+	      for (; *s1 != '\0'; s1++, s2++)
+		{
+		  unsigned char c1 = *s1;
+		  unsigned char c2 = *s2;
+		  if ((c1 >= 'A' && c1 <= 'Z' ? c1 - 'A' + 'a' : c1)
+		      != (c2 >= 'A' && c2 <= 'Z' ? c2 - 'A' + 'a' : c2))
+		    goto simple_append;
+		}
+	      /* Insert ".bin" before EXEEXT or its equivalent.  */
+	      memcpy (result, filename, filename_len - exeext_len);
+	      memcpy (result + filename_len - exeext_len, ".bin", 4);
+	      memcpy (result + filename_len - exeext_len + 4,
+		      filename + filename_len - exeext_len,
+		      exeext_len + 1);
+	      return result;
+	    }
+	}
+     simple_append:
+      /* Simply append ".bin".  */
+      memcpy (result, filename, filename_len);
+      memcpy (result + filename_len, ".bin", 4 + 1);
+      return result;
+    }
+  else
+    {
+      fprintf (stderr, "%s: %s\n", program_name, "memory exhausted");
+      exit (1);
+    }
+}
+
+/* List of directories that contain the libraries.  */
+static const char *libdirs[] = { LIBDIRS NULL };
+/* Verify that at least one directory is given.  */
+typedef int verify1[2 * (sizeof (libdirs) / sizeof (libdirs[0]) > 1) - 1];
+
+/* Relocate the list of directories that contain the libraries.  */
+static void
+relocate_libdirs ()
+{
+  size_t i;
+
+  for (i = 0; i < sizeof (libdirs) / sizeof (libdirs[0]) - 1; i++)
+    libdirs[i] = relocate (libdirs[i]);
+}
+
+/* Activate the list of directories in the LIBPATHVAR.  */
+static void
+activate_libdirs ()
+{
+  const char *old_value;
+  size_t total;
+  size_t i;
+  char *value;
+  char *p;
+
+  old_value = getenv (LIBPATHVAR);
+  if (old_value == NULL)
+    old_value = "";
+
+  total = 0;
+  for (i = 0; i < sizeof (libdirs) / sizeof (libdirs[0]) - 1; i++)
+    total += strlen (libdirs[i]) + 1;
+  total += strlen (old_value) + 1;
+
+  value = (char *) malloc (total);
+  if (value == NULL)
+    {
+      fprintf (stderr, "%s: %s\n", program_name, "memory exhausted");
+      exit (1);
+    }
+  p = value;
+  for (i = 0; i < sizeof (libdirs) / sizeof (libdirs[0]) - 1; i++)
+    {
+      size_t len = strlen (libdirs[i]);
+      memcpy (p, libdirs[i], len);
+      p += len;
+      *p++ = ':';
+    }
+  if (old_value[0] != '\0')
+    strcpy (p, old_value);
+  else
+    p[-1] = '\0';
+
+  if (setenv (LIBPATHVAR, value, 1) < 0)
+    {
+      fprintf (stderr, "%s: %s\n", program_name, "memory exhausted");
+      exit (1);
+    }
+}
+
+int
+main (int argc, char *argv[])
+{
+  char *full_program_name;
+
+  /* Set the program name and perform preparations for
+     get_full_program_name() and relocate().  */
+  set_program_name_and_installdir (argv[0], INSTALLPREFIX, INSTALLDIR);
+
+  /* Get the full program path.  (Important if accessed through a symlink.)  */
+  full_program_name = get_full_program_name ();
+  if (full_program_name == NULL)
+    full_program_name = argv[0];
+
+  /* Invoke the real program, with suffix ".bin".  */
+  argv[0] = add_dotbin (full_program_name);
+  relocate_libdirs ();
+  activate_libdirs ();
+  execv (argv[0], argv);
+  fprintf (stderr, "%s: could not execute %s: %s\n",
+	   program_name, argv[0], strerror (errno));
+  exit (127);
+}
new file mode 100644
--- /dev/null
+++ b/m4/relocatable.m4
@@ -0,0 +1,119 @@
+# relocatable.m4 serial 7 (gettext-0.16)
+dnl Copyright (C) 2003, 2005-2006 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl From Bruno Haible.
+
+dnl Support for relocateble programs.
+AC_DEFUN([AC_RELOCATABLE],
+[
+  AC_REQUIRE([AC_RELOCATABLE_BODY])
+  if test $RELOCATABLE = yes; then
+    AC_LIBOBJ([relocatable])
+  fi
+])
+dnl The guts of AC_RELOCATABLE. Needs to be expanded only once.
+AC_DEFUN([AC_RELOCATABLE_BODY],
+[
+  AC_REQUIRE([AC_PROG_INSTALL])
+  dnl This AC_BEFORE invocation leads to unjustified autoconf warnings
+  dnl when AC_RELOCATABLE_BODY is invoked more than once.
+  dnl We need this AC_BEFORE because AC_PROG_INSTALL is documented to
+  dnl overwrite earlier settings of INSTALL and INSTALL_PROGRAM (even
+  dnl though in autoconf-2.52..2.60 it doesn't do so), but we want this
+  dnl macro's setting of INSTALL_PROGRAM to persist.
+  AC_BEFORE([AC_PROG_INSTALL],[AC_RELOCATABLE_BODY])
+  AC_REQUIRE([AC_LIB_LIBPATH])
+  AC_REQUIRE([AC_RELOCATABLE_LIBRARY])
+  AC_REQUIRE([AC_EXEEXT])
+  is_noop=no
+  use_elf_origin_trick=no
+  if test $RELOCATABLE = yes; then
+    # --enable-relocatable implies --disable-rpath
+    enable_rpath=no
+    AC_DEFINE([ENABLE_RELOCATABLE], 1,
+      [Define to 1 if the package shall run at any location in the filesystem.])
+    AC_CHECK_HEADERS([unistd.h mach-o/dyld.h])
+    AC_CHECK_FUNCS([_NSGetExecutablePath])
+    case "$host_os" in
+      mingw*) is_noop=yes ;;
+      linux*) use_elf_origin_trick=yes ;;
+    esac
+    if test $is_noop = yes; then
+      SET_RELOCATABLE="RELOCATABLE_LDFLAGS = :"
+    else
+      if test $use_elf_origin_trick = yes; then
+        dnl Use the dynamic linker's support for relocatable programs.
+        case "$ac_aux_dir" in
+          /*) reloc_ldflags="$ac_aux_dir/reloc-ldflags" ;;
+          *) reloc_ldflags="\$(top_builddir)/$ac_aux_dir/reloc-ldflags" ;;
+        esac
+        SET_RELOCATABLE="RELOCATABLE_LDFLAGS = \"$reloc_ldflags\" \"\$(host)\" \"\$(RELOCATABLE_LIBRARY_PATH)\""
+      else
+        dnl Unfortunately we cannot define INSTALL_PROGRAM to a command
+        dnl consisting of more than one word - libtool doesn't support this.
+        dnl So we abuse the INSTALL_PROGRAM_ENV hook, originally meant for the
+        dnl 'install-strip' target.
+        SET_RELOCATABLE="INSTALL_PROGRAM_ENV = RELOC_LIBRARY_PATH_VAR=\"$shlibpath_var\" RELOC_LIBRARY_PATH_VALUE=\"\$(RELOCATABLE_LIBRARY_PATH)\" RELOC_PREFIX=\"\$(prefix)\" RELOC_COMPILE_COMMAND=\"\$(CC) \$(CPPFLAGS) \$(CFLAGS) \$(LDFLAGS)\" RELOC_SRCDIR=\"\$(RELOCATABLE_SRC_DIR)\" RELOC_BUILDDIR=\"\$(RELOCATABLE_BUILD_DIR)\" RELOC_CONFIG_H_DIR=\"\$(RELOCATABLE_CONFIG_H_DIR)\" RELOC_EXEEXT=\"\$(EXEEXT)\" RELOC_INSTALL_PROG=\"$INSTALL_PROGRAM\""
+        case "$ac_aux_dir" in
+          /*) INSTALL_PROGRAM="$ac_aux_dir/install-reloc" ;;
+          *) INSTALL_PROGRAM="\$(top_builddir)/$ac_aux_dir/install-reloc" ;;
+        esac
+      fi
+    fi
+  else
+    SET_RELOCATABLE=
+  fi
+  AC_SUBST([SET_RELOCATABLE])
+  AM_CONDITIONAL([RELOCATABLE_VIA_LD],
+    [test $is_noop = yes || test $use_elf_origin_trick = yes])
+])
+
+dnl Support for relocatable libraries.
+AC_DEFUN([AC_RELOCATABLE_LIBRARY],
+[
+  AC_REQUIRE([AC_RELOCATABLE_NOP])
+  dnl Easier to put this here once, instead of into the DEFS of each Makefile.
+  if test "X$prefix" = "XNONE"; then
+    reloc_final_prefix="$ac_default_prefix"
+  else
+    reloc_final_prefix="$prefix"
+  fi
+  AC_DEFINE_UNQUOTED([INSTALLPREFIX], ["${reloc_final_prefix}"],
+    [Define to the value of ${prefix}, as a string.])
+])
+
+dnl Support for relocatable packages for which it is a nop.
+AC_DEFUN([AC_RELOCATABLE_NOP],
+[
+  AC_MSG_CHECKING([whether to activate relocatable installation])
+  AC_ARG_ENABLE(relocatable,
+    [  --enable-relocatable    install a package that can be moved in the filesystem],
+    [if test "$enableval" != no; then
+       RELOCATABLE=yes
+     else
+       RELOCATABLE=no
+     fi
+    ], RELOCATABLE=no)
+  AC_SUBST(RELOCATABLE)
+  AC_MSG_RESULT([$RELOCATABLE])
+])
+
+dnl Determine the platform dependent parameters needed to use relocatability:
+dnl shlibpath_var.
+AC_DEFUN([AC_LIB_LIBPATH],
+[
+  AC_REQUIRE([AC_LIB_PROG_LD])            dnl we use $LD
+  AC_REQUIRE([AC_CANONICAL_HOST])         dnl we use $host
+  AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT]) dnl we use $ac_aux_dir
+  AC_CACHE_CHECK([for shared library path variable], acl_cv_libpath, [
+    LD="$LD" \
+    ${CONFIG_SHELL-/bin/sh} "$ac_aux_dir/config.libpath" "$host" > conftest.sh
+    . ./conftest.sh
+    rm -f ./conftest.sh
+    acl_cv_libpath=${acl_cv_shlibpath_var:-none}
+  ])
+  shlibpath_var="$acl_cv_shlibpath_var"
+])