Configurer CMake dans Windows pour utiliser clang depuis la ligne de commande pour obtenir un support OpenMP moderne

11

J'ai un petit projet de test qui utilise OpenMP pour la parallélisation. Mon objectif est de le compiler pour qu'il produise .dllet .libpour les bibliothèques (parce que mon vrai projet est lié à des bibliothèques externes distribuées à l'aide de ces types), avec le support d'OpenMP 4.5 ou plus récent et le faire à partir de la ligne de commande afin qu'il puisse être fait sur un docker pour test et vérification (la partie docker est hors de portée de cette question, c'est juste pour référence sur pourquoi j'en ai besoin pour travailler à partir de la ligne de commande). Je peux compiler ce projet avec différents compilateurs dont je ne suis pas content:

  • MSVC:, mkdir build-msvcpuis cmake ..(à partir du dossier nouvellement créé) et enfin cmake --build . --config Release. Cela compile bien mais ne prend en charge que OpenMP 2.0, ce n'est donc pas une bonne option pour mon vrai projet.
  • Intel Parallel Studio:, mkdir build-intelpuis cmake .. -T "Intel C++ Compiler 19.0"(à partir du dossier nouvellement créé) et enfin cmake --build . --config Release. Cela prend en charge OpenMP 5.0 mais ses licences sont assez chères pour moi.
  • MinGW x64 g ++:, mkdir build-g++puis cmake .. -G "MinGW Makefiles"(à partir du dossier nouvellement créé) et enfin cmake --build .. Il prend en charge OpenMP 4.5 mais ce compilateur n'est pas compatible avec .lib(pour autant que je sache) que j'ai déjà mentionné est nécessaire pour moi.

J'ai essayé sans succès d'utiliser clang:

  • CLANG de MSVC:, mkdir build-clang-msvcpuis cmake -G Ninja -DCMAKE_CXX_COMPILER=clang-cl ..(à partir du dossier nouvellement créé), mais il échoue avec l'erreur suivante:
- L'identification du compilateur CXX est Clang 8.0.1 avec une ligne de commande de type MSVC
- Vérifiez que le compilateur CXX fonctionne: C: / Program Files (x86) / Microsoft Visual Studio / 2019 / Community / VC / Tools / Llvm / bin / clang-cl.exe
- Vérifiez que le compilateur CXX fonctionne: C: / Program Files (x86) / Microsoft Visual Studio / 2019 / Community / VC / Tools / Llvm / bin / clang-cl.exe - cassé
Erreur CMake sur C: / Program Files / CMake / share / cmake-3.15 / Modules / CMakeTestCXXCompiler.cmake: 53 (message):
  Le compilateur C ++

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

  n'est pas en mesure de compiler un programme de test simple.

  Il échoue avec la sortie suivante:

    Changer le répertoire: C: / Users / [USER NAME] / source / repos / test_openmp / build-clang-msvc / CMakeFiles / CMakeTmp

    Exécutez la ou les commandes de génération: C: /PROGRA~2/MICROS~1/2019/COMMUN~1/Common7/IDE/COMMON~1/MICROS~1/CMake/Ninja/ninja.exe cmTC_bd131 && [1/2] Génération de l'objet CXX CMakeFiles \ cmTC_bd131.dir \ testCXXCompiler.cxx.obj
    [2/2] Liaison de l'exécutable CXX cmTC_bd131.exe
    ÉCHEC: 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 - manifestes - 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 / sous-système: console kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32 .lib advapi32.lib && cd. "
    RC Pass 1: la commande "rc / fo CMakeFiles \ cmTC_bd131.dir / manifest.res CMakeFiles \ cmTC_bd131.dir / manifest.rc" a échoué (code de sortie 0) avec la sortie suivante:
    Le système ne peut pas trouver le fichier spécifié
    ninja: build arrêté: la sous-commande a échoué.





  CMake ne pourra pas générer correctement ce projet.
Pile d'appels (appel le plus récent en premier):
  CMakeLists.txt: 2 (projet)


- Configuration incomplète, des erreurs se sont produites!
Voir aussi "C: / Users / [USER NAME] /source/repos/test_openmp/build-clang-msvc/CMakeFiles/CMakeOutput.log".
Voir aussi "C: / Users / [USER NAME] /source/repos/test_openmp/build-clang-msvc/CMakeFiles/CMakeError.log".
  • Clang et Ninja en dehors de MSVC:, mkdir build-clang-ninjapuis cmake -G Ninja -DCMAKE_CXX_COMPILER=clang-cl ..(à partir du dossier nouvellement créé et en changeant la PATHvariable d'environnement afin que les non-msvc soient trouvés en premier), mais il échoue avec l'erreur suivante:
- L'identification du compilateur CXX est Clang 9.0.0 avec une ligne de commande de type MSVC
- Vérifiez que le compilateur CXX fonctionne: C: / Program Files / LLVM / bin / clang-cl.exe
- Vérifiez que le compilateur CXX fonctionne: C: / Program Files / LLVM / bin / clang-cl.exe - cassé
CMake Error at C:/Program Files/CMake/share/cmake-3.15/Modules/CMakeTestCXXCompiler.cmake:53 (message):
  The C++ compiler

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

  is not able to compile a simple test program.

  It fails with the following output:

    Change Dir: C:/Users/[USER NAME]/source/repos/test_openmp/buid-clang-ninja/CMakeFiles/CMakeTmp

    Run Build Command(s):C:/Ninja/ninja.exe cmTC_50b73 && [1/2] Building CXX object CMakeFiles\cmTC_50b73.dir\testCXXCompiler.cxx.obj
    [2/2] Linking CXX executable 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 --manifests  -- 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  /debug /INCREMENTAL /subsystem:console  kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib && cd ."
    RC Pass 1: command "rc /fo CMakeFiles\cmTC_50b73.dir/manifest.res CMakeFiles\cmTC_50b73.dir/manifest.rc" failed (exit code 0) with the following output:
    The system cannot find the file specified
    ninja: build stopped: subcommand failed.





  CMake will not be able to correctly generate this project.
Pile d'appels (appel le plus récent en premier):
  CMakeLists.txt: 2 (projet)


- Configuration incomplète, des erreurs se sont produites!
Voir aussi "C: / Users / [USER NAME] /source/repos/test_openmp/buid-clang-ninja/CMakeFiles/CMakeOutput.log".
Voir aussi "C: / Users / [USER NAME] /source/repos/test_openmp/buid-clang-ninja/CMakeFiles/CMakeError.log".

Des idées sur la façon de procéder avec le clang? Je pense que c'est ma meilleure option pour ce que je veux réaliser (compiler mon programme de test avec le support d'OpenMP 4.5 ou plus récent et produire .libet .dll).

Messages / pages Web connexes que j'ai vérifiés mais qui n'ont pas été utiles pour résoudre ce problème:

apalomère
la source
Avez-vous essayé de charger le fichier vcvarsXX.bat correspondant avant d'émettre la commande cmake?
Le Ngoc Thuong
Je n'en ai aucune idée, donc je suppose que non. J'ouvre simplement une invite de commande, navigue jusqu'au dossier de build et exécute les commandes CMake que j'ai écrites. Comment puis-je charger ce fichier pertinent?
apalomère
1
Je travaille avec un projet qui se construit avec MSVC. Chaque fois que je veux créer le projet, j'ai toujours besoin d'exécuter "% VCINSTALLDIR% \ vcvarsall.bat amd64" en premier. En outre, sur la base de la réponse de cette page stackoverflow.com/questions/22585874/… . Il recommande également de "charger le fichier vcvarsXX.bat correspondant (par exemple" <Votre emplacement Visual Studio> \ VC \ vcvarsall.bat "x86)". J'ai rencontré le même message d'erreur que vous lorsque j'oublie d'exécuter vcvarsall.bat
Le Ngoc Thuong
Cela m'a définitivement fait avancer. Maintenant , je suis bloqué à l'étape suivante: Could NOT find OpenMP_CXX (missing: OpenMP_CXX_FLAGS OpenMP_CXX_LIB_NAMES). Je vais creuser cette nouvelle erreur et si je ne trouve pas de réponse, je posterai une nouvelle question. Je vous remercie!
apalomère

Réponses:

4

J'ai pu dupliquer cette erreur pour le cas Clang + MSVC . Étant donné que nous tentons d'utiliser le compilateur adapté à Visual-Studio depuis l'extérieur de Visual Studio (c'est-à-dire la ligne de commande), il est nécessaire d' initialiser l'environnement de génération VS dans notre ligne de commande avant d'utiliser le compilateur. Les VCVarsXX.batfichiers accomplissent cela; ils font partie des outils d'invite de commande VS. Donc , en choisissant votre architecture ( x86, x64, etc.) et l' exécution du script, ce qui devrait permettre à CMake de construire le programme de test simple clang-clet continuez. Voici où il se trouve pour 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
...

Pour développer le problème d'OpenMP, j'ai personnellement trouvé que l'utilisation find_package(OpenMP REQUIRED)était plutôt infructueuse. Comme vous l'avez mentionné, j'ai également reçu cette erreur CMake:

Could NOT find OpenMP_CXX (missing: OpenMP_CXX_FLAGS OpenMP_CXX_LIB_NAMES)

Il y a quelques suggestions sur ce site (par exemple ici et ici ) affirmant que le remplissage manuel de toutes les variables permet FindOpenMP.cmakede trouver avec succès les bibliothèques. J'ai essayé cela avec votre exemple de fichier CMake, avec un certain succès:

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)

Cela a réussi à "trouver" les bibliothèques lors de la deuxième tentative de configuration de CMake (la première a toujours produit la même Could NOT find OpenMP_CXXerreur qu'auparavant):

>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

Cependant , cela n'a pas réussi à construire l'exécutable, car aucune des variables CMake OpenMP (en particulier OpenMP_CXX_LIBRARIES) ne pointe réellement vers l'emplacement de la bibliothèque. Les lacunes de CMake FindOpenMP.cmakeont été soulevées sur le site de problème CMake ici , et il semble y avoir des limitations pertinentes sur l'extrémité LLVM / Clang également.


Quoi qu'il en soit, la façon la plus propre dont j'ai pu obtenir l'exemple fonctionne était d'abandonner find_package()complètement. Ce qui suit m'a permis de générer avec succès le buildsystem, de compiler et d'exécuter l'exécutable:

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
la source
CMake 3.17 intègre un support pour cela qui résout cette erreur. Les erreurs sont corrigées dans ce commit.
apalomère
@apalomer Merci! Si vous connaissez une solution plus simple, veuillez en poster une!
squareskittles
La course vcvarsall.batne met pas clang-cl dans le CHEMIN pour moi. Une idée pourquoi?
Alex Reinking le
@AlexReinking Avez-vous installé clang-cl? Il est difficile de savoir sans connaître votre configuration et comment vous avez installé ces composants. Je vous encourage à poser une autre question, si nécessaire!
squareskittles
Oui, il est installé via le programme d'installation VS2019
Alex Reinking