Implement setting environment variables and additional arguments for shell wrappers to uninstalled programs. Using this forces all uninstalled programs to have wrappers. * libltdl/config/ltmain.m4sh (func_mode_link, shell wrapper): New variables `wrapper_env', `wrapper_args' for the new link flags `-wrapper-arg', `-wrapper-env'. Cause a shell wrapper to always be created for uninstalled programs, put the wrapper_env variables in the environment before executing the real program, and add the wrapper_args as its first arguments; both with suitable quoting for active characters. (link mode help): Add the new flags. * doc/libtool.texi (Link mode): Document the new flags. Note the override of `-no-install'. (Linking executables): Add cross reference to the wrapper script discussion. * tests/wrapper.at: New test. * NEWS, THANKS, Makefile.am: Update. Suggested by Behdad Esfahbod. Index: Makefile.am =================================================================== RCS file: /cvsroot/libtool/libtool/Makefile.am,v retrieving revision 1.194 diff -u -r1.194 Makefile.am --- Makefile.am 15 May 2006 16:14:24 -0000 1.194 +++ Makefile.am 20 May 2006 12:47:09 -0000 @@ -390,6 +390,7 @@ tests/link-order.at \ tests/fail.at \ tests/static.at \ + tests/wrapper.at \ tests/old-m4-iface.at \ tests/am-subdir.at \ tests/standalone.at \ Index: NEWS =================================================================== RCS file: /cvsroot/libtool/libtool/NEWS,v retrieving revision 1.194 diff -u -r1.194 NEWS --- NEWS 15 May 2006 16:40:42 -0000 1.194 +++ NEWS 20 May 2006 12:47:09 -0000 @@ -34,6 +34,8 @@ * Fix error with -version-info on systems with version_type=none, such as BeOS. * Initial support for the Sun compiler suite on GNU/Linux. +* New flags -wrapper-args and -wrapper-env to force uninstalled program + wrappers and supply extra arguments and environment variables. * Bug fixes. New in 1.9f: 2004-10-23; CVS version 1.9e, Libtool team: Index: THANKS =================================================================== RCS file: /cvsroot/libtool/libtool/THANKS,v retrieving revision 1.56 diff -u -r1.56 THANKS --- THANKS 14 May 2006 08:20:11 -0000 1.56 +++ THANKS 20 May 2006 12:47:09 -0000 @@ -70,6 +70,7 @@ Andreas Schwab address@hidden Andrey Slepuhin address@hidden Aneesh Kumar K.V address@hidden + Behdad Esfahbod address@hidden Brad Smith address@hidden Bruno Haible address@hidden Carl D. Roth address@hidden Index: doc/libtool.texi =================================================================== RCS file: /cvsroot/libtool/libtool/doc/libtool.texi,v retrieving revision 1.215 diff -u -r1.215 libtool.texi --- doc/libtool.texi 18 May 2006 00:10:37 -0000 1.215 +++ doc/libtool.texi 20 May 2006 12:47:10 -0000 @@ -844,6 +844,10 @@ kilobytes. So, having a shared @file{libhello} won't be an advantage until we link it against at least a few more programs. +There is another point to using wrapper scripts: they allow the +developer to pass arguments and environment variables to the uninstalled +program (@pxref{Link mode}). + @node Debugging executables @section Debugging executables @@ -1384,7 +1388,8 @@ @item -no-install Link an executable @var{output-file} that can't be installed and -therefore doesn't need a wrapper script. Useful if the program is only +therefore doesn't need a wrapper script (unless @option{-wrapper_env} +or @option{-wrapper-arg} are used also). Useful if the program is only used in the build tree, e.g., for testing or generating other files. @item -no-undefined @@ -1472,6 +1477,27 @@ @itemx -Xlinker @var{flag} Pass a linker specific flag directly to the linker. address@hidden -wrapper-arg @var{flag} +If @var{output-file} is a program, then always create a shell wrapper script +for the uninstalled program. When the uninstalled program is executed through +the wrapper, add @samp{flag} to its arguments before all user-provided arguments. +Multiple @option{-wrapper-arg} arguments append more flags. + address@hidden -wrapper-env @var{var=value} +If @var{output-file} is a program, then always create a shell wrapper script +for the uninstalled program. When the uninstalled program is executed through +the wrapper, set environment variable @code{var} to @samp{value} for the +execution of the uninstalled program. The argument will not be interpreted by +the shell, so handling is similar to the putenv function. Multiple address@hidden arguments append more environment variables. + +Typically this is used to set some path for uninstalled files or paths: + address@hidden +libtool --mode=link $CC -o prog prog.lo \ + -wrapper-env 'MYDATADIR=../data' address@hidden example + @item -XCClinker @var{flag} Pass a link specific flag to the compiler driver (@var{CC}) during linking. @end table Index: libltdl/config/ltmain.m4sh =================================================================== RCS file: /cvsroot/libtool/libtool/libltdl/config/ltmain.m4sh,v retrieving revision 1.48 diff -u -r1.48 ltmain.m4sh --- libltdl/config/ltmain.m4sh 19 May 2006 02:23:04 -0000 1.48 +++ libltdl/config/ltmain.m4sh 20 May 2006 12:55:00 -0000 @@ -383,6 +383,9 @@ -version-info CURRENT[[:REVISION[:AGE]]] specify library version info [[each variable defaults to 0]] -weak LIBNAME declare that the target provides the LIBNAME interface + -wrapper-arg ARG Prepend arguments to uninstalled program wrappers + -wrapper-env ENV Add environment variables to uninstalled program wrappers + (-wrapper-arg and -wrapper-env will force wrapper creation) All other options (arguments beginning with \`-') are ignored. @@ -2256,6 +2259,8 @@ vinfo= vinfo_number=no weak_libs= + wrapper_env= + wrapper_args= single_module="${wl}-single_module" func_infer_tag $base_compile @@ -2531,6 +2536,24 @@ prev= continue ;; + wrapper-arg) + case $arg in + *\'*) wqarg=`$ECHO "X$arg" | $Xsed -e "s/'/'\\\\\\\\''/g"` ;; + *) wqarg=$arg ;; + esac + wrapper_args="$wrapper_args '$wqarg'" + prev= + continue + ;; + wrapper-env) + wrap_var=`$ECHO "$arg" | $SED '1s/^\([[^=]]*\)=.*/\1/;q'` + wrap_val=`$ECHO "$arg" | $SED "1s/^[[^=]]*=//;s/'/'\\\\\\\\''/g"` + wrapper_env="$wrapper_env + $wrap_var='$wrap_val' + export $wrap_var" + prev= + continue + ;; xcclinker) linker_flags="$linker_flags $qarg" compiler_flags="$compiler_flags $qarg" @@ -2879,6 +2902,16 @@ arg=$func_stripname_result ;; + -wrapper-arg) + prev=wrapper-arg + continue + ;; + + -wrapper-env) + prev=wrapper-env + continue + ;; + -Xcompiler) prev=xcompiler continue @@ -5701,18 +5734,20 @@ fi wrappers_required=yes - case $host in - *cygwin* | *mingw* ) - if test "$build_libtool_libs" != yes; then - wrappers_required=no - fi - ;; - *) - if test "$need_relink" = no || test "$build_libtool_libs" != yes; then - wrappers_required=no - fi - ;; - esac + if test -z "$wrapper_args$wrapper_env"; then + case $host in + *cygwin* | *mingw* ) + if test "$build_libtool_libs" != yes; then + wrappers_required=no + fi + ;; + *) + if test "$need_relink" = no || test "$build_libtool_libs" != yes; then + wrappers_required=no + fi + ;; + esac + fi if test "$wrappers_required" = no; then # Replace the output file specification. compile_command=`$ECHO "X$compile_command" | $Xsed -e 'address@hidden@%'"$output"'%g'` @@ -5758,7 +5793,7 @@ fi fi - if test "$no_install" = yes; then + if test "$no_install$wrapper_args$wrapper_env" = yes; then # We don't need to create a wrapper script. link_command="$compile_var$compile_command$compile_rpath" # Replace the output file specification. @@ -6368,22 +6403,28 @@ if test \"\$libtool_execute_magic\" != \"$magic\"; then # Run the actual program with our arguments. " + if test -n "$wrapper_env"; then + $ECHO "$wrapper_env" >> $output + fi + if test -n "$wrapper_args"; then + qwrapper_args=`$ECHO "X$wrapper_args" | $Xsed -e "$sed_quote_subst"` + fi case $host in # Backslashes separate directories on plain windows *-*-mingw | *-*-os2*) $ECHO >> $output "\ - exec \"\$progdir\\\\\$program\" \${1+\"address@hidden"} + exec \"\$progdir\\\\\$program\"$wrapper_args \${1+\"address@hidden"} " ;; *) $ECHO >> $output "\ - exec \"\$progdir/\$program\" \${1+\"address@hidden"} + exec \"\$progdir/\$program\"$wrapper_args \${1+\"address@hidden"} " ;; esac $ECHO >> $output "\ - \$ECHO \"\$0: cannot exec \$program \$*\" + \$ECHO \"\$0: cannot exec \$program$qwrapper_args \$*\" exit 1 fi else Index: tests/testsuite.at =================================================================== RCS file: /cvsroot/libtool/libtool/tests/testsuite.at,v retrieving revision 1.41 diff -u -r1.41 testsuite.at --- tests/testsuite.at 15 May 2006 16:14:24 -0000 1.41 +++ tests/testsuite.at 20 May 2006 12:47:10 -0000 @@ -139,10 +139,10 @@ ]) -# LT_AT_EXEC_CHECK(EXECUTABLE, [STATUS = 0], [STDOUT], [STDERR]) -# -------------------------------------------------------------- +# LT_AT_EXEC_CHECK(EXECUTABLE, [STATUS = 0], [STDOUT], [STDERR], [ARGS]) +# ---------------------------------------------------------------------- m4_define([LT_AT_EXEC_CHECK], -[AT_CHECK([$1; lt_status=$?; if test $lt_status -eq 0; then :; +[AT_CHECK([$1 $5; lt_status=$?; if test $lt_status -eq 0; then :; elif test "X$host" != "X$build" && \ { test -x "$1" || test -x "$1"$EXEEXT; } then (exit 77); else (exit $lt_status); fi],[$2],[$3],[$4]) --- /dev/null 1970-01-01 00:00:01.000000000 +0200 +++ tests/wrapper.at 2006-05-20 17:23:10.000000000 +0200 @@ -0,0 +1,83 @@ +# Hand crafted tests for GNU Libtool. -*- Autotest -*- +# Copyright 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. + +AT_SETUP([wrapper flags and environment]) +AT_KEYWORDS([libtool]) + +AT_DATA([prog.c], +[[#include +#include +int main(int argc, char **argv) +{ + int i = 1; + char *p = getenv ("FOO"); + while (i < argc) + { + puts (argv[i++]); + } + printf ("FOO:%s\n", p != NULL ? p : ""); + return 0; +} +]]) + +AT_CHECK([$CC $CPPFLAGS $CFLAGS -c prog.c], [], [ignore], [ignore]) + +# First, check to make sure our program works. +$as_unset FOO || FOO= +AT_CHECK([$LIBTOOL --mode=link $CC $CFLAGS $LDFLAGS -o prog prog.$OBJEXT], + [], [ignore], [ignore]) +LT_AT_EXEC_CHECK([./prog], [], +[-foo +FOO: +], [], [-foo]) + +# Check that -wrapper-arg works. +AT_CHECK([$LIBTOOL --mode=link $CC $CFLAGS $LDFLAGS -wrapper-arg -bar \ + -wrapper-arg '-option with args "and quotes '\'' and $special char\s' \ + -o prog prog.$OBJEXT], + [], [ignore], [ignore]) +LT_AT_EXEC_CHECK([./prog], [], +[-bar +-option with args "and quotes ' and $special char\s +-foo +FOO: +], [], [-foo]) + +# Now check that the installed program doesn't have these +# and also (important!) that relinking is not triggered here! +AT_CHECK([$LIBTOOL --mode=install cp prog `pwd`/prog-installed], [], [ignore]) +LT_AT_EXEC_CHECK([./prog-installed], [], +[-foo +FOO: +], [], [-foo]) + +# Check wrapper-env; also check that we override -no-install. +AT_CHECK([$LIBTOOL --mode=link $CC $CFLAGS $LDFLAGS \ + -wrapper-env 'FOO=X "y'\'' $specia\l' -no-install -o prog prog.$OBJEXT], + [], [ignore], [ignore]) +LT_AT_EXEC_CHECK([./prog], [], +[FOO:X "y' $specia\l +]) + +AT_CHECK([$LIBTOOL --mode=install cp prog `pwd`/prog-installed], [], [ignore]) +LT_AT_EXEC_CHECK([./prog-installed], [], +[-foo +FOO: +], [], [-foo]) + +AT_CLEANUP