Building with CMake, Ninja and Clang on Windows
I was running into similar problems when trying to use clang cmake and msvc 2017 together. At least for a very simple test project, I was able to get everything running, but I'm quite new to that stuff, so maybe my solution won't solve your probles.
Anyway. As far as I know, you should use clang-cl.exe
rather than clang.exe
with VS. However, building still failed for me in x86 configurations due to some linker problems regarding x86 vs x64 library incompatibilities.
So here's my solution to get both, x64 and x86 configurations, building in VS 2017.
- Download and install BOTH windows clang/llvm installers from http://releases.llvm.org/download.html. You don't have to add them to the path, as we'll explicitly specify the path later.
- Create a folder with a
CMakeLists.txt
, and open that in VS via theOpen Folder
dialog. - In the
CMake
menu, selectChange CMake Settings > CMakeLists.txt
. This will generate aCMakeSettings.json
containing settings for all build configs. Specify the paths of the x64/x86 cmake compilers in the
cmakeCommandArgs
for all configurations. Mine looks like this:{ // See https://go.microsoft.com//fwlink//?linkid=834763 for more information about this file. "configurations": [ { "name": "x86-Debug", "generator": "Ninja", "configurationType": "Debug", "inheritEnvironments": [ "msvc_x86" ], "buildRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\build\\${name}", "installRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\install\\${name}", "cmakeCommandArgs": "-D CMAKE_CXX_COMPILER=D:/windows/LLVM5_x86/bin/clang-cl.exe", "buildCommandArgs": "-v", "ctestCommandArgs": "" }, { "name": "x86-Release", "generator": "Ninja", "configurationType": "RelWithDebInfo", "inheritEnvironments": [ "msvc_x86" ], "buildRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\build\\${name}", "installRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\install\\${name}", "cmakeCommandArgs": "-D CMAKE_CXX_COMPILER=D:/windows/LLVM5_x86/bin/clang-cl.exe", "buildCommandArgs": "-v", "ctestCommandArgs": "" }, { "name": "x64-Debug", "generator": "Ninja", "configurationType": "Debug", "inheritEnvironments": [ "msvc_x64" ], "buildRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\build\\${name}", "installRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\install\\${name}", "cmakeCommandArgs": "-D CMAKE_CXX_COMPILER=D:/windows/LLVM5/bin/clang-cl.exe", "buildCommandArgs": "-v", "ctestCommandArgs": "" }, { "name": "x64-Release", "generator": "Ninja", "configurationType": "RelWithDebInfo", "inheritEnvironments": [ "msvc_x64" ], "buildRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\build\\${name}", "installRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\install\\${name}", "cmakeCommandArgs": "-D CMAKE_CXX_COMPILER=D:/windows/LLVM5/bin/clang-cl.exe", "buildCommandArgs": "-v", "ctestCommandArgs": "" } ]
}
Now you should be able to build both x64 and x86 configurations without errors.
Inspired by the "Ways to Compile with Clang on Windows" blog post from @Unspongeful and after some extended testing, the following command line worked for me (and yes, it's one big command I just splitted into several lines for better readability):
> cmake -E env LDFLAGS="-fuse-ld=lld-link" PATH="<path\to\ninja>"
cmake -H. -G Ninja -Bbuild
-DCMAKE_C_COMPILER:PATH="%ProgramFiles(x86)%\LLVM\bin\clang.exe"
-DCMAKE_CXX_COMPILER:PATH="%ProgramFiles(x86)%\LLVM\bin\clang.exe"
-DCMAKE_C_COMPILER_ID="Clang"
-DCMAKE_CXX_COMPILER_ID="Clang"
-DCMAKE_SYSTEM_NAME="Generic"
Here is some background information:
I injected your linker flags with the
LDFLAGS
environment variableSee Passing compiler options cmake
I reduced the
PATH
environment variable to just point to whereninja
is located, because CMake was picking myMinGW
toolchain (which I didn't want included in the build process)Related to Environment variable used by CMake to detect Visual C++ compiler tools for Ninja
Defining the compiler ids "bypasses the check for working compiler and basic compiler information tests"
See obsolete, but sometimes useful
CMakeForceCompiler
moduleAnd I set
CMAKE_SYSTEM_NAME
toGeneric
to avoid having any additional platform specific compiler/linker flags added by CMakeSee How to partially disabling cmake C/C++ custom compiler checking
It seems at the moment you have to bypass a lot of CMake's automatic checks to get it working. So probably check with the CMake team or raise an issue to get this scenario officially supported.
And the last part with a Generic
system is probably not the best choice, because it will skip Windows specific settings like the .exe
suffix.
But it was the only constellation that actually worked:
-- The C compiler identification is Clang
-- The CXX compiler identification is Clang
-- Check for working C compiler: C:/Program Files (x86)/LLVM/bin/clang.exe
-- Check for working C compiler: C:/Program Files (x86)/LLVM/bin/clang.exe -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: C:/Program Files (x86)/LLVM/bin/clang.exe
-- Check for working CXX compiler: C:/Program Files (x86)/LLVM/bin/clang.exe -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: build
I finally found a way to use my favoured tools in a way that pleases me. It's not perfect, but it works better than Florians approach with setting the system name to Generic (which I've been using for some time now)
I first set up VS Code to use the VS developers terminal as its standard terminal. I did this by adding the following line to the VS Code preferences
"terminal.integrated.shell.windows": "C:\\MeineProgramme\\Visual_Studio\\2017\\BuildTools\\Common7\\Tools\\LaunchDevCmd.bat"
After starting the terminal within VS Code I need to call the respective batch file which sets the required environment variables (in my case vcvars64.bat
). These can be found in
C:\MeineProgramme\Visual_Studio\2017\BuildTools\VC\Auxiliary\Build
After navigating to my build directory I run CMake with the following options
cmake .. -G Ninja -DCMAKE_CXX_COMPILER:PATH="C:\MeineProgramme\LLVM\bin\clang-cl.exe" -DCMAKE_LINKER:PATH="C:\MeineProgramme\LLVM\bin\lld-link.exe"
this encourages CMake to use all my installed LLVM tools. Not only clang
and lld
(make sure to use lld-link which supports the options led by a /
), but also llvm-ar
and llvm-ranlib
. The only MS build tool used is the resource compiler which I don't use at the moment.
So far success I think.
Don't hesitate to contact me or comment below if you got further questions.