Configure o CMake no Windows para usar o clang na linha de comando para obter suporte moderno ao OpenMP

11

Eu tenho um pequeno projeto de teste que usa o OpenMP para paralelização. Meu objetivo é compilá-lo para que ele produza .dlle .libpara bibliotecas (porque meu projeto real vincula-se a bibliotecas externas distribuídas usando esses tipos), com suporte ao OpenMP 4.5 ou mais recente e faça-o na linha de comando para que possa ser feito em uma janela de encaixe para teste e verificação (a parte do docker está fora do escopo desta pergunta, é apenas para referência sobre por que eu preciso que ela funcione na linha de comando). Posso compilar este projeto com diferentes compiladores com os quais não estou feliz:

  • MSVC:, mkdir build-msvcentão cmake ..(da pasta recém-criada) e finalmente cmake --build . --config Release. Isso compila bem, mas suporta apenas o OpenMP 2.0, portanto, não é uma boa opção para o meu projeto real.
  • Intel Parallel Studio:, mkdir build-intelentão cmake .. -T "Intel C++ Compiler 19.0"(da pasta recém-criada) e finalmente cmake --build . --config Release. Isso suporta o OpenMP 5.0, mas suas licenças são muito caras para mim.
  • MinGW x64 g ++:, mkdir build-g++então cmake .. -G "MinGW Makefiles"(da pasta recém-criada) e finalmente cmake --build .. Ele suporta o OpenMP 4.5, mas este compilador não é compatível com .lib(até onde eu sei), o que eu já mencionei, é necessário para mim.

Eu tentei sem sucesso usar o clang:

  • CLANG do MSVC:, mkdir build-clang-msvcthen cmake -G Ninja -DCMAKE_CXX_COMPILER=clang-cl ..(da pasta recém-criada), mas falha com o seguinte erro:
- A identificação do compilador CXX é Clang 8.0.1 com linha de comando semelhante ao MSVC
- Verifique se o compilador CXX está funcionando: C: / Arquivos de Programas (x86) / Microsoft Visual Studio / 2019 / Community / VC / Tools / Llvm / bin / clang-cl.exe
- Verifique se o compilador CXX está funcionando: C: / Arquivos de Programas (x86) / Microsoft Visual Studio / 2019 / Comunidade / VC / Ferramentas / Llvm / bin / clang-cl.exe - quebrado
Erro do CMake em C: / Arquivos de Programas / CMake / share / cmake-3.15 / Modules / CMakeTestCXXCompiler.cmake: 53 (message):
  O compilador C ++

    "C: / Arquivos de Programas (x86) / Microsoft Visual Studio / 2019 / Comunidade / VC / Ferramentas / Llvm / bin / clang-cl.exe"

  não é capaz de compilar um programa de teste simples.

  Falha com a seguinte saída:

    Alterar diretório: C: / Users / [NOME DO USUÁRIO] / source / repos / test_openmp / build-clang-msvc / CMakeFiles / CMakeTmp

    Executar comando (s) de compilação: C: /PROGRA~2/MICROS~1/2019/COMMUN~1/Common7/IDE/COMMON~1/MICROS~1/CMake/Ninja/ninja.exe cmTC_bd131 && [1/2] Criando o objeto CXX CMakeFiles \ cmTC_bd131.dir \ testCXXCompiler.cxx.obj
    [2/2] Vinculando o executável CXX cmTC_bd131.exe
    FAILED: cmTC_bd131.exe
    cmd.exe / C "cd. &&" C: \ Arquivos de Programas \ CMake \ bin \ cmake.exe "-E vs_link_exe --intdir = CMakeFiles \ cmTC_bd131.dir --rc = rc --mt = CMAKE_MT-NOTFOUND - manifestos - C: \ PROGRA ~ 1 \ MINGW- ~ 1 \ X86_64 ~ 1.0-P \ mingw64 \ bin \ ld.exe / não CMakeFiles \ cmTC_bd131.dir \ testCXXCompiler.cxx.obj /out:cmTC_bd131.exe / implib: cmTC_bd131.lib /pdb:cmTC_bd131.pdb /versionAdd.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: comando "rc / fo CMakeFiles \ cmTC_bd131.dir / manifest.res CMakeFiles \ cmTC_bd131.dir / manifest.rc" falhou (código de saída 0) com a seguinte saída:
    O sistema não pode encontrar o arquivo especificado
    ninja: build parado: subcomando falhou.





  O CMake não poderá gerar corretamente este projeto.
Pilha de chamadas (chamada mais recente primeiro):
  CMakeLists.txt: 2 (projeto)


- Configurando incompleto, ocorreram erros!
Consulte também "C: / Users / [NOME DO USUÁRIO] /source/repos/test_openmp/build-clang-msvc/CMakeFiles/CMakeOutput.log".
Consulte também "C: / Users / [NOME DO USUÁRIO] /source/repos/test_openmp/build-clang-msvc/CMakeFiles/CMakeError.log".
  • Clang e Ninja, além do MSVC:, mkdir build-clang-ninjathen cmake -G Ninja -DCMAKE_CXX_COMPILER=clang-cl ..(da pasta recém-criada e alterando a PATHvariável de ambiente para que os não-msvc sejam encontrados primeiro), mas falha com o seguinte erro:
- A identificação do compilador CXX é Clang 9.0.0 com linha de comando semelhante ao MSVC
- Verifique se o compilador CXX está funcionando: C: / Arquivos de Programas / LLVM / bin / clang-cl.exe
- Verifique se o compilador CXX está funcionando: C: / Arquivos de Programas / LLVM / bin / clang-cl.exe - quebrado
Erro do CMake em C: / Arquivos de Programas / CMake / share / cmake-3.15 / Modules / CMakeTestCXXCompiler.cmake: 53 (message):
  O compilador C ++

    "C: / Arquivos de Programas / LLVM / bin / clang-cl.exe"

  não é capaz de compilar um programa de teste simples.

  Falha com a seguinte saída:

    Alterar diretório: C: / Users / [NOME DO USUÁRIO] / source / repos / test_openmp / buid-clang-ninja / CMakeFiles / CMakeTmp

    Executar comando (s) de compilação: C: /Ninja/ninja.exe cmTC_50b73 && [1/2] Criando o objeto CXX CMakeFiles \ cmTC_50b73.dir \ testCXXCompiler.cxx.obj
    [2/2] Vinculando o executável CXX cmTC_50b73.exe
    FAILED: cmTC_50b73.exe
    cmd.exe / C "cd. &&" C: \ Arquivos de Programas \ CMake \ bin \ cmake.exe "-E vs_link_exe --intdir = CMakeFiles \ cmTC_50b73.dir --rc = rc --mt = CMAKE_MT-NOTFOUND - manifestos - CMAKE_LINKER-NOTFOUND / nologo CMakeFiles \ cmTC_50b73.dir \ testCXXCompiler.cxx.obj /out:cmTC_50b73.exe /implib:cmTC_50b73.lib /pdb:cmTC_50b73.pdb /versionified.0 / machine: x64 / debug subsistema: 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: comando "rc / fo CMakeFiles \ cmTC_50b73.dir / manifest.res CMakeFiles \ cmTC_50b73.dir / manifest.rc" falhou (código de saída 0) com a seguinte saída:
    O sistema não pode encontrar o arquivo especificado
    ninja: build parado: subcomando falhou.





  O CMake não poderá gerar corretamente este projeto.
Pilha de chamadas (chamada mais recente primeiro):
  CMakeLists.txt: 2 (projeto)


- Configurando incompleto, ocorreram erros!
Consulte também "C: / Users / [NOME DO USUÁRIO] /source/repos/test_openmp/buid-clang-ninja/CMakeFiles/CMakeOutput.log".
Consulte também "C: / Users / [NOME DO USUÁRIO] /source/repos/test_openmp/buid-clang-ninja/CMakeFiles/CMakeError.log".

Alguma idéia de como proceder com o clang? Eu acho que é a minha melhor opção para o que eu quero alcançar (compile meu programa de teste com suporte ao OpenMP 4.5 ou mais recente e produza .libe .dll).

Postagens / páginas da web relacionadas que verifiquei, mas que não foram úteis para resolver isso:

apalômero
fonte
Você tentou carregar o arquivo vcvarsXX.bat relevante antes de emitir o comando cmake?
Le Ngoc Thuong
Eu não tenho ideia, então acho que não. Acabei de abrir um prompt de comando, navegue até a pasta build e execute os comandos do CMake que escrevi. Como posso carregar este arquivo relevante?
Apalomer 11/10/19
11
Estou trabalhando com um projeto que cria com o MSVC. Sempre que quero criar o projeto, sempre preciso executar "% VCINSTALLDIR% \ vcvarsall.bat amd64" primeiro. Além disso, com base na resposta nesta página stackoverflow.com/questions/22585874/… . Ele também recomenda que "carregue o arquivo vcvarsXX.bat relevante (por exemplo," <Local do seu Visual Studio> \ VC \ vcvarsall.bat "x86)". Eu enfrentei a mesma mensagem de erro que você quando eu esqueço de executar o vcvarsall.bat
Le Ngoc Thuong
Isso definitivamente me fez seguir em frente. Agora eu estou preso no próximo passo: Could NOT find OpenMP_CXX (missing: OpenMP_CXX_FLAGS OpenMP_CXX_LIB_NAMES). Analisarei esse novo erro e, se não encontrar uma resposta, postarei uma nova pergunta. Obrigado!
Apalomer 11/10/19

Respostas:

4

Consegui duplicar esse erro no caso Clang + MSVC . Como estamos tentando usar o compilador personalizado do Visual Studio de fora do Visual Studio (ou seja, a linha de comando), é necessário inicializar o ambiente de compilação VS em nossa linha de comando antes de usar o compilador. Os VCVarsXX.batarquivos fazem isso; eles fazem parte das ferramentas do prompt de comando do VS. Portanto, escolhendo sua arquitetura ( x86, x64etc) e executando o script, isso deve permitir ao CMake criar o programa de teste simples clang-cle prosseguir. Aqui está o local para o 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 expandir a questão do OpenMP, eu pessoalmente achei find_package(OpenMP REQUIRED)bastante inútil. Como você mencionou, também recebi este erro do CMake:

Could NOT find OpenMP_CXX (missing: OpenMP_CXX_FLAGS OpenMP_CXX_LIB_NAMES)

Existem algumas sugestões neste site (por exemplo, aqui e aqui ) alegando que o preenchimento de todas as variáveis ​​manualmente permite FindOpenMP.cmakeencontrar com sucesso as bibliotecas. Eu tentei isso com o seu arquivo CMake de exemplo, com algum sucesso:

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)

Isso conseguiu "localizar" as bibliotecas na segunda tentativa de configuração do CMake (a primeira sempre produzia o mesmo Could NOT find OpenMP_CXXerro de 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

No entanto , isso falhou ao criar o executável, pois nenhuma das variáveis ​​do CMake OpenMP (particularmente OpenMP_CXX_LIBRARIES) aponta para o local da biblioteca. As deficiências do CMake FindOpenMP.cmakeforam levantadas no site de assuntos do CMake aqui , e também parece haver limitações relevantes no final do LLVM / Clang.


Independentemente disso, a maneira mais limpa de obter o exemplo de trabalho foi abandonar find_package()completamente. O seguinte me permitiu gerar com êxito o sistema de compilação, compilar e executar o executável:

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
fonte
O CMake 3.17 incorpora suporte para isso que resolve esse erro. Os erros são corrigidos neste commit.
apalomer 21/02
@apalomer Thanks! Se você conhece uma solução mais simples, poste uma!
squareskittles
Correr vcvarsall.batnão coloca clang-cl no PATH para mim. Alguma idéia do porquê?
Alex Reinking
@AlexReinking Você tem o clang-cl instalado? É difícil saber sem conhecer sua configuração e como você instalou esses componentes. Convido você a fazer outra pergunta, se necessário!
squareskittles
Sim, é instalado através do instalador do VS2019
Alex Reinking