如何解决未定义的参考简历:....在 Linux/Ubuntu 中编译 openCV 应用程序时?

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

提问人:roschach 提问时间:8/10/2018 最后编辑:roschach 更新时间:8/10/2018 访问量:1921

问:

按照以下步骤,我设法在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
C++ OpenCV Makefile 未定义引用

评论


答:

1赞 PaulR 8/10/2018 #1

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

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

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

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

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

评论

0赞 roschach 8/10/2018
嗨,谢谢,我真的快疯了。但是为什么 MacOS 上的 g++ 以另一种方式工作,而 Ubuntu 中的 g++ 则不然呢?
1赞 PaulR 8/10/2018
@FrancescoBoi:MacOS 使用与 Linux 不同的对象和可执行格式,MachO 而不是 elf,因此需要不同的链接器。也许 MacOS 链接器别无选择,或者它的名称不同,没有人费心启用它。此外,gcc 的版本可能不同。--as-needed