Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Building with CMake, Ninja and Clang on Windows

This question is from 2017 and probably outdated. Please take the provided instructions with a pinch of salt since better solutions might be available now.


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.

like image 995
Simon Avatar asked Oct 03 '17 21:10

Simon


People also ask

Does Clang work on Windows?

For best IDE support in Visual Studio, we recommend using the latest Clang compiler tools for Windows. If you don't already have the tools, you can install them by opening the Visual Studio Installer and choosing C++ Clang tools for Windows under Desktop development with C++ optional components.

Is Ninja faster than CMake?

Mostly because the people who wrote cmake never learned to write Makefiles and as a result using ninja with cmake is much faster. Actually it's more like a "second step" for make. You can use make to generate ninja files, and then ninja does the actual build.

What is the difference between Ninja and CMake?

CMake is a build generator while Ninja is a build tool. CMake can use any build tool like Make or Ninja while Ninja has to use CMake as its build generator which is compulsory.

Do I need CMake on Windows?

The short answer is that you don't, but it would probably be difficult to build the project without it. CMake does not build code, but is instead a build file generator. It was developed by KitWare (during the ITK project around 2000) to make building code across multiple platforms "simpler".


1 Answers

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 variable

    See Passing compiler options cmake

  • I reduced the PATH environment variable to just point to where ninja is located, because CMake was picking my MinGW 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 module

  • And I set CMAKE_SYSTEM_NAME to Generic to avoid having any additional platform specific compiler/linker flags added by CMake

    See 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 
like image 140
Florian Avatar answered Oct 03 '22 20:10

Florian