1#!/bin/sh 2# install-reloc - install a program including a relocating wrapper 3# Copyright (C) 2003-2020 Free Software Foundation, Inc. 4# Written by Bruno Haible <bruno@clisp.org>, 2003. 5# 6# This program is free software: you can redistribute it and/or modify 7# it under the terms of the GNU General Public License as published by 8# the Free Software Foundation; either version 3 of the License, or 9# (at your option) any later version. 10# 11# This program is distributed in the hope that it will be useful, 12# but WITHOUT ANY WARRANTY; without even the implied warranty of 13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14# GNU General Public License for more details. 15# 16# You should have received a copy of the GNU General Public License 17# along with this program. If not, see <https://www.gnu.org/licenses/>. 18 19# Usage 1: 20# install-reloc -- library_path_var library_path_value prefix destdir \ 21# compile_command srcdir builddir config_h_dir exeext \ 22# strip_command \ 23# install_command... destprog 24# where 25# - library_path_var is the platform dependent runtime library path variable 26# - library_path_value is a colon separated list of directories that contain 27# the libraries at installation time (use this instead of -rpath) 28# - prefix is the base directory at installation time 29# - destdir is a string that is prepended to all file names at installation 30# time; it is already prepended to destprog but not to library_path_value 31# and prefix 32# - compile_command is a C compiler compilation and linking command 33# - srcdir is the directory where to find relocwrapper.c and its dependencies 34# - builddir is the directory where to find built dependencies (namely, 35# alloca.h and stdbool.h) 36# - config_h_dir is the directory where to find config.h 37# - exeext is platform dependent suffix of executables 38# - strip_command is the command for stripping executables, or : if no 39# stripping is desired 40# - install_command is the install command line, excluding the final destprog 41# - destprog is the destination program name 42# Usage 2: 43# env RELOC_LIBRARY_PATH_VAR=library_path_var \ 44# RELOC_LIBRARY_PATH_VALUE=library_path_value \ 45# RELOC_PREFIX=prefix \ 46# RELOC_DESTDIR=destdir \ 47# RELOC_COMPILE_COMMAND=compile_command \ 48# RELOC_SRCDIR=srcdir \ 49# RELOC_BUILDDIR=builddir \ 50# RELOC_CONFIG_H_DIR=config_h_dir \ 51# RELOC_EXEEXT=exeext \ 52# RELOC_STRIP_PROG=strip_command \ 53# RELOC_INSTALL_PROG=install_command... \ 54# install-reloc prog1 ... destprog 55# where destprog is either the destination program name (when only one program 56# is specified) or the destination directory for all programs. 57# install-reloc renames destprog to destprog.bin and installs a relocating 58# wrapper in the place of destprog. 59 60progname=$0 61 62if test $# -ge 12 && test "x$1" = "x--"; then 63 # Get fixed position arguments. 64 shift 65 library_path_var=$1 66 library_path_value=$2 67 prefix=$3 68 destdir=$4 69 shift 70 shift 71 shift 72 shift 73 compile_command=$1 74 srcdir=$2 75 builddir=$3 76 config_h_dir=$4 77 exeext=$5 78 shift 79 shift 80 shift 81 shift 82 shift 83 strip_prog=$1 84 shift 85 install_prog=$1 # maybe not including the "-c" option 86 shift 87else 88 if test $# -ge 2; then 89 # Get arguments from environment variables. 90 library_path_var=$RELOC_LIBRARY_PATH_VAR 91 library_path_value=$RELOC_LIBRARY_PATH_VALUE 92 prefix=$RELOC_PREFIX 93 destdir=$RELOC_DESTDIR 94 compile_command=$RELOC_COMPILE_COMMAND 95 srcdir=$RELOC_SRCDIR 96 builddir=$RELOC_BUILDDIR 97 config_h_dir=$RELOC_CONFIG_H_DIR 98 exeext=$RELOC_EXEEXT 99 strip_prog=$RELOC_STRIP_PROG 100 install_prog=$RELOC_INSTALL_PROG # including the "-c" option 101 else 102 echo "Usage: $0 -- library_path_var library_path_value prefix destdir" \ 103 "compile_command srcdir builddir config_h_dir exeext" \ 104 "strip_command" \ 105 "install_command... destprog" 1>&2 106 exit 1 107 fi 108fi 109 110# Get destprog, last argument. 111destprog= 112for arg 113do 114 destprog=$arg 115done 116# Determine whether destprog is a program name or a directory name. 117if test -d "$destprog"; then 118 sed_remove_trailing_slashes='s|//*$||' 119 destprog_directory=`echo "$destprog" | sed -e "$sed_remove_trailing_slashes"` 120 if test -z "$destprog_directory"; then 121 destprog_directory='/' 122 fi 123else 124 destprog_directory= 125fi 126# Prepare for remove trailing $exeext, if present. 127if test -n "$exeext"; then 128 sed_quote='s,\.,\\.,g' 129 sed_remove_exeext='s|'`echo "$exeext" | sed -e "$sed_quote"`'$||' 130fi 131if test -z "$destprog_directory"; then 132 # Remove trailing $exeext, if present. 133 if test -n "$exeext"; then 134 destprog=`echo "$destprog" | sed -e "$sed_remove_exeext"` 135 fi 136fi 137 138# Outputs a command and runs it. 139func_verbose () 140{ 141 # Make it easy to copy&paste the printed command into a shell in most cases, 142 # by escaping '\\', '"', and '$'. This is not perfect, just good enough. 143 echo "$@" | sed -e 's/\([\\"$]\)/\\\1/g' 144 "$@" 145} 146 147# Run install_command. 148func_verbose $install_prog "$@" || exit $? 149 150# Iterate over all destination program names. 151# func_iterate f 152# applies f to each destination program names, after setting destprog. 153sed_basename_of_file='s|^.*/||' 154func_iterate () 155{ 156 if test -n "$destprog_directory"; then 157 prev_arg= 158 for arg 159 do 160 if test -n "prev_arg"; then 161 destprog="$destprog_directory"/`echo "$prev_arg" | sed -e "$sed_basename_of_file"` 162 $1 163 fi 164 prev_arg="$arg" 165 done 166 else 167 $1 168 fi 169} 170 171# Run strip_command. 172func_strip () 173{ 174 # Remove trailing $exeext, if present. 175 if test -n "$exeext"; then 176 destprog=`echo "$destprog" | sed -e "$sed_remove_exeext"` 177 fi 178 func_verbose "$strip_prog" "$destprog$exeext" || exit $? 179} 180if test "$strip_prog" != ':'; then 181 func_iterate func_strip 182fi 183 184# If the platform doesn't support LD_LIBRARY_PATH or similar, we cannot build 185# a wrapper. 186test -n "$library_path_var" || exit 0 187 188libdirs= 189save_IFS="$IFS"; IFS=":" 190for dir in $library_path_value; do 191 IFS="$save_IFS" 192 if test -n "$dir"; then 193 case "$libdirs" in 194 *"\"$dir\""*) ;; # remove duplicate 195 *) libdirs="$libdirs\"$dir\"," ;; 196 esac 197 fi 198done 199IFS="$save_IFS" 200# If there are no library directories to add at runtime, we don't need a 201# wrapper. 202test -n "$libdirs" || exit 0 203 204# Determine installdir from destprog, removing a leading destdir if present. 205if test -n "$destprog_directory"; then 206 installdir="$destprog_directory" 207else 208 installdir=`echo "$destprog" | sed -e 's,/[^/]*$,,'` 209fi 210if test -n "$destdir"; then 211 sed_quote='s,\([|.\*^$[]\),\\\1,g' 212 sed_remove_destdir='s|^'`echo "$destdir" | sed -e "$sed_quote"`'||' 213 installdir=`echo "$installdir" | sed -e "$sed_remove_destdir"` 214fi 215 216# Compile and install wrapper. 217func_create_wrapper () 218{ 219 # Remove trailing $exeext, if present. 220 if test -n "$exeext"; then 221 destprog=`echo "$destprog" | sed -e "$sed_remove_exeext"` 222 fi 223 224 # Compile wrapper. 225 func_verbose $compile_command \ 226 -I"$builddir" -I"$srcdir" -I"$config_h_dir" \ 227 -DHAVE_CONFIG_H -DIN_RELOCWRAPPER -DNO_XMALLOC \ 228 -D"INSTALLPREFIX=\"$prefix\"" -D"INSTALLDIR=\"$installdir\"" \ 229 -D"LIBPATHVAR=\"$library_path_var\"" -D"LIBDIRS=$libdirs" \ 230 -D"EXEEXT=\"$exeext\"" \ 231 "$srcdir"/relocwrapper.c \ 232 "$srcdir"/progname.c \ 233 "$srcdir"/progreloc.c \ 234 "$srcdir"/areadlink.c \ 235 "$srcdir"/careadlinkat.c \ 236 "$srcdir"/allocator.c \ 237 "$srcdir"/readlink.c \ 238 "$srcdir"/stat.c \ 239 "$srcdir"/canonicalize-lgpl.c \ 240 "$srcdir"/malloca.c \ 241 "$srcdir"/lstat.c \ 242 "$srcdir"/relocatable.c \ 243 "$srcdir"/setenv.c \ 244 "$srcdir"/c-ctype.c \ 245 -o "$destprog.wrapper$exeext" 246 rc=$? 247 # Clean up object files left over in the current directory by the native C 248 # compilers on Solaris, HP-UX, OSF/1, IRIX. 249 rm -f relocwrapper.o \ 250 progname.o \ 251 progreloc.o \ 252 areadlink.o \ 253 careadlinkat.o \ 254 allocator.o \ 255 readlink.o \ 256 stat.o \ 257 canonicalize-lgpl.o \ 258 malloca.o \ 259 lstat.o \ 260 relocatable.o \ 261 setenv.o \ 262 c-ctype.o 263 test $rc = 0 || exit $? 264 # Clean up debugging information left over by the native C compiler on MacOS X. 265 rm -rf "$destprog.wrapper$exeext.dSYM" 266 test $rc = 0 || exit $? 267 268 # Strip wrapper. 269 test "$strip_prog" = ':' || func_verbose "$strip_prog" "$destprog.wrapper$exeext" || exit $? 270 271 # Rename $destprog.wrapper -> $destprog -> $destprog.bin. 272 ln -f "$destprog$exeext" "$destprog.bin$exeext" \ 273 || { rm -f "$destprog.bin$exeext" \ 274 && cp -p "$destprog$exeext" "$destprog.bin$exeext"; } \ 275 || exit 1 276 mv "$destprog.wrapper$exeext" "$destprog$exeext" || exit 1 277} 278func_iterate func_create_wrapper 279 280exit 0 281