在catkin_make/CMake中链接MKL出现未定义引用错误该如何解决
修复MKL链接报错方案
核心报错原因
- 自定义的
GCC_COVERAGE_LINK_FLAGS变量不会被CMake默认识别,你配置的MKL链接参数完全没有生效 - MKL接口位数不匹配:你当前写的是
-lmkl_intel_ilp64(ILP64 64位整数接口),但报错中出现mkl_spblas_lp64_xxx前缀的未定义符号,说明你的依赖库(OpenCV、Eigen)编译时使用的是LP64 32位整数接口的MKL,接口不匹配导致符号找不到 - 线程模型不匹配:你配置的是
-lmkl_gnu_thread(GNU线程模型),但报错中缺失的符号来自libmkl_intel_thread.so(Intel线程模型),和你配置的线程库不匹配
具体修复步骤
- 替换CMake中的MKL配置逻辑,不要使用自定义的链接变量,修改为CMake原生可识别的配置:
在所有用到MKL的CMakeLists.txt开头添加以下内容:
# 调用CMake自带的FindMKL模块检测MKL路径和库 find_package(MKL REQUIRED) # 导入MKL头文件路径 include_directories(${MKL_INCLUDE_DIRS}) # 全局定义EIGEN_USE_MKL_ALL宏,必须写在add_executable/add_library之前 add_definitions(-DEIGEN_USE_MKL_ALL) # 配置MKL链接参数,根据依赖库的接口选择LP64/ILP64,这里默认选和报错匹配的LP64+GNU线程模型 set(MKL_LINK_FLAGS "-L${MKLROOT}/lib/intel64 -Wl,--no-as-needed -lmkl_intel_lp64 -lmkl_gnu_thread -lmkl_core -lgomp -lpthread -lm -ldl") # 将MKL链接参数写入CMake原生的可执行文件和动态库链接变量 set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${MKL_LINK_FLAGS}") set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${MKL_LINK_FLAGS}")
- 针对每个编译目标,显式链接MKL库,放在其他依赖库的前面:
# 你的目标生成语句示例 add_executable(your_target src/your_code.cpp) target_link_libraries(your_target ${MKL_LIBRARIES} # 其他依赖放在MKL后面 ${OpenCV_LIBS} )
- 编译前先初始化MKL环境变量,确保编译时能正确找到MKL路径:
在执行catkin_make的终端先运行:
source /opt/intel/oneapi/mkl/2021.3.0/env/vars.sh intel64
再执行catkin_make -j1即可。
- 如果依然报错,重新编译依赖的OpenCV库,编译时指定和当前项目完全一致的MKL接口、线程模型参数,避免跨版本或接口不兼容问题。
内容的提问来源于stack exchange,提问作者ad99
相关产品推荐
相关产品推荐

