bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

first draft of "relocatable" module


From: Ben Pfaff
Subject: first draft of "relocatable" module
Date: Wed, 21 Feb 2007 21:24:04 -0800
User-agent: Gnus/5.110006 (No Gnus v0.6) Emacs/21.4 (gnu/linux)

I've finished my first stab at a "relocatable" module for gnulib.
I haven't done anything on the Automake side yet.  In this
message, I'm going to present what I've done, and then I'm going
ask some (possibly stupid) questions about how to proceed.

What I've done is essentially to assemble the relocatable stuff
into a gnulib module, and then test it a little bit.  The first
patch below shows this work.  Its contents are:

        * config.libpath, reloc-ldflags straight from gettext.

        * relocatable.texi is my interpretation of Bruno's
          http://lists.gnu.org/archive/html/bug-gnulib/2003-03/msg00020.html.
          I hope it is all correct.

        * progreloc.c needed to be updated for the changed
          xreadlink interface.

        * relocatable.c is from gettext, but I was able to take
          advantage of new gnulib modules to drop quite a bit of
          boilerplate from the beginning.  Perhaps my use of the
          c-ctype module will be rejected, but I hope that the
          rest is not controversial.

          relocwrapper.c is similar, with fewer changes.

          Ditto for relocatable.m4.

          I've enclosed a diff against the gettext version of
          these files.

        * relocatable.h is from gettext, without change.

        * relocatable.sh.in is an extract from gettext's
          gettextize.sh.in explained in relocatable.texi.

        * I wrote modules/relocatable myself.

The final patch is against GNU hello CVS to enable
relocatability.  After applying the patch, do a gnulib update and
import the relocatable module, run "automake --add-missing" and
autogen.sh, and configure with --enable-relocatable to see it
work.

Now, my questions, which I hope do not sound too stupid:

        * First, the Automake variables required for
          relocatability.  It seems like three of these
          (RELOCATABLE_SRC_DIR, RELOCATABLE_BUILD_DIR,
          RELOCATABLE_CONFIG_H_DIR) are completely mechanical and
          that they could just be produced by AC_RELOCATABLE and
          AC_SUBST'd.  Any reason not to do that?

        * It seems that $(libdir) is a reasonable default for
          RELOCATABLE_LIBRARY_PATH.  Is it reasonable to make
          this an optional argument to AC_RELOCATABLE and use
          $(libdir) as the default?

        * @SET_RELOCATABLE@ just expands to a variable
          definition.  Do we need this extra level of
          indirection?

        * The suggested method of setting INSTALLDIR uses a
          program-specific variable.  I think that this prevents
          sharing object files between programs, increasing the
          number of compilations necessary if programs share
          source files.  If so, should we instead generate a .c
          file that defines orig_installdir and
          orig_installprefix?  (Do many packages have programs
          with source files in common anyhow?)

        * Should I rename AC_RELOCATABLE to gl_RELOCATABLE?

        * It looks like Automake support is wanted for
          automatically defining foo_CFLAGS and foo_LDFLAGS.  Any
          suggestion about what mechanism should be used to
          trigger this?  e.g. something in AUTOMAKE_OPTIONS, a
          magic AM_CONDITIONAL directive, something else?  Being
          no Automake guru I'm not sure what would be considered
          in the "spirit of Automake" here.

Thanks!

(Apologies if sending these patches as attachments is a bad idea.
I thought it was a good way to group them.  I hope Gnus doesn't
mangle them; I don't send attachments very often.)

Index: build-aux/config.libpath
===================================================================
RCS file: build-aux/config.libpath
diff -N build-aux/config.libpath
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ build-aux/config.libpath    22 Feb 2007 04:51:33 -0000
@@ -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 <address@hidden>, 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
Index: build-aux/install-reloc
===================================================================
RCS file: build-aux/install-reloc
diff -N build-aux/install-reloc
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ build-aux/install-reloc     22 Feb 2007 04:51:34 -0000
@@ -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 <address@hidden>, 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 
"$srcdir"/c-ctype.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
Index: build-aux/reloc-ldflags
===================================================================
RCS file: build-aux/reloc-ldflags
diff -N build-aux/reloc-ldflags
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ build-aux/reloc-ldflags     22 Feb 2007 04:51:34 -0000
@@ -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 <address@hidden>, 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
Index: doc/gnulib.texi
===================================================================
RCS file: /cvsroot/gnulib/gnulib/doc/gnulib.texi,v
retrieving revision 1.31
diff -u -p -r1.31 gnulib.texi
--- doc/gnulib.texi     3 Jan 2007 18:51:20 -0000       1.31
+++ doc/gnulib.texi     22 Feb 2007 04:51:34 -0000
@@ -365,6 +365,7 @@ Of course the license texts themselves s
 * gcd::
 * inet_ntoa::
 * Regular expressions::
+* Relocatability::
 @end menu
 
 @include quote.texi
@@ -372,6 +373,7 @@ Of course the license texts themselves s
 @include ctime.texi
 @include gcd.texi
 @include inet_ntoa.texi
address@hidden relocatable.texi
 
 @node Regular expressions
 @section Regular expressions
Index: doc/relocatable.texi
===================================================================
RCS file: doc/relocatable.texi
diff -N doc/relocatable.texi
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ doc/relocatable.texi        22 Feb 2007 04:51:34 -0000
@@ -0,0 +1,146 @@
address@hidden Relocatability
address@hidden Relocatability
+
+It has been a pain for many users of GNU packages for a long time that
+packages are not relocatable.  It means a user cannot copy a program,
+installed by another user on the same machine, to his home directory,
+and have it work correctly (including i18n).  So many users need to go
+through @code{configure; make; make install} with all its
+dependencies, options, and hurdles.
+
+Red Hat, Debian, and similar package systems solve the ``ease of
+installation'' problem, but they hardwire path names, usually to
address@hidden/usr} or @file{/usr/local}.  This means that users need root
+privileges to install a binary package, and prevents installing two
+different versions of the same binary package.
+
+The @code{relocatable} module aims to ease the process of making a GNU
+program relocatable.  It helps overcome two obstacles.  First, it aids
+with relocating the hard-coded references to absolute file names that
+GNU programs often contain.  These references must be fixed up at
+runtime if a program is to be successfully relocated.  The
address@hidden module provides a function @code{relocate} that
+does this job.
+
+Second, the loader must be able to find shared libraries linked to
+relocatable executables or referenced by other shared libraries linked
+to relocatable executables.  The @code{relocatable} module helps out
+here in a platform-specific way:
+
address@hidden
address@hidden
+On GNU/Linux, it adds a linker option (@option{-rpath}) that causes
+the dynamic linker to search for libraries in a directory relative to
+the location of the invoked executable.
+
address@hidden
+On other Unix systems, it installs a wrapper executable.  The wrapper
+sets the environment variable that controls shared library searching
+(usually @env{LD_LIBRARY_PATH}) and then invokes the real executable.
+
address@hidden
+On Windows, the executable's own directory is searched for libraries,
+so installing shared libraries into the executable's directory is
+sufficient.
address@hidden itemize
+
+To make your program relocatable, start by importing the
address@hidden module.  You must also make some changes to your
+source files:
+
address@hidden
address@hidden
+In every program, add to @code{main} as the first statement (even
+before setting the locale or doing anthing related to libintl):
+
address@hidden
+set_program_name (argv[0]);
address@hidden example
+
+The prototype for this function is in @file{progname.h}.
+
address@hidden
+Everywhere where you use a constant pathname from installation-time,
+wrap it in @code{relocate} so it gets translated to the run-time situation.
+Example:
+
address@hidden
+bindtextdomain (PACKAGE, LOCALEDIR);
address@hidden example
+
address@hidden
+becomes:
+
address@hidden 
+bindtextdomain (PACKAGE, relocate (LOCALEDIR));
address@hidden example
+
+The prototype for this function is in @file{relocatable.h}.
+
address@hidden
+In every shell script, add near the beginning the contents of
address@hidden/relocatable.sh.in} (in Gnulib).  You can take the two
+functions without modifications; only the following need to be
+adapted:
+
address@hidden
+if test "@@RELOCATABLE@@" = yes; then
+  exec_prefix="@@exec_prefix@@"
+  bindir="@@bindir@@"
+  orig_installdir="$bindir" # see Makefile.am's *_SCRIPTS variables
+  func_find_curr_installdir # determine curr_installdir
+  func_find_prefixes
+  # Relocate the directory variables that we use.
+  gettext_dir=`echo "$gettext_dir/" | sed -e 
+"address@hidden@}/address@hidden@}/%" | sed -e 's,/$,,'`
+fi
address@hidden example
+
+Here you adapt the definition of @code{orig_installdir}, depending on
+where the script gets installed.  Also, at the end, instead of
address@hidden, transform those variables that you need.
address@hidden enumerate
+
address@hidden
+Your @file{Makefile.am} requires some adaptation as well:
+
address@hidden
address@hidden
+For every program @command{foo} that gets installed in, say,
address@hidden(bindir)}, you add:
+
address@hidden
+foo_CFLAGS = -DINSTALLDIR=\"$(bindir)\"
+if RELOCATABLE_VIA_LD
+foo_LDFLAGS = `$(RELOCATABLE_LDFLAGS) $(bindir)`
+endif
address@hidden example
+
address@hidden
+The following is also necessary once per @file{Makefile.am} that
+installs a program:
+
address@hidden
+# Support for relocatability.
+RELOCATABLE_LIBRARY_PATH = $(libdir)
+RELOCATABLE_SRC_DIR = $(top_srcdir)/lib
+RELOCATABLE_BUILD_DIR = ../lib
+RELOCATABLE_CONFIG_H_DIR = ..
+@@SET_RELOCATABLE@@
address@hidden example
+
+Here, @code{RELOCATABLE_LIBRARY_PATH} is the directories in which your
+package (or any package you rely on, e.g.@: gettext-runtime) has
+installed libraries.  It is a colon separated list.
+
address@hidden denotes where to find @file{relocwrapper.c}
+and the related sources, so you need them only once in your package,
+even if you have multiple directories which install programs.
+
address@hidden denotes where to find the
address@hidden which defines the various @code{HAVE_} macros that
address@hidden and the related sources need.
+
address@hidden@@SET_RELOCATABLE@@} is some black magic that is filled in by the
address@hidden macro.
address@hidden enumerate
Index: lib/progreloc.c
===================================================================
RCS file: /cvsroot/gnulib/gnulib/lib/progreloc.c,v
retrieving revision 1.11
diff -u -p -r1.11 progreloc.c
--- lib/progreloc.c     14 Jan 2007 11:32:10 -0000      1.11
+++ lib/progreloc.c     22 Feb 2007 04:51:35 -0000
@@ -27,9 +27,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <fcntl.h>
-#if HAVE_UNISTD_H
-# include <unistd.h>
-#endif
+#include <unistd.h>
 #include <sys/stat.h>
 
 /* Get declaration of _NSGetExecutablePath on MacOS X 10.2 or newer.  */
@@ -174,7 +172,7 @@ find_executable (const char *argv0)
   {
     char *link;
 
-    link = xreadlink ("/proc/self/exe");
+    link = xreadlink ("/proc/self/exe", 4096);
     if (link != NULL && link[0] != '[')
       return link;
     if (executable_fd < 0)
@@ -183,7 +181,7 @@ find_executable (const char *argv0)
     {
       char buf[6+10+5];
       sprintf (buf, "/proc/%d/exe", getpid ());
-      link = xreadlink (buf);
+      link = xreadlink (buf, 4096);
       if (link != NULL && link[0] != '[')
        return link;
       if (executable_fd < 0)
Index: lib/relocatable.c
===================================================================
RCS file: lib/relocatable.c
diff -N lib/relocatable.c
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ lib/relocatable.c   22 Feb 2007 04:51:35 -0000
@@ -0,0 +1,440 @@
+/* Provide relocatable packages.
+   Copyright (C) 2003-2006, 2007 Free Software Foundation, Inc.
+   Written by Bruno Haible <address@hidden>, 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.  */
+
+#include <config.h>
+
+/* Specification.  */
+#include "relocatable.h"
+
+#if ENABLE_RELOCATABLE
+
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "pathname.h"
+#include "xalloc.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
+
+/* 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)
+         {
+            unsigned char c1, c2;
+            
+           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.  */
+            c1 = *rpi;
+            c2 = *cpi;
+#if defined _WIN32 || defined __WIN32__ || defined __CYGWIN__ || defined 
__EMX__ || defined __DJGPP__
+           /* Win32, Cygwin, OS/2, DOS - case insignificant filesystem */
+           if (c_toupper (c1) != c_toupper (c2))
+             break;
+#else
+           if (c1 != c2)
+             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
Index: lib/relocatable.h
===================================================================
RCS file: lib/relocatable.h
diff -N lib/relocatable.h
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ lib/relocatable.h   22 Feb 2007 04:51:35 -0000
@@ -0,0 +1,79 @@
+/* Provide relocatable packages.
+   Copyright (C) 2003, 2005 Free Software Foundation, Inc.
+   Written by Bruno Haible <address@hidden>, 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 */
Index: lib/relocatable.sh.in
===================================================================
RCS file: lib/relocatable.sh.in
diff -N lib/relocatable.sh.in
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ lib/relocatable.sh.in       22 Feb 2007 04:51:35 -0000
@@ -0,0 +1,111 @@
+#! /bin/sh
+#
+# From gettext/gettext-tools/misc/gettextize.in.
+#
+# The functions in this file provide support for relocatability of
+# shell scripts.  They should be included at the beginning of each
+# shell script in a relocatable program.  Some adaptation is required;
+# see relocatable.texi for details.
+#
+# Copyright (C) 1995-1998, 2000-2006 Free Software Foundation, Inc.
+#
+# 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.
+#
+
+# Support for relocatability.
+func_find_curr_installdir ()
+{
+  # Determine curr_installdir, even taking into account symlinks.
+  curr_executable="$0"
+  case "$curr_executable" in
+    */* | *\\*) ;;
+    *) # Need to look in the PATH.
+      if test "${PATH_SEPARATOR+set}" != set; then
+        func_tmpdir
+        { echo "#! /bin/sh"; echo "exit 0"; } > "$tmp"/conf.sh
+        chmod +x "$tmp"/conf.sh
+        if (PATH="/nonexistent;$tmp"; conf.sh) >/dev/null 2>&1; then
+          PATH_SEPARATOR=';'
+        else
+          PATH_SEPARATOR=:
+        fi
+        rm -rf "$tmp"
+      fi
+      save_IFS="$IFS"; IFS="$PATH_SEPARATOR"
+      for dir in $PATH; do
+        IFS="$save_IFS"
+        test -z "$dir" && dir=.
+        for exec_ext in ''; do
+          if test -f "$dir/$curr_executable$exec_ext"; then
+            curr_executable="$dir/$curr_executable$exec_ext"
+            break 2
+          fi
+        done
+      done
+      IFS="$save_IFS"
+      ;;
+  esac
+  # Make absolute.
+  case "$curr_executable" in
+    /* | ?:/* | ?:\\*) ;;
+    *) curr_executable=`pwd`/"$curr_executable" ;;
+  esac
+  # Resolve symlinks.
+  sed_dirname='s,/[^/]*$,,'
+  sed_linkdest='s,^.* -> \(.*\),\1,p'
+  while : ; do
+    lsline=`LC_ALL=C ls -l "$curr_executable"`
+    case "$lsline" in
+      *" -> "*)
+        linkdest=`echo "$lsline" | sed -n -e "$sed_linkdest"`
+        case "$linkdest" in
+          /* | ?:/* | ?:\\*) curr_executable="$linkdest" ;;
+          *) curr_executable=`echo "$curr_executable" | sed -e 
"$sed_dirname"`/"$linkdest" ;;
+        esac ;;
+      *) break ;;
+    esac
+  done
+  curr_installdir=`echo "$curr_executable" | sed -e 's,/[^/]*$,,'`
+  # Canonicalize.
+  curr_installdir=`cd "$curr_installdir" && pwd`
+}
+func_find_prefixes ()
+{
+  # Compute the original/current installation prefixes by stripping the
+  # trailing directories off the original/current installation directories.
+  orig_installprefix="$orig_installdir"
+  curr_installprefix="$curr_installdir"
+  while true; do
+    orig_last=`echo "$orig_installprefix" | sed -n -e 's,^.*/\([^/]*\)$,\1,p'`
+    curr_last=`echo "$curr_installprefix" | sed -n -e 's,^.*/\([^/]*\)$,\1,p'`
+    if test -z "$orig_last" || test -z "$curr_last"; then
+      break
+    fi
+    if test "$orig_last" != "$curr_last"; then
+      break
+    fi
+    orig_installprefix=`echo "$orig_installprefix" | sed -e 's,/[^/]*$,,'`
+    curr_installprefix=`echo "$curr_installprefix" | sed -e 's,/[^/]*$,,'`
+  done
+}
+if test "@RELOCATABLE@" = yes; then
+  exec_prefix="@exec_prefix@"
+  bindir="@bindir@"
+  orig_installdir="$bindir" # see Makefile.am's *_SCRIPTS variables
+  func_find_curr_installdir # determine curr_installdir
+  func_find_prefixes
+  # Relocate the directory variables that we use.
+  gettext_dir=`echo "$gettext_dir/" | sed -e 
"s%^${orig_installprefix}/%${curr_installprefix}/%" | sed -e 's,/$,,'`
+fi
Index: lib/relocwrapper.c
===================================================================
RCS file: lib/relocwrapper.c
diff -N lib/relocwrapper.c
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ lib/relocwrapper.c  22 Feb 2007 04:51:35 -0000
@@ -0,0 +1,193 @@
+/* Relocating wrapper program.
+   Copyright (C) 2003, 2005-2006, 2007 Free Software Foundation, Inc.
+   Written by Bruno Haible <address@hidden>, 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
+    -> c-ctype
+
+   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>
+#include <unistd.h>
+#include <errno.h>
+
+#include "progname.h"
+#include "relocatable.h"
+#include "setenv.h"
+#include "c-ctype.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 (c_tolower (c1) != c_tolower (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);
+}
Index: m4/relocatable.m4
===================================================================
RCS file: m4/relocatable.m4
diff -N m4/relocatable.m4
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ m4/relocatable.m4   22 Feb 2007 04:51:36 -0000
@@ -0,0 +1,118 @@
+# relocatable.m4 serial 8 (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])
+  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"
+])
Index: modules/relocatable
===================================================================
RCS file: modules/relocatable
diff -N modules/relocatable
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ modules/relocatable 22 Feb 2007 04:51:36 -0000
@@ -0,0 +1,41 @@
+Description:
+Help make programs relocatable, that is, to allow them to function
+properly when copied to an arbitrary directory.
+
+Files:
+build-aux/config.libpath
+build-aux/install-reloc
+build-aux/reloc-ldflags
+lib/progreloc.c
+lib/relocatable.c
+lib/relocatable.h
+lib/relocwrapper.c
+m4/relocatable.m4
+
+Depends-on:
+canonicalize
+c-ctype
+extensions
+pathname
+progname
+setenv
+strerror
+unistd
+xalloc
+
+configure.ac:
+AC_RELOCATABLE
+
+Makefile.am:
+DEFS += -DEXEEXT=\"$(EXEEXT)\"
+lib_SOURCES += progreloc.c relocatable.c relocatable.h
+
+Include:
+"progname.h"
+"relocatable.h"
+
+License:
+GPL
+
+Maintainer:
+
--- gettext/build-aux/install-reloc     2006-11-09 06:26:40.000000000 -0800
+++ gnulib/build-aux/install-reloc      2007-02-19 22:31:39.000000000 -0800
@@ -119,8 +119,8 @@
 
 # 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 $?
+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 
"$srcdir"/c-ctype.c -o "$destprog.wrapper$exeext" || exit $?
 
 # Rename $destprog.wrapper -> $destprog -> $destprog.bin.
 ln -f "$destprog$exeext" "$destprog.bin$exeext" \

--- gettext/gnulib-local/lib/relocatable.c      2006-09-15 05:01:51.000000000 
-0700
+++ gnulib/lib/relocatable.c    2007-02-19 22:03:21.000000000 -0800
@@ -1,5 +1,5 @@
 /* Provide relocatable packages.
-   Copyright (C) 2003-2006 Free Software Foundation, Inc.
+   Copyright (C) 2003-2006, 2007 Free Software Foundation, Inc.
    Written by Bruno Haible <address@hidden>, 2003.
 
    This program is free software; you can redistribute it and/or modify it
@@ -17,14 +17,6 @@
    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.  */
@@ -32,11 +24,15 @@
 
 #if ENABLE_RELOCATABLE
 
+#include <stdbool.h>
 #include <stddef.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 
+#include "pathname.h"
+#include "xalloc.h"
+
 #ifdef NO_XMALLOC
 # define xmalloc malloc
 #else
@@ -58,34 +54,6 @@
 # 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;
@@ -224,6 +192,8 @@
 
        while (rpi > rel_installdir && cpi > cp_base)
          {
+            unsigned char c1, c2;
+            
            rpi--;
            cpi--;
            if (ISSLASH (*rpi) || ISSLASH (*cpi))
@@ -232,16 +202,18 @@
                  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.  */
+            c1 = *rpi;
+            c2 = *cpi;
 #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))
+           if (c_toupper (c1) != c_toupper (c2))
              break;
 #else
-           if (*rpi != *cpi)
+           if (c1 != c2)
              break;
 #endif
          }

--- gettext/gnulib-local/lib/relocwrapper.c     2006-09-15 05:01:51.000000000 
-0700
+++ gnulib/lib/relocwrapper.c   2007-02-19 22:02:58.000000000 -0800
@@ -1,5 +1,5 @@
 /* Relocating wrapper program.
-   Copyright (C) 2003, 2005-2006 Free Software Foundation, Inc.
+   Copyright (C) 2003, 2005-2006, 2007 Free Software Foundation, Inc.
    Written by Bruno Haible <address@hidden>, 2003.
 
    This program is free software; you can redistribute it and/or modify
@@ -28,6 +28,7 @@
     -> setenv
        -> allocsa
     -> strerror
+    -> c-ctype
 
    Macros that need to be set while compiling this file:
      - ENABLE_RELOCATABLE 1
@@ -47,14 +48,13 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#if HAVE_UNISTD_H
-# include <unistd.h>
-#endif
+#include <unistd.h>
 #include <errno.h>
 
 #include "progname.h"
 #include "relocatable.h"
 #include "setenv.h"
+#include "c-ctype.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}".  */
@@ -83,8 +83,7 @@
                {
                  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))
+                 if (c_tolower (c1) != c_tolower (c2))
                    goto simple_append;
                }
              /* Insert ".bin" before EXEEXT or its equivalent.  */

--- gettext/gnulib-local/m4/relocatable.m4      2006-10-26 04:50:38.000000000 
-0700
+++ gnulib/m4/relocatable.m4    2007-02-21 19:30:08.000000000 -0800
@@ -1,4 +1,4 @@
-# relocatable.m4 serial 7 (gettext-0.16)
+# relocatable.m4 serial 8 (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,
@@ -27,7 +27,6 @@
   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
Index: ChangeLog
===================================================================
RCS file: /sources/hello/hello/ChangeLog,v
retrieving revision 1.32
diff -u -p -r1.32 ChangeLog
--- ChangeLog   23 Nov 2006 15:02:24 -0000      1.32
+++ ChangeLog   22 Feb 2007 03:35:48 -0000
@@ -1,3 +1,18 @@
+2007-02-20  Ben Pfaff  <address@hidden>
+
+       Add support for relocatability.
+       
+       * Imported gnulib "relocatable" module.
+       
+       * configure.ac: AM_PROG_CC_C_O needed for target-specific flags.
+
+       * src/Makefile.am: Add Automake magic for relocatability.
+
+       * src/hello.c: Use program_name from gnulib progname and progreloc
+       modules, instead of rolling our own.
+       (main): Call set_program_name.  Call relocate on LOCALEDIR when
+       passing to bindtextdomain.
+
 2006-11-23  Karl Berry  <address@hidden>
 
        * Version 2.2.
Index: configure.ac
===================================================================
RCS file: /sources/hello/hello/configure.ac,v
retrieving revision 1.22
diff -u -p -r1.22 configure.ac
--- configure.ac        23 Nov 2006 15:02:24 -0000      1.22
+++ configure.ac        22 Feb 2007 03:35:48 -0000
@@ -24,6 +24,7 @@ AC_CONFIG_SRCDIR([src/hello.c])
 dnl Checks for programs.
 # We need a C compiler.
 AC_PROG_CC
+AM_PROG_CC_C_O
 
 # Since we use gnulib: gl_EARLY must be called as soon as possible after
 # the C compiler is checked.  The others could be later, but we just
Index: src/Makefile.am
===================================================================
RCS file: /sources/hello/hello/src/Makefile.am,v
retrieving revision 1.9
diff -u -p -r1.9 Makefile.am
--- src/Makefile.am     17 Oct 2006 21:57:42 -0000      1.9
+++ src/Makefile.am     22 Feb 2007 03:35:48 -0000
@@ -26,3 +26,15 @@ localedir = $(datadir)/locale
 
 AM_CPPFLAGS = -I$(top_srcdir)/gnulib/lib -I$(top_builddir)/gnulib/lib
 DEFS = -DLOCALEDIR=\"$(localedir)\" @DEFS@
+
+hello_CFLAGS = -DINSTALLDIR=\"$(bindir)\"
+if RELOCATABLE_VIA_LD
+hello_LDFLAGS = `$(RELOCATABLE_LDFLAGS) $(bindir)`
+endif
+
+# Support for relocatability.
+RELOCATABLE_LIBRARY_PATH = $(libdir)
+RELOCATABLE_SRC_DIR = $(top_srcdir)/lib
+RELOCATABLE_BUILD_DIR = ../lib
+RELOCATABLE_CONFIG_H_DIR = ..
address@hidden@
Index: src/hello.c
===================================================================
RCS file: /sources/hello/hello/src/hello.c,v
retrieving revision 1.27
diff -u -p -r1.27 hello.c
--- src/hello.c 12 Dec 2006 02:01:11 -0000      1.27
+++ src/hello.c 22 Feb 2007 03:35:48 -0000
@@ -18,11 +18,10 @@
    Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
 
 #include <config.h>
+#include "progname.h"
+#include "relocatable.h"
 #include "system.h"
 
-/* String containing name the program is called with.  */
-const char *program_name;
-
 static const struct option longopts[] =
 {
   { "greeting", required_argument, NULL, 'g' },
@@ -43,14 +42,14 @@ main (int argc, char *argv[])
   int t = 0, n = 0, lose = 0;
   const char *greeting = NULL;
 
-  program_name = argv[0];
+  set_program_name (argv[0]);
 
   /* Set locale via LC_ALL.  */
   setlocale (LC_ALL, "");
 
 #if ENABLE_NLS
   /* Set the text message domain.  */
-  bindtextdomain (PACKAGE, LOCALEDIR);
+  bindtextdomain (PACKAGE, relocate (LOCALEDIR));
   textdomain (PACKAGE);
 #endif
 
-- 
"...In the UNIX world, people tend to interpret `non-technical user'
 as meaning someone who's only ever written one device driver."
--Daniel Pead

reply via email to

[Prev in Thread] Current Thread [Next in Thread]