使用此 CMake 链接命令仍然需要针对 OpenMP::OpenMP_CXX 的显式链接吗?

Hir*_*rek 2 c++ gcc cmake openmp

我正在使用 CMake 和 GNU 的并行算法以及以下代码片段CMakeLists.txt

if (OPENMP_FOUND)
    set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
    set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
    set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${OpenMP_EXE_LINKER_FLAGS}")
endif().
Run Code Online (Sandbox Code Playgroud)

这会让下面的命令变得多余吗?

target_link_libraries(MyTarget OpenMP::OpenMP_CXX)?
Run Code Online (Sandbox Code Playgroud)

我试图在这里找到答案,但没有成功。使用命令打印上述变量的输出后message,我看到最后两个是空的。

-- OpenMP_CXX_FLAGS are: -fopenmp
-- OpenMP_C_FLAGS are: -Xclang -fopenmp 
-- CMAKE_EXE_LINKER_FLAGS are:  
-- OpenMP_EXE_LINKER_FLAGS are:
Run Code Online (Sandbox Code Playgroud)

我尝试在这里查找变量定义,但没有找到更多信息。一个小测试程序使用:

__gnu_parallel::for_each 
Run Code Online (Sandbox Code Playgroud)

无论我是否包含以下内容,都会并行运行:

target_link_libraries(MyTarget OpenMP::OpenMP_CXX) 
Run Code Online (Sandbox Code Playgroud)

这使我得出结论:没有必要。真的吗?

我的gccg++-9 (Homebrew GCC 9.3.0_1) 9.3.0.

squ*_*les 5

而代码:

set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
Run Code Online (Sandbox Code Playgroud)

将使用正确的-fopenmp选项更新您的 C++ 编译标志,这是一种过时的方法。

通过链接提供的导入目标OpenMP::OpenMP_CXX,您可以达到相同的效果,因为该目标-fopenmp在其INTERFACE_COMPILE_OPTIONS属性中提供了编译选项。同样,此导入的目标会传播您可能需要的任何依赖 OpenMP 库(取决于语言),否则需要额外的手动步骤来链接到${OpenMP_CXX_LIBRARIES}. 因此,直接链接到导入的目标OpenMP::OpenMP_CXX应该是首选方法;它为您节省了额外的手动步骤并遵循现代 CMake 公理:

target_link_libraries(MyTarget PRIVATE OpenMP::OpenMP_CXX)
Run Code Online (Sandbox Code Playgroud)

请注意,CMake OpenMP 查找模块及其提供的变量/目标的官方文档位于此处