it-swarm.com.de

Erstellen mit CMake, Ninja und Clang unter Windows

Sehr geehrte C++ - Programmierer,

nachdem ich die Visual Studio-Toolchain für einige Zeit verwendet hatte, um Fenster aufzubauen, entschied ich mich, Clang 5 eine Chance zu geben.

Ich habe die LLVM 5.0.0-Binärdateien, die Ninja-Build-Umgebung, die VS 2017-Tools und CMake 3.9.3 installiert. Das Endziel besteht darin, C- und C++ - Anwendungen für Windows unter Verwendung von VS Code mit der CMake-Integration als "IDE" und Clang mit LLD als Compiler und Linker kompilieren zu können.

Die Erstellung und Ausführung eines einfachen Programms funktionierte einwandfrei ( Screenshot der jeweiligen Terminalhistorie ). Clang erkannte automatisch die Standard-Bibliothek für Windows in den VS Tools-Verzeichnissen und erzeugte eine ausführbare Ausgabe.

Der nächste Schritt war das Einrichten eines einfachen Builds mit Ninja ( Screenshot der Datei ninja.build und des Terminalverlaufs ). Der Build-Prozess funktionierte wie erwartet und produzierte wie zuvor eine ausführbare Datei.

Die Probleme begannen, als ich anfing, CMake in den Prozess zu integrieren. Ich gehe davon aus, dass CMake eine Ninja-Build-Datei erstellt und diese ausführt, richtig? Ich habe die folgende CMakeLists-Datei ausprobiert

cmake_minimum_required(VERSION 3.9)

project(Test)

add_executable(Test main.c)

und rief CMake mit cmake -G Ninja..__ an. Die resultierende Ausgabe war enttäuschend und ich verstehe nicht genug, um das Problem selbst zu lösen bzw. zu lösen.

-- 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".

Ich vermute, das Problem hängt mit CMake zusammen, das clang mit VS-Stiloptionen verwendet, und zwar mit einem Schrägstrich anstelle eines vorangestellten Minus, wie es clang erfordert.

Danke, dass ihr mir geholfen habt, ich weiß es zu schätzen :-)

Hinterlassen Sie einfach einen Kommentar, wenn Sie weitere Informationen benötigen.

Antwort auf Florians Post

Ich habe Florians Befehl ausprobiert, aber für eine kürzere Notation den Weg zum Ninja weggelassen, und es hat sich herausgestellt, dass er gut funktioniert.

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 produzierte eine Ninja-Build-Datei.

Ich habe ninja all ausgeführt, um die ausführbare Datei als Test zu erstellen. Ich habe es in Test.exe umbenannt und das Programm wurde glücklich ausgeführt. Bis jetzt ... Erfolg !!! Aber viel komplizierter als ich erwartet hatte.

16
Simon

Ich habe endlich einen Weg gefunden, meine bevorzugten Werkzeuge auf eine Art und Weise einzusetzen, die mir gefällt. Es ist nicht perfekt, aber es funktioniert besser als Florians Ansatz, wenn Sie den Systemnamen auf Generic setzen (was ich schon seit einiger Zeit verwende)

Ich habe zuerst VS Code eingerichtet, um das VS-Entwicklerterminal als Standardterminal zu verwenden. Ich habe dies gemacht, indem ich die folgenden Einstellungen zu den Voreinstellungen von VS Code hinzugefügt habe

"terminal.integrated.Shell.windows": "C:\\MeineProgramme\\Visual_Studio\\2017\\BuildTools\\Common7\\Tools\\LaunchDevCmd.bat"

Nach dem Starten des Terminals innerhalb von VS Code muss ich die entsprechende Batchdatei aufrufen, die die erforderlichen Umgebungsvariablen festlegt (in meinem Fall vcvars64.bat). Diese finden Sie in

C:\MeineProgramme\Visual_Studio\2017\BuildTools\VC\Auxiliary\Build

Nach dem Navigieren zu meinem Build-Verzeichnis führe ich CMake mit den folgenden Optionen aus

cmake .. -G Ninja -DCMAKE_CXX_COMPILER:PATH="C:\MeineProgramme\LLVM\bin\clang-cl.exe" -DCMAKE_LINKER:PATH="C:\MeineProgramme\LLVM\bin\lld-link.exe"

dies ermutigt CMake, alle meine installierten LLVM-Tools zu verwenden. Nicht nur clang und lld (stellen Sie sicher, dass Sie lld-link verwenden, der die durch einen / geführten Optionen unterstützt), sondern auch llvm-ar und llvm-ranlib. Das einzige MS-Build-Tool ist der Ressourcen-Compiler, den ich im Moment nicht verwende.

Bis jetzt Erfolg, denke ich.

Zögern Sie nicht, mich zu kontaktieren oder einen Kommentar zu schreiben, wenn Sie weitere Fragen haben.

3
Simon

Inspiriert von den "Ways to Compile mit Clang unter Windows" blogpost von @Unspongeful und nach einigen längeren Tests funktionierte die folgende Befehlszeile für mich (und ja, es ist ein großer Befehl, den ich einfach in mehrere Zeilen aufgeteilt habe, um besser zu sein Lesbarkeit):

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

Hier einige Hintergrundinformationen:

Im Moment scheint es so, als müssten Sie eine Menge automatischer Prüfungen von CMake umgehen, damit es funktioniert. Also wahrscheinlich beim CMake-Team nachfragen oder ein Problem aufwerfen , um dieses Szenario offiziell zu unterstützen.

Und der letzte Teil mit einem Generic-System ist wahrscheinlich nicht die beste Wahl, da Windows-spezifische Einstellungen wie das Suffix .exe übersprungen werden.

Aber es war die einzige Konstellation, die tatsächlich funktionierte:

-- 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
10
Florian

Ich hatte ähnliche Probleme, als ich versuchte, clang cmake und msvc 2017 zusammen zu verwenden. Zumindest für ein sehr einfaches Testprojekt konnte ich alles zum Laufen bringen, aber ich bin ziemlich neu in diesem Bereich, daher löst meine Lösung möglicherweise Ihre Probleme nicht. 

Sowieso. Soweit ich weiß, sollten Sie clang-cl.exe anstelle von clang.exe mit VS verwenden. In x86-Konfigurationen schlug das Bauen jedoch wegen einiger Linker-Probleme in Bezug auf Inkompatibilitäten von x86- und x64-Bibliotheken fehl.

Hier ist meine Lösung, um sowohl x64- als auch x86-Konfigurationen zu erhalten, die in VS 2017 erstellt werden.

  1. Laden Sie BEIDE Windows clang/llvm-Installationsprogramme von http://releases.llvm.org/download.html herunter und installieren Sie sie. Sie müssen sie nicht zum Pfad hinzufügen, da wir den Pfad später explizit angeben.
  2. Erstellen Sie einen Ordner mit einem CMakeLists.txt und öffnen Sie diesen in VS über den Open Folder-Dialog.
  3. Wählen Sie im Menü CMakeChange CMake Settings > CMakeLists.txt aus. Dadurch wird ein CMakeSettings.json generiert, der Einstellungen für alle Build-Konfigurationen enthält.
  4. Geben Sie die Pfade der x64/x86-cmake-Compiler in der cmakeCommandArgs für alle Konfigurationen an. Meines sieht so aus:

    {    // 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": ""
        }
    ]
    

    }

Jetzt sollten Sie in der Lage sein, x64- und x86-Konfigurationen fehlerfrei zu erstellen.

1
florestan