From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on dcvr.yhbt.net X-Spam-Level: X-Spam-ASN: AS22989 209.51.188.0/24 X-Spam-Status: No, score=-3.8 required=3.0 tests=AWL,BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI,SPF_PASS shortcircuit=no autolearn=ham autolearn_force=no version=3.4.2 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by dcvr.yhbt.net (Postfix) with ESMTPS id 8AEC920248 for ; Mon, 4 Mar 2019 16:34:59 +0000 (UTC) Received: from localhost ([127.0.0.1]:56900 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h0qYM-0004eH-1U for normalperson@yhbt.net; Mon, 04 Mar 2019 11:34:58 -0500 Received: from eggs.gnu.org ([209.51.188.92]:48328) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h0qVo-0002sM-5M for bug-gnulib@gnu.org; Mon, 04 Mar 2019 11:32:22 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1h0qVl-0005Ma-IN for bug-gnulib@gnu.org; Mon, 04 Mar 2019 11:32:20 -0500 Received: from mo6-p00-ob.smtp.rzone.de ([2a01:238:20a:202:5300::8]:20737) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1h0qVi-0005Eg-N0; Mon, 04 Mar 2019 11:32:17 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; t=1551717130; s=strato-dkim-0002; d=clisp.org; h=References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From: X-RZG-CLASS-ID:X-RZG-AUTH:From:Subject:Sender; bh=VYHUJpBqZuuThxxfEvlyIslJ3BFF5qbtbIcYvA6bsW0=; b=N2haKrMPucRSUMdroRrQYlDSZ13wd/kcfSwaegR+xaNT+35LGse3PMtYxtKGMqlx4p ox+iVFuEjh6flNBFCN9dlhpIqQdbNJuJM2OW7FS06O3ylqMKVEIkPZhqdtXBrAGpnA73 1n8krjEeib7dDbMEdgJB5xgkIliYYjZT+8eVexM1CWcb2Gf62fFIAyoSmuKDs212a+P8 saeVjvkrQWlS9jalw5KLFO7Eyh8MeUFGJGCrQMHspu8yGj+gXu9INchsIGRmHkMxTJK8 SlDDjZDH47tWy7eZj6dhzqJDTuHYE0BbOllGd9d9jkJRGZoB4pAyLL4L5auQEhcnxsOJ xLYQ== X-RZG-AUTH: ":Ln4Re0+Ic/6oZXR1YgKryK8brlshOcZlIWs+iCP5vnk6shH+AHjwLuWOGaf3zJZW" X-RZG-CLASS-ID: mo00 Received: from bruno.haible.de by smtp.strato.de (RZmta 44.13 DYNA|AUTH) with ESMTPSA id 60865ev24GW9ajB (using TLSv1 with cipher ECDHE-RSA-AES256-SHA (curve secp521r1 with 521 ECDH bits, eq. 15360 bits RSA)) (Client did not present a certificate); Mon, 4 Mar 2019 17:32:09 +0100 (CET) From: Bruno Haible To: bug-gnulib@gnu.org Subject: Re: relocatable-prog: Use $ORIGIN trick on more platforms Date: Mon, 04 Mar 2019 17:32:08 +0100 Message-ID: <1702887.A1lOhvFh9L@omega> User-Agent: KMail/5.1.3 (Linux/4.4.0-141-generic; KDE/5.18.0; x86_64; ; ) In-Reply-To: <2384247.2fb6EbktOH@omega> References: <2334191.0oAdKfnz2d@omega> <6f76c2012b3d6fc5ba21ff6c98dd6c855da0e7e6.camel@gnu.org> <2384247.2fb6EbktOH@omega> MIME-Version: 1.0 Content-Transfer-Encoding: 7Bit Content-Type: text/plain; charset="us-ascii" X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 2a01:238:20a:202:5300::8 X-BeenThere: bug-gnulib@gnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: Gnulib discussion list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: psmith@gnu.org Errors-To: bug-gnulib-bounces+normalperson=yhbt.net@gnu.org Sender: "bug-gnulib" > 2019-02-23 Bruno Haible > > relocatable-prog: Use wrapper-free installation also on Mac OS X. > Reported by Paul Smith . > * 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 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 , 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 . + +# 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 . - 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 . + 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 + # . + 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