Сконфигурируйте CMake в Windows для использования clang из командной строки, чтобы получить современную поддержку OpenMP - PullRequest
9 голосов
/ 08 октября 2019

У меня небольшой тест проект , который использует OpenMP для распараллеливания. Моя цель состоит в том, чтобы скомпилировать его так, чтобы он генерировал .dll и .lib для библиотек (потому что мой реальный проект ссылается на внешние библиотеки, распространяемые с использованием этих типов), с поддержкой OpenMP 4.5 или более новой версии и делает это из командной строки, чтобы он могбыть сделано на докере для тестирования и проверки (часть докера выходит за рамки этого вопроса, это просто для справки о том, почему мне нужно, чтобы он работал из командной строки). Я могу скомпилировать этот проект с разными компиляторами, которые меня не устраивают:

  • MSVC: mkdir build-msvc, затем cmake .. (из вновь созданной папки) и, наконец, cmake --build . --config Release. Это прекрасно компилируется, но поддерживает только OpenMP 2.0, поэтому не подходит для моего реального проекта.
  • Intel Parallel Studio: mkdir build-intel, затем cmake .. -T "Intel C++ Compiler 19.0" (из вновь созданной папки) и, наконец, cmake --build . --config Release,Это поддерживает OpenMP 5.0, но его лицензии довольно дороги для меня.
  • MinGW x64 g ++: mkdir build-g++, затем cmake .. -G "MinGW Makefiles" (из вновь созданной папки) и, наконец, cmake --build .. Он поддерживает OpenMP 4.5, но этот компилятор несовместим с .lib (насколько я знаю), который я уже упоминал, мне необходимо.

Я безуспешно пытался использовать clang:

  • CLANG из MSVC: mkdir build-clang-msvc, затем cmake -G Ninja -DCMAKE_CXX_COMPILER=clang-cl .. (из вновь созданной папки), но происходит сбой со следующей ошибкой:
-- The CXX compiler identification is Clang 8.0.1 with MSVC-like command-line
-- 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 -- broken
CMake Error at C:/Program Files/CMake/share/cmake-3.15/Modules/CMakeTestCXXCompiler.cmake:53 (message):
  The C++ compiler

    "C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Tools/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/build-clang-msvc/CMakeFiles/CMakeTmp

    Run Build Command(s):C:/PROGRA~2/MICROS~1/2019/COMMUN~1/Common7/IDE/COMMON~1/MICROS~1/CMake/Ninja/ninja.exe cmTC_bd131 && [1/2] Building CXX object CMakeFiles\cmTC_bd131.dir\testCXXCompiler.cxx.obj
    [2/2] Linking CXX executable 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 --manifests  -- 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: command "rc /fo CMakeFiles\cmTC_bd131.dir/manifest.res CMakeFiles\cmTC_bd131.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.
Call Stack (most recent call first):
  CMakeLists.txt:2 (project)


-- Configuring incomplete, errors occurred!
See also "C:/Users/[USER NAME]/source/repos/test_openmp/build-clang-msvc/CMakeFiles/CMakeOutput.log".
See also "C:/Users/[USER NAME]/source/repos/test_openmp/build-clang-msvc/CMakeFiles/CMakeError.log".
  • Clang и Ninja, кроме MSVC: mkdir build-clang-ninja, затем cmake -G Ninja -DCMAKE_CXX_COMPILER=clang-cl .. (из вновь созданной папки и изменения переменной окружения PATH, чтобы сначала находить не-msvc), но происходит сбой со следующей ошибкой:
-- The CXX compiler identification is Clang 9.0.0 with MSVC-like command-line
-- Check for working CXX compiler: C:/Program Files/LLVM/bin/clang-cl.exe
-- Check for working CXX compiler: C:/Program Files/LLVM/bin/clang-cl.exe -- broken
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.
Call Stack (most recent call first):
  CMakeLists.txt:2 (project)


-- Configuring incomplete, errors occurred!
See also "C:/Users/[USER NAME]/source/repos/test_openmp/buid-clang-ninja/CMakeFiles/CMakeOutput.log".
See also "C:/Users/[USER NAME]/source/repos/test_openmp/buid-clang-ninja/CMakeFiles/CMakeError.log".

Есть идеи, как поступить с лязгом? Я думаю, что это мой лучший вариант для того, чего я хочу достичь (скомпилировать мою тестовую программу с поддержкой OpenMP 4.5 или более новой версии и получить .lib и .dll).

Связанные посты / веб-страницы, которые я проверил, но которые были бесполезны для решения этой проблемы:

1 Ответ

2 голосов
/ 12 октября 2019

Мне удалось продублировать эту ошибку для случая Clang + MSVC . Поскольку мы пытаемся использовать специальный компилятор Visual-Studio из-за пределов Visual Studio (то есть из командной строки), необходимо инициализировать среду сборки VS в нашей командной строке перед использованием компилятора. Файлы VCVarsXX.bat выполняют это;они являются частью инструментов командной строки VS. Таким образом, выбрав вашу архитектуру (x86, x64 и т. Д.) И запустив сценарий, это должно позволить CMake создать простую тестовую программу с clang-cl и продолжить. Вот где он находится для 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
...

Если говорить о проблеме OpenMP, я лично обнаружил, что использование find_package(OpenMP REQUIRED) довольно бесполезно. Как вы упомянули, я также получил эту ошибку CMake:

Could NOT find OpenMP_CXX (missing: OpenMP_CXX_FLAGS OpenMP_CXX_LIB_NAMES)

На этом сайте есть несколько предложений (например, здесь и здесь ), утверждающих, что заполнениевсе переменные вручную позволяют FindOpenMP.cmake успешно найти библиотеки. Я попытался сделать это с вашим примером файла CMake, но с некоторым успехом:

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)

Это позволило "найти" библиотеки при второй попытке конфигурации CMake (первая всегда выдает ту же ошибку Could NOT find OpenMP_CXX, что и раньше):

>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

Однако не удалось создать исполняемый файл, поскольку ни одна из переменных CMake OpenMP (особенно OpenMP_CXX_LIBRARIES) фактически не указывает на местоположение библиотеки. Недостатки CMake FindOpenMP.cmake были подняты на сайте выпуска CMake здесь , и, по-видимому, также имеются соответствующие ограничения на стороне LLVM / Clang.


Несмотря ни на что, самым чистым способом, которым я смог заставить пример работать, было полностью отказаться от find_package(). Следующее позволило мне успешно сгенерировать систему сборки, скомпилировать и запустить исполняемый файл:

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)
...