基于CMake正确链接Armadillo库的技术问询(Windows+MinGW)
问题描述
在Windows系统使用MinGW编译器搭建基于Armadillo库的C++项目,基础程序可正常运行,但添加依赖Armadillo的自定义库后,运行时提示:
The code execution cannot proceed because the libopenblas.dll was not found. Reinstalling the program may fix this problem.
需解决两个问题:
- 如何通过CMake正确链接Armadillo库?
- 是否可以使用Armadillo提供的预编译
libopenblas.lib,还是必须单独安装BLAS/LAPACK/OPENBLAS?
项目文件结构
ProjectDIR | +-- CMakeLists.txt +-- test.cxx +-- testConfig.h.in +-- thirdParty | +-- armadillo | +-- include +-- lib_win64
注:armadillo/include来自armadillo-14.0.3安装包,armadillo/lib_win64来自该版本的示例文件。
项目代码文件
test.cxx
#include <iostream> #include <armadillo> #include "testConfig.h" int main() { arma::mat A = {{1.0, 2.0, 3.0},{4.0, 5.0, 6.0},{7.0, 8.0, 9.0}}; std::cout << "A:\n" << A << std::endl; std::cout << "A.t():\n" << A.t() << std::endl; std::cout << "A*A.t():\n" << A*A.t() << std::endl; return 0; }
testConfig.h.in
#define MyLatestFrustration_VERSION_MAJOR @MyLatestFrustration_VERSION_MAJOR@ #define MyLatestFrustration_VERSION_MINOR @MyLatestFrustration_VERSION_MINOR@
顶层CMakeLists.txt
cmake_minimum_required(VERSION 3.15) project(MyLatestFrustration VERSION 0.1) add_library(CompilerFlags INTERFACE) target_compile_features(CompilerFlags INTERFACE cxx_std_11) configure_file(testConfig.h.in testConfig.h) add_executable(MyLatestFrustration test.cxx) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/thirdParty/armadillo/include) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/thirdParty/armadillo/lib_win64) #add_subdirectory(custom) target_link_libraries(MyLatestFrustration PUBLIC CompilerFlags ${CMAKE_CURRENT_SOURCE_DIR}/thirdParty/armadillo/lib_win64/libopenblas.lib ) target_include_directories(MyLatestFrustration PUBLIC "${PROJECT_BINARY_DIR}")
自定义库custom相关文件
启用自定义库时,需取消顶层CMakeLists.txt中add_subdirectory(custom)的注释,将MatrixFunctions加入target_link_libraries,并修改test.cxx引入matrices.h并调用f1函数。此时编译正常,但运行时出现DLL缺失错误。
matrices.h
#pragma once #include <armadillo> arma::mat f1(arma::mat A);
matrices.cxx
#include "matrices.h" arma::mat f1(arma::mat A) { arma::mat B = A*A.t(); return B; }
自定义库CMakeLists.txt
add_library(MatrixFunctions matrices.cxx) target_include_directories(MatrixFunctions INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) target_link_libraries(MatrixFunctions PUBLIC CompilerFlags)
解决方案
1. CMake正确链接Armadillo库的方法
改用现代CMake语法优化配置
避免全局include_directories,改用目标级别的依赖管理,确保自定义库能继承Armadillo的链接依赖:
修改顶层CMakeLists.txt
cmake_minimum_required(VERSION 3.15) project(MyLatestFrustration VERSION 0.1) add_library(CompilerFlags INTERFACE) target_compile_features(CompilerFlags INTERFACE cxx_std_11) configure_file(testConfig.h.in testConfig.h) # 定义Armadillo路径 set(ARMADILLO_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/thirdParty/armadillo/include) set(ARMADILLO_LIB_DIR ${CMAKE_CURRENT_SOURCE_DIR}/thirdParty/armadillo/lib_win64) # 创建Armadillo接口库,统一管理依赖 add_library(Armadillo INTERFACE) target_include_directories(Armadillo INTERFACE ${ARMADILLO_INCLUDE_DIR}) target_link_libraries(Armadillo INTERFACE ${ARMADILLO_LIB_DIR}/libopenblas.lib) add_executable(MyLatestFrustration test.cxx) add_subdirectory(custom) # 启用自定义库 target_link_libraries(MyLatestFrustration PUBLIC CompilerFlags Armadillo MatrixFunctions ) target_include_directories(MyLatestFrustration PUBLIC "${PROJECT_BINARY_DIR}") # 自动复制DLL到可执行文件目录,解决运行时缺失问题 add_custom_command(TARGET MyLatestFrustration POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different ${ARMADILLO_LIB_DIR}/libopenblas.dll $<TARGET_FILE_DIR:MyLatestFrustration> )
修改自定义库CMakeLists.txt
让自定义库链接Armadillo,确保依赖传递:
add_library(MatrixFunctions matrices.cxx) target_include_directories(MatrixFunctions INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) target_link_libraries(MatrixFunctions PUBLIC CompilerFlags Armadillo)
2. 预编译库的使用说明
可以直接使用Armadillo提供的预编译libopenblas.lib,无需单独安装BLAS/LAPACK/OpenBLAS,但需注意:
- 确保预编译库的架构与你的编译器匹配:你使用MinGW 64位,需对应
lib_win64下的库; libopenblas.lib是动态链接库的导入库,运行时必须拥有对应的libopenblas.dll文件;- 若后续需要更高性能或特定功能,也可自行编译OpenBLAS或使用其他实现(如MKL),但预编译库已能满足基础需求。
内容的提问来源于stack exchange,提问作者James
相关产品推荐
相关产品推荐

