# Cannot build with vanilla clang on windows

**URL:** <https://forum.juce.com/t/cannot-build-with-vanilla-clang-on-windows/46299>\
**Category:** CMake\
**Created:** [June 2, 2021, 9:54am UTC](https://forum.juce.com/t/cannot-build-with-vanilla-clang-on-windows/46299 "2021-06-02T09:54:55Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![vallant](https://avatars.discourse-cdn.com/v4/letter/v/c57346/32.png) [@vallant](https://forum.juce.com/u/vallant)\
**Post date:** [June 2, 2021, 9:54am UTC](https://forum.juce.com/t/cannot-build-with-vanilla-clang-on-windows/46299/1 "2021-06-02T09:54:55Z")

</div>

I’m trying to build a CMake JUCE project using Ninja with clang (_not_ clang-cl), with LLVM 12 on Windows.  
While clang-cl does work, i’d like to unify the compiler flags between MacOS and Windows.  
However, the building of juceaide fails, it seems like it tries to compile something with MSVC compiler flags.  
This happens with the current juce-develop tip (commit 3fd4f7a2315ea05eabd1551e6603eb4fae17cdc4).

Error message:

```auto
-- 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
-- Configuring juceaide
-- Building juceaide
CMake Error at extras/Build/juceaide/CMakeLists.txt:86 (message):
  Failed to build juceaide

  [0/2] Re-checking globbed directories...

  [1/8] Building CXX object
  extras/Build/juceaide/CMakeFiles/juceaide.dir/Main.cpp.obj

  FAILED: extras/Build/juceaide/CMakeFiles/juceaide.dir/Main.cpp.obj

  C:\PROGRA~1\LLVM\bin\CLANG_~1.EXE -DDEBUG=1
  -DJUCE_DISABLE_JUCE_VERSION_PRINTING=1
  -DJUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1
  -DJUCE_MODULE_AVAILABLE_juce_build_tools=1
  -DJUCE_MODULE_AVAILABLE_juce_core=1
  -DJUCE_MODULE_AVAILABLE_juce_data_structures=1
  -DJUCE_MODULE_AVAILABLE_juce_events=1
  -DJUCE_MODULE_AVAILABLE_juce_graphics=1
  -DJUCE_MODULE_AVAILABLE_juce_gui_basics=1 -DJUCE_STANDALONE_APPLICATION=1
  -DJUCE_USE_CURL=0 -D_CONSOLE=1 -D_DEBUG=1
  -Iextras/Build/juceaide/juceaide_artefacts/JuceLibraryCode
  -I../../extras/Build -I../../modules /bigobj /Od /EHsc /W4 -MD -MT
  extras/Build/juceaide/CMakeFiles/juceaide.dir/Main.cpp.obj -MF
  extras\Build\juceaide\CMakeFiles\juceaide.dir\Main.cpp.obj.d -o
  extras/Build/juceaide/CMakeFiles/juceaide.dir/Main.cpp.obj -c
  ../../extras/Build/juceaide/Main.cpp

  CLANG_~1: error: no such file or directory: '/bigobj'

  CLANG_~1: error: no such file or directory: '/Od'

  CLANG_~1: error: no such file or directory: '/EHsc'

  CLANG_~1: error: no such file or directory: '/W4'

```

Steps to reproduce:

```auto
git clone git@github.com:juce-framework/JUCE.git
mkdir JUCE/build && cd JUCE/build
cmake .. -G Ninja -DCC="C:\Program Files\LLVM\bin\clang.exe" -DCXX="C:\Program Files\LLVM\bin\clang++.exe"

```

Is there any way around this, or am i missing something?

---

<div class="post-metadata">

**Author:** ![reuk](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/reuk/32/21494_2.png) [@reuk](https://forum.juce.com/u/reuk)\
**Post date:** [June 2, 2021, 2:18pm UTC](https://forum.juce.com/t/cannot-build-with-vanilla-clang-on-windows/46299/2 "2021-06-02T14:18:29Z")

</div>

I can reproduce the issue, but I’m not sure why it’s happening. It seems that the `CMAKE_CXX_COMPILER_ID` is set to `MSVC` even for Clang 11 with GNU-like command-line, at least with CMake 3.20. There’s not a great deal of documentation for `CMAKE_CXX_COMPILER_ID` so it’s not clear what the expected behaviour should be in this case, or whether there’s a recommended way of checking for Clang variants on Windows. I suspect that the meaning of “drop in replacement” in [the docs](https://cmake.org/cmake/help/v3.15/variable/CMAKE_LANG_SIMULATE_ID.html) refers to ABI, rather than to the commandline interface.

There’s also `CMAKE_CXX_COMPILER_FRONTEND_VARIANT` which is set to `GNU` in the case above, but this has even less documentation than `CMAKE_CXX_COMPILER_ID` so I’m not sure whether it’s alright to depend on it.

---

<div class="post-metadata">

**Author:** ![vallant](https://avatars.discourse-cdn.com/v4/letter/v/c57346/32.png) [@vallant](https://forum.juce.com/u/vallant)\
**Post date:** [June 2, 2021, 3:38pm UTC](https://forum.juce.com/t/cannot-build-with-vanilla-clang-on-windows/46299/3 "2021-06-02T15:38:16Z")

</div>

So i just tested the behaviour of `CMAKE_CXX_COMPILER_ID` and `CMAKE_CXX_SIMULATE_ID` on my machine, with the following result:

```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

```

This almost seems like a bug in CMake, clang.exe shouldn’t report any `CMAKE_CXX_SIMULATE_ID`, otherwise how should one distinguish between the two!

---

<div class="post-metadata">

**Author:** ![mcmartin](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/mcmartin/32/7432_2.png) [@mcmartin](https://forum.juce.com/u/mcmartin)\
**Post date:** [June 3, 2021, 8:18pm UTC](https://forum.juce.com/t/cannot-build-with-vanilla-clang-on-windows/46299/4 "2021-06-03T20:18:57Z")

</div>

Quoting [a comment from a CMake issue](https://gitlab.kitware.com/cmake/cmake/-/issues/22022#note_934156):

> Clang has two front-ends that both simulate MSVC (define `_MSC_VER` ): The MSVC-like front-end `clang-cl` and the GNU-like front-end `clang` / `clang++` .

i.e. `CMAKE_CXX_SIMULATE_ID` would mean “define `_MSC_VER`”, and not “can handle MSVC compiler flags”.

If this is correct, then the JUCE code needs to be adapted.

---

<div class="post-metadata">

**Author:** ![reuk](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/reuk/32/21494_2.png) [@reuk](https://forum.juce.com/u/reuk)\
**Post date:** [June 3, 2021, 8:42pm UTC](https://forum.juce.com/t/cannot-build-with-vanilla-clang-on-windows/46299/5 "2021-06-03T20:42:02Z")

</div>

Thanks to both of you for the extra information. I’ve pushed this change which substitutes `CMAKE_CXX_SIMULATE_ID` for `CMAKE_CXX_COMPILER_FRONTEND_VARIANT`.

> <https://github.com/juce-framework/JUCE/commit/db2a809832ed50a34ce08e7090486cecca6eb4da>

---

<div class="post-metadata">

**Author:** ![rafa1981](https://avatars.discourse-cdn.com/v4/letter/r/8dc957/32.png) [@rafa1981](https://forum.juce.com/u/rafa1981)\
**Post date:** [June 4, 2021, 6:25am UTC](https://forum.juce.com/t/cannot-build-with-vanilla-clang-on-windows/46299/6 "2021-06-04T06:25:53Z")

</div>

Notice that you can pass GNU flags to clang-cl. I took that approach. I will post my workaround the in case you don’t want to maintain own patches or use bleeding edge CMake.

---

<div class="post-metadata">

**Author:** ![rafa1981](https://avatars.discourse-cdn.com/v4/letter/r/8dc957/32.png) [@rafa1981](https://forum.juce.com/u/rafa1981)\
**Post date:** [June 4, 2021, 7:19am UTC](https://forum.juce.com/t/cannot-build-with-vanilla-clang-on-windows/46299/7 "2021-06-04T07:19:16Z")

</div>

This is a reduced example of how I’m doing:

```auto
cmake_minimum_required(VERSION 3.12.0)

...

if ("${CMAKE_BUILD_TYPE}" MATCHES "Release")
    set (ARTV_DSP_COMPILE_OPTIONS -O2 -ffast-math -ftree-vectorize -msse2)
    set (ARTV_PLAIN_COMPILE_OPTIONS -Os)
else()
    set (ARTV_DSP_COMPILE_OPTIONS -Wall)
    set (ARTV_PLAIN_COMPILE_OPTIONS -Wall)
endif()

if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
    if (CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "MSVC")
        list (TRANSFORM ARTV_DSP_COMPILE_OPTIONS PREPEND "/clang:")
        list (TRANSFORM ARTV_PLAIN_COMPILE_OPTIONS PREPEND "/clang:")
    endif()
endif()

add_library (plain_target_compile_options INTERFACE)
add_library (dsp_target_compile_options INTERFACE)

target_compile_options(
    plain_target_compile_options INTERFACE ${ARTV_PLAIN_COMPILE_OPTIONS}
    )
target_compile_options(
    dsp_target_compile_options INTERFACE ${ARTV_DSP_COMPILE_OPTIONS}
    )

```

This approach is using clang-cl and linking my libraries with interface libraries that provide the compile flags. This way:

- Projects with old CMakeLists that automatically consider Windows-\>MSVC still keep working. Not everyone is so fast to patch as JUCE. It is rare at this point of time for imported projects to work right with GNU flags on Windows.
- The global build flags are not modified. This allows imported projects to keep working normally (e.g. some require no ffast-math). Notice “/clang:-flag” flags are of higher precedence than those passed through the CL frontend. The compiler flag interface libraries have to be linked as the last one.

I don’t know if there is a better way of doing this.

---

<div class="post-metadata">

**Author:** ![vallant](https://avatars.discourse-cdn.com/v4/letter/v/c57346/32.png) [@vallant](https://forum.juce.com/u/vallant)\
**Post date:** [June 4, 2021, 11:28am UTC](https://forum.juce.com/t/cannot-build-with-vanilla-clang-on-windows/46299/8 "2021-06-04T11:28:16Z")

</div>

Awesome!  
I actually realized that i was using the wrong variables to change to compiler, and indeed the `FRONTEND_VARIANT` seems to be the correct switch:

```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

```

I’m still fighting with the linker, but this is a different story i guess 😉  
Thank you for the quick fix!

---

<div class="post-metadata">

**Author:** ![reuk](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/reuk/32/21494_2.png) [@reuk](https://forum.juce.com/u/reuk)\
**Post date:** [June 4, 2021, 11:31am UTC](https://forum.juce.com/t/cannot-build-with-vanilla-clang-on-windows/46299/9 "2021-06-04T11:31:56Z")

</div>

What linker problems are you having? I’m currently setting up clang with gnu-command-line on our CI system and it looks like clang’s LTO is incompatible with the MSVC linker. I’m working around this by passing `-D CMAKE_CXX_FLAGS=-fuse-ld=lld-link.exe`, which allows Release builds with LTO to link successfully.

---

<div class="post-metadata">

**Author:** ![vallant](https://avatars.discourse-cdn.com/v4/letter/v/c57346/32.png) [@vallant](https://forum.juce.com/u/vallant)\
**Post date:** [June 4, 2021, 12:28pm UTC](https://forum.juce.com/t/cannot-build-with-vanilla-clang-on-windows/46299/10 "2021-06-04T12:28:43Z")

</div>

Currently i’m using the VS2019 developer powershell, because otherwise some of the libraries (`oldnames.lib` and `msvcrtd.lib` to be specific) weren’t found, but this is just a search-path issue i guess.  
The libs are found correctly in the dev-powershell, but the linker still encounters undefined symbols.  
Did you encounter anything similar already? Maybe my setup is just broken, hehe.

```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 -Xclang --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:** ![reuk](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/reuk/32/21494_2.png) [@reuk](https://forum.juce.com/u/reuk)\
**Post date:** [June 4, 2021, 12:42pm UTC](https://forum.juce.com/t/cannot-build-with-vanilla-clang-on-windows/46299/11 "2021-06-04T12:42:20Z")

</div>

Yes, I think this can happen when no runtime library is specified. If your `cmake_minimum_required` is set to 3.15 or greater, you can set the property [`MSVC_RUNTIME_LIBRARY`](https://cmake.org/cmake/help/latest/prop_tgt/MSVC_RUNTIME_LIBRARY.html) or the variable [`CMAKE_MSVC_RUNTIME_LIBRARY`](https://cmake.org/cmake/help/latest/variable/CMAKE_MSVC_RUNTIME_LIBRARY.html?highlight=cmake_msvc) to explicitly request a specific runtime library.

---

<div class="post-metadata">

**Author:** ![vallant](https://avatars.discourse-cdn.com/v4/letter/v/c57346/32.png) [@vallant](https://forum.juce.com/u/vallant)\
**Post date:** [June 4, 2021, 12:59pm UTC](https://forum.juce.com/t/cannot-build-with-vanilla-clang-on-windows/46299/12 "2021-06-04T12:59:27Z")

</div>

Just tried this, but it didn’t resolve the problem. But this is more of an cmake issue than a juce issue, i’ll seek help in the proper channels 🙂

---

<div class="post-metadata">

**Author:** ![vallant](https://avatars.discourse-cdn.com/v4/letter/v/c57346/32.png) [@vallant](https://forum.juce.com/u/vallant)\
**Post date:** [June 7, 2021, 6:51am UTC](https://forum.juce.com/t/cannot-build-with-vanilla-clang-on-windows/46299/13 "2021-06-07T06:51:29Z")

</div>

For the reference, this is the thread on the cmake-discorse forum:

> **[clang on Windows detected with MSVC interface](https://discourse.cmake.org/t/clang-on-windows-detected-with-msvc-interface/3470)**
>
> 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...

---

<div class="post-metadata">

**Author:** ![vallant](https://avatars.discourse-cdn.com/v4/letter/v/c57346/32.png) [@vallant](https://forum.juce.com/u/vallant)\
**Post date:** [June 15, 2021, 10:15am UTC](https://forum.juce.com/t/cannot-build-with-vanilla-clang-on-windows/46299/14 "2021-06-15T10:15:54Z")

</div>

I’ve finally tracked down the problem.  
I’ve been using the `Developer Powershell for VS 2019` to try the compilation using clang, since there all paths for the SDKs are set up correctly. But it seems like the powershell was configured for x86 compilation, which led to the linker errors i’ve encountered.  
Using the `x64 Native Tools Command Prompt for VS 2019`, compilation works fine now.
