Not setting -fms-compatibility-version= when -fno-ms-compatibility is set

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

Not setting -fms-compatibility-version= when -fno-ms-compatibility is set

Hans Wennborg via cfe-dev
I'm trying to use Clang to cross-compile runtimes for Fuchsia on Windows. The problem I'm hitting is that CMake checks the existence of _MSC_VER macro, and if set it detects the compiler as "Clang with GNU-like command line" which is a special mode in which CMake treats clang as clang-cl. This breaks cross-compilation for runtimes because CMake no longer passes --target= flag even if CMAKE_*_COMPILER_TARGET is set, etc. because of this logic: https://github.com/Kitware/CMake/blob/master/Modules/Compiler/Clang.cmake#L13

This is IMHO a bug in CMake: it shouldn't blindly assume that Clang is clang-cl without first consulting other variables like CMAKE_*_COMPILER_TARGET or CMAKE_SYSTEM_NAME, but I'm not sure how easy or difficult would it be to change CMake, and even then we would have a problem with rolling out new CMake version everywhere.

So instead, I'm hoping to bypass CMake's detection and force it to treat Clang as clang (note that this is only for the purpose of cross-compilation) and to do so I need to unset _MSC_VER. Looking at the driver code, it seems like _MSC_VER is only defined if -fms-compatibility-version is set. I was hoping that setting -fno-ms-compatibility would do the trick, but it doesn't because -fms-compatibility-version is set independently of -f[no]-ms-compatibility: https://github.com/llvm/llvm-project/blob/69bf40c45fd7f6dfe11b47de42571d8bff5ef94f/clang/lib/Driver/ToolChains/Clang.cpp#L5395. When MSVC target is the default driver, -fms-compatibility-version is going to be set because https://github.com/llvm/llvm-project/blob/69bf40c45fd7f6dfe11b47de42571d8bff5ef94f/clang/lib/Driver/ToolChains/MSVC.cpp#L1320 returns a non-empty string, and AFAICT there's no way to disable it, which doesn't match the documentation: https://github.com/llvm/llvm-project/blob/69bf40c45fd7f6dfe11b47de42571d8bff5ef94f/clang/include/clang/Driver/Options.td#L1362

Does anyone know if this is intentional or just a bug? Would it make sense to change the driver to avoid setting -fms-compatibility-version when -fno-ms-compatibility is set?

_______________________________________________
cfe-dev mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: Not setting -fms-compatibility-version= when -fno-ms-compatibility is set

Hans Wennborg via cfe-dev
On Fri, 7 Feb 2020, Petr Hosek via cfe-dev wrote:

> I'm trying to use Clang to cross-compile runtimes for Fuchsia on Windows.
> The problem I'm hitting is that CMake checks the existence of _MSC_VER
> macro, and if set it detects the compiler as "Clang with GNU-like command
> line" which is a special mode in which CMake treats clang as clang-cl. This
> breaks cross-compilation for runtimes because CMake no longer passes
> --target= flag even if CMAKE_*_COMPILER_TARGET is set, etc. because of thislogic: https://github.com/Kitware/CMake/blob/master/Modules/Compiler/Clang.
> cmake#L13
> This is IMHO a bug in CMake: it shouldn't blindly assume that Clang is
> clang-cl without first consulting other variables
> like CMAKE_*_COMPILER_TARGET or CMAKE_SYSTEM_NAME, but I'm not sure how easy
> or difficult would it be to change CMake, and even then we would have a
> problem with rolling out new CMake version everywhere.
This sounds like an issue with how CMake does compiler identification in
mode advanced setups; I've often run into issues where I'd like to
configure with something like CMAKE_C_COMPILER=clang
CMAKE_C_FLAGS="-target <other-system-tuple>", but it first does all the
compiler identification steps only with ${CMAKE_C_COMPILER} in isolation.
This is much more straightforward with GCC like cross compilers, where one
would have CMAKE_C_COMPILER=<other-system-tuple>-gcc. For that case iirc I
managed it to behave correctly by using CMAKE_C_FLAGS_INIT="-target
<other-system-tuple>", which ensures that the flag is used along with
CMAKE_C_COMPILER even for the very first compiler identification steps.

However, I'm not very proficient with CMake, I'm just fumblingly trying to
make things work for me.

// Martin

_______________________________________________
cfe-dev mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: Not setting -fms-compatibility-version= when -fno-ms-compatibility is set

Hans Wennborg via cfe-dev
Passing --target= through CMAKE_*_FLAGS works, but it defeats the point of using CMAKE_*_COMPILER_TARGET, which feels more idiomatic.

After reading a bit more through CMake internals, I think I can workaround this by setting:

set(CMAKE_C_COMPILER_ID_RUN OFF)
set(CMAKE_CXX_COMPILER_ID_RUN OFF)
set(CMAKE_C_COMPILER_ID Clang)
set(CMAKE_CXX_COMPILER_ID Clang)

in the runtimes build, and then set:

set(CMAKE_C_SIMULATE_ID MSVC)
set(CMAKE_CXX_SIMULATE_ID MSVC)

when targeting *-pc-windows-msvc with Clang.

On Fri, Feb 7, 2020 at 2:26 PM Martin Storsjö <[hidden email]> wrote:
On Fri, 7 Feb 2020, Petr Hosek via cfe-dev wrote:

> I'm trying to use Clang to cross-compile runtimes for Fuchsia on Windows.
> The problem I'm hitting is that CMake checks the existence of _MSC_VER
> macro, and if set it detects the compiler as "Clang with GNU-like command
> line" which is a special mode in which CMake treats clang as clang-cl. This
> breaks cross-compilation for runtimes because CMake no longer passes
> --target= flag even if CMAKE_*_COMPILER_TARGET is set, etc. because of thislogic: https://github.com/Kitware/CMake/blob/master/Modules/Compiler/Clang.
> cmake#L13
> This is IMHO a bug in CMake: it shouldn't blindly assume that Clang is
> clang-cl without first consulting other variables
> like CMAKE_*_COMPILER_TARGET or CMAKE_SYSTEM_NAME, but I'm not sure how easy
> or difficult would it be to change CMake, and even then we would have a
> problem with rolling out new CMake version everywhere.

This sounds like an issue with how CMake does compiler identification in
mode advanced setups; I've often run into issues where I'd like to
configure with something like CMAKE_C_COMPILER=clang
CMAKE_C_FLAGS="-target <other-system-tuple>", but it first does all the
compiler identification steps only with ${CMAKE_C_COMPILER} in isolation.
This is much more straightforward with GCC like cross compilers, where one
would have CMAKE_C_COMPILER=<other-system-tuple>-gcc. For that case iirc I
managed it to behave correctly by using CMAKE_C_FLAGS_INIT="-target
<other-system-tuple>", which ensures that the flag is used along with
CMAKE_C_COMPILER even for the very first compiler identification steps.

However, I'm not very proficient with CMake, I'm just fumblingly trying to
make things work for me.

// Martin

_______________________________________________
cfe-dev mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev