使用 CMake 链接到犰狳

问题描述 投票:0回答:1

我一直在尝试使用 Armadillo 库创建一个小型 C++ 项目,作为学习 C++ 和 CMake 的一部分 - 我对两者都是新手。我使用的是带有 MinGW 编译器的 Windows 计算机。经过比我愿意承认的更多的时间,在网上查看各种问题的答案,例如这里这里,我终于得到了以下内容:

文件/文件夹结构

ProjectDIR
 |
 +-- CMakeLists.txt
 +-- test.cxx
 +-- testConfig.h.in
 +-- thirdParty
     |
     +-- armadillo
         |
         +-- include
         +-- lib_win64

测试.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}")

其中

armadillo/include
文件夹是直接从 armadillo-14.0.3 下载中复制的,而
armadillo/lib_win64
文件夹是从 armadillo-14.0.3 提供的示例中复制的。

虽然这个解决方案适用于这个基本实现,但我感觉这不是应该如何完成的。当我尝试创建并链接一个使用犰狳的自定义库时,我证实了我的怀疑,方法是将一个名为

custom
的文件夹添加到
ProjectDiR
,其中包含

矩阵.h

#pragma once

#include <armadillo>

arma::mat f1(arma::mat A);

矩阵.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)

以及取消注释

add_subdirectory(custom)
并将
MatrixFunctions
添加到顶级 CMakeLists.txt 文件中的
target_link_libraries
中,然后修改 test.cxx 以包含 matrices.h 并调用
f1
。这构建得很好,但在尝试运行时会产生以下错误“代码执行无法继续,因为找不到 libopenblas.dll。重新安装程序可能会解决此问题。”

所以,我想了解如何使用 CMake 正确链接到犰狳,以及是否可以在使用提供的预编译 libopenblas.lib 时完成,或者是否必须安装 BLAS 和 LAPACK 或 OPENBLAS;我之前曾尝试遵循这条路线,但遇到了更多问题,显然做错了什么。

c++ cmake armadillo
1个回答
0
投票

按照评论中的建议,我通过使用CMake复制所需文件解决了问题。特别是,我使用解决方案here将 libopenblas.dll 复制到构建目录。我的 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)

add_custom_command(TARGET MyLatestFrustration POST_BUILD
    COMMAND ${CMAKE_COMMAND} -E copy_if_different
        "${PROJECT_SOURCE_DIR}/thirdParty/armadillo/lib_win64/libopenblas.dll"
        $<TARGET_FILE_DIR:MyLatestFrustration>)

target_link_libraries(MyLatestFrustration PUBLIC
                        CompilerFlags
                        ${CMAKE_CURRENT_SOURCE_DIR}/thirdParty/armadillo/lib_win64/libopenblas.lib
                    )

target_include_directories(MyLatestFrustration PUBLIC "${PROJECT_BINARY_DIR}")

其中自定义命令会在构建后复制 .dll 文件。

这个解决方案感觉并不理想,但希望它对面临类似问题的任何人都有用。

© www.soinside.com 2019 - 2024. All rights reserved.