在Linux/Ubuntu中编译openCV应用程序时如何解决undefined reference cv:....?

How to solve undefined reference cv:.... when compiling openCV application in Linux/Ubuntu?

我在 .

之后的 OSX 环境中的本地文件夹中成功构建了 OpenCV(版本 4.0.0)

我在 Linux 和 Ubuntu 中尝试了相同的步骤并做了

export LD_LIBRARY_PATH=../your/path/lib/:$LD_LIBRARY_PATH

一切看起来都很好,但是当我尝试使用 Makefile 编译测试项目时,我在问题中发布了这个错误

/tmp/ccVvPXNi.o: In function `cv::String::~String()':
test.cpp:(.text._ZN2cv6StringD2Ev[_ZN2cv6StringD5Ev]+0x14): undefined reference to `cv::String::deallocate()'
/tmp/ccVvPXNi.o: In function `cv::String::operator=(cv::String const&)':
test.cpp:(.text._ZN2cv6StringaSERKS0_[_ZN2cv6StringaSERKS0_]+0x28): undefined reference to `cv::String::deallocate()'
collect2: error: ld returned 1 exit status
Makefile:23: recipe for target 'test.o' failed
make: *** [test.o] Error 1

通过以下 Makefile 我得到了更多未定义的引用:

CPP = g++

# OpenCV trunk
CPPFLAGS = -std=c++11  \
           `pkg-config --cflags --libs ../cmake_bin_dir/instDir/lib/pkgconfig/opencv.pc`

# Opencv 2.4.8
#CPPFLAGS = -L/home/krystof/libs/opencv-2.4.8/release/installed/libs \
       -I/home/krystof/libs/opencv-2.4.8/release/installed/include

all: provaMat

provaMat.o: provaMat.cpp
    $(CPP) $(CPPFLAGS) $^ -o $@

在这种情况下我得到以下错误:

/tmp/ccwJs00N.o: In function `main':
provaMat.cpp:(.text+0x38): undefined reference to `cv::VideoCapture::VideoCapture(int)'
provaMat.cpp:(.text+0x47): undefined reference to `cv::VideoCapture::isOpened() const'
provaMat.cpp:(.text+0x91): undefined reference to `cv::namedWindow(cv::String const&, int)'
provaMat.cpp:(.text+0xb3): undefined reference to `cv::VideoCapture::operator>>(cv::Mat&)'
provaMat.cpp:(.text+0x118): undefined reference to `cv::cvtColor(cv::_InputArray const&, cv::_OutputArray const&, int, int)'
provaMat.cpp:(.text+0x1c5): undefined reference to `cv::GaussianBlur(cv::_InputArray const&, cv::_OutputArray const&, cv::Size_<int>, double, double, int)'
provaMat.cpp:(.text+0x245): undefined reference to `cv::Canny(cv::_InputArray const&, cv::_OutputArray const&, double, double, int, bool)'
provaMat.cpp:(.text+0x2ab): undefined reference to `cv::imshow(cv::String const&, cv::_InputArray const&)'
provaMat.cpp:(.text+0x2d3): undefined reference to `cv::waitKey(int)'
provaMat.cpp:(.text+0x322): undefined reference to `cv::VideoCapture::~VideoCapture()'
provaMat.cpp:(.text+0x41b): undefined reference to `cv::VideoCapture::~VideoCapture()'
/tmp/ccwJs00N.o: In function `cv::String::String(char const*)':
provaMat.cpp:(.text._ZN2cv6StringC2EPKc[_ZN2cv6StringC5EPKc]+0x54): undefined reference to `cv::String::allocate(unsigned long)'
/tmp/ccwJs00N.o: In function `cv::String::~String()':
provaMat.cpp:(.text._ZN2cv6StringD2Ev[_ZN2cv6StringD5Ev]+0x14): undefined reference to `cv::String::deallocate()'
/tmp/ccwJs00N.o: In function `cv::String::operator=(cv::String const&)':
provaMat.cpp:(.text._ZN2cv6StringaSERKS0_[_ZN2cv6StringaSERKS0_]+0x28): undefined reference to `cv::String::deallocate()'
/tmp/ccwJs00N.o: In function `cv::Mat::~Mat()':
provaMat.cpp:(.text._ZN2cv3MatD2Ev[_ZN2cv3MatD5Ev]+0x39): undefined reference to `cv::fastFree(void*)'
/tmp/ccwJs00N.o: In function `cv::Mat::release()':
provaMat.cpp:(.text._ZN2cv3Mat7releaseEv[_ZN2cv3Mat7releaseEv]+0x4b): undefined reference to `cv::Mat::deallocate()'
collect2: error: ld returned 1 exit status
Makefile:14: recipe for target 'provaMat.o' failed
make: *** [provaMat.o] Error 1

我错过了哪一步?有人有什么建议吗?

编辑: pkg-config --cflags --libs ../cmake_bin_dir/instDir/lib/pkgconfig/opencv.pc 的结果是

-I/root/openCV4/cmake_bin_dir/instDir/include/opencv -I/root/openCV4/cmake_bin_dir/instDir/include -L/root/openCV4/cmake_bin_dir/instDir/lib -lopencv_dnn -lopencv_ml -lopencv_objdetect -lopencv_shape -lopencv_stitching -lopencv_superres -lopencv_videostab -lopencv_calib3d -lopencv_features2d -lopencv_highgui -lopencv_videoio -lopencv_imgcodecs -lopencv_video -lopencv_photo -lopencv_imgproc -lopencv_flann -lopencv_core

尝试将 provaMat.o 的配方更改为以下内容:

provaMat.o: provaMat.cpp
    $(CPP) $^ $(CPPFLAGS) -o $@

一段时间以来,GCC 使用的默认链接器选项包括 --as-needed 标志。这使得链接器丢弃任何在命令行中出现时从未引用过的对象。因此,如果一个库出现在对其符号的任何引用之前,它就会被完全丢弃。

将规则更改为以下内容并将所有与库相关的标志放在 LIBS 变量中可能是有意义的。

provaMat.o: provaMat.cpp
    $(CPP) $(CPPFLAGS) $^ $(LIBS) -o $@