Fifth time lucky! (Why do I say these things, I'm only asking for trouble!)
libtool/ChangeLog: * Makefile.am (TESTSUITE_AT): Add bindir.at. * libltdl/config/general.m4sh (func_normal_abspath): New function. (func_relative_path): Likewise. * libltdl/config/ltmain.m4sh (func_mode_help): Document "-bindir". (func_mode_link): Accept new "-bindir" option and use it, if supplied, to place Windows DLLs. * tests/bindir.at: New file for install tests using "-bindir". * doc/libtool.texi (Link Mode): Update documentation. Built and tested on i686-pc-cygwin and i686-pc-linux-gnu with no regressions and all new tests passing. Ok now? cheers, DaveK -- ==================== All 124 tests passed ==================== ## ------------- ## ## Test results. ## ## ------------- ## 89 tests behaved as expected. 2 tests were skipped. [da...@ubique libtool]$ ./libltdl/config/config.guess i686-pc-linux-gnu [da...@ubique libtool]$ uname -a Linux ubique.localdomain 2.6.27.21-170.2.56.fc10.i686 #1 SMP Mon Mar 23 23:37:54 EDT 2009 i686 athlon i386 GNU/Linux [da...@ubique libtool]$ -- ====================== All 122 tests passed (2 tests were not run) ====================== 39: bindir compile check ok 40: bindir basic lib test ok 41: bindir install tests ok ## ------------- ## ## Test results. ## ## ------------- ## 85 tests behaved as expected. 6 tests were skipped. ad...@ubik /gnu/libtool/libtool $ ./libltdl/config/config.guess i686-pc-cygwin ad...@ubik /gnu/libtool/libtool $ uname -a CYGWIN_NT-5.0 ubik 1.7.0(0.212/5/3) 2009-08-12 20:18 i686 Cygwin ad...@ubik /gnu/libtool/libtool
diff --git a/Makefile.am b/Makefile.am index a18955e..d68ed33 100644 --- a/Makefile.am +++ b/Makefile.am @@ -468,6 +468,7 @@ TESTSUITE_AT = tests/testsuite.at \ tests/indirect_deps.at \ tests/archive-in-archive.at \ tests/execute-mode.at \ + tests/bindir.at \ tests/cwrapper.at \ tests/infer-tag.at \ tests/localization.at \ diff --git a/doc/libtool.texi b/doc/libtool.texi index a7872c6..f862217 100644 --- a/doc/libtool.texi +++ b/doc/libtool.texi @@ -1376,6 +1376,18 @@ Tries to avoid versioning (@pxref{Versioning}) for libraries and modules, i.e.@: no version information is stored and no symbolic links are created. If the platform requires versioning, this option has no effect. +...@item -bindir +Pass the absolute name of the directory for installing executable +programs (@pxref{Directory Variables, , Directory Variables, standards, +The GNU Coding Standards}). @command{libtool} may use this value to +install shared libraries there on systems that do not provide for any +library hardcoding and use the directory of a program and the @env{PATH} +variable as library search path. This is typically used for DLLs on +Windows or other systems using the PE (Portable Executable) format. +On other systems, @option{-bindir} is ignored. The default value used +is @fi...@var{libdir}/../bin} for libraries installed to +...@file{@var{libdir}}. You should not use @option{-bindir} for modules. + @item -dlopen @var{file} Same as @option{-dlpreopen @var{file}}, if native dlopening is not supported on the host platform (@pxref{Dlopened modules}) or if @@ -1460,7 +1472,12 @@ the @option{-version-info} flag instead (@pxref{Versioning}). @item -rpath @var{libdir} If @var{output-file} is a library, it will eventually be installed in @var{libdir}. If @var{output-file} is a program, add @var{libdir} to -the run-time path of the program. +the run-time path of the program. On platforms that don't support +hardcoding library paths into executables and only search PATH for +shared libraries, such as when @var{output-file} is a Windows (or +other PE platform) DLL, the @samp{.la} control file will be installed in +...@var{libdir}, but see @option{-bindir} above for the eventual destination +of the @samp{.dll} or other library file itself. @item -R @var{libdir} If @var{output-file} is a program, add @var{libdir} to its run-time diff --git a/libltdl/config/general.m4sh b/libltdl/config/general.m4sh index 4bc304c..c751629 100644 --- a/libltdl/config/general.m4sh +++ b/libltdl/config/general.m4sh @@ -100,6 +100,151 @@ func_dirname_and_basename () # Generated shell functions inserted here. +# These SED scripts presuppose an absolute path with a trailing slash. +pathcar="s,^/\([^/]*\).*$,\1," +pathcdr="s,^/[^/]*,," +removedotparts="s,/\(\./\)\{1\,\},/,g;s,/\.$,/," +collapseslashes="s,/\{1\,\},/,g" +finalslash="s,/*$,/," + +# func_normal_abspath PATH +# Remove doubled-up and trailing slashes, "." path components, +# and cancel out any ".." path components in PATH after making +# it an absolute path. +# value returned in "$func_normal_abspath_result" +func_normal_abspath () +{ + # Start from root dir and reassemble the path. + func_normal_abspath_result= + func_normal_abspath_tpath=$1 + func_normal_abspath_altnamespace= + case $func_normal_abspath_tpath in + "") + # Empty path, that just means $cwd. + func_stripname '' '/' "`pwd`" + func_normal_abspath_result=$func_stripname_result + return + ;; + # The next three entries are used to spot a run of precisely + # two leading slashes without using negated character classes; + # we take advantage of case's first-match behaviour. + ///*) + # Unusual form of absolute path, do nothing. + ;; + //*) + # Not necessarily an ordinary path; POSIX reserves leading '//' + # and for example Cygwin uses it to access remote file shares + # over CIFS/SMB, so we conserve a leading double slash if found. + func_normal_abspath_altnamespace=/ + ;; + /*) + # Absolute path, do nothing. + ;; + *) + # Relative path, prepend $cwd. + func_normal_abspath_tpath=`pwd`/$func_normal_abspath_tpath + ;; + esac + # Cancel out all the simple stuff to save iterations. We also want + # the path to end with a slash for ease of parsing, so make sure + # there is one (and only one) here. + func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ + -e "$removedotparts" -e "$collapseslashes" -e "$finalslash"` + while :; do + # Processed it all yet? + if test "$func_normal_abspath_tpath" = / ; then + # If we ascended to the root using ".." the result may be empty now. + if test -z "$func_normal_abspath_result" ; then + func_normal_abspath_result=/ + fi + break + fi + func_normal_abspath_tcomponent=`$ECHO "$func_normal_abspath_tpath" | $SED \ + -e "$pathcar"` + func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ + -e "$pathcdr"` + # Figure out what to do with it + case $func_normal_abspath_tcomponent in + "") + # Trailing empty path component, ignore it. + ;; + ..) + # Parent dir; strip last assembled component from result. + func_dirname "$func_normal_abspath_result" + func_normal_abspath_result=$func_dirname_result + ;; + *) + # Actual path component, append it. + func_normal_abspath_result=$func_normal_abspath_result/$func_normal_abspath_tcomponent + ;; + esac + done + # Restore leading double-slash if one was found on entry. + func_normal_abspath_result=$func_normal_abspath_altnamespace$func_normal_abspath_result +} + +# func_relative_path SRCDIR DSTDIR +# generates a relative path from SRCDIR to DSTDIR, with a trailing +# slash if non-empty, suitable for immediately appending a filename +# without needing to append a separator. +# value returned in "$func_relative_path_result" +func_relative_path () +{ + func_relative_path_result= + func_normal_abspath "$1" + func_relative_path_tlibdir=$func_normal_abspath_result + func_normal_abspath "$2" + func_relative_path_tbindir=$func_normal_abspath_result + + # Ascend the tree starting from libdir + while :; do + # check if we have found a prefix of bindir + case $func_relative_path_tbindir in + $func_relative_path_tlibdir) + # found an exact match + func_relative_path_tcancelled= + break + ;; + $func_relative_path_tlibdir*) + # found a matching prefix + func_stripname "$func_relative_path_tlibdir" '' "$func_relative_path_tbindir" + func_relative_path_tcancelled=$func_stripname_result + if test -z "$func_relative_path_result"; then + func_relative_path_result=. + fi + break + ;; + *) + func_dirname $func_relative_path_tlibdir + func_relative_path_tlibdir=${func_dirname_result} + if test "x$func_relative_path_tlibdir" = x ; then + # Have to descend all the way to the root! + func_relative_path_result=../$func_relative_path_result + func_relative_path_tcancelled=$func_relative_path_tbindir + break + fi + func_relative_path_result=../$func_relative_path_result + ;; + esac + done + + # Now calculate path; take care to avoid doubling-up slashes. + func_stripname '' '/' "$func_relative_path_result" + func_relative_path_result=$func_stripname_result + func_stripname '/' '/' "$func_relative_path_tcancelled" + if test "x$func_stripname_result" != x ; then + func_relative_path_result=${func_relative_path_result}/${func_stripname_result} + fi + + # Normalisation. If bindir is libdir, return empty string, + # else relative path ending with a slash; either way, target + # file name can be directly appended. + if test ! -z "$func_relative_path_result"; then + func_stripname './' '' "$func_relative_path_result/" + func_relative_path_result=$func_stripname_result + fi +} + # The name of this program: func_dirname_and_basename "$progpath" progname=$func_basename_result diff --git a/libltdl/config/ltmain.m4sh b/libltdl/config/ltmain.m4sh index ebd3909..a7a0cbc 100644 --- a/libltdl/config/ltmain.m4sh +++ b/libltdl/config/ltmain.m4sh @@ -1129,6 +1129,8 @@ The following components of LINK-COMMAND are treated specially: -all-static do not do any dynamic linking at all -avoid-version do not add a version suffix if possible + -bindir BINDIR specify path to binaries directory (for systems where + libraries must be found in the PATH setting at runtime) -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) @@ -3659,6 +3661,7 @@ func_mode_link () new_inherited_linker_flags= avoid_version=no + bindir= dlfiles= dlprefiles= dlself=no @@ -3751,6 +3754,11 @@ func_mode_link () esac case $prev in + bindir) + bindir="$arg" + prev= + continue + ;; dlfiles|dlprefiles) if test "$preload" = no; then # Add the symbol object into the linking commands. @@ -4012,6 +4020,11 @@ func_mode_link () continue ;; + -bindir) + prev=bindir + continue + ;; + -dlopen) prev=dlfiles continue @@ -7704,9 +7717,27 @@ EOF fi $RM $output # place dlname in correct position for cygwin + # In fact, it would be nice if we could use this code for all target + # systems that can't hard-code library paths into their executables + # and that have no shared library path variable independent of PATH, + # but it turns out we can't easily determine that from inspecting + # libtool variables, so we have to hard-code the OSs to which it + # applies here; at the moment, that means platforms that use the PE + # object format with DLL files. See the long comment at the top of + # tests/bindir.at for full details. tdlname=$dlname case $host,$output,$installed,$module,$dlname in - *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll) tdlname=../bin/$dlname ;; + *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll) + # If a -bindir argument was supplied, place the dll there. + if test "x$bindir" != x ; + then + func_relative_path "$install_libdir" "$bindir" + tdlname=$func_relative_path_result$dlname + else + # Otherwise fall back on heuristic. + tdlname=../bin/$dlname + fi + ;; esac $ECHO > $output "\ # $outputname - a libtool library file diff --git a/tests/bindir.at b/tests/bindir.at new file mode 100644 index 0000000..e0e1b05 --- /dev/null +++ b/tests/bindir.at @@ -0,0 +1,380 @@ +# bindir.at - Test the -bindir option +# +# Copyright (C) 2009 Free Software Foundation, Inc. +# Written by Dave Korn, 2009 +# +# This file is part of GNU Libtool. +# +# GNU Libtool 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 of +# the License, or (at your option) any later version. +# +# GNU Libtool 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 GNU Libtool; see the file COPYING. If not, a copy +# can be downloaded from http://www.gnu.org/licenses/gpl.html, +# or obtained by writing to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +#### + +#### +# In this testcase, and in the chunk of code that makes use +# of $bindir in ltmain.m4sh, we would very much have liked to +# automatically decide which systems require dynamically-loaded +# libraries to be installed to a directory in $PATH according +# to the libtool properties that tell us that "the system provides +# no way to hard-code library paths into executables, and also +# has no $shlibpath_var independent of the PATH variable", in +# Ralf's words. But it turns out this is not possible, as:- +# +#> * Dave Korn wrote on Fri, Aug 14, 2009 at 04:30:27AM CEST: +#>>> Ralf Wildenhues wrote: +#>>> +#>>>>> But in this particular case, I would argue that either you look at +#>>>>> the libtool variables shlibpath_var and hardcode_action for "PATH" +#>>>>> and "unsupported". +#>>> +#>>> On Cygwin, $hardcode_action = "immediate" in the generated libtool +#>>> script. Did you perhaps mean $hardcode_shlibpath_var, which is indeed +#>>> "unsupported"? +#> +#> Oh brother, yes, I forgot about those bogus hardcode_libdir_flag_spec +#> settings. They fool _LT_LINKER_HARDCODE_LIBPATH. I don't remember whether +#> they were needed in order to not break some semantics in ltmain (they +#> probably were). +#> +#> Anyway, $hardcode_action = "immediate" is definitely wrong, but fixing that +#> now is also way out of scope of this patch. So I guess we need to stick to +#> host matching in the code, and work out a separate fix for the setting of +#> $hardcode_libdir_flag_spec. +# +# So alas we punt for now, and just hardcode the relevant OSs that require +# this functionality. That's Cygwin, MinGW and CeGCC for now; see the case +# statement in libtool.m4sh around where the 'tdlname' variable is set. + +#### +# Verify compiling works, and skip remaining tests if not. +# + +AT_SETUP([bindir compile check]) + +AT_DATA([simple.c] ,[[ +int main() { return 0;} +]]) + +$CC $CPPFLAGS $CFLAGS -o simple simple.c 2>&1 > /dev/null || noskip=false +rm -f simple + +AT_CHECK([$noskip || (exit 77)]) + +AT_CLEANUP + +#### +# Now run the tests themselves. First a simple test that we can +# build and run an executable with a couple of tiny libraries. + +AT_SETUP([bindir basic lib test]) + +bindirneeded=: +case "$host_os" in + cygwin*|mingw*|cegcc*) + ;; + *) + bindirneeded=false + ;; +esac + +#### +# These routines save the PATH before a test and restore it after, +# prepending a chosen directory to the path on the platforms where +# -bindir is needed after saving. +# + +func_save_and_prepend_path () +{ + save_PATH=$PATH + if $bindirneeded ; then + PATH=$1:$PATH + fi + export PATH +} + +func_restore_path () +{ + PATH=$save_PATH + export PATH +} + +AT_DATA([foo.c],[[ +int x=11; +]]) + +AT_DATA([baz.c],[[ +extern int x; +int baz (void); +int baz (void) { return x;} +]]) + +AT_DATA([bar.c],[[ +extern int baz (void); +int y=3; +int bar (void); +int bar (void) { return y + baz ();} +]]) + +AT_DATA([main.c],[[ +extern int baz (void); +extern int bar (void); +extern void abort (void); +int main() { +if (baz () + bar () - 25) abort (); +return 0; +} +]]) + + +curdir=`pwd` +eval "`$LIBTOOL --config | grep '^objdir='`" + +AT_CHECK([$LIBTOOL --mode=compile --tag=CC $CC -c -o foo.lo $CPPFLAGS $CFLAGS foo.c],[0],[ignore],[ignore]) +AT_CHECK([$LIBTOOL --mode=compile --tag=CC $CC -c -o baz.lo $CPPFLAGS $CFLAGS baz.c],[0],[ignore],[ignore]) +AT_CHECK([$LIBTOOL --mode=link --tag=CC $CC -no-undefined -o libfoo.la $CPPFLAGS $CFLAGS $LDFLAGS foo.lo baz.lo -rpath $curdir/$objdir],[0],[ignore],[ignore]) + +AT_CHECK([$LIBTOOL --mode=compile --tag=CC $CC -c -o bar.lo $CPPFLAGS $CFLAGS bar.c],[0],[ignore],[ignore]) +AT_CHECK([$LIBTOOL --mode=link --tag=CC $CC -no-undefined -o libbar.la $CPPFLAGS $CFLAGS $LDFLAGS bar.lo libfoo.la -rpath $curdir/$objdir],[0],[ignore],[ignore]) + +AT_CHECK([$LIBTOOL --mode=compile --tag=CC $CC -c -o main.lo $CPPFLAGS $CFLAGS main.c],[0],[ignore],[ignore]) +AT_CHECK([$LIBTOOL --mode=link --tag=CC $CC -o main$EXEEXT $CPPFLAGS $CFLAGS $LDFLAGS main.lo libbar.la libfoo.la],[0],[ignore],[ignore]) + +# Check both static and shared versions run. We don't install them +# here, that will be covered by the later tests; we've rpath'd things +# so that they can all be run in situ. + +LT_AT_NOINST_EXEC_CHECK([$LIBTOOL], [], [0], [ignore], [ignore], [--mode=execute ./main$EXEEXT]) + +# Ensure libraries can be found on PATH, if we are on one +# of the affected platforms, before testing the shared version. + +func_save_and_prepend_path $curdir/$objdir +$bindirneeded && { + LT_AT_NOINST_EXEC_CHECK([$LIBTOOL], [], [0], [ignore], [ignore], [--mode=execute $objdir/main$EXEEXT]) +} + +# In fact, prepending the PATH as above is superfluous on the windows +# platforms that this feature is primarily aimed at, as the DLL search +# path always includes the directory from which the app was launched. +# To make sure it still works even when not side-by-side, we'll install +# the main executable and execute it from there while the PATH still +# points to the shared libs in the .libs subdir. On other platforms, +# the rpaths we set at link time will guarantee it runs from the bindir. + +mkdir $curdir/bin +AT_CHECK([$LIBTOOL --mode=install $lt_INSTALL main$EXEEXT $curdir/bin/main$EXEEXT], [], [ignore], [ignore]) +LT_AT_EXEC_CHECK([$curdir/bin/main$EXEEXT], [0], [ignore], [ignore], []) +func_restore_path + +AT_CLEANUP + +#### +# This is the main testcase. For a variety of bindir and libdir +# settings, it verifies that all the files get installed exactly +# where we want them to go, and that they can be executed once +# installed. +# + +AT_SETUP([bindir install tests]) + +bindirneeded=: +case "$host_os" in + cygwin*|mingw*|cegcc*) + ;; + *) + bindirneeded=false + ;; +esac + +#### +# These routines save the PATH before a test and restore it after, +# prepending a chosen directory to the path on the platforms where +# -bindir is needed after saving. +# + +func_save_and_prepend_path () +{ + save_PATH=$PATH + if $bindirneeded ; then + PATH=$1:$PATH + fi + export PATH +} + +func_restore_path () +{ + PATH=$save_PATH + export PATH +} + +AT_DATA([foo.c],[[ +int x=11; +]]) + +AT_DATA([baz.c],[[ +extern int x; +int baz (void); +int baz (void) { return x;} +]]) + +AT_DATA([bar.c],[[ +extern int baz (void); +int y=3; +int bar (void); +int bar (void) { return y + baz ();} +]]) + +AT_DATA([main.c],[[ +extern int baz (void); +extern int bar (void); +extern void abort (void); +int main() { +if (baz () + bar () - 25) abort (); +return 0; +} +]]) + +# We only need to compile once, but we'll need to relink for each different value +# of libdir in order to set the rpath, and we'll install for each combination of +# libdir and bindir. + +AT_CHECK([$LIBTOOL --mode=compile --tag=CC $CC -c -o foo.lo $CPPFLAGS $CFLAGS foo.c],[0],[ignore],[ignore]) +AT_CHECK([$LIBTOOL --mode=compile --tag=CC $CC -c -o baz.lo $CPPFLAGS $CFLAGS baz.c],[0],[ignore],[ignore]) +AT_CHECK([$LIBTOOL --mode=compile --tag=CC $CC -c -o bar.lo $CPPFLAGS $CFLAGS bar.c],[0],[ignore],[ignore]) +AT_CHECK([$LIBTOOL --mode=compile --tag=CC $CC -c -o main.lo $CPPFLAGS $CFLAGS main.c],[0],[ignore],[ignore]) + +# Now try installing the libs. There are the following cases: +# No -bindir +# -bindir below lib install dir +# -bindir is lib install dir +# -bindir beside lib install dir +# -bindir above lib dir +# -bindir above and beside lib dir +# -bindir in entirely unrelated prefix. + +curdir=`pwd` +for libdir in \ + $curdir/usr/lib/gcc/i686-pc-cygwin/4.5.0 \ + $curdir/usr/lib/gcc/../gcc/.//i686-pc-cygwin/4.5.0/../../././//. \ + $curdir/usr/lib/ \ + $curdir/usr/lib \ + $curdir/baz \ + $curdir/baz/lib/ ; +do + + # Do a basic install with no -bindir option for reference. We use the sbin/ + # dir for the main exe to avoid the potential "this only works because it's + # side-by-side with the libs" default DLL search path problem mentioned above. + rm -rf $libdir $curdir/bin $curdir/sbin $curdir/baz $curdir/usr + AS_MKDIR_P($libdir) + AS_MKDIR_P($curdir/sbin) + AT_CHECK([$LIBTOOL --mode=link --tag=CC $CC -no-undefined -o libfoo.la $CPPFLAGS $CFLAGS $LDFLAGS foo.lo bar.lo baz.lo -rpath $libdir],[0],[ignore],[ignore]) + AT_CHECK([$LIBTOOL --mode=link --tag=CC $CC -o main$EXEEXT $CPPFLAGS $CFLAGS $LDFLAGS main.lo libfoo.la -rpath $libdir],[0],[ignore],[ignore]) + AT_CHECK([$LIBTOOL --mode=install $lt_INSTALL libfoo.la $libdir], [], [ignore], [ignore]) + AT_CHECK([$LIBTOOL --mode=install $lt_INSTALL main$EXEEXT $curdir/sbin/main$EXEEXT], [], [ignore], [ignore]) + + # And ensure it went where we expect. Could be looking for any of 'cygfoo-0.dll', + # 'libfoo-0.dll', or 'libfoo.so.0'. We'll simplify this check by taking advantage + # of the fact that if it's a DLL, it has to go in bindir, so we'll not check for + # both forms in libdir. + AT_CHECK([$bindirneeded && { test -f $libdir/../bin/???foo-0.dll || ls $libdir/../bin/*foo*0* 2>/dev/null ; } || ls $libdir/*foo*0* 2>/dev/null], [], [ignore], [ignore]) + + # And that it can be executed. + extrapath= + $bindirneeded && extrapath=$libdir/../bin + func_save_and_prepend_path $extrapath + LT_AT_EXEC_CHECK([$curdir/sbin/main$EXEEXT], [0], [ignore], [ignore], []) + func_restore_path + + for bindir in \ + $curdir/usr/lib/gcc/i686-pc-cygwin/4.5.0/bin/ \ + $curdir/usr/lib/gcc/i686-pc-cygwin/4.5.0/bin \ + $curdir/usr/lib/gcc/i686-pc-cygwin/4.5.0/ \ + $curdir/usr/lib/gcc/i686-pc-cygwin/4.5.0 \ + $curdir/usr/lib/gcc/i686-pc-cygwin/bin/ \ + $curdir/usr/lib/gcc/i686-pc-cygwin/bin \ + $curdir/usr/lib/gcc/i686-pc-cygwin/ \ + $curdir/usr/lib/gcc/i686-pc-cygwin \ + $curdir/usr/lib/bin/ \ + $curdir/usr/lib/bin \ + $curdir/usr/bin/ \ + $curdir/usr/bin \ + $curdir/bin/ \ + $curdir/bin \ + /tmp/foo/bar ; + do + + # Clear any old stuff out before we install. Because bindir + # may be in /tmp, we have to take care to create it securely + # and not to delete and recreate it if we do. + rm -rf $libdir $curdir/bin $curdir/sbin $curdir/baz $curdir/usr + + tmp= + case $bindir in + /tmp*) + # Create a temporary directory $tmp in $TMPDIR (default /tmp). + # Use mktemp if possible; otherwise fall back on mkdir, + # with $RANDOM to make collisions less likely. + : ${TMPDIR=/tmp} + { + tmp=` + (umask 077 && mktemp -d "$TMPDIR/fooXXXXXX") 2>/dev/null + ` && + test -n "$tmp" && test -d "$tmp" + } || { + tmp=$TMPDIR/foo$$-$RANDOM + (umask 077 && mkdir "$tmp") + } || exit 77 + bindir=$tmp/bar + ;; + *) + # Clear any old stuff out before we install. + rm -rf $bindir + AS_MKDIR_P($bindir) + ;; + esac + + # Relink with new rpaths. + AT_CHECK([$LIBTOOL --mode=link --tag=CC $CC -no-undefined -bindir $bindir -o libfoo.la $CPPFLAGS $CFLAGS $LDFLAGS foo.lo bar.lo baz.lo -rpath $libdir],[0],[ignore],[ignore]) + AT_CHECK([$LIBTOOL --mode=link --tag=CC $CC -o main$EXEEXT $CPPFLAGS $CFLAGS $LDFLAGS main.lo libfoo.la],[0],[ignore],[ignore]) + + # Recreate directories (bindir already done) and install. + AS_MKDIR_P($libdir) + AS_MKDIR_P($curdir/sbin) + AT_CHECK([$LIBTOOL --mode=install $lt_INSTALL libfoo.la $libdir], [], [ignore], [ignore]) + AT_CHECK([$LIBTOOL --mode=install $lt_INSTALL main$EXEEXT $curdir/sbin/main$EXEEXT], [], [ignore], [ignore]) + + # Ensure it went to bindir rather than default dir this time. + AT_CHECK([$bindirneeded && { test -f $bindir/???foo-0.dll || ls $bindir/*foo*0* 2>/dev/null ; } || ls $libdir/*foo*0* 2>/dev/null], [], [ignore], [ignore]) + + # And that it can be executed. + extrapath= + $bindirneeded && extrapath=$bindir + func_save_and_prepend_path $extrapath + LT_AT_EXEC_CHECK([$curdir/sbin/main$EXEEXT], [0], [ignore], [ignore], []) + func_restore_path + + # Clean up if we made a temp dir. Subdirs under our testdir get rm'd + # and recreated at the top of the loop. Securely created subdirs under + # /tmp get created precisely once and rm'd when we're done with them. + if test ! -z "$tmp" ; then + rm -rf "$tmp" + fi + + done +done + +AT_CLEANUP +