# clang on Windows detected with MSVC interface

**URL:** <https://discourse.cmake.org/t/clang-on-windows-detected-with-msvc-interface/3470>\
**Category:** Usage\
**Created:** [June 2, 2021, 6:01pm UTC](https://discourse.cmake.org/t/clang-on-windows-detected-with-msvc-interface/3470 "2021-06-02T18:01:20Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![vallant](https://discourse.cmake.org/user_avatar/discourse.cmake.org/vallant/32/1503_2.png) [@vallant](https://discourse.cmake.org/u/vallant)\
**Post date:** [June 2, 2021, 6:01pm UTC](https://discourse.cmake.org/t/clang-on-windows-detected-with-msvc-interface/3470/1 "2021-06-02T18:01:21Z")

</div>

Hello,  
i try to compile a program on windows with ninja using clang++ (_not_ clang-cl), in order to be able to use the same flags as on macOS and simplify the cmake scripts.  
However i encountered some strange behaviour, it seems like clang++ is detected having a MSVC-compatible interface. I ran some tests to understand the information better:

```auto
cmake .. -G "Visual Studio 16 2019"
CMAKE_CXX_COMPILER_ID: MSVC
CMAKE_CXX_SIMULATE_ID:
CMAKE_CXX_COMPILER_FRONTEND_VARIANT:

cmake .. -G "Visual Studio 16 2019" -T ClangCL
CMAKE_CXX_COMPILER_ID: Clang
CMAKE_CXX_SIMULATE_ID: MSVC
CMAKE_CXX_COMPILER_FRONTEND_VARIANT: MSVC

cmake .. -G Ninja -DCC="C:\Program Files\LLVM\bin\clang.exe" -DCXX="C:\Program Files\LLVM\bin\clang++.exe"
CMAKE_CXX_COMPILER_ID: Clang
CMAKE_CXX_SIMULATE_ID: MSVC
CMAKE_CXX_COMPILER_FRONTEND_VARIANT: GNU

cmake .. -G Ninja -DCC="C:\Program Files\LLVM\bin\clang-cl.exe" -DCXX="C:\Program Files\LLVM\bin\clang-cl.exe"
CMAKE_CXX_COMPILER_ID: Clang
CMAKE_CXX_SIMULATE_ID: MSVC
CMAKE_CXX_COMPILER_FRONTEND_VARIANT: GNU

```

Clang-cl that is shipped alongside VS2019 is reported, as expected, to be clang simulating MSVC with a MSVC frontent.  
However both clang and clang-cl shipped via the official LLVM reports to be Clang simulating MSVC (which clang actually isn’t), having a GNU interface (which clang-cl actually hasn’t).  
How does one distinguish between clang-cl and clang given this situation?  
Thank you, Stephan

---

<div class="post-metadata">

**Author:** ![brad.king](https://discourse.cmake.org/user_avatar/discourse.cmake.org/brad.king/32/11_2.png) [@brad.king](https://discourse.cmake.org/u/brad.king)\
**Post date:** [June 3, 2021, 10:35am UTC](https://discourse.cmake.org/t/clang-on-windows-detected-with-msvc-interface/3470/2 "2021-06-03T10:35:30Z")

</div>

> `-DCC="..." -DCXX="..."`

Those options will not set the compiler. `CC` and `CXX` are supported only as _environment_ variables to initialize the `CMAKE_C_COMPILER` and `CMAKE_CXX_COMPILER` CMake variables. What is the rest of the CMake output in each case? In particular, what are the lines

```auto
-- The C compiler identification is ...
...
-- Check for working C compiler: ...
...
-- The CXX compiler identification is ...
...
-- Check for working CXX compiler: ...

```

?

---

<div class="post-metadata">

**Author:** ![vallant](https://discourse.cmake.org/user_avatar/discourse.cmake.org/vallant/32/1503_2.png) [@vallant](https://discourse.cmake.org/u/vallant)\
**Post date:** [June 4, 2021, 8:34am UTC](https://discourse.cmake.org/t/clang-on-windows-detected-with-msvc-interface/3470/3 "2021-06-04T08:34:08Z")

</div>

Thanks for your reply, i re-run the commands using `-DCMAKE_C_COMPILER` instead of `-DCC`, these are the relevant output lines.  
It now indeed seems to distinguish between `CMAKE_CXX_COMPILER_FRONTEND_VARIANT: GNU` for  
`clang` and `CMAKE_CXX_COMPILER_FRONTEND_VARIANT: MSVC` for `clang-cl`.  
So I guess this is the variable that i should be looking at, right?

```auto
cmake .. -G "Visual Studio 16 2019"
-- Selecting Windows SDK version 10.0.18362.0 to target Windows 10.0.19042.
-- The C compiler identification is MSVC 19.28.29914.0
-- The CXX compiler identification is MSVC 19.28.29914.0
-- Check for working C compiler: C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Tools/MSVC/14.28.29910/bin/Hostx64/x64/cl.exe - skipped
-- Check for working CXX compiler: C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Tools/MSVC/14.28.29910/bin/Hostx64/x64/cl.exe - skipped
CMAKE_CXX_COMPILER_ID: MSVC
CMAKE_CXX_SIMULATE_ID:
CMAKE_CXX_COMPILER_FRONTEND_VARIANT:

cmake .. -G "Visual Studio 16 2019" -T ClangCL
-- Selecting Windows SDK version 10.0.18362.0 to target Windows 10.0.19042.
-- The C compiler identification is Clang 11.0.0 with MSVC-like command-line
-- The CXX compiler identification is Clang 11.0.0 with MSVC-like command-line
-- Check for working C compiler: C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Tools/Llvm/x64/bin/clang-cl.exe - skipped
-- Check for working CXX compiler: C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Tools/Llvm/x64/bin/clang-cl.exe - skipped
CMAKE_CXX_COMPILER_ID: Clang
CMAKE_CXX_SIMULATE_ID: MSVC
CMAKE_CXX_COMPILER_FRONTEND_VARIANT: MSVC

cmake .. -G Ninja -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang
-- The C compiler identification is Clang 12.0.0 with GNU-like command-line
-- The CXX compiler identification is Clang 12.0.0 with GNU-like command-line
-- Check for working C compiler: C:/Program Files/LLVM/bin/clang.exe - skipped
-- Check for working CXX compiler: C:/Program Files/LLVM/bin/clang.exe - skipped
CMAKE_CXX_COMPILER_ID: Clang
CMAKE_CXX_SIMULATE_ID: MSVC
CMAKE_CXX_COMPILER_FRONTEND_VARIANT: GNU

cmake .. -G Ninja -DCMAKE_C_COMPILER=clang-cl -DCMAKE_CXX_COMPILER=clang-cl
-- The C compiler identification is Clang 12.0.0 with MSVC-like command-line
-- The CXX compiler identification is Clang 12.0.0 with MSVC-like command-line
-- Check for working C compiler: C:/Program Files/LLVM/bin/clang-cl.exe - skipped
-- Check for working CXX compiler: C:/Program Files/LLVM/bin/clang-cl.exe - skipped
CMAKE_CXX_COMPILER_ID: Clang
CMAKE_CXX_SIMULATE_ID: MSVC
CMAKE_CXX_COMPILER_FRONTEND_VARIANT: MSVC

```

---

<div class="post-metadata">

**Author:** ![brad.king](https://discourse.cmake.org/user_avatar/discourse.cmake.org/brad.king/32/11_2.png) [@brad.king](https://discourse.cmake.org/u/brad.king)\
**Post date:** [June 4, 2021, 3:25pm UTC](https://discourse.cmake.org/t/clang-on-windows-detected-with-msvc-interface/3470/4 "2021-06-04T15:25:29Z")

</div>

> [@vallant](#):
>
> So I guess [`CMAKE_C_COMPILER`] is the variable that i should be looking at, right?

Yes.

---

<div class="post-metadata">

**Author:** ![vallant](https://discourse.cmake.org/user_avatar/discourse.cmake.org/vallant/32/1503_2.png) [@vallant](https://discourse.cmake.org/u/vallant)\
**Post date:** [June 4, 2021, 4:19pm UTC](https://discourse.cmake.org/t/clang-on-windows-detected-with-msvc-interface/3470/5 "2021-06-04T16:19:36Z")

</div>

Thanks for your help, the compiler is now identified correctly, but i’m struggeling with the linker now.  
It fails because of missing symbols:  
`lld-link: error: <root>: undefined symbol: mainCRTStartup`  
From what i understand this means that the windows runtime isn’t linked correctly.  
I would assume that `CMAKE_MSVC_RUNTIME_LIBRARY` is the variable i want to look at, but none of the possible values led to correct linking. Changing the `CMAKE_BUILD_TYPE` didn’t help either.  
Is there another option that is needed for this setup?

```auto
cmake .. -G Ninja -D CMAKE_C_COMPILER=clang -D CMAKE_CXX_COMPILER=clang++
-- The C compiler identification is Clang 12.0.0 with GNU-like command-line
-- The CXX compiler identification is Clang 12.0.0 with GNU-like command-line
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - failed
-- Check for working C compiler: C:/Program Files/LLVM/bin/clang.exe
-- Check for working C compiler: C:/Program Files/LLVM/bin/clang.exe - broken
...

    Run Build Command(s):C:/ProgramData/chocolatey/bin/ninja.exe cmTC_3fdcc && [1/2] Building C object CMakeFiles/cmTC_3fdcc.dir/testCCompiler.c.obj
    [2/2] Linking C executable cmTC_3fdcc.exe
    FAILED: cmTC_3fdcc.exe
    cmd.exe /C "cd . && C:\PROGRA~1\LLVM\bin\clang.exe -fuse-ld=lld-link -nostartfiles -nostdlib -g -Xclang -gcodeview -O0 -D_DEBUG -D_DLL -D_MT -XAlso clang --dependent-lib=msvcrtd -fuse-ld=lld-link -Xlinker /subsystem:console CMakeFiles/cmTC_3fdcc.dir/testCCompiler.c.obj -o cmTC_3fdcc.exe -Xlinker /implib:cmTC_3fdcc.lib -Xlinker /pdb:cmTC_3fdcc.pdb -Xlinker /version:0.0 -lkernel32 -luser32 -lgdi32 -lwinspool -lshell32 -lole32 -loleaut32 -luuid -lcomdlg32 -ladvapi32 -loldnames && cd ."
    lld-link: error: <root>: undefined symbol: mainCRTStartup
    clang: error: linker command failed with exit code 1 (use -v to see invocation)
    ninja: build stopped: subcommand failed.

```

---

<div class="post-metadata">

**Author:** ![brad.king](https://discourse.cmake.org/user_avatar/discourse.cmake.org/brad.king/32/11_2.png) [@brad.king](https://discourse.cmake.org/u/brad.king)\
**Post date:** [June 4, 2021, 4:49pm UTC](https://discourse.cmake.org/t/clang-on-windows-detected-with-msvc-interface/3470/6 "2021-06-04T16:49:53Z")

</div>

The default `CMAKE_MSVC_RUNTIME_LIBRARY` should work fine. We do have nightly testing for the GNU-like Clang compiler with the MSVC ABI. Please be sure you are using a fresh/empty build directory and not trying to change the compiler in an existing directory.

---

<div class="post-metadata">

**Author:** ![teajay-fr](https://discourse.cmake.org/user_avatar/discourse.cmake.org/teajay-fr/32/1526_2.png) [@teajay-fr](https://discourse.cmake.org/u/teajay-fr)\
**Post date:** [June 6, 2021, 8:43pm UTC](https://discourse.cmake.org/t/clang-on-windows-detected-with-msvc-interface/3470/7 "2021-06-06T20:43:08Z")

</div>

I’ll try to reproduce this situation on a windows machine. As Brad mentioned, some test run checks for this case and they seem to work…

---

<div class="post-metadata">

**Author:** ![vallant](https://discourse.cmake.org/user_avatar/discourse.cmake.org/vallant/32/1503_2.png) [@vallant](https://discourse.cmake.org/u/vallant)\
**Post date:** [June 7, 2021, 6:49am UTC](https://discourse.cmake.org/t/clang-on-windows-detected-with-msvc-interface/3470/8 "2021-06-07T06:49:05Z")

</div>

Of course I’ve run the commands with a clean directory, i’ve even just re-installed visual studio with no success.  
For the reference: I’m using CMake 3.20.3, LLVM 12.0 (both installed via chocolatey), and Visual Studio Community 2019 Version 16.10.0 on Windows 10 Pro 21H1 (build 19043.985).  
Thanks for checking this out!

---

<div class="post-metadata">

**Author:** ![teajay-fr](https://discourse.cmake.org/user_avatar/discourse.cmake.org/teajay-fr/32/1526_2.png) [@teajay-fr](https://discourse.cmake.org/u/teajay-fr)\
**Post date:** [June 11, 2021, 4:24am UTC](https://discourse.cmake.org/t/clang-on-windows-detected-with-msvc-interface/3470/9 "2021-06-11T04:24:28Z")

</div>

I used the windows development evaluation vm and once the tools setup, I ran inside a vs native development console the following:

`C:\Users\User\Documents\Test\build>cmake -G Ninja -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ .. -- The C compiler identification is Clang 12.0.0 with GNU-like command-line -- The CXX compiler identification is Clang 12.0.0 with GNU-like command-line -- Detecting C compiler ABI info -- Detecting C compiler ABI info - done -- Check for working C compiler: c:/Program Files/LLVM/bin/clang.exe - skipped -- Detecting C compile features -- Detecting C compile features - done -- Detecting CXX compiler ABI info -- Detecting CXX compiler ABI info - done -- Check for working CXX compiler: c:/Program Files/LLVM/bin/clang++.exe - skipped -- Detecting CXX compile features -- Detecting CXX compile features - done -- Configuring done -- Generating done -- Build files have been written to: C:/Users/User/Documents/Test/build`

There must be something causing the failure on your setup.  
Are you sure, you used the development environment command prompt ?  
If it still fails, could you send the output of the command:  
`cmake -G Ninja -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ --trace ..`

---

<div class="post-metadata">

**Author:** ![barcharcraz](https://discourse.cmake.org/user_avatar/discourse.cmake.org/barcharcraz/32/1558_2.png) [@barcharcraz](https://discourse.cmake.org/u/barcharcraz)\
**Post date:** [June 14, 2021, 5:11am UTC](https://discourse.cmake.org/t/clang-on-windows-detected-with-msvc-interface/3470/10 "2021-06-14T05:11:50Z")

</div>

fwiw I use -Xclang when setting my options on clang through cmake, that works on both clang-cl and clang++, and will be a clang option on both. This doesn’t work with some options, for some reason.

In particular you _must_ do this when setting `-Wall -Wextra ...` with clang, since if you don’t then on windows clang-cl will translate `-Wall` to `/Wall` which it implements as `-Weverything`, probably not what you had in mind.

---

<div class="post-metadata">

**Author:** ![vallant](https://discourse.cmake.org/user_avatar/discourse.cmake.org/vallant/32/1503_2.png) [@vallant](https://discourse.cmake.org/u/vallant)\
**Post date:** [June 15, 2021, 10:07am UTC](https://discourse.cmake.org/t/clang-on-windows-detected-with-msvc-interface/3470/11 "2021-06-15T10:07:25Z")

</div>

Ah, now i noticed something.  
I’ve been using the developer powershell. It seems like this was configured for x86, and failed to invoke the compiler with the error that i’ve posted before.  
I get the same behaviour using the `x86 Native Tools Command Prompt for VS 2019`.  
If i use the `x64 Native Tools Command Prompt for VS 2019`, the compiler check indeed passes!  
Thank you for your help!

---

<div class="post-metadata">

**Author:** ![klirichek](https://discourse.cmake.org/user_avatar/discourse.cmake.org/klirichek/32/1657_2.png) [@klirichek](https://discourse.cmake.org/u/klirichek)\
**Post date:** [July 23, 2021, 6:05am UTC](https://discourse.cmake.org/t/clang-on-windows-detected-with-msvc-interface/3470/12 "2021-07-23T06:05:20Z")

</div>

Unfortunately with `-Wall` it doesn’t work on clang-cl.  
`-Xclang -Wall` is transformed into `/Wall` and orphaned `-Xclang` there. Other options, like `-Xclang -Wextra` is passed as is (however, implies deduplication, like `"SHELL:-Xclang -Wextra"`).  
`/clang:-Wall`, however, works. But it is clang-cl specific and is not suitable as GNU clang/clang++ param.  
So, `-Wall` is anyway needs special massaging like `if()` branching with `CMAKE_CXX_COMPILER_FRONTEND_VARIANT`, or testing it in GenEx (however, in last case it became testing of constant over constant, so, looks overenginered)
