Konfigurieren Sie CMake in Windows so, dass Clang über die Befehlszeile verwendet wird, um moderne OpenMP-Unterstützung zu erhalten

11

Ich habe ein kleines Testprojekt , das OpenMP für Parallelisierung verwendet. Mein Ziel ist es, es so zu kompilieren, dass es produziert .dllund .libfür Bibliotheken (da mein reales Projekt Links zu externen Bibliotheken enthält, die mit diesen Typen verteilt werden), mit Unterstützung für OpenMP 4.5 oder neuer, und dies über die Befehlszeile zu tun, damit es auf einem Docker für ausgeführt werden kann Testen und Überprüfen (der Docker-Teil fällt nicht in den Geltungsbereich dieser Frage, er dient nur als Referenz dafür, warum ich ihn für die Arbeit über die Befehlszeile benötige). Ich kann dieses Projekt mit verschiedenen Compilern kompilieren, mit denen ich nicht zufrieden bin:

  • MSVC: mkdir build-msvcdann cmake ..(aus dem neu erstellten Ordner) und schließlich cmake --build . --config Release. Dies lässt sich gut kompilieren, unterstützt jedoch nur OpenMP 2.0 und ist daher keine gute Option für mein reales Projekt.
  • Intel Parallel Studio: mkdir build-inteldann cmake .. -T "Intel C++ Compiler 19.0"(aus dem neu erstellten Ordner) und schließlich cmake --build . --config Release. Dies unterstützt OpenMP 5.0, aber seine Lizenzen sind für mich ziemlich teuer.
  • MinGW x64 g ++ : mkdir build-g++, dann cmake .. -G "MinGW Makefiles"(aus dem neu erstellten Ordner) und schließlich cmake --build .. Es unterstützt OpenMP 4.5, aber dieser Compiler ist nicht kompatibel mit .lib(soweit ich weiß), was ich bereits erwähnt habe, ist für mich notwendig.

Ich habe erfolglos versucht, clang zu verwenden:

  • CLANG von MSVC : mkdir build-clang-msvc, dann cmake -G Ninja -DCMAKE_CXX_COMPILER=clang-cl ..(aus dem neu erstellten Ordner), aber es schlägt mit dem folgenden Fehler fehl:
- Die CXX-Compiler-Identifikation lautet Clang 8.0.1 mit MSVC-ähnlicher Befehlszeile
- Überprüfen Sie, ob der CXX-Compiler funktioniert: C: / Programme (x86) / Microsoft Visual Studio / 2019 / Community / VC / Tools / Llvm / bin / clang-cl.exe
- Überprüfen Sie, ob der CXX-Compiler funktioniert: C: / Programme (x86) / Microsoft Visual Studio / 2019 / Community / VC / Tools / Llvm / bin / clang-cl.exe - defekt
CMake-Fehler bei C: / Programme / CMake / share / cmake-3.15 / Modules / CMakeTestCXXCompiler.cmake: 53 (Nachricht):
  Der C ++ - Compiler

    "C: / Programme (x86) / Microsoft Visual Studio / 2019 / Community / VC / Tools / Llvm / bin / clang-cl.exe"

  kann kein einfaches Testprogramm kompilieren.

  Es schlägt mit der folgenden Ausgabe fehl:

    Ändern Sie Dir: C: / Users / [BENUTZERNAME] / source / repos / test_openmp / build-clang-msvc / CMakeFiles / CMakeTmp

    Führen Sie die Build-Befehle aus: C: /PROGRA~2/MICROS~1/2019/COMMUN~1/Common7/IDE/COMMON~1/MICROS~1/CMake/Ninja/ninja.exe cmTC_bd131 && [1/2] Erstellen des CXX-Objekts CMakeFiles \ cmTC_bd131.dir \ testCXXCompiler.cxx.obj
    [2/2] Verknüpfen der ausführbaren CXX-Datei cmTC_bd131.exe
    FEHLGESCHLAGEN: cmTC_bd131.exe
    cmd.exe / C "cd. &&" C: \ Programme \ CMake \ bin \ cmake.exe "-E vs_link_exe --intdir = CMakeFiles \ cmTC_bd131.dir --rc = rc --mt = CMAKE_MT-NOTFOUND - Manifeste - C: \ PROGRA ~ 1 \ MINGW- ~ 1 \ X86_64 ~ 1.0-P \ mingw64 \ bin \ ld.exe / nologo CMakeFiles \ cmTC_bd131.dir \ testCXXCompiler.cxx.obj /out:cmTC_bd131.exe / implib: cmTC_bd131.lib /pdb:cmTC_bd131.pdb /version:0.0 / machine: X86 / debug / INCREMENTAL / subsystem: Konsolenkernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comd .lib advapi32.lib && cd. "
    RC Pass 1: Befehl "rc / fo CMakeFiles \ cmTC_bd131.dir / manifest.res CMakeFiles \ cmTC_bd131.dir / manifest.rc" fehlgeschlagen (Exit-Code 0) mit der folgenden Ausgabe:
    Die angegebene Datei wurde vom System nicht gefunden
    ninja: build gestoppt: Unterbefehl fehlgeschlagen.





  CMake kann dieses Projekt nicht korrekt generieren.
Call Stack (letzter Anruf zuerst):
  CMakeLists.txt: 2 (Projekt)


- Bei unvollständiger Konfiguration sind Fehler aufgetreten!
Siehe auch "C: / Users / [USER NAME] /source/repos/test_openmp/build-clang-msvc/CMakeFiles/CMakeOutput.log".
Siehe auch "C: / Users / [USER NAME] /source/repos/test_openmp/build-clang-msvc/CMakeFiles/CMakeError.log".
  • Clang und Ninja abgesehen von MSVC : mkdir build-clang-ninja, dann cmake -G Ninja -DCMAKE_CXX_COMPILER=clang-cl ..(aus dem neu erstellten Ordner und Ändern der PATHUmgebungsvariablen, sodass die Nicht-MSVC zuerst gefunden werden), aber es schlägt mit dem folgenden Fehler fehl:
- Die CXX-Compiler-Identifikation lautet Clang 9.0.0 mit MSVC-ähnlicher Befehlszeile
- Überprüfen Sie, ob der CXX-Compiler funktioniert: C: / Programme / LLVM / bin / clang-cl.exe
- Überprüfen Sie, ob der CXX-Compiler funktioniert: C: / Programme / LLVM / bin / clang-cl.exe - defekt
CMake-Fehler bei C: / Programme / CMake / share / cmake-3.15 / Modules / CMakeTestCXXCompiler.cmake: 53 (Nachricht):
  Der C ++ - Compiler

    "C: / Programme / LLVM / bin / clang-cl.exe"

  kann kein einfaches Testprogramm kompilieren.

  Es schlägt mit der folgenden Ausgabe fehl:

    Ändern Sie Dir: C: / Users / [BENUTZERNAME] / source / repos / test_openmp / buid-clang-ninja / CMakeFiles / CMakeTmp

    Führen Sie die Build-Befehle aus: C: /Ninja/ninja.exe cmTC_50b73 && [1/2] Erstellen des CXX-Objekts CMakeFiles \ cmTC_50b73.dir \ testCXXCompiler.cxx.obj
    [2/2] Verknüpfen der ausführbaren CXX-Datei cmTC_50b73.exe
    FEHLGESCHLAGEN: cmTC_50b73.exe
    cmd.exe / C "cd. &&" C: \ Programme \ CMake \ bin \ cmake.exe "-E vs_link_exe --intdir = CMakeFiles \ cmTC_50b73.dir --rc = rc --mt = CMAKE_MT-NOTFOUND - Manifeste - CMAKE_LINKER-NOTFOUND / nologo CMakeFiles \ cmTC_50b73.dir \ testCXXCompiler.cxx.obj /out:cmTC_50b73.exe /implib:cmTC_50b73.lib /pdb:cmTC_50b73.pdb /version:0. / deb / /: Subsystem: Konsole kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib && cd. "
    RC Pass 1: Befehl "rc / fo CMakeFiles \ cmTC_50b73.dir / manifest.res CMakeFiles \ cmTC_50b73.dir / manifest.rc" fehlgeschlagen (Exit-Code 0) mit der folgenden Ausgabe:
    Die angegebene Datei wurde vom System nicht gefunden
    ninja: build gestoppt: Unterbefehl fehlgeschlagen.





  CMake kann dieses Projekt nicht korrekt generieren.
Call Stack (letzter Anruf zuerst):
  CMakeLists.txt: 2 (Projekt)


- Bei unvollständiger Konfiguration sind Fehler aufgetreten!
Siehe auch "C: / Users / [USER NAME] /source/repos/test_openmp/buid-clang-ninja/CMakeFiles/CMakeOutput.log".
Siehe auch "C: / Users / [USER NAME] /source/repos/test_openmp/buid-clang-ninja/CMakeFiles/CMakeError.log".

Irgendwelche Ideen, wie man mit dem Klirren umgeht? Ich denke, es ist meine beste Option für das, was ich erreichen möchte (kompiliere mein Testprogramm mit Unterstützung für OpenMP 4.5 oder neuer und produziere .libund .dll).

Verwandte Beiträge / Webseiten, die ich überprüft habe, aber zur Lösung dieses Problems nicht hilfreich waren:

Apalomer
quelle
Haben Sie versucht, die entsprechende Datei vcvarsXX.bat zu laden, bevor Sie den Befehl cmake ausführen?
Le Ngoc Thuong
Ich habe keine Ahnung, also denke ich nicht. Ich öffne einfach eine Eingabeaufforderung, navigiere zum Build-Ordner und führe die von mir geschriebenen CMake-Befehle aus. Wie kann ich diese relevante Datei laden?
Apalomer
1
Ich arbeite mit einem Projekt, das mit MSVC erstellt. Wann immer ich das Projekt erstellen möchte, muss ich zuerst "% VCINSTALLDIR% \ vcvarsall.bat amd64" ausführen. Basierend auf der Antwort auf dieser Seite stackoverflow.com/questions/22585874/… . Er / sie empfiehlt außerdem, "die entsprechende Datei vcvarsXX.bat zu laden (z. B." <Ihr Visual Studio-Speicherort> \ VC \ vcvarsall.bat "x86)". Ich habe die gleiche Fehlermeldung wie Sie erhalten, als ich vergesse, vcvarsall.bat
Le Ngoc Thuong
Das hat mich definitiv weitergebracht. Jetzt stecke ich beim nächsten Schritt fest : Could NOT find OpenMP_CXX (missing: OpenMP_CXX_FLAGS OpenMP_CXX_LIB_NAMES). Ich werde mich mit diesem neuen Fehler befassen und wenn ich keine Antwort finde, werde ich eine neue Frage stellen. Vielen Dank!
Apalomer

Antworten:

4

Ich konnte diesen Fehler für den Fall Clang + MSVC duplizieren . Da wir versuchen, den auf Visual-Studio zugeschnittenen Compiler von außerhalb von Visual Studio (dh der Befehlszeile) zu verwenden, muss die VS-Buildumgebung in unserer Befehlszeile initialisiert werden , bevor der Compiler verwendet wird. Die VCVarsXX.batDateien erreichen dies; Sie sind Teil der VS-Eingabeaufforderungstools. So durch Ihre Architektur Kommissionierung ( x86, x64usw.) und das Skript ausgeführt wird , sollte dies ermöglichen CMake die einfache Testprogramm mit aufzubauen clang-clund fortzufahren. Hier befindet es sich für VS 2019:

>"C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvarsall.bat" x86

>cmake -G Ninja -DCMAKE_CXX_COMPILER=clang-cl ..
-- The CXX compiler identification is Clang 8.0.1
-- Check for working CXX compiler: C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Tools/Llvm/bin/clang-cl.exe
-- Check for working CXX compiler: C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Tools/Llvm/bin/clang-cl.exe -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
...

Um das OpenMP-Problem zu erweitern, fand ich find_package(OpenMP REQUIRED)es ziemlich fruchtlos, es zu verwenden. Wie Sie erwähnt haben, habe ich auch diesen CMake-Fehler erhalten:

Could NOT find OpenMP_CXX (missing: OpenMP_CXX_FLAGS OpenMP_CXX_LIB_NAMES)

Auf dieser Site gibt es einige Vorschläge (zum Beispiel hier und hier ), die besagen, dass das manuelle Auffüllen aller Variablen FindOpenMP.cmakedas erfolgreiche Auffinden der Bibliotheken ermöglicht. Ich habe dies mit Ihrer Beispiel-CMake-Datei mit einigem Erfolg versucht:

cmake_minimum_required (VERSION 2.8)
project(test_openmp LANGUAGES CXX)

set(OpenMP_CXX "${CMAKE_CXX_COMPILER}")
set(OpenMP_CXX_FLAGS "-Xclang -fopenmp")
set(OpenMP_CXX_LIB_NAMES "libomp" "libiomp5")
set(OpenMP_libomp_LIBRARY libomp)
set(OpenMP_libiomp5_LIBRARY libiomp5)

#OPENMP
find_package(OpenMP REQUIRED)
if(OPENMP_FOUND)
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
    set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${OpenMP_EXE_LINKER_FLAGS}")
endif()

# Library
add_library(example_lib SHARED example_lib.h example_lib.cpp)
target_link_libraries(example_lib PUBLIC ${OpenMP_CXX_LIBRARIES})
target_compile_definitions(example_lib PRIVATE EXEMPLE_LIB_EXPORT)

# Executable
add_executable(test_openmp test_openmp.cpp)
target_link_libraries(test_openmp example_lib)

Dies gelang es, die Bibliotheken beim zweiten CMake-Konfigurationsversuch zu "finden" (der erste ergab immer den gleichen Could NOT find OpenMP_CXXFehler wie zuvor):

>cmake -G Ninja -DCMAKE_CXX_COMPILER=clang-cl ..
-- Found OpenMP_CXX: -Xclang -fopenmp (found version "3.1")
-- Found OpenMP: TRUE (found version "3.1")
-- Configuring done
-- Generating done

Dies konnte jedoch die ausführbare Datei nicht erstellen, da keine der CMake OpenMP-Variablen (insbesondere OpenMP_CXX_LIBRARIES) tatsächlich auf den Speicherort der Bibliothek verweist. Die Mängel von CMake FindOpenMP.cmakewurden auf der CMake-Issue-Site hier angesprochen , und es scheint auch relevante Einschränkungen für das LLVM / Clang-Ende zu geben.


Unabhängig davon war der sauberste Weg, das Beispiel zum Laufen zu bringen, den Graben find_package()insgesamt. Folgendes ermöglichte es mir, das Buildsystem erfolgreich zu generieren und die ausführbare Datei zu kompilieren und auszuführen:

cmake_minimum_required (VERSION 2.8)
project(test_openmp LANGUAGES CXX)

set(OpenMP_LIBRARY_DIR "C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Tools/Llvm/lib")
set(OpenMP_CXX_FLAGS "-Xclang -fopenmp")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")

# Tell CMake where to find the OpenMP libraries.
link_directories(${OpenMP_LIBRARY_DIR})

# Library
add_library(example_lib SHARED example_lib.h example_lib.cpp)
# Link in the OpenMP libraries.
target_link_libraries(example_lib PUBLIC libomp libiomp5md)
target_compile_definitions(example_lib PRIVATE EXEMPLE_LIB_EXPORT)

# Executable
add_executable(test_openmp test_openmp.cpp)
target_link_libraries(test_openmp example_lib)
Squareskittles
quelle
CMake 3.17 unterstützt dies, um diesen Fehler zu beheben. Die Fehler werden in diesem Commit behoben .
Apalomer
@apalomer Danke! Wenn Sie eine einfachere Lösung kennen, posten Sie bitte eine!
Squareskittles
Laufen vcvarsall.batbringt für mich kein Klirren in den PFAD. Irgendeine Idee warum?
Alex Reinking
@AlexReinking Hast du clang-cl installiert? Es ist schwierig zu wissen, ohne Ihr Setup zu kennen und wie Sie diese Komponenten installiert haben. Ich ermutige Sie, bei Bedarf eine andere Frage zu stellen!
Squareskittles
Ja, es wird über das VS2019-Installationsprogramm installiert
Alex Reinking