conan
conan copied to clipboard
[bug] `AutotoolsDeps` is not suitable to Visual Studio
Environment details
- Operating System+version: Windows 11
- Compiler+version: Visual Studio 2022
- Conan version: 1.56.0
- Python version: 3.10.2
Steps to reproduce
- checkout https://github.com/SpaceIm/conan-center-index/tree/76a44f95038c2addd04b377deeb80627ce3c6180 (from https://github.com/conan-io/conan-center-index/pull/14792, it's the first attempt of a conan v2 migration of a CCI recipe which uses Autotools AND AutotoolsDeps for msvc build).
- try to build with Visual Studio
config test fails because usual autotools wrapper scripts for cl don't understand /I & /LIBPATH, so they are passed as is. They expect to receive GNU like flags (-I & -L) and translate them to cl like flags, not the opposite. These wrappers can't be avoided in the case of https://github.com/conan-io/conan-center-index/pull/14792.
It comes from GNUDepsFlags in conan, but it can't be fixed naively because it seems that MesonDeps & PkgConfigDeps also rely on it.
I think that AutotoolsDeps should provide an argument to ask whether it should generate regular cl like options or gnu like options if compiler is msvc.
Or maybe these msvc flags can be passed but they are not properly quoted or something like that, I'm not sure.
Logs
configure:4077: /c/users/spaceim/.conan/data/xapian-core/1.4.19/_/_/build/cdb6fd543ab5677fd09e2c988f468d700c5445bc/src/compile cl -nologo -MD -O2 -Ob2 -FS -DNDEBUG /I/c/users/spaceim/.conan/data/zlib/1.2.13/_/_/package/5a61a86bb3e07ce4262c80e1510f9c05e9b6d48b/include /LIBPATH:/c/users/spaceim/.conan/data/zlib/1.2.13/_/_/package/5a61a86bb3e07ce4262c80e1510f9c05e9b6d48b/lib conftest.c zlib.lib >&5
cl : Command line warning D9024 : unrecognized source file type 'I:/c/users/spaceim/.conan/data/zlib/1.2.13/_/_/package/5a61a86bb3e07ce4262c80e1510f9c05e9b6d48b/include', object file assumed
cl : Command line warning D9024 : unrecognized source file type 'C:\Users\spaceim\.conan_short\e44064\1\bin\msys64\LIBPATH;C:\users\spaceim\.conan\data\zlib\1.2.13\_\_\package\5a61a86bb3e07ce4262c80e1510f9c05e9b6d48b\lib', object file assumed
conftest.c
LINK : fatal error LNK1181: cannot open input file 'I:\c\users\spaceim\.conan\data\zlib\1.2.13\_\_\package\5a61a86bb3e07ce4262c80e1510f9c05e9b6d48b\include.obj'
configure:4081: $? = 2
configure:4119: result: no
A workaround may be to use NMakeDeps instead of AutotoolsDeps when compiler is Visual Studio. Indeed variables populated by NMakeDeps are not specific to NMake, but cl & link executables.
A workaround may be to use NMakeDeps instead of AutotoolsDeps when compiler is Visual Studio. Indeed variables populated by NMakeDeps are not specific to NMake, but cl & link executables.
Well no it doesn't work. Here is the best workaround I've found: https://github.com/conan-io/conan-center-index/blob/693ddd87004ca7ee70500f992bb2a135179798c3/recipes/libgettext/all/conanfile.py#L152-L181
I have been investigating this, and it seems even more complex than expected.
The problem is not only the - or / flags prefix, but also autotools is creating compile lines with some specific order that is not evident to change, and that order does not work with the env-vars defined by AutotoolsDeps and cl (cl rejects/doesn't work with that order). I need to keep investigating, but AutotoolsDeps might result being not adequate for Windows-MSVC
I have been investigating this, and it seems even more complex than expected.
The problem is not only the
- or /flags prefix, but also autotools is creating compile lines with some specific order that is not evident to change, and that order does not work with the env-vars defined byAutotoolsDepsandcl(clrejects/doesn't work with that order). I need to keep investigating, butAutotoolsDepsmight result being not adequate for Windows-MSVC
From what I remember last time I looked into this - it was a potential interaction between two path converters:
-
The path converter in the compile wrapper https://github.com/autotools-mirror/automake/blob/master/lib/compile#L64-L74 - although I suspect this codepath only kicks in for
-I(https://github.com/autotools-mirror/automake/blob/master/lib/compile#L165-L168) - If I understand this correctly, the cl-wrapper script should be "okay" with flags that start with/I- it will just forward it "as is" -
The path converted by the mys2 runtime, which affects arguments passed to processes: https://www.msys2.org/docs/filesystem-paths/ (the "Process Arguments" section). I suspect when msys2 sees
/I/c/users/xxx/.conan/data/zlib/yyy/include, it thinks it's a path and interprets the first/Ias something to be converted to a path in theI:/drive. But/Iis a flag, and what follows (without a space!) is the path, and that path does need to be converted toC:/format.
I think there's multiple potential solutions that are worth trying, but I think there were other potential issues.
- Passing
-I/c/users/xxx- I think that might prevent the msys2 converter, and then the cl wrapper will take care of the conversion - Passing
-IC:/users/xxor/IC:/- - Adding a space between
/Iand the path - then only the second part will be converted - Trying
MSYS2_ARG_CONV_EXCL=/Ishould prevent theI:/conversion, but I think that because the flag doesnt start with-I, then nobody will perform the path conversion.
This problem could be related to https://github.com/conan-io/conan-center-index/issues/23309. On the conan-center-index I am not able to build the ffmpeg on Windows with MSVC and Msys2. ffmpeg is applying the same workaround as reported in this PR.
The reason seems because PKG_CONFIG_PATH is not set and calling auto tools fails in resolving dependencies.
Another ticket that can be related is: https://github.com/conan-io/conan-center-index/issues/21694
@jcar87 it doesn't seem something related to the path conversions, but to the way that autotools creates the compiler command. From a file/env-var definition like:
export CPPFLAGS="$CPPFLAGS -I/c/users/memsharded/.conan2/p/b/mypkgc6939319c5d01/p/include"
export LIBS="$LIBS mypkg.lib"
export LDFLAGS="$LDFLAGS /LIBPATH:/c/users/memsharded/.conan2/p/b/mypkgc6939319c5d01/p/lib"
export CXXFLAGS="$CXXFLAGS"
export CFLAGS="$CFLAGS"
It is creating:
cl /std:c++14 -MD -O2 -Ob2 -FS -I/c/users/memsharded/.conan2/p/b/mypkgc6939319c5d01/p/include -DNDEBUG
/LIBPATH:/c/users/memsharded/.conan2/p/b/mypkgc6939319c5d01/p/lib conftest.cpp mypkg.lib >&5
But it should create something like:
cl /std:c++14 -MD -O2 -Ob2 -FS /IC:\Users\memsharded\.conan2\p\b\mypkgc6939319c5d01\p\include -DNDEBUG
test_package/main.cpp mypkg.lib /EHsc /link /LIBPATH:"c:\Users\memsharded\.conan2\p\b\mypkgc6939319c5d01\p\lib"
Note:
- use
/linkspecifier - put
LIBPATHafter/link - everything at the end of the
cl.execommand.
I am not sure if autotools is this smart, or how this can be tuned in autotools to achieve this behavior.
I have done some further research.
It seems that AutotoolsDeps for msvc will not work without the compile and ar-lib wrappers from automake.
I am checking how to implement this in Conan gnu integrations.