我使用Homebrew的最新CMake(3.9.3)以及Brew的LLVM 5.0.0,因为Clang在这里有OpenMP支持。
这适用于CMake 3.8.2和LLVM 5。
在我的CMakeLists.txt
我有
find_package( OpenMP )
后来我想做
if( OpenMP_CXX_FOUND )
然而,CMake似乎没有接受find_package
指令。
我用CMake运行
cmake .. -DCMAKE_BUILD_TYPE=Debug -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_C_COMPILER=clang -DUSE_WERROR=ON
在那里我检查了clang
和clang++
正确指向/usr/local/opt/llvm/bin/clang
和/usr/local/opt/llvm/bin/clang++
我得到的只是这两行:
-- Could NOT find OpenMP_C (missing: OpenMP_C_FLAGS OpenMP_C_LIB_NAMES) (found version "1.0")
-- Could NOT find OpenMP_CXX (missing: OpenMP_CXX_FLAGS OpenMP_CXX_LIB_NAMES) (found version "1.0")
如果我自己设置OpenMP_C_FLAGS
(使用-DOpenMP_C_FLAGS=-fopenmp=libomp
),它会将错误更改为
-- Could NOT find OpenMP_C (missing: OpenMP_C_LIB_NAMES) (found version "3.1")
请注意,它会更改版本号,因此必须找到一些东西,对吗?
我错过了什么才能正常工作?
好吧,似乎在CMake提供的FindOpenMP.cmake
中我们做了一个try_compile
,它无声地失败(因为我们做了很多次,而且大多数都会失败,这是有道理的)。但是,对于Clang,提供了-Werror
标志,由于未使用的命令行参数而失败。我可以这样补充:
if(APPLE)
if(CMAKE_C_COMPILER_ID STREQUAL "Clang")
set(OpenMP_C_FLAG "-fopenmp=libomp -Wno-unused-command-line-argument")
endif()
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
set(OpenMP_CXX_FLAG "-fopenmp=libomp -Wno-unused-command-line-argument")
endif()
endif()
我的项目,因为我知道-fopenmp=libomp
将为这个Clang工作。
这是正确的做法吗?
该消息基本上告诉您必须提供库的路径和库的名称。以下示例应该可以解决您的问题(另请参阅find_package(OpenMP))。请注意,我使用命令“brew install llvm”使用brew安装。前四行只是为了完整性。
set(CMAKE_C_COMPILER "/usr/local/Cellar/llvm/5.0.1/bin/clang")
set(CMAKE_CXX_COMPILER "/usr/local/Cellar/llvm/5.0.1/bin/clang++")
set(OPENMP_LIBRARIES "/usr/local/Cellar/llvm/5.0.1/lib")
set(OPENMP_INCLUDES "/usr/local/Cellar/llvm/5.0.1/include")
OPTION (USE_OpenMP "Use OpenMP to enamble <omp.h>" ON)
# Find OpenMP
if(APPLE AND USE_OpenMP)
if(CMAKE_C_COMPILER_ID MATCHES "Clang")
set(OpenMP_C "${CMAKE_C_COMPILER}")
set(OpenMP_C_FLAGS "-fopenmp=libomp -Wno-unused-command-line-argument")
set(OpenMP_C_LIB_NAMES "libomp" "libgomp" "libiomp5")
set(OpenMP_libomp_LIBRARY ${OpenMP_C_LIB_NAMES})
set(OpenMP_libgomp_LIBRARY ${OpenMP_C_LIB_NAMES})
set(OpenMP_libiomp5_LIBRARY ${OpenMP_C_LIB_NAMES})
endif()
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
set(OpenMP_CXX "${CMAKE_CXX_COMPILER}")
set(OpenMP_CXX_FLAGS "-fopenmp=libomp -Wno-unused-command-line-argument")
set(OpenMP_CXX_LIB_NAMES "libomp" "libgomp" "libiomp5")
set(OpenMP_libomp_LIBRARY ${OpenMP_CXX_LIB_NAMES})
set(OpenMP_libgomp_LIBRARY ${OpenMP_CXX_LIB_NAMES})
set(OpenMP_libiomp5_LIBRARY ${OpenMP_CXX_LIB_NAMES})
endif()
endif()
if(USE_OpenMP)
find_package(OpenMP REQUIRED)
endif(USE_OpenMP)
if (OPENMP_FOUND)
include_directories("${OPENMP_INCLUDES}")
link_directories("${OPENMP_LIBRARIES}")
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(OPENMP_FOUND)
您可能想要设置,例如set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lpthread")
使链接器自动检测适当的pthread库(请参阅pthread和wiki)。
显然,案件很重要。对于一个不相关的项目,我可以使用它
find_package ( OPENMP REQUIRED )
这不起作用:
find_package ( OpenMP REQUIRED )
使用该指令,无需手动设置所有其他标志。 cmake 3.13.2,clang-1000.11.45.5(High Sierra)