Subject: Re: bug#15831: Absolute library paths with Cygwin + MSVC cl

From: Peter Rosin <[email-masked]>
Date: Fri, 08 Nov 2013 15:46:53 +0100

On 2013-11-08 05:12, Tony Kelman wrote:
> Hi all,
> 
> I'm working with a set of projects that save their inter-dependencies in
> AC_SUBST variables as absolute paths to the relevant .la files. In Cygwin
> using the MSVC cl compiler and building only static libraries, I'm seeing
> libtool replace the Unix-style absolute path to .la files with the
> Unix-style absolute path to the corresponding .libs/<libname>.lib file.
> Unsurprisingly, the cl compiler doesn't understand the Unix-style path.
> If I modify the Makefile to add `cygpath -w ...` around the absolute path
> to the .la file, then libtool instead replaces the Windows-style absolute
> path to the .la file with just ./.libs/<libname>.lib, which isn't right
> since I'm in a different directory than that library was built in.
> 
> My test case here is the COIN-OR Open Solver Interface project
> (https://projects.coin-or.org/Osi/wiki) release 0.106.2, but updated to a
> recent set of autotools by svn switch'ing the BuildTools directory to
> https://projects.coin-or.org/BuildTools/browser/branches/autotools-update.
> The same behavior described below happens with the very old libtool
> (1.5.22) distributed with the release, but I updated to test whether the
> problem still exists in recent libtool. Started Cygwin (64-bit) from the
> "VS Command Prompt" to set the right environment variables, and configured
> Osi with --enable-doscompile=msvc to use cl compiler.
> 
> The problem comes at make test. With the Unix-style absolute path to the
> .la file in the variable OSILIB_LIBS, the problem invocation looks like:
> 
> /bin/sh ../libtool --tag=CXX -n -v  --mode=link cl  -MT -O2 -nologo -EHsc
>  -GR -wd4996 -D_CRT_SECURE_NO_DEPRECATE -DNDEBUG    -DOSI_BUILD   -o
>  unitTest.exe unitTest.obj OsiTestSolver.obj OsiTestSolverInterface.obj
>  OsiTestSolverInterfaceIO.obj OsiTestSolverInterfaceTest.obj
>  ../src/OsiCommonTest/libOsiCommonTests.la       ../src/Osi/libOsi.la
>  /home/Tony/Osi-0.106.2/build02/CoinUtils/src/libCoinUtils.la
> libtool: link: cl -MT -O2 -nologo -EHsc -GR -wd4996
>  -D_CRT_SECURE_NO_DEPRECATE -DNDEBUG -DOSI_BUILD -o unitTest.exe
>  unitTest.obj OsiTestSolver.obj OsiTestSolverInterface.obj
>  OsiTestSolverInterfaceIO.obj OsiTestSolverInterfaceTest.obj
>  ../src/OsiCommonTest/.libs/OsiCommonTests.lib ../src/Osi/.libs/Osi.lib
>  /home/Tony/Osi-0.106.2/build02/CoinUtils/src/.libs/libCoinUtils.lib
> libtool: link: lt_outputfile="unitTest.exe"
> libtool: link:  lt_tool_outputfile="unitTest.exe"
> libtool: link:  case  in *.exe|*.EXE) ;; *) lt_outputfile=".exe"
>  lt_tool_outputfile=".exe" ;; esac
> libtool: link:  func_to_tool_file ""
> libtool: link:  if test "mt" != ":" && test -f ".manifest"; then mt
>  -manifest ".manifest" -outputresource:"" || exit 1; rm -f ".manifest"; fi
> 
> If I take out -n from AM_LIBTOOLFLAGS then I get hundreds of unresolved
> externals to everything from libCoinUtils, since cl ignored the "unknown
> option" of the Unix-style absolute path to libCoinUtils.la.
> 
> Adding `cygpath -w ...` around the absolute path to libCoinUtils.la in the
> Osi/test/Makefile variable OSILIB_LIBS results in the following:
> 
> /bin/sh ../libtool --tag=CXX -v  --mode=link cl  -MT -O2 -nologo -EHsc
>  -GR -wd4996 -D_CRT_SECURE_NO_DEPRECATE -DNDEBUG    -DOSI_BUILD   -o
>  unitTest.exe unitTest.obj OsiTestSolver.obj OsiTestSolverInterface.obj
>  OsiTestSolverInterfaceIO.obj OsiTestSolverInterfaceTest.obj
>  ../src/OsiCommonTest/libOsiCommonTests.la       ../src/Osi/libOsi.la
>  `cygpath -w /home/Tony/Osi-0.106.2/build02/CoinUtils/src/libCoinUtils.la`
> libtool: link: cl -MT -O2 -nologo -EHsc -GR -wd4996
>  -D_CRT_SECURE_NO_DEPRECATE -DNDEBUG -DOSI_BUILD -o unitTest.exe
>  unitTest.obj OsiTestSolver.obj OsiTestSolverInterface.obj
>  OsiTestSolverInterfaceIO.obj OsiTestSolverInterfaceTest.obj
>  ../src/OsiCommonTest/.libs/OsiCommonTests.lib ../src/Osi/.libs/Osi.lib
>  ./.libs/libCoinUtils.lib
> cl : Command line warning D9035 : option 'o' has been deprecated and will
>  be removed in a future release
> LINK : fatal error LNK1181: cannot open input file './.libs/libCoinUtils.lib'
> libtool: link: lt_outputfile="unitTest.exe"
> libtool: link:  lt_tool_outputfile="unitTest.exe"
> libtool: link:  case unitTest.exe in *.exe|*.EXE) ;; *)
>  lt_outputfile="unitTest.exe.exe" lt_tool_outputfile="unitTest.exe.exe" ;; esac
> libtool: link:  func_to_tool_file "unitTest.exe"
> libtool: link:  if test "mt" != ":" && test -f "unitTest.exe.manifest";
>  then mt -manifest "unitTest.exe.manifest" -outputresource:"unitTest.exe"
>  || exit 1; rm -f "unitTest.exe.manifest"; fi
> Makefile:476: recipe for target 'unitTest.exe' failed
> make: *** [unitTest.exe] Error 2
> 
> Is this a bug in libtool, or am I doing something wrong/unsupported? MSYS
> works better here, but it would be ideal to be able to use Cygwin as well.
> 
> Relevant info from the end of libtool --help:
> 
> host-triplet:    x86_64-unknown-cygwin
> shell:        /bin/sh
> compiler:        cl
> compiler flags:        -MT -O2 -nologo -wd4996 -D_CRT_SECURE_NO_DEPRECATE -DNDEBUG
> linker:        link (gnu? no)
> libtool:    (GNU libtool) 2.4.2
> automake:
> autoconf:    autoconf (GNU Autoconf) 2.69
> 
> Automake was version 1.12, not sure why libtool didn't see that.
> 
> Appreciate any advice here, let me know if there's any more information I
> can provide that would be useful.

Using the terminology from [1], there are two options for building with
cl on Cygwin. You either fake it or you lie. I recommend faking it.

For that to have any chance to work with absolute file names, you have to
include lt_cv_to_tool_file_cmd=func_convert_file_cygwin_to_w32 as one of
your configure arguments (or do as [1] suggests and
   export lt_cv_to_tool_file_cmd=func_convert_file_cygwin_to_w32
but I prefer to add it as a configure arg, it is then preserved even if
the project happens to be reconfigured from some other environment w/o
that export).

If you instead lie, you also need
  lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32

It was not clear from your message if you had taken care of that detail?

Cheers,
Peter

[1] http://www.gnu.org/software/libtool/manual/html_node/Cygwin-to-MinGW-Cross.html