[ this is: http://thread.gmane.org/gmane.comp.gnu.libtool.bugs/5319
or http://lists.gnu.org/archive/html/bug-libtool/2006-03/msg00013.html ]
Hi Behdad, everyone,
Sorry for the delay again.
* Behdad Esfahbod wrote on Thu, Mar 09, 2006 at 04:59:38PM CET:
> On Wed, 1 Mar 2006, Ralf Wildenhues wrote:
> > * Behdad Esfahbod wrote on Wed, Mar 01, 2006 at 05:15:17AM CET:
> > >
> > > This is a feature request for libtool. Let me describe the
> > > problem as I face it, so you may have a workaround for it
> > > already: I'm using libtool in the Pango text rendering engine.
> > > The Pango library accesses a file in $prefix/etc/pango/pangorc to
> > > find its modules at run-time. Now all I want to do is to be able
> > > to run the examples in pango/example when Pango is not installed.
> > >
> > > The easiest way that can be done is to set the PANGO_RC_PATH
> > > envvar to a special pangorc file. Another is to pass the
> > > --pangorc path-to-pango-rc to the examples if they understand it.
> > > What I need from libtool is to let me do one of these things in
> > > the wrapper it creates for uninstalled binaries.
[ my concerns were: we don't always build a wrapper ATM. ]
> > If we can find an answer to this question to define coherent semantics,
> > I'm all for it.
> Ok, this is my view of the problem: Running uninstalled programs
> requires some modifications to the environment. One is to make
> sure that the uninstalled libraries are linked. Other changes
> may be needed, on a per application basis. Libtool is free to
> choose how to implement these. So far it has only supported the
> library path modification, and implemented that using a wrapper
> script on some platforms, or using rpath on others (right?)
More or less, yes.
> The same goes with the other modifications. They can be easily
> implemented using a wrapper. So if there are such modifications
> requested, a wrapper should be used.
Yep. And that's really the easiest solution: as soon as extra arguments
or extra environment variables are passed, we always build a wrapper.
> My current workaround has been making pango-view accept a
> --pangorc path-to-pangorc parameter and defaulting to ./pangorc.
> But that opens up a known security problem... So I really want
> to "fix" it the right way.
I don't quite understand how this fixes any security problems...
but here you go with a suggestion (against current CVS HEAD).
The attached patch implements two new link flags, -wrapper-arg and
-wrapper-env, to prepend arguments to programs, and modify their
environment. They will force creating a (shell) wrapper.
Here's the hairy part about it: somebody may eventually want to extend
the C wrapper that is currently used on w32 to encompass all the
functionality that the shell wrapper currently has. And while I don't
have current plans about this, I still don't want to add any
unnecessary obstackles to it.
So whatever we add to the shell wrapper should be doable easily in a C
wrapper as well. This led me to add these restrictions: the
-wrapper-env works like putenv: you pass an argument `var=value', the
variable will be exported, the value will _not_ be interpreted by the
shell any more. For now you cannot unset variables (this is to cater
for hosts with a shell that does not support `unset'), and, e.g.,
-wrapper-env 'foo=$bar'
will cause the environment variable `foo' to contain the four characters
$, b, a, and r, not the contents of the variable $bar.
Similarly, -wrapper-arg will add exactly one literal argument to the
exec. I've put suitable quoting in place for this to work with most
kinds of input, and of course a test to this end.
What do you think? OK for HEAD right now, or do you think this is too
intrusive now?
I think we should not backport this to 1.5.x, it is a new feature.
Cheers,
Ralf
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 [EMAIL PROTECTED]
Andrey Slepuhin [EMAIL PROTECTED]
Aneesh Kumar K.V [EMAIL PROTECTED]
+ Behdad Esfahbod [EMAIL PROTECTED]
Brad Smith [EMAIL PROTECTED]
Bruno Haible [EMAIL PROTECTED]
Carl D. Roth [EMAIL PROTECTED]
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.
[EMAIL PROTECTED] -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.
+
[EMAIL PROTECTED] -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
[EMAIL PROTECTED] arguments append more environment variables.
+
+Typically this is used to set some path for uninstalled files or paths:
+
[EMAIL PROTECTED]
+libtool --mode=link $CC -o prog prog.lo \
+ -wrapper-env 'MYDATADIR=../data'
[EMAIL PROTECTED] 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 '[EMAIL
PROTECTED]@%'"$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+\"[EMAIL PROTECTED]"}
+ exec \"\$progdir\\\\\$program\"$wrapper_args \${1+\"[EMAIL PROTECTED]"}
"
;;
*)
$ECHO >> $output "\
- exec \"\$progdir/\$program\" \${1+\"[EMAIL PROTECTED]"}
+ exec \"\$progdir/\$program\"$wrapper_args \${1+\"[EMAIL PROTECTED]"}
"
;;
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 <stdio.h>
+#include <stdlib.h>
+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
_______________________________________________
Bug-libtool mailing list
[email protected]
http://lists.gnu.org/mailman/listinfo/bug-libtool