我正在开发一个当前基于mac的业余爱好项目,涉及一些并行化,我想使用OpenMP,因为这看起来非常便携,而且在我的情况下相对容易实现。经过一些在线阅读后,我发现gcc和clang都可以在当前版本中使用-fopenmp进行编译。但是,Xcode中包含的默认macOS编译器被剥夺了此功能。所以,我在我的macOS上安装了gcc 7和clang 5。由于我的项目是通过CMake构建的,所以我编写了以下makefile。
cmake_minimum_required(VERSION 3.0)
project(Project C CXX)
#SET(CMAKE_C_COMPILER /usr/local/bin/gcc-7)
#SET(CMAKE_CXX_COMPILER /usr/local/bin/gcc-7)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -O2 -mavx2 -march=haswell -flto=thin -g0")
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lpthread")
set(Boost_USE_STATIC_LIBS OFF)
set(Boost_USE_MULTITHREADED ON)
set(Boost_USE_STATIC_RUNTIME OFF)
FIND_PACKAGE(Boost 1.65 COMPONENTS filesystem system thread atomic chrono regex)
FIND_PACKAGE(OpenCV REQUIRED core imgproc imgcodecs calib3d)
set(HDF5_USE_STATIC_LIBRARIES ON)
set(HDF5_ROOT /usr/local/HDF_GROUP/HDF5/1.10.0/)
FIND_PACKAGE(HDF5 REQUIRED)
include_directories(${CMAKE_SOURCE_DIR}/include ${Boost_INCLUDE_DIRS} ${OpenCV_INCLUDE_DIRS} ${HDF5_INCLUDE_DIRS})
add_executable(Project /path/to/many/files..)
TARGET_LINK_LIBRARIES(Project ${Boost_LIBRARIES})
TARGET_LINK_LIBRARIES(Project ${OpenCV_LIBS})
TARGET_LINK_LIBRARIES(Project ${HDF5_LIBRARIES})
在禁用CMAKE_CXX_COMPILER设置的此版本中,代码编译,链接和运行没有任何障碍。一旦我将CMake设置为使用gcc或vanilla-clang进行完全相同的项目而没有任何进一步的更改,编译完成没有任何问题,但链接失败。链接器报告数百个缺失的符号,范围从几个OpenCV符号到大多数libc ++之类的东西,如
"std::basic_ostream<char, std::char_traits<char> >& std::endl<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&)", referenced from:
_main in main.cpp.o
因此,我显然缺少一些基本的东西。使用vanilla-clang,我尝试添加-L / usr / local / opt / llvm / lib将链接器指向clang附带的lib。不幸的是,这没有任何改变。
我很欣赏有关此事的任何暗示。谢谢
答案 0 :(得分:2)
我遇到了同样的问题,需要一整天才能找到解决方案。我正在使用Mac-Sierra 10.13.4。我想使用Opencv3(我认为opencv2也出现了同样的问题)和openMP。我实际上使用Clion作为IDE(CLion使用cmake来配置项目,与其他IDE不同),所以我必须编写CMakeLists.txt文件。
使用gcc作为openCV和openMP的编译器存在冲突。如果你使用gcc作为编译器,那么它会给opencv带来错误:
OS X上的imwrite()错误:未定义的符号
您需要在OS X上专门使用llvm编译器来解决此问题。接下来,我给出了在Mac-Sierra上使用OpenCV和OpenMP的正确代码:
cmake_minimum_required(VERSION 3.10)
project(MyOpenCVTest)
set(CMAKE_CXX_STANDARD 11)
add_executable(MyOpenCVTest main.cpp)
# set("OpenCV_DIR" "/modules/opencv/3.4.1/share/OpenCV/")
set(CMAKE_PREFIX_PATH "/usr/local/Cellar/opencv@3/")
set(OpenCV_INCLUDE_DIRS "/usr/local/Cellar/opencv@3/include/")
set(OpenCV_LIBS "/usr/local/Cellar/opencv@3/lib/")
find_package(OpenCV REQUIRED)
message(STATUS "OpenCV library status:")
message(STATUS " version: ${OpenCV_VERSION}")
message(STATUS " libraries: ${OpenCV_LIBS}")
message(STATUS " include path: ${OpenCV_INCLUDE_DIRS}")
if(UNIX)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -std=gnu++0x")
endif()
set(CMAKE_C_COMPILER "/usr/local/Cellar/llvm/6.0.0/bin/clang")
set(CMAKE_CXX_COMPILER "/usr/local/Cellar/llvm/6.0.0/bin/clang++")
set(OPENMP_LIBRARIES "/usr/local/Cellar/llvm/6.0.0/lib")
set(OPENMP_INCLUDES "/usr/local/Cellar/llvm/6.0.0/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)
include_directories( ${OpenCV_INCLUDE_DIRS} )
target_link_libraries( MyOpenCVTest ${OpenCV_LIBS})
TARGET_LINK_LIBRARIES(MyOpenCVTest opencv_core opencv_highgui opencv_imgproc opencv_imgcodecs)
您可能想要设置,例如set(CMAKE_EXE_LINKER_FLAGS“$ {CMAKE_EXE_LINKER_FLAGS} -lpthread”),以便链接器自动检测相应的pthread库
做
brew重新安装llvm
安装llvm编译器。 请注意,您不能在Mac-Sierra上使用gcc编译器来处理需要openMP和openCV的项目。您需要使用llvm编译器。
验证llvm和opencv安装目录的正确位置。
答案 1 :(得分:1)
如果使用gcc编译器驱动程序执行链接,请将编译器更改为&#39; g ++&#39;来自&#39; gcc&#39;,g ++自动引入标准c ++库,而gcc没有,或者添加-lstdc ++,可能还需要其他的,但使用g ++作为编译器驱动程序通常更容易。