【问题标题】:CMake linking error, finding library but "undefined reference"CMake链接错误,找到库但“未定义的引用”
【发布时间】:2020-08-10 20:58:24
【问题描述】:

我正在尝试构建一个以 libtorch 和 opencv 作为依赖项的项目。我使用 cmake 作为我的构建系统,因为这两个库都推荐使用它。我目前卡住了,我正在尝试使用 libtorch 和 opencv 编译一个最小的程序。

我的程序是这样的

#include <opencv2/opencv.hpp>
#include <torch/torch.h>

void showImage(cv::Mat);
at::Tensor imgToTensor(std::string img_path);

using namespace cv;
using std::cout;
using std::endl;

int main() {
    std::string img_path = "./images/01 HEAVENLY STAR080.png";
    auto tensor = imgToTensor(img_path);
    cout << tensor << endl;
}


at::Tensor imgToTensor(std::string img_path){
    Mat origImage;
    Mat normalizedImage;
    Mat sizedImage(500, 200, CV_32FC3);
    origImage = imread(img_path, 1);
    origImage.convertTo(normalizedImage, CV_32FC3);
    resize(normalizedImage, sizedImage, sizedImage.size(), 0, 0, INTER_LINEAR);
    auto input = torch::from_blob(sizedImage.data, {sizedImage.rows, sizedImage.cols, 3});
    return input;
}
void showImage(Mat image){
    namedWindow("Display window", WINDOW_AUTOSIZE);
    imshow("Display window", image);
    waitKey(0);
}

这是我的 CMakeLists.txt:

cmake_minimum_required(VERSION 2.8 FATAL_ERROR)
project(ConvNet)

set(Torch_DIR /usr/local/libtorch/share/cmake/Torch)

find_package(OpenCV REQUIRED)
find_package(Torch REQUIRED)
include_directories( ${OpenCV_INCLUDE_DIRS} )
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${TORCH_CXX_FLAGS}")
add_executable(main main.cpp)
target_link_libraries(main "${OpenCV_LIBS}" "${TORCH_LIBRARIES}")

这是cmake的输出,所以我知道库找到了:

-- The C compiler identification is GNU 9.3.0
-- The CXX compiler identification is GNU 9.3.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc - works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ - works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Found OpenCV: /usr/local (found version "4.3.0") 
-- Looking for pthread.h
-- Looking for pthread.h - found
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD - Failed
-- Looking for pthread_create in pthreads
-- Looking for pthread_create in pthreads - not found
-- Looking for pthread_create in pthread
-- Looking for pthread_create in pthread - found
-- Found Threads: TRUE  
-- Found Torch: /usr/local/libtorch/lib/libtorch.so  
-- Configuring done
-- Generating done
-- Build files have been written to: /home/jacob/Documents/KTH/KEX/codeEnvironment/ML_Classification_Toolkit/ML_tool/ConvNet/build

这是我得到的错误:

/usr/bin/ld: CMakeFiles/main.dir/main.cpp.o: in function `imgToTensor(std::string)':
main.cpp:(.text+0x8d9): undefined reference to `cv::imread(std::string const&, int)'
/usr/bin/ld: CMakeFiles/main.dir/main.cpp.o: in function `showImage(cv::Mat)':
main.cpp:(.text+0xbac): undefined reference to `cv::namedWindow(std::string const&, int)'
/usr/bin/ld: main.cpp:(.text+0xc0d): undefined reference to `cv::imshow(std::string const&, cv::_InputArray const&)'
collect2: error: ld returned 1 exit status
make[2]: *** [CMakeFiles/main.dir/build.make:122: main] Error 1
make[1]: *** [CMakeFiles/Makefile2:96: CMakeFiles/main.dir/all] Error 2
make: *** [Makefile:104: all] Error 2

任何帮助将不胜感激!

【问题讨论】:

  • 这是我第一次使用cmake,我不知道我在做什么。非常感谢您的建设性批评!
  • 您确定OpenCV_LIBS 变量实际上包含OpenCV 库吗?请参阅that question(和它的 cmets)来检查这个事实。
  • 是的,确实如此。当我只编译 opencv 时,相同的语法有效。
  • Puting message(STATUS "${Open_CV_LIBS}") 打印库列表。
  • 所以是OpenCV_LIBS 或Open_CV_LIBS 变量包含库列表?您的最后一条评论似乎与问题帖子中的代码相矛盾。在任何地方,您都可以使用make VERBOSE=1 构建项目并检查用于链接的确切命令行。

标签: c++ opencv cmake


【解决方案1】:

我下载的libtorch版本不支持cxx11 abi,​​因此不兼容opencv。通过更改使用的 libtorch 版本修复。

我使用的版本是来自这里的 cxx11 之前的 abi: https://pytorch.org/get-started/locally/

我切换到 cxx11 abi。

【讨论】:

    【解决方案2】:

    不要使用那些遗留的 cmake 东西

    CMake 大大简化了构建和链接库的过程。

    您可以只使用库创建目标的依赖关系,而不是手动告诉库路径和链接器选项。

    以下是关于它应该是什么样子的简短 sn-p:

    cmake_minimum_required(VERSION 3.10 FATAL_ERROR)
    project(ConvNet)
    
    find_package(OpenCV REQUIRED COMPONENTS opencv_highgui)
    find_package(Torch REQUIRED)
    
    add_executable(main main.cpp)
    
    target_link_libraries(main PRIVATE opencv_highgui torch)
    

    观察

    1. 没有包含目录!这是因为库的包含目录是库自己知道的!
    2. target_link_libraries 即使看起来一样,这里也有很大的不同!因为现在我们不是告诉编译器要做什么,而是将目标 main 链接到目标 opencv_highgui 和 torch。

    opencv_highgui 和 torch 是 targets 类似于 main。目标是使用add_library 和add_executable 创建的。

    目标具有公共和私有接口。要设置目标属性,我们调用函数target_*(例如target_compile_features(mytarget PUBLIC cxx_std_20) 表示目标mytarget 将使用C++20 功能,如果有人链接到我们,他将自动使用相同的编译器选项`

    【讨论】:

    • 好的,我根据你的建议更新了我的 cmake 文件。我仍然定义了 Torch_DIR,否则它将无法工作。但是,我犯了同样的错误。您是说问题可能是由于 opencv 和 libtorch 之间的兼容性问题造成的?
    • 我会尝试在我的笔记本电脑上编译...也许我打错了,让我下载opencv和torch :)
    • 可能是因为 2 个库使用了不同的 ABI?无论如何我可以检查一下吗?
    • 我认为问题在于我下载了一个使用 _GLIBCXX_USE_CXX11_ABI=0 标志编译的预编译 libtorch 库,这破坏了与 opencv 的兼容性。我将从源代码下载它并自己构建 libtorch,看看它是否有效。
    猜你喜欢
    • 2016-06-10
    • 2021-01-11
    • 2020-10-08
    • 2017-08-03
    • 2014-01-19
    • 2011-12-08
    • 2016-06-01
    • 2010-10-19
    • 1970-01-01
    相关资源
    最近更新 更多