For next public release:
************************
-* Kenneth Albanowski suggests an `execute' mode, where the paths from
-libtool libraries are extracted and put into shlibpath_var, then a
-command is executed with the wrapped binary as argument.
+* Document `execute' mode, and the experimental nature of -dlopen and
+-dlpreopen.
- KA> And 'libtool --mode=execute java test Java/libJavaPisock.la
- KA> libsock/libpisock.la' turns into:
+* Some packages, such as GIMP, choose to put a note about
+`--disable-shared' in their README:
- KA> LD_LIBRARY_PATH="libsock/.libs:Java/.libs" java test
+----------------------------------------------------------------------
+The GIMP uses GNU libtool in order to build shared libraries on a
+variety of systems. While this is very nice for making usable
+binaries, it can be a pain when trying to debug a program. For that
+reason, compilation of shared libraries can be turned off by
+specifying the "--disable-shared" option to "configure".
+----------------------------------------------------------------------
+Simply invoke configure in the top-level directory. Besides the usual
+GNU configure options, there are the following SANE specific options:
-I think this is a good idea, but the nonobvious behaviour with libtool
-library arguments should be enabled by a flag, such as -dlopen LIB.
-Maybe -dlpreopen LIB should put these libraries in LD_PRELOAD.
+ --disable-shared
+ Don't use shared libraries. Useful for debugging or when there
+ is a problem building shared libraries.
+----------------------------------------------------------------------
-Use *db | *dbx as triggers for this mode.
+Perhaps a similar note could be added to ABOUT-NLS.
-* Document `execute' mode.
+I'll add a suggestion to the libtool documentation, so that other
+maintainers add this kind of note to their package documentation.
In the future:
**************
+* Eliminate broken handling of single-quotes in arguments to
+ltmain.sh. I've decided that we should backslashify `"', `$' and `\'.
+Then, if there are any other metacharacters in the argument, surround
+it with double quotes.
+
* Implement full multi-language support. Currently, this is only for
C++, but there are beginnings of this in the manual (Other Languages).
This includes writing libtool not to be so dependent on the compiler
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
+# WARNING: An implicit problem with writing libtool as a shell script
+# is that arguments with embedded whitespace probably will cause
+# problems, and arguments with embedded single quotes *definitely*
+# will cause problems.
+
+# It would take a serious effort to fix the problems with whitespace.
+# These occur because we use space-separated arguments to "for"
+# commands. It is nearly impossible to fix the problems with single
+# quotes, because we use them to do quoting in strings that we "eval".
+
# The name of this program.
progname=`echo "$0" | sed 's%^.*/%%'`
run=
show=echo
show_help=
+execute_dlfiles=
# Parse our command line options once, thoroughly.
while test $# -gt 0
# If the previous option needs an argument, assign it.
if test -n "$prev"; then
- eval "$prev=\$arg"
+ case "$prev" in
+ execute_dlfiles)
+ eval "$prev=\"\$$prev \$arg\""
+ ;;
+ *)
+ eval "$prev=\$arg"
+ ;;
+ esac
+
prev=
prevopt=
continue
show=:
;;
+ -dlopen)
+ prevopt="-dlopen"
+ prev=execute_dlfiles
+ ;;
+
-*)
echo "$progname: unrecognized option \`$arg'" 1>&2
echo "$help" 1>&2
esac
done
-
if test -n "$prevopt"; then
echo "$progname: option \`$prevopt' requires an argument" 1>&2
echo "$help" 1>&2
exit 1
fi
-
if test -z "$show_help"; then
# Infer the operation mode.
esac
done
;;
+ *db | *dbx)
+ mode=execute
+ ;;
*install*|cp)
mode=install
;;
mode=uninstall
;;
*)
+ # If we have no mode, but dlfiles were specified, then do execute mode.
+ test -n "$execute_dlfiles" && mode=execute
+
# Just use the default operation mode.
if test -z "$mode"; then
if test -n "$nonopt"; then
esac
fi
+ # Only execute mode is allowed to have -dlopen flags.
+ if test -n "$execute_dlfiles" && test "$mode" != execute; then
+ echo "$progname: unrecognized option \`-dlopen'" 1>&2
+ echo "$help" 1>&2
+ exit 1
+ fi
+
# Change the help message to a mode-specific one.
generic_help="$help"
help="Try \`$progname --help --mode=$mode' for more information."
for arg
do
# Quote any args containing shell metacharacters.
+ # Many Bourne shells cannot handle close brackets correctly in scan
+ # sets, so we specify it separately.
case "$arg" in
- *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*|*\"*)
- quote_arg="'$arg'" ;;
- *) quote_arg="$arg" ;;
+ *[[~#$^\&*\(\){}\\\|\;\<\>?\ \ \"]*|*]*)
+ quote_arg="'$arg'"
+ ;;
+ *)
+ quote_arg="$arg"
+ ;;
esac
base_compile="$base_compile$lastarg"
# Find the relevant object directory and library name.
file=`echo "$arg" | sed 's%^.*/%%'`
dir=`echo "$arg" | sed 's%/[^/]*$%/%'`
- test "$dir" = "$arg" && dir=
+ test "X$dir" = "X$arg" && dir=
# Standard archive.
objs="$objs $arg"
# Find the relevant object directory and library name.
name=`echo "$arg" | sed -e 's%^.*/%%' -e 's/\.la$//' -e 's/^lib//'`
dir=`echo "$arg" | sed 's%/[^/]*$%%'`
- if test "$dir" = "$arg"; then
+ if test "X$dir" = "X$arg"; then
dir="$objdir"
else
dir="$dir/$objdir"
link_against_libtool_libs='$link_against_libtool_libs'
finalize_command='$finalize_command'
else
+ # When we are sourced in execute mode, \$file is already set.
+ test "\$libtool_execute_magic" = "$magic" || file="\$0"
+
# Find the directory that this script lives in.
- thisdir=\`echo \$0 | sed 's%/[^/]*$%%'\`
- test "x\$thisdir" = "x\$0" && thisdir=.
+ thisdir=\`echo "\$file" | sed 's%/[^/]*$%%'\`
+ test "x\$thisdir" = "x\$file" && thisdir=.
# Try to get the absolute directory name.
absdir=\`cd "\$thisdir" && pwd\`
progdir="\$thisdir/$objdir"
program='$output'
- # If the \$0 dir failed (maybe due to symlink), try a hardcoded dir.
- test -f "\$progdir/\$program" || progdir='`pwd`/$objdir'
+ # If the \$file dir failed (maybe due to symlink), try a hardcoded dir.
+ oprogdir="\$progdir"
+ if test -f "\$progdir/\$program"; then :
+ else
+ thisdir='`pwd`'
+ progdir="\$thisdir/$objdir"
+ fi
if test -f "\$progdir/\$program"; then
- # Run the actual program with our arguments.
- args=
- for arg
- do
- # Quote arguments (to preserve shell metacharacters).
- args="\$args '\$arg'"
- done
-
- # Export the path to the program.
- PATH="\$progdir:\$PATH"
- export PATH
EOF
# Export our shlibpath_var if we have one.
if test -n "$shlibpath_var" && test -n "$temp_rpath"; then
cat >> $output <<EOF
-
# Add our own library path to $shlibpath_var
$shlibpath_var="$temp_rpath\$$shlibpath_var"
$shlibpath_var=\`echo \$$shlibpath_var | sed -e 's/:*\$//'\`
export $shlibpath_var
+
EOF
fi
cat >> $output <<EOF
+ if test "\$libtool_execute_magic" != "$magic"; then
+ # Run the actual program with our arguments.
+ args=
+ for arg
+ do
+ # Quote arguments (to preserve shell metacharacters).
+ args="\$args '\$arg'"
+ done
- eval "exec \$program \$args"
+ # Export the path to the program.
+ PATH="\$progdir:\$PATH"
+ export PATH
- echo "\$0: cannot exec \$program \$args"
- exit 1
+ eval "exec \$program \$args"
+
+ echo "\$0: cannot exec \$program \$args"
+ exit 1
+ fi
else
# The program doesn't exist.
- echo "\$0: error: neither \$thisdir/$objdir/\$program nor \$progdir/\$program exists" 1>&2
+ echo "\$0: error: neither \$oprogdir/\$program nor \$progdir/\$program exists" 1>&2
echo "This script is just a wrapper for \$program." 1>&2
echo "See the $PACKAGE documentation for more information." 1>&2
exit 1
destname=
else
destdir=`echo "$dest" | sed 's%/[^/]*$%%'`
- test "$destdir" = "$dest" && destdir=.
+ test "X$destdir" = "X$dest" && destdir=.
destname=`echo "$dest" | sed 's%^.*/%%'`
# Not a directory, so check to see that there is only one file specified.
;;
esac
+ # This variable tells wrapper scripts just to set variables rather
+ # than running their programs.
+ libtool_install_magic="$magic"
+
staticlibs=
future_libdirs=
current_libdirs=
esac
# Add the libdir to current_libdirs if it is the destination.
- if test "$destdir" = "$libdir"; then
+ if test "X$destdir" = "X$libdir"; then
case "$current_libdirs " in
"* $libdir *") ;;
*) current_libdirs="$current_libdirs $libdir" ;;
fi
dir="`echo "$file" | sed 's%/[^/]*$%%'`/"
- test "$dir" = "$file/" && dir=
+ test "X$dir" = "X$file/" && dir=
dir="$dir$objdir"
# See the names of the shared library.
*)
# Do a test to see if this is really a libtool program.
- if egrep "^# Generated by ltmain.sh" $file >/dev/null 2>&1; then
- # This variable tells wrapper scripts just to set variables rather
- # than running their programs.
- libtool_install_magic="$magic"
+ if egrep '^# Generated by ltmain.sh' $file >/dev/null 2>&1; then
link_against_libtool_libs=
finalize_command=
fi
else
# Install the binary that we compiled earlier.
- dir=`echo "$file" | sed 's%/[^/]*$%%'`
- if test "$file" = "$dir"; then
- file="$objdir/$file"
- else
- file="$dir/$objdir/`echo "$file" | sed 's%^.*/%%'`"
- fi
+ file=`echo "$file" | sed "s%\([^/]*\)$%$objdir/\1%"`
fi
fi
exit 0
;;
+ # libtool execute mode
+ execute)
+ progname="$progname: execute"
+
+ # The first argument is the command name.
+ cmd="$nonopt"
+ if test -z "$cmd"; then
+ echo "$progname: you must specify a COMMAND" 1>&2
+ echo "$help"
+ exit 1
+ fi
+
+ # Handle -dlopen flags immediately.
+ for file in $execute_dlfiles; do
+ if test -f "$file"; then :
+ else
+ echo "$progname: \`$file' is not a file" 1>&2
+ echo "$help" 1>&2
+ exit 1
+ fi
+
+ dir=
+ case "$file" in
+ *.la)
+ # Check to see that this really is a libtool archive.
+ if egrep "^# Generated by ltmain.sh" $file >/dev/null 2>&1; then :
+ else
+ echo "$progname: \`$lib' is not a valid libtool archive" 1>&2
+ echo "$help" 1>&2
+ exit 1
+ fi
+
+ # Read the libtool library.
+ dlname=
+ library_names=
+
+ # If there is no directory component, then add one.
+ case "$file" in
+ */*) . $file ;;
+ *) . ./$file ;;
+ esac
+
+ # Skip this library if it cannot be dlopened.
+ if test -z "$dlname"; then
+ # Warn if it was a shared library.
+ test -n "$library_names" && echo "$progname: warning: \`$file' was not linked with \`-export-dynamic'"
+ continue
+ fi
+
+ dir=`echo "$file" | sed 's%/[^/]*$%%'`
+ test "X$dir" = "X$file" && dir=.
+
+ if test -f "$dir/$objdir/$dlname"; then
+ dir="$dir/$objdir"
+ else
+ echo "$progname: cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" 1>&2
+ exit 1
+ fi
+ ;;
+
+ *.lo)
+ # Just add the directory containing the .lo file.
+ dir=`echo "$file" | sed 's%/[^/]*$%%'`
+ test "X$dir" = "X$file" && dir=.
+ ;;
+
+ *)
+ echo "$progname: warning \`-dlopen' is ignored for non-libtool libraries and objects" 1>&2
+ continue
+ ;;
+ esac
+
+ # Get the absolute pathname.
+ absdir=`cd "$dir" && pwd`
+ test -n "$absdir" && dir="$absdir"
+
+ # Now add the directory to shlibpath_var.
+ if eval "test -z \"\$$shlibpath_var\""; then
+ eval "$shlibpath_var=\"\$dir\""
+ else
+ eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\""
+ fi
+ done
+
+ # This variable tells wrapper scripts just to set shlibpath_var
+ # rather than running their programs.
+ libtool_execute_magic="$magic"
+
+ # Check if any of the arguments is a wrapper script.
+ args=
+ for file
+ do
+ case "$file" in
+ -*) ;;
+ *)
+ if egrep '^# Generated by ltmain.sh' $file >/dev/null 2>&1; then
+ # If there is no directory component, then add one.
+ case "$file" in
+ */*) . $file ;;
+ *) . ./$file ;;
+ esac
+
+ # Transform arg to wrapped name.
+ file="$progdir/$program"
+ fi
+ ;;
+ esac
+ # Quote arguments (to preserve shell metacharacters).
+ args="$args '$file'"
+ done
+
+ if test -z "$run"; then
+ # Export the shlibpath_var.
+ eval "export $shlibpath_var"
+
+ # Now actually exec the command.
+ eval "exec '$cmd'$args"
+
+ echo "$progname: cannot exec '$cmd'$args"
+ exit 1
+ else
+ # Display what would be done.
+ eval "echo \"\$shlibpath_var=\$$shlibpath_var\""
+ echo "export $shlibpath_var"
+ echo "'$cmd'$args"
+ exit 0
+ fi
+ ;;
+
# libtool uninstall mode
uninstall)
progname="$progname: uninstall"
for file in $files; do
dir=`echo "$file" | sed -e 's%/[^/]*$%%'`
- test "$dir" = "$file" && dir=.
+ test "X$dir" = "X$file" && dir=.
name=`echo "$file" | sed -e 's%^.*/%%'`
rmfiles="$file"
MODE must be one of the following:
compile compile a source file into a libtool object
+ execute automatically set library path, then run a program
finish complete the installation of libtool libraries
install install libraries or executables
link create a library or an executable
EOF
;;
+execute)
+ cat <<EOF
+Usage: $progname [OPTION]... --mode=execute COMMAND [ARGS]...
+
+Automatically set library path, then run a program.
+
+This mode accepts the following additional options:
+
+ -dlopen FILE add the directory containing FILE to the library path
+
+This mode sets the library path environment variable according to \`-dlopen'
+flags.
+
+If any of the ARGS are libtool executable wrappers, then they are translated
+into their corresponding uninstalled binary, and any of their required library
+directories are added to the library path.
+
+Then, COMMAND is executed, with ARGS as arguments.
+EOF
+ ;;
+
finish)
cat <<EOF
Usage: $progname [OPTION]... --mode=finish [LIBDIR]...