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

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

这会使以下命令变得多余吗?
target_link_libraries(MyTarget OpenMP::OpenMP_CXX)?

我试图找到答案here,但无济于事。使用message命令打印上述变量的输出后,我看到最后两个为空。
-- OpenMP_CXX_FLAGS are: -fopenmp
-- OpenMP_C_FLAGS are: -Xclang -fopenmp
-- CMAKE_EXE_LINKER_FLAGS are:
-- OpenMP_EXE_LINKER_FLAGS are:

我尝试查找变量定义here,但未发现更多内容。一个小型测试程序,使用:
__gnu_parallel::for_each

并行运行,无论我是否包括:
target_link_libraries(MyTarget OpenMP::OpenMP_CXX)

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

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

最佳答案

而代码:

set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")

会使用适当的-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)

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

09-09 23:21
查看更多