Configure CMake en Windows para usar clang desde la línea de comandos para obtener soporte moderno de OpenMP

11

Tengo un pequeño proyecto de prueba que usa OpenMP para la paralelización. Mi objetivo es compilarlo para que produzca .dlly .libpara bibliotecas (porque mi proyecto real se vincula a bibliotecas externas distribuidas usando estos tipos), con soporte para OpenMP 4.5 o posterior y hacerlo desde la línea de comandos para que se pueda hacer en un acoplador para prueba y verificación (la parte del acoplador está fuera del alcance de esta pregunta, es solo una referencia de por qué necesito que funcione desde la línea de comandos). Puedo compilar este proyecto con diferentes compiladores con los que no estoy contento:

  • MSVC:, mkdir build-msvcluego cmake ..(desde la carpeta recién creada) y finalmente cmake --build . --config Release. Esto compila bien pero solo es compatible con OpenMP 2.0, por lo tanto, no es una buena opción para mi proyecto real.
  • Intel Parallel Studio:, mkdir build-intelluego cmake .. -T "Intel C++ Compiler 19.0"(desde la carpeta recién creada) y finalmente cmake --build . --config Release. Esto es compatible con OpenMP 5.0, pero sus licencias son bastante caras para mí.
  • MinGW x64 g ++:, mkdir build-g++luego cmake .. -G "MinGW Makefiles"(desde la carpeta recién creada) y finalmente cmake --build .. Es compatible con OpenMP 4.5 pero este compilador no es compatible con .lib(que yo sepa) que ya mencioné es necesario para mí.

He intentado sin éxito utilizar clang:

  • CLANG desde MSVC:, mkdir build-clang-msvcluego cmake -G Ninja -DCMAKE_CXX_COMPILER=clang-cl ..(desde la carpeta recién creada), pero falla con el siguiente error:
- La identificación del compilador CXX es Clang 8.0.1 con línea de comandos similar a MSVC
- Compruebe si funciona el compilador CXX: C: / Archivos de programa (x86) / Microsoft Visual Studio / 2019 / Community / VC / Tools / Llvm / bin / clang-cl.exe
- Compruebe si funciona el compilador CXX: C: / Archivos de programa (x86) / Microsoft Visual Studio / 2019 / Community / VC / Tools / Llvm / bin / clang-cl.exe - roto
Error de CMake en C: / Archivos de programa / CMake / share / cmake-3.15 / Módulos / CMakeTestCXXCompiler.cmake: 53 (mensaje):
  El compilador de C ++

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

  no puede compilar un programa de prueba simple.

  Falla con el siguiente resultado:

    Cambiar Dir: C: / Usuarios / [NOMBRE DE USUARIO] / source / repos / test_openmp / build-clang-msvc / CMakeFiles / CMakeTmp

    Ejecutar comandos de compilación: C: /PROGRA~2/MICROS~1/2019/COMMUN~1/Common7/IDE/COMMON~1/MICROS~1/CMake/Ninja/ninja.exe cmTC_bd131 && [1/2] Creación de objetos CXX CMakeFiles \ cmTC_bd131.dir \ testCXXCompiler.cxx.obj
    [2/2] Vinculación del ejecutable CXX cmTC_bd131.exe
    FALLIDO: cmTC_bd131.exe
    cmd.exe / C "cd. &&" C: \ Archivos de programa \ CMake \ bin \ cmake.exe "-E vs_link_exe --intdir = CMakeFiles \ cmTC_bd131.dir --rc = rc --mt = CMAKE_MT-NOTFOUND - manifiestos: 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 comdlg32 .lib advapi32.lib && cd ".
    RC Pass 1: el comando "rc / fo CMakeFiles \ cmTC_bd131.dir / manifest.res CMakeFiles \ cmTC_bd131.dir / manifest.rc" falló (código de salida 0) con el siguiente resultado:
    El sistema no puede encontrar el archivo especificado
    ninja: compilación detenida: el subcomando falló.





  CMake no podrá generar correctamente este proyecto.
Pila de llamadas (la llamada más reciente primero):
  CMakeLists.txt: 2 (proyecto)


- ¡Configuración incompleta, se produjeron errores!
Consulte también "C: / Usuarios / [NOMBRE DE USUARIO] /source/repos/test_openmp/build-clang-msvc/CMakeFiles/CMakeOutput.log".
Consulte también "C: / Usuarios / [NOMBRE DE USUARIO] /source/repos/test_openmp/build-clang-msvc/CMakeFiles/CMakeError.log".
  • Clang y Ninja, aparte de MSVC:, mkdir build-clang-ninjaluego cmake -G Ninja -DCMAKE_CXX_COMPILER=clang-cl ..(desde la carpeta recién creada y cambiando la PATHvariable de entorno para que los que no sean msvc se encuentren primero), pero falla con el siguiente error:
- La identificación del compilador CXX es Clang 9.0.0 con línea de comandos similar a MSVC
- Compruebe si funciona el compilador CXX: C: / Archivos de programa / LLVM / bin / clang-cl.exe
- Compruebe si funciona el compilador CXX: C: / Archivos de programa / LLVM / bin / clang-cl.exe - roto
Error de CMake en C: / Archivos de programa / CMake / share / cmake-3.15 / Módulos / CMakeTestCXXCompiler.cmake: 53 (mensaje):
  El compilador de C ++

    "C: / Archivos de programa / LLVM / bin / clang-cl.exe"

  no puede compilar un programa de prueba simple.

  Falla con el siguiente resultado:

    Cambiar Dir: C: / Usuarios / [NOMBRE DE USUARIO] / source / repos / test_openmp / buid-clang-ninja / CMakeFiles / CMakeTmp

    Ejecute los comandos de compilación: C: /Ninja/ninja.exe cmTC_50b73 && [1/2] Construyendo objetos CXX CMakeFiles \ cmTC_50b73.dir \ testCXXCompiler.cxx.obj
    [2/2] Vinculación del ejecutable CXX cmTC_50b73.exe
    FALLIDO: cmTC_50b73.exe
    cmd.exe / C "cd. &&" C: \ Archivos de programa \ CMake \ bin \ cmake.exe "-E vs_link_exe --intdir = CMakeFiles \ cmTC_50b73.dir --rc = rc --mt = CMAKE_MT-NOTFOUND - manifiestos: 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 / machine: x64 / debug / machine: INC64MENT / debug subsistema: consola kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib && cd ".
    RC Pass 1: el comando "rc / fo CMakeFiles \ cmTC_50b73.dir / manifest.res CMakeFiles \ cmTC_50b73.dir / manifest.rc" falló (código de salida 0) con el siguiente resultado:
    El sistema no puede encontrar el archivo especificado
    ninja: compilación detenida: el subcomando falló.





  CMake no podrá generar correctamente este proyecto.
Pila de llamadas (la llamada más reciente primero):
  CMakeLists.txt: 2 (proyecto)


- ¡Configuración incompleta, se produjeron errores!
Consulte también "C: / Usuarios / [NOMBRE DE USUARIO] /source/repos/test_openmp/buid-clang-ninja/CMakeFiles/CMakeOutput.log".
Consulte también "C: / Usuarios / [NOMBRE DE USUARIO] /source/repos/test_openmp/buid-clang-ninja/CMakeFiles/CMakeError.log".

¿Alguna idea sobre cómo proceder con el sonido metálico? Creo que es mi mejor opción para lo que quiero lograr (compilar mi programa de prueba con soporte para OpenMP 4.5 o posterior y producir .liby .dll).

Publicaciones / páginas web relacionadas que he verificado pero que no han sido útiles para resolver esto:

apalomer
fuente
¿Intentó cargar el archivo vcvarsXX.bat relevante antes de emitir el comando cmake?
Le Ngoc Thuong
No tengo idea, así que supongo que no. Acabo de abrir un símbolo del sistema, navego a la carpeta de compilación y ejecuto los comandos CMake que escribí. ¿Cómo puedo cargar este archivo relevante?
apalomer
1
Estoy trabajando con un proyecto que se construye con MSVC. Siempre que quiera compilar el proyecto, primero necesito ejecutar "% VCINSTALLDIR% \ vcvarsall.bat amd64". Además, según la respuesta en esta página stackoverflow.com/questions/22585874/… . También recomienda que "cargue el archivo vcvarsXX.bat relevante (por ejemplo," <Su ubicación de Visual Studio> \ VC \ vcvarsall.bat "x86)". Me he enfrentado al mismo mensaje de error que tú cuando me olvido de ejecutar vcvarsall.bat
Le Ngoc Thuong
Eso definitivamente me hizo seguir adelante. Ahora estoy atascado en el paso siguiente: Could NOT find OpenMP_CXX (missing: OpenMP_CXX_FLAGS OpenMP_CXX_LIB_NAMES). Investigaré este nuevo error y si no encuentro una respuesta, publicaré una nueva pregunta. ¡Gracias!
apalomer

Respuestas:

4

Pude duplicar este error para el caso Clang + MSVC . Debido a que estamos tratando de usar el compilador personalizado de Visual-Studio desde fuera de Visual Studio (es decir, la línea de comandos), es necesario inicializar el entorno de compilación VS en nuestra línea de comandos antes de usar el compilador. Los VCVarsXX.batarchivos logran esto; son parte de las herramientas del símbolo del sistema VS. Así que por la selección de su arquitectura ( x86, x64, etc.) y ejecutar el script, esto debería permitir CMake para construir el programa de prueba simple con clang-cly proceder. Aquí es donde se encuentra para 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
...

Para ampliar el tema de OpenMP, personalmente encontré que usar find_package(OpenMP REQUIRED)es bastante infructuoso. Como mencionó, también recibí este error de CMake:

Could NOT find OpenMP_CXX (missing: OpenMP_CXX_FLAGS OpenMP_CXX_LIB_NAMES)

Hay algunas sugerencias en este sitio (por ejemplo, aquí y aquí ) que afirman que completar todas las variables manualmente permite FindOpenMP.cmakeencontrar con éxito las bibliotecas. Intenté esto con su archivo CMake de ejemplo, con cierto éxito:

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)

Esto logró "encontrar" las bibliotecas en el segundo intento de configuración de CMake (el primero siempre produjo el mismo Could NOT find OpenMP_CXXerror que antes):

>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

Sin embargo , esto no pudo generar el ejecutable, ya que ninguna de las variables CMake OpenMP (en particular OpenMP_CXX_LIBRARIES) realmente apuntan a la ubicación de la biblioteca. Las deficiencias de CMake FindOpenMP.cmakese han planteado en el sitio del problema de CMake aquí , y también parece haber limitaciones relevantes en el extremo LLVM / Clang.


De todos modos, la forma más limpia en que pude hacer que el ejemplo funcionara fue deshacerse por find_package()completo. Lo siguiente me permitió generar con éxito el sistema de compilación y compilar y ejecutar el ejecutable:

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)
cuadrados
fuente
CMake 3.17 incorpora soporte para esto que resuelve este error. Los errores se corrigen en este commit.
apalomer
@apalomer ¡Gracias! Si conoce una solución más simple, ¡publique una!
squareskittles
Correr vcvarsall.batno me pone clang-cl en la RUTA. ¿Alguna idea de por qué?
Alex Reinking
@AlexReinking ¿Tienes instalado clang-cl? Es difícil saberlo sin conocer su configuración y cómo instaló estos componentes. ¡Te animo a hacer otra pregunta, si es necesario!
squareskittles
Sí, se instala a través del instalador VS2019
Alex Reinking