# How to determine if \`clang\` or \`clang-cl\` is used on Windows?

**URL:** <https://discourse.cmake.org/t/how-to-determine-if-clang-or-clang-cl-is-used-on-windows/4129>\
**Category:** Code\
**Created:** [September 21, 2021, 12:51pm UTC](https://discourse.cmake.org/t/how-to-determine-if-clang-or-clang-cl-is-used-on-windows/4129 "2021-09-21T12:51:38Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![dbahadir](https://discourse.cmake.org/user_avatar/discourse.cmake.org/dbahadir/32/197_2.png) [@dbahadir](https://discourse.cmake.org/u/dbahadir)\
**Post date:** [September 21, 2021, 12:51pm UTC](https://discourse.cmake.org/t/how-to-determine-if-clang-or-clang-cl-is-used-on-windows/4129/1 "2021-09-21T12:51:39Z")

</div>

Lately, I started developing more on Windows and I now want to determine if I am using `clang` or `clang-cl`?

While googling I became aware of `CMAKE_<LANG>_COMPILER_FRONTEND_VARIANT`. However, I am not finding any documentation about it.  
Is it a CMake-internal variable that should not be used by normal developers? Or is it just missing documentation?

If it is internal, is there some other established way to determine with which `<mode>` value (`cl`, `gcc`, `g++`) for the `--driver-mode=<mode>` option Clang was called?

---

<div class="post-metadata">

**Author:** ![ben.boeckel](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/b/ea5d25/32.png) [@ben.boeckel](https://discourse.cmake.org/u/ben.boeckel)\
**Post date:** [September 21, 2021, 1:10pm UTC](https://discourse.cmake.org/t/how-to-determine-if-clang-or-clang-cl-is-used-on-windows/4129/2 "2021-09-21T13:10:32Z")

</div>

I think you’re looking for [`CMAKE_<LANG>_SIMULATE_ID`](https://cmake.org/cmake/help/latest/variable/CMAKE_LANG_SIMULATE_ID.html).

---

<div class="post-metadata">

**Author:** ![dbahadir](https://discourse.cmake.org/user_avatar/discourse.cmake.org/dbahadir/32/197_2.png) [@dbahadir](https://discourse.cmake.org/u/dbahadir)\
**Post date:** [September 21, 2021, 2:36pm UTC](https://discourse.cmake.org/t/how-to-determine-if-clang-or-clang-cl-is-used-on-windows/4129/3 "2021-09-21T14:36:21Z")

</div>

Thanks, that probably really is the variable I am looking for.  
(I probably overlooked it because it did not contain the `COMPILER` keyword.)

Is `CMAKE_<LANG>_COMPILER_FRONTEND_VARIANT` therefore really only an internal variable that should not be used by `CMakeLists.txt` writers/developers?

---

<div class="post-metadata">

**Author:** ![ben.boeckel](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/b/ea5d25/32.png) [@ben.boeckel](https://discourse.cmake.org/u/ben.boeckel)\
**Post date:** [September 21, 2021, 3:14pm UTC](https://discourse.cmake.org/t/how-to-determine-if-clang-or-clang-cl-is-used-on-windows/4129/4 "2021-09-21T15:14:30Z")

</div>

Yeah, it seems to be internal AFAICT.

---

<div class="post-metadata">

**Author:** ![dbahadir](https://discourse.cmake.org/user_avatar/discourse.cmake.org/dbahadir/32/197_2.png) [@dbahadir](https://discourse.cmake.org/u/dbahadir)\
**Post date:** [September 22, 2021, 10:22am UTC](https://discourse.cmake.org/t/how-to-determine-if-clang-or-clang-cl-is-used-on-windows/4129/5 "2021-09-22T10:22:14Z")

</div>

Sadly, I realized that `CMAKE_<LANG>_SIMULATE_ID` is not really helpful.

Whether I use `clang` or `clang-cl` it always evaluates to `MSVC`.  
`CMAKE_<LANG>_COMPILER_FRONTEND_VARIANT` on the other hand only evaluates to `MSVC` if using `clang-cl` and to `GNU` for `clang`.

So what I really need to pass options to Clang with the correct format is `CMAKE_<LANG>_COMPILER_FRONTEND_VARIANT`.

Is there any reason, why that variable is supposed to be a CMake-internal one?

I would suggest to officially expose it to users and to provide proper documentation to both variables, because the documentation for `CMAKE_<LANG>_SIMULATE_ID` seems not to reflect what that variable really shows. (It seems more as if `CMAKE_<LANG>_SIMULATE_ID` determines if I am calling Clang from a Visual Studio prompt but not in what _driver-mode_ it is running.)

---

<div class="post-metadata">

**Author:** ![dbahadir](https://discourse.cmake.org/user_avatar/discourse.cmake.org/dbahadir/32/197_2.png) [@dbahadir](https://discourse.cmake.org/u/dbahadir)\
**Post date:** [September 22, 2021, 11:08am UTC](https://discourse.cmake.org/t/how-to-determine-if-clang-or-clang-cl-is-used-on-windows/4129/6 "2021-09-22T11:08:29Z")

</div>

I created an issue ([#22666](https://gitlab.kitware.com/cmake/cmake/-/issues/22666)) in CMake’s issue tracker that suggests to officially support `CMAKE_<LANG>_COMPILER_FRONTEND_VARIANT` by documenting it.

---

<div class="post-metadata">

**Author:** ![ClausKlein](https://discourse.cmake.org/user_avatar/discourse.cmake.org/clausklein/32/352_2.png) [@ClausKlein](https://discourse.cmake.org/u/ClausKlein)\
**Post date:** [September 25, 2021, 6:13pm UTC](https://discourse.cmake.org/t/how-to-determine-if-clang-or-clang-cl-is-used-on-windows/4129/7 "2021-09-25T18:13:56Z")

</div>

I found this, but I am not sure, if it works (I prefer to work on unix systems)  
see [ApprovalTests.cpp/WarningsAsErrors.cmake at master · approvals/ApprovalTests.cpp · GitHub](https://github.com/approvals/ApprovalTests.cpp/blob/master/CMake/WarningsAsErrors.cmake)

```cmake
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND CMAKE_CXX_SIMULATE_ID MATCHES "MSVC")
  target_compile_options(${PROJECT_NAME} PRIVATE /W4 /WX)
elseif(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
  target_compile_options(${PROJECT_NAME} PRIVATE -Wall -Wextra -Wpedantic -Werror -Wshadow)

  if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND CMAKE_CXX_COMPILER_VERSION GREATER_EQUAL 10.0)
    target_compile_options(${PROJECT_NAME} PRIVATE -Wdeprecated-copy-dtor -Wnewline-eof)
  endif()
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
  string(REGEX REPLACE " /W[0-4]" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
  target_compile_options(${PROJECT_NAME} PRIVATE /W4 /WX)
endif()

```

---

<div class="post-metadata">

**Author:** ![dbahadir](https://discourse.cmake.org/user_avatar/discourse.cmake.org/dbahadir/32/197_2.png) [@dbahadir](https://discourse.cmake.org/u/dbahadir)\
**Post date:** [September 27, 2021, 2:56pm UTC](https://discourse.cmake.org/t/how-to-determine-if-clang-or-clang-cl-is-used-on-windows/4129/8 "2021-09-27T14:56:36Z")

</div>

No, sadly this will fail if `clang` or `clang++` (and not `clang-cl`) is used on Windows (unless probably used from Cygwin/MSYS2 environment).

---

<div class="post-metadata">

**Author:** ![fdk17](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/f/ea666f/32.png) [@fdk17](https://discourse.cmake.org/u/fdk17)\
**Post date:** [September 27, 2021, 3:25pm UTC](https://discourse.cmake.org/t/how-to-determine-if-clang-or-clang-cl-is-used-on-windows/4129/9 "2021-09-27T15:25:19Z")

</div>

Is there something wrong with just checking the executable name `CMAKE_<LANG>_COMPILER`?

The basic `CMAKE_<LANG>_COMPILER_FRONTEND_VARIANT` test looks like:

```auto
        # Test whether an MSVC-like command-line option works.
        execute_process(COMMAND "${CMAKE_${lang}_COMPILER}" -?
          RESULT_VARIABLE _clang_result
          OUTPUT_VARIABLE _clang_stdout
          ERROR_VARIABLE _clang_stderr)
        if(_clang_result EQUAL 0)
          set(CMAKE_${lang}_COMPILER_FRONTEND_VARIANT "MSVC")
        else()
          set(CMAKE_${lang}_COMPILER_FRONTEND_VARIANT "GNU")
        endif()

```

You probably could test `-?` is usable with `CheckCompilerFlag`.  
Or you could see what the default build flags look like to judge which frontend is being used.

If it were me I’d probably just use `CMAKE_<LANG>_COMPILER_FRONTEND_VARIANT` while checking that it is defined and either `MSVC` or `GNU` in case something about CMake changes. You could always propose a patch to document and test the variable.

---

<div class="post-metadata">

**Author:** ![williamr](https://discourse.cmake.org/user_avatar/discourse.cmake.org/williamr/32/1238_2.png) [@williamr](https://discourse.cmake.org/u/williamr)\
**Post date:** [September 27, 2021, 7:25pm UTC](https://discourse.cmake.org/t/how-to-determine-if-clang-or-clang-cl-is-used-on-windows/4129/10 "2021-09-27T19:25:25Z")

</div>

`CMAKE_<LANG>_SIMULATE_ID` is telling what kind of ABI compatibility the generated code will have, whereas `CMAKE_<LANG>_COMPILER_FONTEND_VARIANT` describes what command line options and language extensions the compiler frontend expects.

The `clang` on Windows you are using has `CMAKE_CXX_SIMULATE_ID` = `MSVC` and will generate code that can link with code generated by other MSVC compilers, like Visual Studio. Since, `clang`'s `CMAKE_CXX_COMPILER_FRONTEND_VARIANT` is `GNU` it will take the gnu-style command line options.

As you have observed, when `CMAKE_CXX_COMPILER_FRONTEND_VARIANT` is `MSVC` the compiler takes the MSVC compatible options.
