Dear fellow C++ coders,
after using the Visual Studio toolchain for building on windows for a while, I decided to give Clang 5 a shot.
I installed the LLVM 5.0.0 binaries, the Ninja build environment, the VS 2017 Tools and CMake 3.9.3. The final aim is to be able to compile C and C++ applications for Windows using VS Code with the CMake integration as "IDE" and Clang with LLD as compiler and linker.
The compilation and execution of a simple program worked perfectly fine (screenshot of the respective terminal history). Clang automatically detected the standard lib for Windows within the VS Tools directories and produced an executable output.
The next step was setting up a simple build with Ninja (screenshot of ninja.build file and terminal history). The build process worked as expected and produced a working executable, just like before.
The problems begun when I started to integrate CMake into the process. My expectation is that CMake produces a ninja build file and runs it, correct? I tried the following CMakeLists file
cmake_minimum_required(VERSION 3.9)
project(Test)
add_executable(Test main.c)
and called CMake with cmake -G Ninja
.
The resulting output was disappointing and I don't understand enough to figure out respectively solve the problem myself.
-- The C compiler identification is Clang 5.0.0
-- The CXX compiler identification is Clang 5.0.0
-- Check for working C compiler: C:/Meine_Programme/LLVM/bin/clang.exe
-- Check for working C compiler: C:/Meine_Programme/LLVM/bin/clang.exe -- broken
CMake Error at C:/Meine_Programme/CMake/share/cmake-3.9/Modules/CMakeTestCCompiler.cmake:51 (message):
The C compiler "C:/Meine_Programme/LLVM/bin/clang.exe" is not able to
compile a simple test program.
It fails with the following output:
Change Dir: D:/Dateien/Downloads/Test/CMakeFiles/CMakeTmp
Run Build Command:"C:/Meine_Programme/Ninja_Build/ninja.exe" "cmTC_eeb5c"
[1/2] Building C object CMakeFiles\cmTC_eeb5c.dir\testCCompiler.c.obj
FAILED: CMakeFiles/cmTC_eeb5c.dir/testCCompiler.c.obj
C:\Meine_Programme\LLVM\bin\clang.exe /nologo /DWIN32 /D_WINDOWS /W3 /MDd
/Zi /Ob0 /Od /RTC1 /showIncludes
/FoCMakeFiles\cmTC_eeb5c.dir\testCCompiler.c.obj
/FdCMakeFiles\cmTC_eeb5c.dir\ -c testCCompiler.c
clang.exe: error: no such file or directory: '/nologo'
clang.exe: error: no such file or directory: '/DWIN32'
clang.exe: error: no such file or directory: '/D_WINDOWS'
clang.exe: error: no such file or directory: '/W3'
clang.exe: error: no such file or directory: '/MDd'
clang.exe: error: no such file or directory: '/Zi'
clang.exe: error: no such file or directory: '/Ob0'
clang.exe: error: no such file or directory: '/Od'
clang.exe: error: no such file or directory: '/RTC1'
clang.exe: error: no such file or directory: '/showIncludes'
clang.exe: error: no such file or directory:
'/FoCMakeFiles\cmTC_eeb5c.dir\testCCompiler.c.obj'
clang.exe: error: no such file or directory:
'/FdCMakeFiles\cmTC_eeb5c.dir\'
ninja: build stopped: subcommand failed.
CMake will not be able to correctly generate this project.
Call Stack (most recent call first):
CMakeLists.txt:3 (project)
-- Configuring incomplete, errors occurred!
See also "D:/Dateien/Downloads/Test/CMakeFiles/CMakeOutput.log".
See also "D:/Dateien/Downloads/Test/CMakeFiles/CMakeError.log".
I guess that the problem is related to CMake calling clang with VS style options using slash instead of preceded by minus, like clang requires.
Thanks for helping me out guys, I appreciate it :-)
Just leave me a comment if you require further information.
Answer to Florians post
I tried Florians command but omitted the path to ninja for a shorter notation and it turned out to work just fine.
cmake -E env LDFLAGS="-fuse-ld=lld" cmake -H. -G Ninja -Bbuild -DCMAKE_C_COMPILER:PATH="C:\MeineProgramme\LLVM\bin\clang.exe" -DCMAKE_CXX_COMPILER:PATH="C:\MeineProgramme\LLVM\bin\clang++.exe" -DCMAKE_C_COMPILER_ID="Clang" -DCMAKE_CXX_COMPILER_ID="Clang" -DCMAKE_SYSTEM_NAME="Generic"
CMake produced a ninja build file.
I ran ninja all
to build the executable as Test
. I renamed it to Test.exe
and the program executed happily. So far... success!!! But much more complicated than I expected.
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
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 inAfter navigating to my build directory I run CMake with the following options
this encourages CMake to use all my installed LLVM tools. Not only
clang
andlld
(make sure to use lld-link which supports the options led by a/
), but alsollvm-ar
andllvm-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.
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):
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:
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 thanclang.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.
CMakeLists.txt
, and open that in VS via theOpen Folder
dialog.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:}
Now you should be able to build both x64 and x86 configurations without errors.