bug-libtool
[Top][All Lists]
Advanced

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

Line endings on Windows with libtool.m4


From: Tom Bramer
Subject: Line endings on Windows with libtool.m4
Date: Wed, 03 Sep 2008 22:13:52 -0400
User-agent: Thunderbird 2.0.0.16 (Windows/20080708)

Hello,

I found an issue which I believe to be a bug, relating to line endings on Windows (like there hasn't been anything like this before). Some likely to be important details about the environment include:

OS: Windows XP
Script host: Cygwin (Bash 3.2.39(20))
Compiler toolchain: GCC 4.3.2 (unofficial mingw32 build as can be found at http://www.tdragon.net/recentgcc/).
Libtool version: 1.5.27a-1 (perhaps a Cygwin patched version?).
Autoconf version: 2.61

The problem:

During the detection of compiler-added object files and libraries (for the runtime), libtool fails to detect an object in the compiler/linker verbose output if :
1.) The system is Windows (of course).
2.) The object in the output is the last token in the output.

This seems to be because there is a trailing '\015' character in the last token, as it's the end of a line, which is terminated with CRLF in this case. The pattern *.o (*.$objext) will not match such arguments, causing it to be ignored.

The part of libtool.m4 the above pertains to:

======================================================================================
dnl Parse the compiler output and extract the necessary
dnl objects, libraries and library flags.
if AC_TRY_EVAL(ac_compile); then
 # Parse the compiler output and extract the necessary
 # objects, libraries and library flags.

 # Sentinel used to keep track of whether or not we are before
 # the conftest object file.
 pre_test_object_deps_done=no

 # The `*' in the case matches for architectures that use `case' in
 # $output_verbose_cmd can trigger glob expansion during the loop
 # eval without this substitution.
output_verbose_link_cmd=`$echo "X$output_verbose_link_cmd" | $Xsed -e "$no_glob_subst"`

 for p in `eval $output_verbose_link_cmd`; do
   case $p in

   -L* | -R* | -l*)
      # Some compilers place space between "-{L,R}" and the path.
      # Remove the space.
      if test $p = "-L" \
     || test $p = "-R"; then
    prev=$p
    continue
      else
    prev=
      fi

      if test "$pre_test_object_deps_done" = no; then
    case $p in
    -L* | -R*)
      # Internal compiler library paths should come after those
      # provided the user.  The postdeps already come after the
      # user supplied libs so there is no need to process them.
      if test -z "$_LT_AC_TAGVAR(compiler_lib_search_path, $1)"; then
        _LT_AC_TAGVAR(compiler_lib_search_path, $1)="${prev}${p}"
      else
_LT_AC_TAGVAR(compiler_lib_search_path, $1)="${_LT_AC_TAGVAR(compiler_lib_search_path, $1)} ${prev}${p}"
      fi
      ;;
    # The "-l" case would never come before the object being
    # linked, so don't bother handling this case.
    esac
      else
    if test -z "$_LT_AC_TAGVAR(postdeps, $1)"; then
      _LT_AC_TAGVAR(postdeps, $1)="${prev}${p}"
    else
_LT_AC_TAGVAR(postdeps, $1)="${_LT_AC_TAGVAR(postdeps, $1)} ${prev}${p}"
    fi
      fi
      ;;

   *.$objext)
      # This assumes that the test object file only shows up
      # once in the compiler output.
      if test "$p" = "conftest.$objext"; then
    pre_test_object_deps_done=yes
    continue
      fi

      if test "$pre_test_object_deps_done" = no; then
    if test -z "$_LT_AC_TAGVAR(predep_objects, $1)"; then
      _LT_AC_TAGVAR(predep_objects, $1)="$p"
    else
_LT_AC_TAGVAR(predep_objects, $1)="$_LT_AC_TAGVAR(predep_objects, $1) $p"
    fi
      else
    if test -z "$_LT_AC_TAGVAR(postdep_objects, $1)"; then
      _LT_AC_TAGVAR(postdep_objects, $1)="$p"
    else
_LT_AC_TAGVAR(postdep_objects, $1)="$_LT_AC_TAGVAR(postdep_objects, $1) $p"
    fi
      fi
      ;;

   *) ;; # Ignore the rest.

   esac
 done

======================================================================================

The following is approximately the output from executing $output_verbose_link_cmd (approximately as I invoked it by hand, using a few of my actual object files, but it still illustrates the issue):

i686-pc-mingw32-g++ -v -shared -o libcrc.dll crc.o common.o

Using built-in specs.
Target: mingw32
Configured with: ../gcc-4.3.2/configure --prefix=/mingw --build=mingw32 --enable -languages=c,ada,c++,fortran,objc,obj-c++ --with-bugurl=http://www.tdragon.net/r ecentgcc/bugs.php --disable-nls --disable-win32-registry --enable-libgomp --disa ble-werror --enable-threads --disable-symvers --enable-cxx-flags='-fno-function- sections -fno-data-sections' --enable-fully-dynamic-string --enable-version-spec ific-runtime-libs --enable-sjlj-exceptions --with-pkgversion='4.3.2-tdm-1 for Mi
nGW'
Thread model: win32
gcc version 4.3.2 (4.3.2-tdm-1 for MinGW)
COMPILER_PATH=g:/mingw32-tdm/bin/../libexec/gcc/mingw32/4.3.2/;g:/mingw32-tdm/bi
n/../libexec/gcc/;g:/mingw32-tdm/bin/../lib/gcc/mingw32/4.3.2/../../../../mingw3
2/bin/
LIBRARY_PATH=g:/mingw32-tdm/bin/../lib/gcc/mingw32/4.3.2/;g:/mingw32-tdm/bin/../
lib/gcc/;g:/mingw32-tdm/bin/../lib/gcc/mingw32/4.3.2/../../../../mingw32/lib/;g:
/mingw32-tdm/bin/../lib/gcc/mingw32/4.3.2/../../../;/mingw/lib/
COLLECT_GCC_OPTIONS='-v' '-shared' '-o' 'libcrc.dll' '-mtune=i386'
g:/mingw32-tdm/bin/../libexec/gcc/mingw32/4.3.2/collect2.exe --shared -Bdynamic -e address@hidden -o libcrc.dll g:/mingw32-tdm/bin/../lib/gcc/mingw32/4. 3.2/../../../dllcrt2.o g:/mingw32-tdm/bin/../lib/gcc/mingw32/4.3.2/crtbegin.o -L g:/mingw32-tdm/bin/../lib/gcc/mingw32/4.3.2 -Lg:/mingw32-tdm/bin/../lib/gcc -Lg: /mingw32-tdm/bin/../lib/gcc/mingw32/4.3.2/../../../../mingw32/lib -Lg:/mingw32-t dm/bin/../lib/gcc/mingw32/4.3.2/../../.. -L/mingw/lib crc.o common.o -lstdc++ -l mingw32 -lgcc -lmoldname -lmingwex -lmsvcrt -luser32 -lkernel32 -ladvapi32 -lshe ll32 -lmingw32 -lgcc -lmoldname -lmingwex -lmsvcrt g:/mingw32-tdm/bin/../lib/gcc
/mingw32/4.3.2/crtend.o

Note the ..../crtend.o at the end. This is skipped, leaving postdep_objects empty, while predep_objects consisted of dllcrt2.o and crtbegin.o (full paths, as one would expect).
Placing:

remove_eolchars="tr -d \'\\r\\n\'"

before the parsing loop, and:

p=`echo $p | $remove_eolchars`

between "for p in `eval $output_verbose_link_cmd`; do" and "case $p in" resulted in having postdep_objects having the contents of "g:/mingw32-tdm/bin/../lib/gcc/mingw32/4.3.2/crtend.o", allowing my shared libraries to be linked properly.

Other not so useful or quite on topic (but interesting) information:
I don't think this is anything new (in terms of GCC on Windows and using libtool), however, this is the first time that it has caused noticeable issues with the functioning of the shared libraries for me. With the unofficial build of GCC and it's associated runtime for mingw32, an access violation occurs while executing code from the entry-point of the DLL (within a function by the name of __cxa_get_globals_fast), when crtend.o is not linked with the DLL. Interestingly, when this happens, the exception is trapped by API code, and LoadLibrary() returns NULL, with GetLastError also returning 0 (ERROR_SUCCESS).


Best Regards,
-- Tom





reply via email to

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