Skonfiguruj CMake w Windows, aby używać clang z wiersza poleceń, aby uzyskać nowoczesną obsługę OpenMP

11

Mam mały projekt testowy , który używa OpenMP do równoległości. Moim celem jest skompilowanie go w taki sposób, aby tworzył .dlli .libdla bibliotek (ponieważ mój prawdziwy projekt łączy się z bibliotekami zewnętrznymi dystrybuowanymi przy użyciu tych typów), ze wsparciem dla OpenMP 4.5 lub nowszego i robię to z wiersza poleceń, aby można było to zrobić w oknie dokowanym dla testowanie i sprawdzanie (część dokera jest poza zakresem tego pytania, jest tylko dla odniesienia, dlaczego potrzebuję go do pracy z wiersza poleceń). Mogę skompilować ten projekt z różnymi kompilatorami, z którymi nie jestem zadowolony:

  • MSVC:, mkdir build-msvcnastępnie cmake ..(z nowo utworzonego folderu) i na końcucmake --build . --config Release . Kompiluje się dobrze, ale obsługuje tylko OpenMP 2.0, dlatego nie jest dobrą opcją dla mojego prawdziwego projektu.
  • Intel Parallel Studio: mkdir build-intelnastępnie cmake .. -T "Intel C++ Compiler 19.0"(z nowo utworzonego folderu) i na końcu cmake --build . --config Release. Obsługuje OpenMP 5.0, ale jego licencje są dla mnie dość drogie.
  • MinGW x64 g ++:, mkdir build-g++następnie cmake .. -G "MinGW Makefiles"(z nowo utworzonego folderu) i na koniec cmake --build .. Obsługuje OpenMP 4.5, ale ten kompilator nie jest kompatybilny z .lib(o ile wiem), o którym wspomniałem, że jest dla mnie konieczny.

Próbowałem bez powodzenia użyć clang:

  • CLANG z MSVC:, mkdir build-clang-msvca następnie cmake -G Ninja -DCMAKE_CXX_COMPILER=clang-cl ..(z nowo utworzonego folderu), ale kończy się niepowodzeniem z następującym błędem:
- Identyfikator kompilatora CXX to Clang 8.0.1 z wierszem poleceń podobnym do MSVC
- Sprawdź działanie kompilatora CXX: C: / Program Files (x86) / Microsoft Visual Studio / 2019 / Community / VC / Tools / Llvm / bin / clang-cl.exe
- Sprawdź działanie kompilatora CXX: C: / Program Files (x86) / Microsoft Visual Studio / 2019 / Community / VC / Tools / Llvm / bin / clang-cl.exe - uszkodzony
CMake Błąd w C: / Program Files / CMake / share / cmake-3.15 / Modules / CMakeTestCXXCompiler.cmake: 53 (komunikat):
  Kompilator C ++

    „C: / Program Files (x86) / Microsoft Visual Studio / 2019 / Community / VC / Tools / Llvm / bin / clang-cl.exe”

  nie jest w stanie skompilować prostego programu testowego.

  Nie działa z następującymi danymi wyjściowymi:

    Zmień katalog: C: / Users / [NAZWA UŻYTKOWNIKA] / source / repos / test_openmp / build-clang-msvc / CMakeFiles / CMakeTmp

    Uruchom komendę kompilacji: C: /PROGRA~2/MICROS~1/2019/COMMUN~1/Common7/IDE/COMMON~1/MICROS~1/CMake/Ninja/ninja.exe cmTC_bd131 && [1/2] Budowanie obiektu CXX CMakeFiles \ cmTC_bd131.dir \ testCXXCompiler.cxx.obj
    [2/2] Łączenie pliku wykonywalnego CXX cmTC_bd131.exe
    FAILED: cmTC_bd131.exe
    cmd.exe / C "cd. &&" C: \ Program Files \ CMake \ bin \ cmake.exe "-E vs_link_exe --intdir = CMakeFiles \ cmTC_bd131.dir --rc = rc --mt = CMAKE_MT-NOTFOUND - manifestuje - 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: console kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg .lib advapi32.lib && cd. ”
    RC Pass 1: polecenie „rc / fo CMakeFiles \ cmTC_bd131.dir / manifest.res CMakeFiles \ cmTC_bd131.dir / manifest.rc” nie powiodło się (kod wyjścia 0) z następującymi danymi wyjściowymi:
    System nie może odnaleźć określonego pliku
    ninja: build zatrzymany: komenda nie powiodła się.





  CMake nie będzie w stanie poprawnie wygenerować tego projektu.
Stos połączeń (najpierw ostatnie połączenie):
  CMakeLists.txt: 2 (projekt)


- Konfiguracja niekompletna, wystąpiły błędy!
Zobacz także „C: / Users / [NAZWA UŻYTKOWNIKA] /source/repos/test_openmp/build-clang-msvc/CMakeFiles/CMakeOutput.log”.
Zobacz także „C: / Users / [NAZWA UŻYTKOWNIKA] /source/repos/test_openmp/build-clang-msvc/CMakeFiles/CMakeError.log”.
  • Clang i Ninja oprócz MSVC:, mkdir build-clang-ninjaa następnie cmake -G Ninja -DCMAKE_CXX_COMPILER=clang-cl ..(z nowo utworzonego folderu i zmiany PATHzmiennej środowiskowej, aby najpierw nie znaleziono msvc), ale błąd kończy się następująco:
- Identyfikator kompilatora CXX to Clang 9.0.0 z wierszem poleceń podobnym do MSVC
- Sprawdź działanie kompilatora CXX: C: / Program Files / LLVM / bin / clang-cl.exe
- Sprawdź działanie kompilatora CXX: C: / Program Files / LLVM / bin / clang-cl.exe - uszkodzony
CMake Błąd w C: / Program Files / CMake / share / cmake-3.15 / Modules / CMakeTestCXXCompiler.cmake: 53 (komunikat):
  Kompilator C ++

    „C: / Program Files / LLVM / bin / clang-cl.exe”

  nie jest w stanie skompilować prostego programu testowego.

  Nie działa z następującymi danymi wyjściowymi:

    Zmień katalog: C: / Users / [NAZWA UŻYTKOWNIKA] / source / repos / test_openmp / buid-clang-ninja / CMakeFiles / CMakeTmp

    Uruchom komendę kompilacji: C: /Ninja/ninja.exe cmTC_50b73 && [1/2] Budowanie obiektu CXX CMakeFiles \ cmTC_50b73.dir \ testCXXCompiler.cxx.obj
    [2/2] Łączenie pliku wykonywalnego CXX cmTC_50b73.exe
    FAILED: cmTC_50b73.exe
    cmd.exe / C "cd. &&" C: \ Program Files \ CMake \ bin \ cmake.exe "-E vs_link_exe --intdir = CMakeFiles \ cmTC_50b73.dir --rc = rc --mt = CMAKE_MT-NOTFOUND - manifesty - 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.0 / machine: x64 / debugowanie podsystem: konsola kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib && cd. ”
    RC Pass 1: komenda „rc / fo CMakeFiles \ cmTC_50b73.dir / manifest.res CMakeFiles \ cmTC_50b73.dir / manifest.rc” nie powiodła się (kod wyjścia 0) z następującymi danymi wyjściowymi:
    System nie może odnaleźć określonego pliku
    ninja: build zatrzymany: komenda nie powiodła się.





  CMake nie będzie w stanie poprawnie wygenerować tego projektu.
Stos połączeń (najpierw ostatnie połączenie):
  CMakeLists.txt: 2 (projekt)


- Konfiguracja niekompletna, wystąpiły błędy!
Zobacz także „C: / Users / [NAZWA UŻYTKOWNIKA] /source/repos/test_openmp/buid-clang-ninja/CMakeFiles/CMakeOutput.log”.
Zobacz także „C: / Users / [NAZWA UŻYTKOWNIKA] /source/repos/test_openmp/buid-clang-ninja/CMakeFiles/CMakeError.log”.

Wszelkie pomysły na kontynuowanie klangu? Myślę, że to moja najlepsza opcja na to, co chcę osiągnąć (skompiluj mój program testowy z obsługą OpenMP 4.5 lub nowszą wersją i produkcją .libi .dll).

Powiązane posty / strony internetowe, które sprawdziłem, ale nie były przydatne do rozwiązania tego:

apalomer
źródło
Czy próbowałeś załadować odpowiedni plik vcvarsXX.bat przed wydaniem polecenia cmake?
Le Ngoc Thuong,
Nie mam pojęcia, więc chyba nie. Po prostu otwieram wiersz polecenia, przechodzę do folderu kompilacji i wykonuję polecenia CMake, które napisałem. Jak mogę załadować ten odpowiedni plik?
apalomer
1
Pracuję z projektem opartym na MSVC. Ilekroć chcę zbudować projekt, zawsze najpierw muszę uruchomić „% VCINSTALLDIR% \ vcvarsall.bat amd64”. Ponadto, na podstawie odpowiedzi na tej stronie stackoverflow.com/questions/22585874/... . Zaleca także, aby „załadować odpowiedni plik vcvarsXX.bat (np.„ <Twoja lokalizacja Visual Studio> \ VC \ vcvarsall.bat ”x86)”. Napotkałem ten sam komunikat o błędzie co ty, gdy zapomniałem uruchomić vcvarsall.bat
Le Ngoc Thuong,
To zdecydowanie sprawiło, że ruszyłem do przodu. Teraz siedzę w następnym etapie Could NOT find OpenMP_CXX (missing: OpenMP_CXX_FLAGS OpenMP_CXX_LIB_NAMES). Zagłębię się w ten nowy błąd i jeśli nie znajdę odpowiedzi, opublikuję nowe pytanie. Dziękuję Ci!
apalomer

Odpowiedzi:

4

Udało mi się zduplikować ten błąd w przypadku Clang + MSVC . Ponieważ próbujemy użyć kompilatora dostosowanego do Visual-Studio spoza Visual Studio (tj. Wiersza poleceń), konieczne jest zainicjowanie środowiska kompilacji VS w naszym wierszu poleceń przed użyciem kompilatora. Te VCVarsXX.batpliki to osiągnąć; są częścią narzędzi VS Command Prompt. Tak więc, wybierając swoją architekturę ( x86, x64itp) i uruchomienie skryptu, powinno to pozwolić CMake zbudować prosty program testowy z clang-cli kontynuować. Oto, gdzie się znajduje dla 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
...

Aby rozwinąć kwestię OpenMP, osobiście uznałem, że jestem find_package(OpenMP REQUIRED)dość bezowocny. Jak wspomniałeś, otrzymałem również błąd CMake:

Could NOT find OpenMP_CXX (missing: OpenMP_CXX_FLAGS OpenMP_CXX_LIB_NAMES)

Istnieje kilka sugestii na tej stronie (na przykład tutaj i tutaj ), które twierdzą, że ręczne wypełnienie wszystkich zmiennych pozwala FindOpenMP.cmakez powodzeniem znaleźć biblioteki. Próbowałem tego z twoim przykładowym plikiem CMake, z pewnym powodzeniem:

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)

Udało się to „znaleźć” biblioteki przy drugiej próbie konfiguracji CMake (pierwsza zawsze dawała taki sam Could NOT find OpenMP_CXXbłąd jak poprzednio):

>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

Jednak nie udało się zbudować pliku wykonywalnego, ponieważ żadna ze zmiennych CMake OpenMP (szczególnie OpenMP_CXX_LIBRARIES) nie wskazuje lokalizacji biblioteki. Braki CUpewnij roku FindOpenMP.cmakezostały podniesione na stronie emisyjnej CMake tutaj , i nie wydają się być odpowiednie ograniczenia na koniec LLVM / Clang także.


Niezależnie od tego, najczystszym sposobem, w jaki udało mi się uruchomić przykład, było find_package()całkowite porzucenie. Poniższe pozwoliło mi pomyślnie wygenerować system kompilacji oraz skompilować i uruchomić plik wykonywalny:

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)
kwadraty
źródło
CMake 3.17 zawiera obsługę tego rozwiązania, które rozwiązuje ten błąd. Błędy są naprawione w tym zatwierdzeniu.
apalomer
@apalomer Thanks! Jeśli znasz prostsze rozwiązanie, opublikuj je!
squareskittles
Dla mnie bieganie vcvarsall.batnie stawia clang-cl w ŚCIEŻCE. Masz pomysł, dlaczego?
Alex Reinking
@AlexReinking Czy masz zainstalowany clang-cl? Trudno jest wiedzieć bez znajomości konfiguracji i sposobu zainstalowania tych składników. W razie potrzeby zachęcam do zadania kolejnego pytania!
squareskittles
Tak, jest instalowany za pomocą instalatora VS2019
Alex Reinking