CMake链接错误,找到库但出现“未定义的引用”

3
我正在尝试使用 libtorch 和 opencv 作为依赖项构建项目。由于这两个库都推荐使用 cmake 作为构建系统,因此我选择使用 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

非常感谢任何帮助!


2
这是我第一次使用cmake,我不知道我在做什么。非常感谢你的建设性批评! - jameshm
你确定 OpenCV_LIBS 变量实际上包含了 OpenCV 库吗?请参考这个问题(以及相关评论)来检查这一点。 - Tsyvarev
是的,它可以。当我只编译OpenCV时,相同的语法也适用。 - jameshm
使用消息(STATUS "${Open_CV_LIBS}")打印库列表。 - jameshm
那么是包含库列表的 OpenCV_LIBS 还是 Open_CV_LIBS 变量?你最后的评论似乎与问题帖子中的代码相矛盾。无论如何,您可以使用 make VERBOSE=1 构建项目并检查用于链接的 确切命令行 - Tsyvarev
抱歉,当我写评论时出现了错误。应该是OpenCV_LIBS。 - jameshm
2个回答

6

我下载的libtorch版本不支持cxx11 abi,因此与opencv不兼容。改用其他版本的libtorch解决了该问题。

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

我切换到了cxx11 abi的版本。


2

不要使用那些过时的CMake内容

CMake大大简化了构建和将库链接在一起的过程。

你不需要手动设置库路径和链接器选项,只需将目标与库创建依赖关系即可。

以下是一个简短的片段,展示应该如何做:

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. 没有include目录!这是因为库的include目录是库本身知道的内容!
  2. target_link_libraries,即使看起来相同,这里有很大的区别!因为现在我们不是告诉编译器要做什么,而是将目标main链接到目标opencv_highguitorch

opencv_highguitorch是像main一样的目标。目标是使用add_libraryadd_executable创建的。

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


好的,我按照你的建议更新了我的cmake文件。我仍然定义了Torch_DIR,否则它就无法工作。然而,我遇到了同样的错误。你是说问题可能是由于opencv和libtorch之间的兼容性问题吗? - jameshm
我会在我的笔记本电脑上尝试编译...可能是我打错了一些字,让我下载OpenCV和Torch :) - Elvis Dukaj
2
这可能是由于两个库使用不同的ABI导致的?有没有办法让我检查一下呢? - jameshm
我认为问题在于我下载了一个预编译的libtorch库,该库是使用_GLIBCXX_USE_CXX11_ABI=0标志编译的,这会破坏与opencv的兼容性。我打算从源代码中下载并构建libtorch,看看是否可以解决问题。 - jameshm

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接