bug-gnulib@gnu.org mirror (unofficial)
 help / color / mirror / Atom feed
* relocatable-prog: Use $ORIGIN trick on more platforms
@ 2019-02-20  1:45 Bruno Haible
  2019-02-20 16:12 ` Paul Smith
  2019-02-23 20:26 ` Bruno Haible
  0 siblings, 2 replies; 6+ messages in thread
From: Bruno Haible @ 2019-02-20  1:45 UTC (permalink / raw)
  To: bug-gnulib; +Cc: Paul Smith

Paul Smith noted on gnu-prog-discuss that other systems than glibc have support
for $ORIGIN in rpath. This patch changes the 'relocatable-prog' module to
make use of this feature, thus removing the need for a "wrapper"/"trampoline"
executable on these platforms.

Tested on
  - FreeBSD 11,
  - NetBSD 7, 8,
  - OpenBSD 6,
  - Solaris 9, 10, 11,
  - Haiku.


2019-02-19  Bruno Haible  <bruno@clisp.org>

	relocatable-prog: Use $ORIGIN trick on more platforms.
	* m4/relocatable.m4 (gl_RELOCATABLE_BODY): Use $ORIGIN trick also on
	FreeBSD >= 7.3, DragonFly >= 3.0, NetBSD >= 8.0, OpenBSD >= 5.4,
	Solaris >= 10, Haiku. But don't use it on Android.
	* build-aux/reloc-ldflags: Allow the use of the $ORIGIN trick also on
	Hurd, FreeBSD, DragonFly, NetBSD, OpenBSD, Solaris, Haiku.

diff --git a/m4/relocatable.m4 b/m4/relocatable.m4
index c55f7b4..0044477 100644
--- a/m4/relocatable.m4
+++ b/m4/relocatable.m4
@@ -1,4 +1,4 @@
-# relocatable.m4 serial 19
+# relocatable.m4 serial 20
 dnl Copyright (C) 2003, 2005-2007, 2009-2019 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -40,10 +40,34 @@ AC_DEFUN([gl_RELOCATABLE_BODY],
     enable_rpath=no
     AC_CHECK_HEADERS([mach-o/dyld.h])
     AC_CHECK_FUNCS([_NSGetExecutablePath])
+changequote(,)dnl
     case "$host_os" in
       mingw*) is_noop=yes ;;
+      # For the platforms that support $ORIGIN, see
+      # <https://lekensteyn.nl/rpath.html>.
+      # glibc systems, Linux with musl libc: yes. Android: no.
+      # Hurd: no <http://lists.gnu.org/archive/html/bug-hurd/2019-02/msg00049.html>.
+      linux*-android*) ;;
+      gnu*) ;;
       linux* | kfreebsd*) use_elf_origin_trick=yes ;;
+      # FreeBSD >= 7.3, DragonFly >= 3.0: yes.
+      freebsd | freebsd[1-7] | freebsd[1-6].* | freebsd7.[0-2]) ;;
+      dragonfly | dragonfly[1-2] | dragonfly[1-2].*) ;;
+      freebsd* | dragonfly*) use_elf_origin_trick=yes ;;
+      # NetBSD >= 8.0: yes.
+      netbsd | netbsd[1-7] | netbsd[1-7].*) ;;
+      netbsdelf | netbsdelf[1-7] | netbsdelf[1-7].*) ;;
+      netbsd*) use_elf_origin_trick=yes ;;
+      # OpenBSD >= 5.4: yes.
+      openbsd | openbsd[1-5] | openbsd[1-4].* | openbsd5.[0-3]) ;;
+      openbsd*) use_elf_origin_trick=yes ;;
+      # Solaris >= 10: yes.
+      solaris | solaris2.[1-9] | solaris2.[1-9].*) ;;
+      solaris*) use_elf_origin_trick=yes ;;
+      # Haiku: yes.
+      haiku*) use_elf_origin_trick=yes ;;
     esac
+changequote([,])dnl
     if test $is_noop = yes; then
       RELOCATABLE_LDFLAGS=:
       AC_SUBST([RELOCATABLE_LDFLAGS])
diff --git a/build-aux/reloc-ldflags b/build-aux/reloc-ldflags
index 4f2b10d..3aed330 100755
--- a/build-aux/reloc-ldflags
+++ b/build-aux/reloc-ldflags
@@ -54,7 +54,12 @@ case "$installdir" in
 esac
 
 case "$host_os" in
-  linux* | kfreebsd*)
+  linux* | gnu* | kfreebsd* | \
+  freebsd* | dragonfly* | \
+  netbsd* | \
+  openbsd* | \
+  solaris* | \
+  haiku*)
     rpath=
     save_IFS="$IFS"; IFS=":"
     for dir in $library_path_value; do
@@ -89,7 +94,14 @@ case "$host_os" in
     IFS="$save_IFS"
     # Output it.
     if test -n "$rpath"; then
-      echo "-Wl,-rpath,$rpath"
+      case "$host_os" in
+        # At least some versions of FreeBSD, DragonFly, and OpenBSD need the
+        # linker option "-z origin". See <https://lekensteyn.nl/rpath.html>.
+        freebsd* | dragonfly* | openbsd*)
+          echo "-Wl,-z,origin -Wl,-rpath,$rpath" ;;
+        *)
+          echo "-Wl,-rpath,$rpath" ;;
+      esac
     fi
     ;;
   *)



^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: relocatable-prog: Use $ORIGIN trick on more platforms
  2019-02-20  1:45 relocatable-prog: Use $ORIGIN trick on more platforms Bruno Haible
@ 2019-02-20 16:12 ` Paul Smith
  2019-02-23 21:54   ` Bruno Haible
  2019-02-23 20:26 ` Bruno Haible
  1 sibling, 1 reply; 6+ messages in thread
From: Paul Smith @ 2019-02-20 16:12 UTC (permalink / raw)
  To: Bruno Haible, bug-gnulib

On Wed, 2019-02-20 at 02:45 +0100, Bruno Haible wrote:
> Paul Smith noted on gnu-prog-discuss that other systems than glibc
> have support for $ORIGIN in rpath. This patch changes the
> 'relocatable-prog' module to make use of this feature, thus removing
> the need for a "wrapper"/"trampoline" executable on these platforms.

MacOS has @executable_path which is the same as $ORIGIN.  See:

https://wincent.com/wiki/%40executable_path%2C_%40load_path_and_%40rpath

Unfortunately on MacOS they have "applications" which are much more
complicated and can have frameworks etc.  But I think @executable_path
is pretty close to exactly the same thing as $ORIGIN and works fine if
you're just building a normal application.



^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: relocatable-prog: Use $ORIGIN trick on more platforms
  2019-02-20  1:45 relocatable-prog: Use $ORIGIN trick on more platforms Bruno Haible
  2019-02-20 16:12 ` Paul Smith
@ 2019-02-23 20:26 ` Bruno Haible
  1 sibling, 0 replies; 6+ messages in thread
From: Bruno Haible @ 2019-02-23 20:26 UTC (permalink / raw)
  To: bug-gnulib; +Cc: Paul Smith

Recent enough Hurd versions support $ORIGIN as well. This patch
enables support for it in the 'relocatable-prog' module.


2019-02-23  Bruno Haible  <bruno@clisp.org>

	relocatable-prog: Use $ORIGIN trick also on GNU/Hurd.
	* m4/relocatable.m4 (gl_RELOCATABLE_BODY): Use $ORIGIN trick also on
	Hurd with glibc >= 2.27.

diff --git a/m4/relocatable.m4 b/m4/relocatable.m4
index 0044477..faa23f2 100644
--- a/m4/relocatable.m4
+++ b/m4/relocatable.m4
@@ -1,4 +1,4 @@
-# relocatable.m4 serial 20
+# relocatable.m4 serial 21
 dnl Copyright (C) 2003, 2005-2007, 2009-2019 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -40,16 +40,24 @@ AC_DEFUN([gl_RELOCATABLE_BODY],
     enable_rpath=no
     AC_CHECK_HEADERS([mach-o/dyld.h])
     AC_CHECK_FUNCS([_NSGetExecutablePath])
-changequote(,)dnl
     case "$host_os" in
       mingw*) is_noop=yes ;;
       # For the platforms that support $ORIGIN, see
       # <https://lekensteyn.nl/rpath.html>.
       # glibc systems, Linux with musl libc: yes. Android: no.
-      # Hurd: no <http://lists.gnu.org/archive/html/bug-hurd/2019-02/msg00049.html>.
       linux*-android*) ;;
-      gnu*) ;;
       linux* | kfreebsd*) use_elf_origin_trick=yes ;;
+      # Hurd: <http://lists.gnu.org/archive/html/bug-hurd/2019-02/msg00049.html>
+      # only after the glibc commit from 2018-01-08
+      # <https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=311ba8dc4416467947eff2ab327854f124226309>
+      gnu*)
+        # Test for a glibc version >= 2.27.
+        AC_CHECK_FUNCS([copy_file_range])
+        if test $ac_cv_func_copy_file_range = yes; then
+          use_elf_origin_trick=yes
+        fi
+        ;;
+changequote(,)dnl
       # FreeBSD >= 7.3, DragonFly >= 3.0: yes.
       freebsd | freebsd[1-7] | freebsd[1-6].* | freebsd7.[0-2]) ;;
       dragonfly | dragonfly[1-2] | dragonfly[1-2].*) ;;
@@ -66,8 +74,8 @@ changequote(,)dnl
       solaris*) use_elf_origin_trick=yes ;;
       # Haiku: yes.
       haiku*) use_elf_origin_trick=yes ;;
-    esac
 changequote([,])dnl
+    esac
     if test $is_noop = yes; then
       RELOCATABLE_LDFLAGS=:
       AC_SUBST([RELOCATABLE_LDFLAGS])



^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: relocatable-prog: Use $ORIGIN trick on more platforms
  2019-02-20 16:12 ` Paul Smith
@ 2019-02-23 21:54   ` Bruno Haible
  2019-02-24  0:51     ` Bruno Haible
  2019-03-04 16:32     ` Bruno Haible
  0 siblings, 2 replies; 6+ messages in thread
From: Bruno Haible @ 2019-02-23 21:54 UTC (permalink / raw)
  To: bug-gnulib; +Cc: psmith

Paul Smith wrote:
> MacOS has @executable_path which is the same as $ORIGIN.  See:
> 
> https://wincent.com/wiki/%40executable_path%2C_%40load_path_and_%40rpath

Thanks for the pointer.

> Unfortunately on MacOS they have "applications" which are much more
> complicated and can have frameworks etc.  But I think @executable_path
> is pretty close to exactly the same thing as $ORIGIN and works fine if
> you're just building a normal application.

I think @loader_path is preferrable over @executable_path. For executables,
both act the same way. @loader_path becomes interesting when creating or
installing a shared library. See
https://developer.apple.com/library/archive/documentation/DeveloperTools/Conceptual/DynamicLibraries/100-Articles/DynamicLibraryDesignGuidelines.html
section "Locating External Resources".


2019-02-23  Bruno Haible  <bruno@clisp.org>

	relocatable-prog: Use wrapper-free installation also on Mac OS X.
	Reported by Paul Smith <psmith@gnu.org>.
	* build-aux/install-reloc: Accept a 'mode' argument as first argument.
	(func_relativize): New function, from gnulib-tool.
	Handle mode 'macosx' through invocations of 'otool' and
	'install_name_tool'.
	* m4/relocatable.m4 (gl_RELOCATABLE_BODY): Determine use_macos_tools.
	If use_macos_tools is true, set INSTALL_PROGRAM_ENV to an
	'install-reloc' invocation with mode 'macosx'.

diff --git a/build-aux/install-reloc b/build-aux/install-reloc
index 980303c..e68386e 100755
--- a/build-aux/install-reloc
+++ b/build-aux/install-reloc
@@ -1,5 +1,8 @@
 #!/bin/sh
-# install-reloc - install a program including a relocating wrapper
+# install-reloc - install a program in a way that it will find its shared
+#                 libraries even when relocated,
+#                 - either including a relocating wrapper,
+#                 - or using Mac OS X specific tools.
 # Copyright (C) 2003-2019 Free Software Foundation, Inc.
 # Written by Bruno Haible <bruno@clisp.org>, 2003.
 #
@@ -17,10 +20,15 @@
 # along with this program.  If not, see <https://www.gnu.org/licenses/>.
 
 # Usage 1:
-#   install-reloc -- library_path_var library_path_value prefix destdir \
+#   install-reloc -- 'wrapper' \
+#                    library_path_var library_path_value prefix destdir \
 #                    compile_command srcdir builddir config_h_dir exeext \
 #                    strip_command \
 #                    install_command... destprog
+#   install-reloc -- 'macosx' \
+#                    prefix destdir \
+#                    strip_command \
+#                    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
@@ -40,7 +48,8 @@
 #   - install_command is the install command line, excluding the final destprog
 #   - destprog is the destination program name
 # Usage 2:
-#   env RELOC_LIBRARY_PATH_VAR=library_path_var \
+#   env RELOC_MODE='wrapper' \
+#       RELOC_LIBRARY_PATH_VAR=library_path_var \
 #       RELOC_LIBRARY_PATH_VALUE=library_path_value \
 #       RELOC_PREFIX=prefix \
 #       RELOC_DESTDIR=destdir \
@@ -51,59 +60,120 @@
 #       RELOC_EXEEXT=exeext \
 #       RELOC_STRIP_PROG=strip_command \
 #       RELOC_INSTALL_PROG=install_command... \
-#   install-reloc prog1 ... destprog
+#     install-reloc prog1 ... destprog
+#   env RELOC_MODE='macosx' \
+#       RELOC_PREFIX=prefix \
+#       RELOC_DESTDIR=destdir \
+#       RELOC_STRIP_PROG=strip_command \
+#       RELOC_INSTALL_PROG=install_command... \
+#     install-reloc prog1 ... destprog
 #   where destprog is either the destination program name (when only one program
 #   is specified) or the destination directory for all programs.
-# install-reloc renames destprog to destprog.bin and installs a relocating
-# wrapper in the place of destprog.
+# In the 'wrapper' mode, install-reloc renames destprog to destprog.bin and
+# installs a relocating wrapper in the place of destprog.
 
 progname=$0
 
-if test $# -ge 12 && test "x$1" = "x--"; then
+func_usage ()
+{
+  echo "Usage: $0 -- 'wrapper'" \
+       "library_path_var library_path_value prefix destdir" \
+       "compile_command srcdir builddir config_h_dir exeext" \
+       "strip_command" \
+       "install_command... destprog"
+  echo "Usage: $0 -- 'macosx'" \
+       "prefix destdir" \
+       "strip_command" \
+       "install_command... destprog"
+}
+
+if test "x$1" = "x--"; then
   # Get fixed position arguments.
-  shift
-  library_path_var=$1
-  library_path_value=$2
-  prefix=$3
-  destdir=$4
-  shift
-  shift
-  shift
-  shift
-  compile_command=$1
-  srcdir=$2
-  builddir=$3
-  config_h_dir=$4
-  exeext=$5
-  shift
-  shift
-  shift
-  shift
-  shift
-  strip_prog=$1
-  shift
-  install_prog=$1 # maybe not including the "-c" option
-  shift
+  case "$2" in
+    wrapper)
+      if test $# -ge 13; then
+        mode=$2
+        shift
+        shift
+        library_path_var=$1
+        library_path_value=$2
+        prefix=$3
+        destdir=$4
+        shift
+        shift
+        shift
+        shift
+        compile_command=$1
+        srcdir=$2
+        builddir=$3
+        config_h_dir=$4
+        exeext=$5
+        shift
+        shift
+        shift
+        shift
+        shift
+        strip_prog=$1
+        shift
+        install_prog=$1 # maybe not including the "-c" option
+        shift
+      else
+        func_usage 1>&2; exit 1
+      fi
+      ;;
+    macosx)
+      if test $# -ge 6; then
+        mode=$2
+        shift
+        shift
+        prefix=$1
+        destdir=$2
+        shift
+        shift
+        exeext=
+        strip_prog=$1
+        shift
+        install_prog=$1 # maybe not including the "-c" option
+        shift
+      else
+        func_usage 1>&2; exit 1
+      fi
+      ;;
+    *)
+      func_usage 1>&2; exit 1
+      ;;
+  esac
 else
   if test $# -ge 2; then
     # Get arguments from environment variables.
-    library_path_var=$RELOC_LIBRARY_PATH_VAR
-    library_path_value=$RELOC_LIBRARY_PATH_VALUE
-    prefix=$RELOC_PREFIX
-    destdir=$RELOC_DESTDIR
-    compile_command=$RELOC_COMPILE_COMMAND
-    srcdir=$RELOC_SRCDIR
-    builddir=$RELOC_BUILDDIR
-    config_h_dir=$RELOC_CONFIG_H_DIR
-    exeext=$RELOC_EXEEXT
-    strip_prog=$RELOC_STRIP_PROG
-    install_prog=$RELOC_INSTALL_PROG # including the "-c" option
+    mode=$RELOC_MODE
+    case "$mode" in
+      wrapper)
+        library_path_var=$RELOC_LIBRARY_PATH_VAR
+        library_path_value=$RELOC_LIBRARY_PATH_VALUE
+        prefix=$RELOC_PREFIX
+        destdir=$RELOC_DESTDIR
+        compile_command=$RELOC_COMPILE_COMMAND
+        srcdir=$RELOC_SRCDIR
+        builddir=$RELOC_BUILDDIR
+        config_h_dir=$RELOC_CONFIG_H_DIR
+        exeext=$RELOC_EXEEXT
+        strip_prog=$RELOC_STRIP_PROG
+        install_prog=$RELOC_INSTALL_PROG # including the "-c" option
+        ;;
+      macosx)
+        prefix=$RELOC_PREFIX
+        destdir=$RELOC_DESTDIR
+        exeext=
+        strip_prog=$RELOC_STRIP_PROG
+        install_prog=$RELOC_INSTALL_PROG # including the "-c" option
+        ;;
+      *)
+        func_usage 1>&2; exit 1
+        ;;
+    esac
   else
-    echo "Usage: $0 -- library_path_var library_path_value prefix destdir" \
-         "compile_command srcdir builddir config_h_dir exeext" \
-         "strip_command" \
-         "install_command... destprog" 1>&2
-    exit 1
+    func_usage 1>&2; exit 1
   fi
 fi
 
@@ -179,30 +249,13 @@ if test "$strip_prog" != ':'; then
   func_iterate func_strip
 fi
 
-# 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
-
 # Determine installdir from destprog, removing a leading destdir if present.
 if test -n "$destprog_directory"; then
+  # There's possibly multiple programs to install, but all go into the same
+  # directory.
   installdir="$destprog_directory"
 else
+  # There's only one program to install.
   installdir=`echo "$destprog" | sed -e 's,/[^/]*$,,'`
 fi
 if test -n "$destdir"; then
@@ -211,68 +264,160 @@ if test -n "$destdir"; then
   installdir=`echo "$installdir" | sed -e "$sed_remove_destdir"`
 fi
 
-# Compile and install wrapper.
-func_create_wrapper ()
+# func_relativize DIR1 DIR2
+# computes a relative pathname RELDIR such that DIR1/RELDIR = DIR2.
+# Input:
+# - DIR1            relative pathname, relative to the current directory
+# - DIR2            relative pathname, relative to the current directory
+# Output:
+# - reldir          relative pathname of DIR2, relative to DIR1
+func_relativize ()
 {
-  # Remove trailing $exeext, if present.
-  if test -n "$exeext"; then
-    destprog=`echo "$destprog" | sed -e "$sed_remove_exeext"`
-  fi
+  dir0=`pwd`
+  dir1="$1"
+  dir2="$2"
+  sed_first='s,^\([^/]*\)/.*$,\1,'
+  sed_rest='s,^[^/]*/*,,'
+  sed_last='s,^.*/\([^/]*\)$,\1,'
+  sed_butlast='s,/*[^/]*$,,'
+  while test -n "$dir1"; do
+    first=`echo "$dir1" | sed -e "$sed_first"`
+    if test "$first" != "."; then
+      if test "$first" = ".."; then
+        dir2=`echo "$dir0" | sed -e "$sed_last"`/"$dir2"
+        dir0=`echo "$dir0" | sed -e "$sed_butlast"`
+      else
+        first2=`echo "$dir2" | sed -e "$sed_first"`
+        if test "$first2" = "$first"; then
+          dir2=`echo "$dir2" | sed -e "$sed_rest"`
+        else
+          dir2="../$dir2"
+        fi
+        dir0="$dir0"/"$first"
+      fi
+    fi
+    dir1=`echo "$dir1" | sed -e "$sed_rest"`
+  done
+  reldir="$dir2"
+}
 
-  # Compile wrapper.
-  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"/areadlink.c \
-               "$srcdir"/careadlinkat.c \
-               "$srcdir"/allocator.c \
-               "$srcdir"/readlink.c \
-               "$srcdir"/stat.c \
-               "$srcdir"/canonicalize-lgpl.c \
-               "$srcdir"/malloca.c \
-               "$srcdir"/lstat.c \
-               "$srcdir"/relocatable.c \
-               "$srcdir"/setenv.c \
-               "$srcdir"/c-ctype.c \
-               -o "$destprog.wrapper$exeext"
-  rc=$?
-  # Clean up object files left over in the current directory by the native C
-  # compilers on Solaris, HP-UX, OSF/1, IRIX.
-  rm -f relocwrapper.o \
-        progname.o \
-        progreloc.o \
-        areadlink.o \
-        careadlinkat.o \
-        allocator.o \
-        readlink.o \
-        stat.o \
-        canonicalize-lgpl.o \
-        malloca.o \
-        lstat.o \
-        relocatable.o \
-        setenv.o \
-        c-ctype.o
-  test $rc = 0 || exit $?
-  # Clean up debugging information left over by the native C compiler on MacOS X.
-  rm -rf "$destprog.wrapper$exeext.dSYM"
-  test $rc = 0 || exit $?
+case "$mode" in
 
-  # Strip wrapper.
-  test "$strip_prog" = ':' || func_verbose "$strip_prog" "$destprog.wrapper$exeext" || exit $?
+  wrapper)
+    # If the platform doesn't support LD_LIBRARY_PATH or similar, we cannot
+    # build a wrapper.
+    test -n "$library_path_var" || exit 0
 
-  # 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
-}
-func_iterate func_create_wrapper
+    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 and install wrapper.
+    func_create_wrapper ()
+    {
+      # Remove trailing $exeext, if present.
+      if test -n "$exeext"; then
+        destprog=`echo "$destprog" | sed -e "$sed_remove_exeext"`
+      fi
+
+      # Compile wrapper.
+      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"/areadlink.c \
+                   "$srcdir"/careadlinkat.c \
+                   "$srcdir"/allocator.c \
+                   "$srcdir"/readlink.c \
+                   "$srcdir"/stat.c \
+                   "$srcdir"/canonicalize-lgpl.c \
+                   "$srcdir"/malloca.c \
+                   "$srcdir"/lstat.c \
+                   "$srcdir"/relocatable.c \
+                   "$srcdir"/setenv.c \
+                   "$srcdir"/c-ctype.c \
+                   -o "$destprog.wrapper$exeext"
+      rc=$?
+      # Clean up object files left over in the current directory by the native C
+      # compilers on Solaris, HP-UX, OSF/1, IRIX.
+      rm -f relocwrapper.o \
+            progname.o \
+            progreloc.o \
+            areadlink.o \
+            careadlinkat.o \
+            allocator.o \
+            readlink.o \
+            stat.o \
+            canonicalize-lgpl.o \
+            malloca.o \
+            lstat.o \
+            relocatable.o \
+            setenv.o \
+            c-ctype.o
+      test $rc = 0 || exit $?
+      # Clean up debugging information left over by the native C compiler on
+      # Mac OS X.
+      rm -rf "$destprog.wrapper$exeext.dSYM"
+      test $rc = 0 || exit $?
+
+      # Strip wrapper.
+      test "$strip_prog" = ':' || func_verbose "$strip_prog" "$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
+    }
+    func_iterate func_create_wrapper
+    ;;
+
+  macosx)
+    # Insert a reference to @loader_path in selected shared library references.
+    # For executables, @executable_path is equivalent to @loader_path.
+    func_reference_loader_path ()
+    {
+      # For using 'install_name_tool -change ...' we need to know the precise
+      # library version of each reference. The linker command line does not give
+      # us the information; only 'otool' provides it.
+      # Documentation:
+      # <https://www.manpagez.com/man/1/otool/>
+      # <https://www.unix.com/man-page/osx/1/otool/>
+      # The install_name_tool exists in versions without and with rpath support:
+      # <https://www.manpagez.com/man/1/install_name_tool/>
+      # <https://www.unix.com/man-page/osx/1/install_name_tool/>
+      otool -L "$destprog" | sed -e '/:$/d' -e 's/^[ 	]*//' -e 's/ (.*$//' | \
+        while read libfilename; do
+          case "$libfilename" in
+            "$prefix"/* )
+              func_relativize "$installdir" "$libfilename"
+              new_libfilename="@loader_path/$reldir"
+              func_verbose install_name_tool -change "$libfilename" "$new_libfilename" "$destprog"
+              ;;
+          esac
+        done
+    }
+    func_iterate func_reference_loader_path
+    ;;
+
+esac
 
 exit 0
diff --git a/m4/relocatable.m4 b/m4/relocatable.m4
index faa23f2..b3da721 100644
--- a/m4/relocatable.m4
+++ b/m4/relocatable.m4
@@ -1,4 +1,4 @@
-# relocatable.m4 serial 21
+# relocatable.m4 serial 22
 dnl Copyright (C) 2003, 2005-2007, 2009-2019 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -34,6 +34,7 @@ AC_DEFUN([gl_RELOCATABLE_BODY],
   AC_REQUIRE([AC_CANONICAL_HOST])
   is_noop=no
   use_elf_origin_trick=no
+  use_macos_tools=no
   use_wrapper=no
   if test $RELOCATABLE = yes; then
     # --enable-relocatable implies --disable-rpath
@@ -74,6 +75,10 @@ changequote(,)dnl
       solaris*) use_elf_origin_trick=yes ;;
       # Haiku: yes.
       haiku*) use_elf_origin_trick=yes ;;
+      # On Mac OS X 10.4 or newer, use Mac OS X tools. See
+      # <https://wincent.com/wiki/@executable_path,_@load_path_and_@rpath>.
+      darwin | darwin[1-8].*) ;;
+      darwin*) use_macos_tools=yes ;;
 changequote([,])dnl
     esac
     if test $is_noop = yes; then
@@ -89,12 +94,16 @@ changequote([,])dnl
         RELOCATABLE_LDFLAGS="\"$reloc_ldflags\" \"\$(host)\" \"\$(RELOCATABLE_LIBRARY_PATH)\""
         AC_SUBST([RELOCATABLE_LDFLAGS])
       else
-        use_wrapper=yes
         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.
-        INSTALL_PROGRAM_ENV="RELOC_LIBRARY_PATH_VAR=\"$shlibpath_var\" RELOC_LIBRARY_PATH_VALUE=\"\$(RELOCATABLE_LIBRARY_PATH)\" RELOC_PREFIX=\"\$(prefix)\" RELOC_DESTDIR=\"\$(DESTDIR)\" 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_STRIP_PROG=\"\$(RELOCATABLE_STRIP)\" RELOC_INSTALL_PROG=\"$INSTALL_PROGRAM\""
+        if test $use_macos_tools = yes; then
+          INSTALL_PROGRAM_ENV="RELOC_MODE=macosx RELOC_PREFIX=\"\$(prefix)\" RELOC_DESTDIR=\"\$(DESTDIR)\" RELOC_STRIP_PROG=\"\$(RELOCATABLE_STRIP)\" RELOC_INSTALL_PROG=\"$INSTALL_PROGRAM\""
+        else
+          use_wrapper=yes
+          INSTALL_PROGRAM_ENV="RELOC_MODE=wrapper RELOC_LIBRARY_PATH_VAR=\"$shlibpath_var\" RELOC_LIBRARY_PATH_VALUE=\"\$(RELOCATABLE_LIBRARY_PATH)\" RELOC_PREFIX=\"\$(prefix)\" RELOC_DESTDIR=\"\$(DESTDIR)\" 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_STRIP_PROG=\"\$(RELOCATABLE_STRIP)\" RELOC_INSTALL_PROG=\"$INSTALL_PROGRAM\""
+        fi
         AC_SUBST([INSTALL_PROGRAM_ENV])
         case "$ac_aux_dir" in
           /*) INSTALL_PROGRAM="$ac_aux_dir/install-reloc" ;;



^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: relocatable-prog: Use $ORIGIN trick on more platforms
  2019-02-23 21:54   ` Bruno Haible
@ 2019-02-24  0:51     ` Bruno Haible
  2019-03-04 16:32     ` Bruno Haible
  1 sibling, 0 replies; 6+ messages in thread
From: Bruno Haible @ 2019-02-24  0:51 UTC (permalink / raw)
  To: bug-gnulib; +Cc: psmith

And here's an update of the documentation:


2019-02-23  Bruno Haible  <bruno@clisp.org>

	relocatable-prog: Update documentation.
	* doc/relocatable-maint.texi (Supporting Relocation): Update to match
	the recent changes.

diff --git a/doc/relocatable-maint.texi b/doc/relocatable-maint.texi
index b95caaf..9f1b893 100644
--- a/doc/relocatable-maint.texi
+++ b/doc/relocatable-maint.texi
@@ -35,14 +35,21 @@ here in a platform-specific way:
 
 @itemize
 @item
-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.
+On most operating systems, 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.  This works on GNU/Linux and
+modern versions of FreeBSD, NetBSD, OpenBSD, Solaris, Haiku.
 
 @item
-On other Unix systems, it installs a wrapper executable.  The wrapper
+On macOS, it modifies the installed executables after installation in a way
+that causes the dynamic linker to search for libraries in a directory relative
+to the location of the invoked executable.
+
+@item
+On other Unix systems, it installs a trampoline executable.  The trampoline
 sets the environment variable that controls shared library searching
 (usually @env{LD_LIBRARY_PATH}) and then invokes the real executable.
+This applies to operating systems such as AIX, HP-UX, or Minix.
 
 @item
 On Windows, the executable's own directory is searched for libraries,



^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: relocatable-prog: Use $ORIGIN trick on more platforms
  2019-02-23 21:54   ` Bruno Haible
  2019-02-24  0:51     ` Bruno Haible
@ 2019-03-04 16:32     ` Bruno Haible
  1 sibling, 0 replies; 6+ messages in thread
From: Bruno Haible @ 2019-03-04 16:32 UTC (permalink / raw)
  To: bug-gnulib; +Cc: psmith

> 2019-02-23  Bruno Haible  <bruno@clisp.org>
> 
> 	relocatable-prog: Use wrapper-free installation also on Mac OS X.
> 	Reported by Paul Smith <psmith@gnu.org>.
> 	* build-aux/install-reloc: Accept a 'mode' argument as first argument.
> 	(func_relativize): New function, from gnulib-tool.
> 	Handle mode 'macosx' through invocations of 'otool' and
> 	'install_name_tool'.
> 	* m4/relocatable.m4 (gl_RELOCATABLE_BODY): Determine use_macos_tools.
> 	If use_macos_tools is true, set INSTALL_PROGRAM_ENV to an
> 	'install-reloc' invocation with mode 'macosx'.

This patch works for executables that reference shared libraries
in the same package. But it does not work for shared libraries that
reference other shared libraries in the same package. I'm therefore
reverting this patch and adding this one instead.


2019-03-04  Bruno Haible  <bruno@clisp.org>

	relocatable-prog: Use wrapper-free installation on Mac OS X, take 2.
	This approach supports relocatable installation of shared libraries
	which depend on other shared libraries from the same package.
	* m4/relocatable.m4 (gl_RELOCATABLE_BODY): Determine use_macos_tools.
	If use_macos_tools is true, use reloc-ldflags and set LIBTOOL to be a
	wrapper around the original LIBTOOL.
	* build-aux/reloc-ldflags: Add support for Mac OS X, which uses the
	token '@loader_path' instead of '$ORIGIN'.
	* build-aux/libtool-reloc: New file.
	* modules/relocatable-prog (Files): Add it.
	* doc/relocatable-maint.texi (Supporting Relocation): Update to match
	the recent changes. Document the need to set the *_LDFLAGS of libraries.
	RELOCATABLE_LIBRARY_PATH and RELOCATABLE_CONFIG_H_DIR should be set in
	Makefile.am, not in configure.ac.

diff --git a/build-aux/libtool-reloc b/build-aux/libtool-reloc
new file mode 100755
index 0000000..9d899ab
--- /dev/null
+++ b/build-aux/libtool-reloc
@@ -0,0 +1,89 @@
+#!/bin/sh
+# libtool-reloc - libtool wrapper with support for relocatable programs
+# Copyright (C) 2019 Free Software Foundation, Inc.
+# Written by Bruno Haible <bruno@clisp.org>, 2019.
+#
+# 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 3 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, see <https://www.gnu.org/licenses/>.
+
+# Usage: libtool-reloc libtool LIBTOOL_ARGUMENTS
+
+# Outputs a command and runs it.
+func_verbose ()
+{
+  # Make it easy to copy&paste the printed command into a shell in most cases,
+  # by escaping '\\', '"', and '$'. This is not perfect, just good enough.
+  echo "$@" | sed -e 's/\([\\"$]\)/\\\1/g'
+  "$@"
+}
+
+# Determine the mode from the arguments.
+mode=
+for arg
+do
+  case "$arg" in
+    --mode=link) mode=link ;;
+  esac
+done
+
+if test "$mode" = link; then
+  # Determine the target from the arguments.
+  target=
+  next_is_target=false
+  for arg
+  do
+    if $next_is_target; then
+      target="$arg"
+      next_is_target=false
+    else
+      case "$arg" in
+        -o) next_is_target=true ;;
+        *) next_is_target=false ;;
+      esac
+    fi
+  done
+  case "$target" in
+    *.la)
+      # When creating a library:
+      # 1. Add a '-Wl,-rpath,@loader_path' option.
+      #    (A '-R @loader_path' option does not work: libtool produces
+      #    an error "error: only absolute run-paths are allowed".)
+      #    (Also note that 'install_name_tool -add_rpath @loader_path ...'
+      #    does not work on Mac OS X 10.5.)
+      #    This is done through the RELOCATABLE_LDFLAGS macro.
+      # 2. After creating the library, run
+      #    install_name_tool -id @rpath/$dlname $target_dir/.libs/$dlname
+      #    (This is easier than to modify the libtool script to emit a different
+      #    install_name. Also, an option '-Wl,-install_name,@rpath/$dlname' does
+      #    not work since libtool emits another option '-Wl,-install_name,...'
+      #    after it.
+      "$@" && {
+        dlname_assignment=`grep '^dlname=' "$target"`
+        dlname=
+        eval "$dlname_assignment"
+        # Nothing to do when --disable-shared was specified.
+        if test -n "$dlname"; then
+          target_dir=`dirname "$target"`
+          if test -f "$target_dir/.libs/$dlname"; then
+            func_verbose install_name_tool -id "@rpath/$dlname" "$target_dir/.libs/$dlname"
+          fi
+        fi
+      }
+      ;;
+    *)
+      "$@"
+      ;;
+  esac
+else
+  "$@"
+fi
diff --git a/build-aux/reloc-ldflags b/build-aux/reloc-ldflags
index 3aed330..625fef2 100755
--- a/build-aux/reloc-ldflags
+++ b/build-aux/reloc-ldflags
@@ -53,6 +53,7 @@ case "$installdir" in
     ;;
 esac
 
+origin_token=
 case "$host_os" in
   linux* | gnu* | kfreebsd* | \
   freebsd* | dragonfly* | \
@@ -60,54 +61,59 @@ case "$host_os" in
   openbsd* | \
   solaris* | \
   haiku*)
-    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
-      case "$host_os" in
-        # At least some versions of FreeBSD, DragonFly, and OpenBSD need the
-        # linker option "-z origin". See <https://lekensteyn.nl/rpath.html>.
-        freebsd* | dragonfly* | openbsd*)
-          echo "-Wl,-z,origin -Wl,-rpath,$rpath" ;;
-        *)
-          echo "-Wl,-rpath,$rpath" ;;
-      esac
-    fi
+    origin_token='$ORIGIN'
     ;;
-  *)
-    echo "relocation via rpath not supported on this system: $host" 1>&2
-    exit 1
+  darwin*)
+    origin_token='@loader_path'
     ;;
 esac
+if test -n "$origin_token"; then
+  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_token"`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
+    case "$host_os" in
+      # At least some versions of FreeBSD, DragonFly, and OpenBSD need the
+      # linker option "-z origin". See <https://lekensteyn.nl/rpath.html>.
+      freebsd* | dragonfly* | openbsd*)
+        echo "-Wl,-z,origin -Wl,-rpath,$rpath" ;;
+      *)
+        echo "-Wl,-rpath,$rpath" ;;
+    esac
+  fi
+else
+  echo "relocation via rpath not supported on this system: $host" 1>&2
+  exit 1
+fi
 
 exit 0
diff --git a/doc/relocatable-maint.texi b/doc/relocatable-maint.texi
index 200fcab..d391598 100644
--- a/doc/relocatable-maint.texi
+++ b/doc/relocatable-maint.texi
@@ -38,13 +38,8 @@ here in a platform-specific way:
 On most operating systems, 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.  This works on GNU/Linux and
-modern versions of GNU/Hurd, GNU/kFreeBSD, FreeBSD, NetBSD, OpenBSD, Solaris,
-Haiku.
-
-@item
-On macOS, it modifies the installed executables after installation in a way
-that causes the dynamic linker to search for libraries in a directory relative
-to the location of the invoked executable.
+modern versions of GNU/Hurd, GNU/kFreeBSD, macOS, FreeBSD, NetBSD, OpenBSD,
+Solaris, Haiku.
 
 @item
 On other Unix systems, it installs a trampoline executable.  The trampoline
@@ -63,7 +58,10 @@ You can make your program relocatable by following these steps:
 @enumerate
 @item
 Import the @code{relocatable-prog} module.  For libraries, use the
-@code{relocatable-lib} or @code{relocatable-lib-lgpl} module.
+@code{relocatable-lib} or @code{relocatable-lib-lgpl} module, if
+the libraries are independent.  For installing multiple libraries,
+at least one of which depends on another one, use the @code{relocatable-prog}
+module.
 If you need more than one module, or you need to use them with different
 settings, you will need multiple copies of gnulib (@pxref{Multiple instances}).
 
@@ -233,20 +231,29 @@ AM_CONDITIONAL([SHLIBS_IN_BINDIR],
 @end smallexample
 
 @item
-You may also need to add a couple of variable assignments to your
-@file{configure.ac}.
+In your @file{Makefile.am}, for every library @command{libfoo} that gets
+installed in, say, @file{$(libdir)}, you add:
+
+@example
+if RELOCATABLE_VIA_LD
+libfoo_la_LDFLAGS = `$(RELOCATABLE_LDFLAGS) $(libdir)`
+endif
+@end example
+
+@item
+Add a couple of variable assignments to your @file{Makefile.am}.
 
 If your package (or any package you rely on, e.g.@: gettext-runtime)
 will be relocated together with a set of installed shared libraries,
-then set @var{RELOCATABLE_LIBRARY_PATH} to a colon-separated list
+then set @code{RELOCATABLE_LIBRARY_PATH} to a colon-separated list
 of those libraries' directories, e.g.
 @example
-RELOCATABLE_LIBRARY_PATH='$(libdir)'
+RELOCATABLE_LIBRARY_PATH = $(libdir)
 @end example
 
 If your @file{config.h} is not in @file{$(top_builddir)}, then set
-@var{RELOCATABLE_CONFIG_H_DIR} to its directory, e.g.
+@code{RELOCATABLE_CONFIG_H_DIR} to its directory, e.g.
 @example
-RELOCATABLE_CONFIG_H_DIR='$(top_builddir)/src'
+RELOCATABLE_CONFIG_H_DIR = $(top_builddir)/src
 @end example
 @end enumerate
diff --git a/m4/relocatable.m4 b/m4/relocatable.m4
index faa23f2..bbfb44c 100644
--- a/m4/relocatable.m4
+++ b/m4/relocatable.m4
@@ -1,4 +1,4 @@
-# relocatable.m4 serial 21
+# relocatable.m4 serial 23
 dnl Copyright (C) 2003, 2005-2007, 2009-2019 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -22,18 +22,28 @@ dnl The guts of gl_RELOCATABLE. Needs to be expanded only once.
 AC_DEFUN([gl_RELOCATABLE_BODY],
 [
   AC_REQUIRE([AC_PROG_INSTALL])
+
   dnl This AC_BEFORE invocation leads to unjustified autoconf warnings
   dnl when gl_RELOCATABLE_BODY is invoked more than once.
+  dnl
   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],[gl_RELOCATABLE_BODY])
+  dnl Arghh: AC_BEFORE does not work in this setting :-(
+  dnl AC_BEFORE([AC_PROG_INSTALL],[gl_RELOCATABLE_BODY])
+  dnl
+  dnl LT_INIT sets LIBTOOL, but we want this macro's setting of LIBTOOL to
+  dnl persist.
+  dnl Arghh: AC_BEFORE does not work in this setting :-(
+  dnl AC_BEFORE([LT_INIT],[gl_RELOCATABLE_BODY])
+
   AC_REQUIRE([AC_LIB_LIBPATH])
   AC_REQUIRE([gl_RELOCATABLE_LIBRARY_BODY])
   AC_REQUIRE([AC_CANONICAL_HOST])
   is_noop=no
   use_elf_origin_trick=no
+  use_macos_tools=no
   use_wrapper=no
   if test $RELOCATABLE = yes; then
     # --enable-relocatable implies --disable-rpath
@@ -74,13 +84,17 @@ changequote(,)dnl
       solaris*) use_elf_origin_trick=yes ;;
       # Haiku: yes.
       haiku*) use_elf_origin_trick=yes ;;
+      # On Mac OS X 10.4 or newer, use Mac OS X tools. See
+      # <https://wincent.com/wiki/@executable_path,_@load_path_and_@rpath>.
+      darwin | darwin[1-7].*) ;;
+      darwin*) use_macos_tools=yes ;;
 changequote([,])dnl
     esac
     if test $is_noop = yes; then
       RELOCATABLE_LDFLAGS=:
       AC_SUBST([RELOCATABLE_LDFLAGS])
     else
-      if test $use_elf_origin_trick = yes; then
+      if test $use_elf_origin_trick = yes || test $use_macos_tools = yes; then
         dnl Use the dynamic linker's support for relocatable programs.
         case "$ac_aux_dir" in
           /*) reloc_ldflags="$ac_aux_dir/reloc-ldflags" ;;
@@ -88,6 +102,13 @@ changequote([,])dnl
         esac
         RELOCATABLE_LDFLAGS="\"$reloc_ldflags\" \"\$(host)\" \"\$(RELOCATABLE_LIBRARY_PATH)\""
         AC_SUBST([RELOCATABLE_LDFLAGS])
+        if test $use_macos_tools = yes; then
+          dnl Use a libtool wrapper that uses Mac OS X tools.
+          case "$ac_aux_dir" in
+            /*) LIBTOOL="${CONFIG_SHELL-$SHELL} $ac_aux_dir/libtool-reloc $LIBTOOL" ;;
+            *) LIBTOOL="${CONFIG_SHELL-$SHELL} \$(top_builddir)/$ac_aux_dir/libtool-reloc $LIBTOOL" ;;
+          esac
+        fi
       else
         use_wrapper=yes
         dnl Unfortunately we cannot define INSTALL_PROGRAM to a command
@@ -104,7 +125,7 @@ changequote([,])dnl
     fi
   fi
   AM_CONDITIONAL([RELOCATABLE_VIA_LD],
-    [test $is_noop = yes || test $use_elf_origin_trick = yes])
+    [test $is_noop = yes || test $use_elf_origin_trick = yes || test $use_macos_tools = yes])
   AM_CONDITIONAL([RELOCATABLE_VIA_WRAPPER], [test $use_wrapper = yes])
 
   dnl RELOCATABLE_LIBRARY_PATH can be set in configure.ac. Default is empty.
diff --git a/modules/relocatable-prog b/modules/relocatable-prog
index d984314..4111665 100644
--- a/modules/relocatable-prog
+++ b/modules/relocatable-prog
@@ -5,6 +5,7 @@ properly when copied to an arbitrary directory.
 Files:
 build-aux/config.libpath
 build-aux/reloc-ldflags
+build-aux/libtool-reloc
 doc/relocatable.texi
 lib/relocatable.h
 lib/relocatable.c



^ permalink raw reply related	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2019-03-04 16:34 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-02-20  1:45 relocatable-prog: Use $ORIGIN trick on more platforms Bruno Haible
2019-02-20 16:12 ` Paul Smith
2019-02-23 21:54   ` Bruno Haible
2019-02-24  0:51     ` Bruno Haible
2019-03-04 16:32     ` Bruno Haible
2019-02-23 20:26 ` Bruno Haible

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).