在Windows中配置CMake以使用命令行中的clang获得最新的OpenMP支持


11

我有一个使用OpenMP进行并行化的小型测试项目。我的目标是对其进行编译,以使其生成.dll.lib用于库(因为我的真实项目链接到使用这些类型分发的外部库),并且支持OpenMP 4.5或更高版本,并且可以从命令行进行操作,因此可以在docker上完成测试和检查(泊坞窗部分不在此问题的范围内,仅供参考,以说明为什么我需要它在命令行中工作)。我可以使用不满意的其他编译器来编译该项目:

  • 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没有成功:

  • 然后从MSVC中进行CLANG:,mkdir build-clang-msvc然后cmake -G Ninja -DCMAKE_CXX_COMPILER=clang-cl ..(从新创建的文件夹中),但失败并显示以下错误:
-CXX编译器标识是Clang 8.0.1,带有类似MSVC的命令行
-检查工作的CXX编译器:C:/ Program Files(x86)/ Microsoft Visual Studio / 2019 / Community / VC / Tools / Llvm / bin / clang-cl.exe
-检查工作的CXX编译器:C:/ Program Files(x86)/ Microsoft Visual Studio / 2019 / Community / VC / Tools / Llvm / bin / clang-cl.exe-损坏
C:/程序文件/CMake/share/cmake-3.15/Modules/CMakeTestCXXCompiler.cmake处的CMake错误:53(消息):
  C ++编译器

    “ C:/程序文件(x86)/ Microsoft Visual Studio / 2019 /社区/VC/Tools/Llvm/bin/clang-cl.exe”

  无法编译简单的测试程序。

  它失败,并显示以下输出:

    更改目录:C:/ Users / [用户名] / source / repos / test_openmp / build-clang-msvc / CMakeFiles / CMakeTmp

    运行构建命令:C:/PROGRA~2/MICROS~1/2019/COMMUN~1/Common7/IDE/COMMON~1/MICROS~1/CMake/Ninja/ninja.exe cmTC_bd131 && [1/2]构建CXX对象CMakeFiles \ cmTC_bd131.dir \ testCXXCompiler.cxx.obj
    [2/2]链接CXX可执行文件cmTC_bd131.exe
    失败: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-清单-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:控制台kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32 .lib advapi32.lib && cd。”
    RC Pass 1:命令“ rc / fo CMakeFiles \ cmTC_bd131.dir / manifest.res CMakeFiles \ cmTC_bd131.dir / manifest.rc”失败(退出代码0),并显示以下输出:
    该系统找不到指定的文件
    ninja:构建已停止:子命令失败。





  CMake将无法正确生成此项目。
呼叫堆栈(最近的呼叫优先):
  CMakeLists.txt:2(项目)


-配置不完整,发生错误!
另请参阅“ C:/ Users / [用户名] /source/repos/test_openmp/build-clang-msvc/CMakeFiles/CMakeOutput.log”。
另请参阅“ C:/ Users / [用户名] /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),但失败并显示以下错误:
-CXX编译器标识是Clang 9.0.0,带有类似MSVC的命令行
-检查可运行的CXX编译器:C:/ Program Files / LLVM / bin / clang-cl.exe
-检查工作中的CXX编译器:C:/ Program Files / LLVM / bin / clang-cl.exe-损坏
C:/程序文件/CMake/share/cmake-3.15/Modules/CMakeTestCXXCompiler.cmake处的CMake错误:53(消息):
  C ++编译器

    “ C:/程序文件/LLVM/bin/clang-cl.exe”

  无法编译简单的测试程序。

  它失败,并显示以下输出:

    更改目录:C:/ Users / [用户名] / source / repos / test_openmp / buid-clang-ninja / CMakeFiles / CMakeTmp

    运行构建命令:C:/Ninja/ninja.exe cmTC_50b73 && [1/2]构建CXX对象CMakeFiles \ cmTC_50b73.dir \ testCXXCompiler.cxx.obj
    [2/2]链接CXX可执行文件cmTC_50b73.exe
    失败: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-清单-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子系统:控制台kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib && cd。”
    RC Pass 1:命令“ rc / fo CMakeFiles \ cmTC_50b73.dir / manifest.res CMakeFiles \ cmTC_50b73.dir / manifest.rc”失败(退出代码0),并显示以下输出:
    该系统找不到指定的文件
    ninja:构建已停止:子命令失败。





  CMake将无法正确生成此项目。
呼叫堆栈(最近的呼叫优先):
  CMakeLists.txt:2(项目)


-配置不完整,发生错误!
另请参见“ C:/ Users / [用户名] /source/repos/test_openmp/buid-clang-ninja/CMakeFiles/CMakeOutput.log”。
另请参阅“ C:/ Users / [用户名] /source/repos/test_openmp/buid-clang-ninja/CMakeFiles/CMakeError.log”。

关于如何继续使用clang的任何想法?我认为这是我想要实现的最佳选择(在支持OpenMP 4.5或更高版本的情况下编译测试程序并生成.lib.dll)。

我检查过但对解决此问题无用的相关帖子/网页:


您是否在发出cmake命令之前尝试加载相关的vcvarsXX.bat文件?
Le Ngoc Thuong

我不知道,所以我猜不知道。我只是打开命令提示符,导航到build文件夹并执行我编写的CMake命令。如何加载此相关文件?
apalomer

1
我正在使用MSVC构建的项目。每当我要构建项目时,始终总是需要首先运行“%VCINSTALLDIR%\ vcvarsall.bat amd64”。另外,根据此页面上的答案stackoverflow.com/questions/22585874/…。他/她还建议“加载相关的vcvarsXX.bat文件(例如“ <您的Visual Studio位置> \ VC \ vcvarsall.bat” x86)。当我忘记运行vcvarsall.bat时,我遇到了与您相同的错误消息
Le Ngoc Thuong

那肯定使我前进。现在,我坚持在接下来的步骤:Could NOT find OpenMP_CXX (missing: OpenMP_CXX_FLAGS OpenMP_CXX_LIB_NAMES)。我将研究这个新错误,如果找不到答案,我将发布一个新问题。谢谢!
apalomer

Answers:


4

对于Clang + MSVC,我能够复制此错误。因为我们试图从Visual Studio外部(即命令行)使用Visual Studio定制的编译器,所以在使用编译器之前,有必要在命令行中初始化 VS构建环境。这些VCVarsXX.bat文件可以完成此任务;它们是VS Command Prompt工具的一部分。因此,通过选择您的体系结构(x86x64等)并运行脚本,这应该使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)

CMake 3.17包含对此的支持以解决此错误。错误已在提交中修复。
apalomer

@apalomer谢谢!如果您知道更简单的解决方案,请发布一个!
squareskittles

vcvarsall.bat对我来说,运行不会将clang-cl放在PATH中。知道为什么吗?
Alex Reinking

@AlexReinking您安装了clang-cl吗?如果不了解您的设置以及如何安装这些组件,就很难知道。如有必要,我建议您再问一个问题!
方舟

是的,它是通过VS2019安装程序安装的
Alex Reinking
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.