diff --git a/ChangeLog b/ChangeLog index ca31aca6..9dab3608 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,35 @@ +2010-06-28 Peter Rosin + + For MSVC, embed the manifest as a resource in the executable. + Fixes a lot of testsuite failures with MSVC 2003 (v8.0) and + above (and perhaps also MSVC .Net) related to running programs + that have been moved (e.g. installed) without their manifests + also having been moved. + * libltdl/m4/libtool.m4 (_LT_PATH_MANIFEST_TOOL): New macro + that locates the Manifest Tool (mt) and verifies that it is + indeed the manifest tool. The result is stored in the new + variable MANIFEST_TOOL. + (_LT_LINKER_SHLIBS) : New tag variable. + [ cygwin, mingw, cegcc ] : Embed the manifest file as a + resource. Make sure the embedding work regardless of if the + @OUTPUT@ file name includes a trailing $EXEEXT. + (_LT_LANG_CXX_CONFIG): Likewise. + (_LT_LINKER_SHLIBS, _LT_LANG_CXX_CONFIG): Require the above + _LT_PATH_MANIFEST_TOOL. + * libltdl/config/ltmain.m4sh (func_mode_link): After linking + a program, replace @OUTPUT@ in $postlink_cmds and then execute + the commands. + * doc/libtool.texi (libtool script contents): Document + new postlink_cmds variable. + (LT_INIT): Add that the MANIFEST_TOOL environment variable can + be used to override the manifest tool to use. + * tests/exeext.at: New. Make sure linking with both -o prog + and -o prog$EXEEXT works. + * Makefile.am (TESTSUITE_AT): Update. + (TESTS_ENVIRONMENT): Propagate $(MANIFEST_TOOL) to the + testsuite. + * NEWS: Add note of the new MANIFEST_TOOL environment variable. + 2010-06-24 Peter Rosin Add MSVC support. diff --git a/Makefile.am b/Makefile.am index 320a2a32..ef3c9846 100644 --- a/Makefile.am +++ b/Makefile.am @@ -472,6 +472,7 @@ TESTSUITE_AT = tests/testsuite.at \ tests/search-path.at \ tests/indirect_deps.at \ tests/archive-in-archive.at \ + tests/exeext.at \ tests/execute-mode.at \ tests/bindir.at \ tests/cwrapper.at \ @@ -521,6 +522,7 @@ TESTS_ENVIRONMENT = MAKE="$(MAKE)" CC="$(CC)" CFLAGS="$(CFLAGS)" \ CPP="$(CPP)" CPPFLAGS="$(CPPFLAGS)" LD="$(LD)" LDFLAGS="$(LDFLAGS)" \ LIBS="$(LIBS)" LN_S="$(LN_S)" NM="$(NM)" RANLIB="$(RANLIB)" \ M4SH="$(M4SH)" SED="$(SED)" STRIP="$(STRIP)" lt_INSTALL="$(INSTALL)" \ + MANIFEST_TOOL="$(MANIFEST_TOOL)" \ OBJEXT="$(OBJEXT)" EXEEXT="$(EXEEXT)" \ SHELL="$(SHELL)" CONFIG_SHELL="$(SHELL)" \ CXX="$(CXX)" CXXFLAGS="$(CXXFLAGS)" CXXCPP="$(CXXCPP)" \ diff --git a/NEWS b/NEWS index 5735b019..95fa97d8 100644 --- a/NEWS +++ b/NEWS @@ -9,7 +9,9 @@ New in 2.2.12 2010-08-??: git version 2.2.11a, Libtool team: * Changes in supported systems or compilers: - Initial support for the Microsoft C/C++ Compiler, with help from - the compile script in unreleased Automake 1.12. + the compile script in unreleased Automake 1.12. Override the manifest + tool used to embed the manifest resource through the environment + variable MANIFEST_TOOL. New in 2.2.10 2010-06-10: git version 2.2.9a, Libtool team: diff --git a/doc/libtool.texi b/doc/libtool.texi index 7ae2c660..af6e13d3 100644 --- a/doc/libtool.texi +++ b/doc/libtool.texi @@ -2306,6 +2306,11 @@ Program to use rather than checking for @command{as}. Only used on Cygwin/MS-Windows at the moment. @end defvar +@defvar MANIFEST_TOOL +Program to use rather than checking for @command{mt}, the Manifest Tool. +Only used on Cygwin/MS-Windows at the moment. +@end defvar + With 1.3 era libtool, if you wanted to know any details of what libtool had discovered about your architecture and environment, you had to run the script with @option{--config} and grep through the @@ -6199,6 +6204,15 @@ Commands run after installing a shared or static library, respectively. Commands run after uninstalling a shared or static library, respectively. @end defvar +@defvar postlink_cmds +Commands necessary for finishing linking programs. @code{postlink_cmds} +are executed immediately after the program is linked. Any occurance of +the string @code{@@OUTPUT@@} in @code{postlink_cmds} is replaced by the +name of the created executable (i.e. not the wrapper, if a wrapper is +generated) prior to execution. Normally disabled (i.e. +@code{postlink_cmds} empty). +@end defvar + @defvar reload_cmds @defvarx reload_flag Commands to create a reloadable object. diff --git a/libltdl/config/ltmain.m4sh b/libltdl/config/ltmain.m4sh index fc2358e6..760b6aa2 100644 --- a/libltdl/config/ltmain.m4sh +++ b/libltdl/config/ltmain.m4sh @@ -7423,6 +7423,11 @@ EOF exit_status=0 func_show_eval "$link_command" 'exit_status=$?' + if test -n "$postlink_cmds"; then + postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g'` + func_execute_cmds "$postlink_cmds" 'exit $?' + fi + # Delete the generated files. if test -f "$output_objdir/${outputname}S.${objext}"; then func_show_eval '$RM "$output_objdir/${outputname}S.${objext}"' @@ -7468,6 +7473,12 @@ EOF $opt_dry_run || $RM $output # Link the executable and exit func_show_eval "$link_command" 'exit $?' + + if test -n "$postlink_cmds"; then + postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g'` + func_execute_cmds "$postlink_cmds" 'exit $?' + fi + exit $EXIT_SUCCESS fi @@ -7501,6 +7512,11 @@ EOF func_show_eval "$link_command" 'exit $?' + if test -n "$postlink_cmds"; then + postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` + func_execute_cmds "$postlink_cmds" 'exit $?' + fi + # Now create the wrapper script. func_verbose "creating $output" diff --git a/libltdl/m4/libtool.m4 b/libltdl/m4/libtool.m4 index 144150c8..89785c12 100644 --- a/libltdl/m4/libtool.m4 +++ b/libltdl/m4/libtool.m4 @@ -3320,6 +3320,28 @@ dnl AC_DEFUN([AM_PROG_NM], []) dnl AC_DEFUN([AC_PROG_NM], []) +# _LT_PATH_MANIFEST_TOOL +# ---------------------- +# locate the manifest tool +m4_defun([_LT_PATH_MANIFEST_TOOL], +[AC_CHECK_TOOL(MANIFEST_TOOL, mt, :) +test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt +AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_mainfest_tool], + [lt_cv_path_mainfest_tool=no + echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&AS_MESSAGE_LOG_FD + $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out + cat conftest.err >&AS_MESSAGE_LOG_FD + if $GREP 'Manifest Tool' conftest.out > /dev/null; then + lt_cv_path_mainfest_tool=yes + fi + rm -f conftest*]) +if test "x$lt_cv_path_mainfest_tool" != xyes; then + MANIFEST_TOOL=: +fi +_LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl +])# _LT_PATH_MANIFEST_TOOL + + # LT_LIB_M # -------- # check for math library @@ -4256,6 +4278,7 @@ _LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1], m4_defun([_LT_LINKER_SHLIBS], [AC_REQUIRE([LT_PATH_LD])dnl AC_REQUIRE([LT_PATH_NM])dnl +m4_require([_LT_PATH_MANIFEST_TOOL])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_DECL_SED])dnl @@ -4855,6 +4878,15 @@ _LT_EOF _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1,DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols' # Don't use ranlib _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' + _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ + case $lt_outputfile in + *.exe | *.EXE) ;; + *) lt_outputfile="$lt_outputfile.exe" ;; + esac~ + if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_outputfile.manifest" -outputresource:"$lt_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' ;; *) # Assume MSVC wrapper @@ -5408,6 +5440,8 @@ _LT_TAGDECL([], [include_expsyms], [1], [Symbols that must always be exported]) _LT_TAGDECL([], [prelink_cmds], [2], [Commands necessary for linking programs (against libraries) with templates]) +_LT_TAGDECL([], [postlink_cmds], [2], + [Commands necessary for finishing linking programs]) _LT_TAGDECL([], [file_list_spec], [1], [Specify filename containing input files]) dnl FIXME: Not yet implemented @@ -5509,6 +5543,7 @@ CC="$lt_save_CC" m4_defun([_LT_LANG_CXX_CONFIG], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_PATH_MANIFEST_TOOL])dnl if test -n "$CXX" && ( test "X$CXX" != "Xno" && ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || (test "X$CXX" != "Xg++"))) ; then @@ -5831,6 +5866,15 @@ if test "$_lt_caught_CXX_error" != yes; then _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes # Don't use ranlib _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' + _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ + case $lt_outputfile in + *.exe *.EXE) ;; + *) lt_outputfile="$lt_outputfile.exe" ;; + esac~ + if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_outputfile.manifest" -outputresource:"$lt_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' ;; *) # g++ diff --git a/tests/exeext.at b/tests/exeext.at new file mode 100644 index 00000000..ee5d7554 --- /dev/null +++ b/tests/exeext.at @@ -0,0 +1,53 @@ +# exeext.at -- ensure that exeext handling works -*- Autotest -*- +# +# Copyright (C) 2010 Free Software Foundation, Inc. +# Written by Peter Rosin +# +# 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. +#### + + +AT_SETUP([both of -o prog and -o prog$EXEEXT work]) +AT_KEYWORDS([libtool]) + +AT_CHECK([test -n "$EXEEXT" || exit 77]) + +bin=`pwd`/bin +binext=`pwd`/binext +mkdir src $bin srcext $binext + +AT_DATA(src/prog.c, +[[ +int main(void) { return 0; } +]]) + +$CC $CPPFLAGS $CFLAGS -c src/prog.c -o src/prog.$OBJEXT + +AT_CHECK($LIBTOOL --mode=link $CC $CFLAGS $LDFLAGS -o src/prog src/prog.$OBJEXT, + [0], [ignore], [ignore]) +AT_CHECK($LIBTOOL --mode=link $CC $CFLAGS $LDFLAGS -o srcext/prog$EXEEXT src/prog.$OBJEXT, + [0], [ignore], [ignore]) + +$LIBTOOL --mode=install cp src/prog $bin/prog +$LIBTOOL --mode=install cp srcext/prog$EXEEXT $binext/prog$EXEEXT + +LT_AT_EXEC_CHECK([$bin/prog]) +LT_AT_EXEC_CHECK([$binext/prog$EXEEXT]) + +AT_CLEANUP