libtool-patches
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH, take 5][cygwin|mingw] Control where win32 DLLs get installed.


From: Dave Korn
Subject: [PATCH, take 5][cygwin|mingw] Control where win32 DLLs get installed.
Date: Mon, 17 Aug 2009 06:25:04 +0100
User-agent: Thunderbird 2.0.0.17 (Windows/20080914)

  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.
address@hidden libtool]$ ./libltdl/config/config.guess
i686-pc-linux-gnu
address@hidden 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
address@hidden 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.

address@hidden /gnu/libtool/libtool
$ ./libltdl/config/config.guess
i686-pc-cygwin

address@hidden /gnu/libtool/libtool
$ uname -a
CYGWIN_NT-5.0 ubik 1.7.0(0.212/5/3) 2009-08-12 20:18 i686 Cygwin

address@hidden /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.
 
address@hidden -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 @address@hidden/../bin} for libraries installed to
address@hidden@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
address@hidden, 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
+

reply via email to

[Prev in Thread] Current Thread [Next in Thread]