[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH, take 3][cygwin|mingw] Control where win32 DLLs get installed.
From: |
Dave Korn |
Subject: |
[PATCH, take 3][cygwin|mingw] Control where win32 DLLs get installed. |
Date: |
Tue, 11 Aug 2009 11:30:47 +0100 |
User-agent: |
Thunderbird 2.0.0.17 (Windows/20080914) |
Oops. Forgot to change the test names when I renamed win32.at; fixed in this
revision. Tests run to completion this time, with no regressions.
libtool/ChangeLog:
* Makefile.am (TESTSUITE_AT): Add pe-dll-inst-bindir.at.
* libltdl/config/general.m4sh (func_relative_path): New function.
* libltdl/config/ltmain.m4sh (func_mode_link): Accept new -bindir
option and use it, if supplied, to place Windows DLLs.
* tests/pe-dll-inst-bindir.at: New file for DLL install tests.
* doc/libtool.texi (Link Mode): Update documentation.
And that, unless anyone has any more review comments, is the final revision.
Now we twiddle our thumbs and wait for the paperwork, I guess!
cheers,
DaveK
diff --git a/Makefile.am b/Makefile.am
old mode 100644
new mode 100755
index a18955e..fdeeffd
--- a/Makefile.am
+++ b/Makefile.am
@@ -494,7 +494,8 @@ TESTSUITE_AT = tests/testsuite.at \
tests/configure-iface.at \
tests/stresstest.at \
tests/cmdline_wrap.at \
- tests/darwin.at
+ tests/darwin.at \
+ tests/pe-dll-inst-bindir.at
EXTRA_DIST += $(srcdir)/$(TESTSUITE) $(TESTSUITE_AT)
$(srcdir)/tests/package.m4
diff --git a/doc/libtool.texi b/doc/libtool.texi
old mode 100644
new mode 100755
index a7872c6..61a4e8e
--- a/doc/libtool.texi
+++ b/doc/libtool.texi
@@ -1376,6 +1376,15 @@ 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
+When linking a DLL for Windows or another PE platform, this option tells
+libtool where to eventually install the @samp{.dll} file. The output path
+is used to install the @samp{.la} control file, usually into a @samp{.../lib/}
+subdirectory of the @var{prefix}; except in the case of a dlopen()-able
+module (@pxref{Modules for libltdl}), it is usually desirable to install the
+DLL into a @samp{.../bin/} directory alongside. This option specifies the
+absolute path to the @var{bindir}.
+
@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 +1469,10 @@ 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. If @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} 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
old mode 100644
new mode 100755
index 4bc304c..496cac5
--- a/libltdl/config/general.m4sh
+++ b/libltdl/config/general.m4sh
@@ -100,6 +100,76 @@ func_dirname_and_basename ()
# Generated shell functions inserted here.
+# func_relative_path libdir bindir
+# generates a relative path from LIBDIR to BINDIR, intended
+# for supporting installation of windows DLLs into -bindir.
+# call:
+# func_dirname:
+# func_dirname file append nondir_replacement
+# Compute the dirname of FILE. If nonempty,
+# add APPEND to the result, otherwise set result
+# to NONDIR_REPLACEMENT.
+# value returned in "$func_dirname_result"
+# func_stripname:
+# func_stripname prefix suffix name
+# Strip PREFIX and SUFFIX off of NAME. PREFIX and
+# SUFFIX must not contain globbing or regex special
+# characters, hashes, percent signs, but SUFFIX may
+# contain a leading dot (in which case that matches
+# only a dot).
+# value returned in "$func_stripname_result"
+func_relative_path ()
+{
+ func_relative_path_result=
+ func_stripname '' '/' "$1"
+ func_relative_path_tlibdir=$func_stripname_result
+ func_stripname '' '/' "$2"
+ func_relative_path_tbindir=$func_stripname_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 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"
+
func_relative_path_result=${func_relative_path_result}${func_stripname_result}
+
+ # Normalisation. If bindir is libdir, return empty string,
+ # if subdir return string beginning './', 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_relative_path_result=./
+ else
+ 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
old mode 100644
new mode 100755
index ebd3909..5403d80
--- 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 $prefix/bin (needed only when installing
+ a Windows DLL)
-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
@@ -7706,7 +7719,17 @@ EOF
# place dlname in correct position for cygwin
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/pe-dll-inst-bindir.at b/tests/pe-dll-inst-bindir.at
new file mode 100755
index 0000000..a0f45e5
--- /dev/null
+++ b/tests/pe-dll-inst-bindir.at
@@ -0,0 +1,171 @@
+# pe-dll-inst-bindir.at - Test the -bindir option for installing
+# DLLs on PE format architectures.
+#
+# 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.
+####
+
+noskip=:
+case "$host_os" in
+cygwin*|mingw*|cegcc*) ;;
+*) noskip=false ;;
+esac
+
+$noskip && {
+
+AT_BANNER([PE DLL install tests])
+AT_SETUP([simple compile check])
+
+# Verify compiling works.
+
+AT_DATA([simple.c] ,[[
+int main() { return 0;}
+]])
+
+$noskip && {
+$CC $CPPFLAGS $CFLAGS -o simple simple.c 2>&1 > /dev/null || noskip=false
+rm -f simple
+}
+
+AT_CHECK([$noskip || (exit 77)])
+
+AT_CLEANUP
+
+# Now the tests themselves.
+
+AT_SETUP([dll basic test])
+
+AT_DATA([foo.c],[[
+int x=0;
+]])
+
+AT_DATA([baz.c],[[
+int y=0;
+]])
+
+AT_DATA([bar.c],[[
+extern int x;
+int bar(void);
+int bar() { return x;}
+]])
+
+AT_DATA([main.c],[[
+extern int x;
+extern int y;
+
+int main() {
+return x+y;
+}
+]])
+
+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 -shared -o libfoo.la
$CPPFLAGS $CFLAGS $LDFLAGS foo.lo baz.lo -rpath
/nonexistent],[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 -shared -o libbar.la
$CPPFLAGS $CFLAGS $LDFLAGS bar.lo libfoo.la -rpath
/nonexistent],[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],[0],[ignore],[ignore])
+
+AT_CLEANUP
+
+AT_SETUP([dll install to bindir])
+
+AT_DATA([foo.c],[[
+int x=0;
+]])
+
+AT_DATA([bar.c],[[
+extern int x;
+int bar(void);
+int bar() { return x;}
+]])
+
+AT_DATA([baz.c],[[
+int y=0;
+]])
+
+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 -shared -o libfoo.la
$CPPFLAGS $CFLAGS $LDFLAGS foo.lo baz.lo -rpath
/nonexistent],[0],[ignore],[ignore])
+
+AT_CHECK([$LIBTOOL --mode=compile --tag=CC $CC -c -o bar.lo $CPPFLAGS $CFLAGS
bar.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`
+libdir=${curdir}/usr/lib/gcc/i686-pc-cygwin/4.5.0
+
+# Do a basic install with no -bindir option for reference
+
+AT_CHECK([$LIBTOOL --mode=link --tag=CC $CC -no-undefined -shared -o libbar.la
$CPPFLAGS $CFLAGS $LDFLAGS bar.lo libfoo.la -rpath
${libdir}],[0],[ignore],[ignore])
+rm -rf ${curdir}/usr
+mkdir -p ${libdir}
+AT_CHECK([$LIBTOOL --mode=install $lt_INSTALL libbar.la $libdir],
+ [], [ignore], [ignore])
+
+# And ensure it went where we expect.
+AT_CHECK(test -f $libdir/../bin/???bar-0.dll)
+
+for x 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
+
+ AT_CHECK([$LIBTOOL --mode=link --tag=CC $CC -no-undefined -bindir $x -shared
-o libbar.la $CPPFLAGS $CFLAGS $LDFLAGS bar.lo libfoo.la -rpath
${libdir}],[0],[ignore],[ignore])
+
+ rm -rf ${curdir}/usr ${curdir}/bin /tmp/$$
+ mkdir -p ${libdir} $x ${curdir}/usr ${curdir}/bin /tmp/$$
+ AT_CHECK([$LIBTOOL --mode=install $lt_INSTALL libbar.la $libdir],
+ [], [ignore], [ignore])
+ # Ensure it went to bindir this time.
+ AT_CHECK(test -f $x/???bar-0.dll)
+done
+
+AT_CLEANUP
+
+}
+
- [PATCH, take 3][cygwin|mingw] Control where win32 DLLs get installed.,
Dave Korn <=
- Re: [PATCH, take 3][cygwin|mingw] Control where win32 DLLs get installed., Dave Korn, 2009/08/12
- Re: [PATCH, take 3][cygwin|mingw] Control where win32 DLLs get installed., Ralf Wildenhues, 2009/08/13
- Re: [PATCH, take 3][cygwin|mingw] Control where win32 DLLs get installed., Ralf Wildenhues, 2009/08/13
- Re: [PATCH, take 3][cygwin|mingw] Control where win32 DLLs get installed., Dave Korn, 2009/08/13
- Re: [PATCH, take 3][cygwin|mingw] Control where win32 DLLs get installed., Ralf Wildenhues, 2009/08/13
- Re: [PATCH, take 3][cygwin|mingw] Control where win32 DLLs get installed., Dave Korn, 2009/08/13
- Re: [PATCH, take 3][cygwin|mingw] Control where win32 DLLs get installed., Dave Korn, 2009/08/13
- Re: [PATCH, take 3][cygwin|mingw] Control where win32 DLLs get installed., Tim Rice, 2009/08/13
- Re: [PATCH, take 3][cygwin|mingw] Control where win32 DLLs get installed., Dave Korn, 2009/08/13