在 Ubuntu 14.04 上从源代码编译时如何链接到 opencv 3.0?

Posted

技术标签:

【中文标题】在 Ubuntu 14.04 上从源代码编译时如何链接到 opencv 3.0?【英文标题】:How to link to opencv 3.0 when compiled from source on Ubuntu 14.04? 【发布时间】:2014-12-07 20:48:35 【问题描述】:

我正在尝试编译和链接我在网上找到的以下 opencv 程序:

main.cpp:

#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/videoio.hpp>

#include <iostream>
#include <stdio.h>

using namespace std;
using namespace cv;
int main( int argc, const char** argv )

        VideoCapture capture(0);

        while(capture.isOpened() )
        
                Mat frame;
                if (! capture.read(frame))
                        continue;

                imshow("lalala", frame);
                if(waitKey(10) == 27)
                        break;
        



        return 0;

我的文件结构如下:

~/dev/opencv-1

~/dev/opencv-示例

opencv-1 是一个 git 克隆:https://github.com/Itseez/opencv

我按照位于http://docs.opencv.org/trunk/doc/tutorials/introduction/linux_install/linux_install.html的说明进行操作

我的目标是调试到 opencv 代码,所以我使用了 CMAKE_BUILD_TYPE=Debug

我能够成功编译 opencv 代码。我编写了以下 makefile 来编译这个示例:

INCPATH =-I../opencv-1/modules/objdetect/include \
   -I../opencv-1/modules/highgui/include \
   -I../opencv-1/modules/imgproc/include \
   -I../opencv-1/modules/core/include \
   -I../opencv-1/modules/imgcodecs/include \
   -I../opencv-1/modules/videoio/include \

LIBPATH =-L../opencv-1/debug/lib

LIBS =-lopencv_core -lopencv_videoio -lopencv_highgui -lopencv_imgproc -lopencv_video -lopencv_objdetect

%:%.cpp
        g++ $(INCPATH) $(LIBS) $(LIBPATH) $^ -o $@

为了编译我跑了:make main

发生这种情况时,我收到以下链接错误:

g++ -I../opencv-1/modules/objdetect/include -I../opencv-1/modules/highgui/include -I../opencv-1/module                                                              s/imgproc/include -I../opencv-1/modules/core/include -I../opencv-1/modules/imgcodecs/include -I../open                                                              cv-1/modules/videoio/include  -lopencv_core -lopencv_videoio -lopencv_highgui -lopencv_imgproc -lopenc                                                              v_video -lopencv_objdetect -L../opencv-1/debug/lib main.cpp -o main
/tmp/cc0PMDdW.o: In function `main':
main.cpp:(.text+0x29): undefined reference to `cv::VideoCapture::VideoCapture(int)'
main.cpp:(.text+0x69): undefined reference to `cv::VideoCapture::read(cv::_OutputArray const&)'
main.cpp:(.text+0xce): undefined reference to `cv::imshow(cv::String const&, cv::_InputArray const&)'
main.cpp:(.text+0xf6): undefined reference to `cv::waitKey(int)'
main.cpp:(.text+0x131): undefined reference to `cv::VideoCapture::isOpened() const'
main.cpp:(.text+0x14d): undefined reference to `cv::VideoCapture::~VideoCapture()'
main.cpp:(.text+0x1b0): undefined reference to `cv::VideoCapture::~VideoCapture()'
/tmp/cc0PMDdW.o: In function `cv::String::String(char const*)':
main.cpp:(.text._ZN2cv6StringC2EPKc[_ZN2cv6StringC5EPKc]+0x4f): undefined reference to `cv::String::al                                                              locate(unsigned long)'
/tmp/cc0PMDdW.o: In function `cv::String::~String()':
main.cpp:(.text._ZN2cv6StringD2Ev[_ZN2cv6StringD5Ev]+0x14): undefined reference to `cv::String::deallo                                                              cate()'
/tmp/cc0PMDdW.o: In function `cv::_InputArray::_InputArray()':
main.cpp:(.text._ZN2cv11_InputArrayC2Ev[_ZN2cv11_InputArrayC5Ev]+0x13): undefined reference to `vtable                                                               for cv::_InputArray'
/tmp/cc0PMDdW.o: In function `cv::_InputArray::_InputArray(cv::Mat const&)':
main.cpp:(.text._ZN2cv11_InputArrayC2ERKNS_3MatE[_ZN2cv11_InputArrayC5ERKNS_3MatE]+0x17): undefined re                                                              ference to `vtable for cv::_InputArray'
/tmp/cc0PMDdW.o: In function `cv::_InputArray::~_InputArray()':
main.cpp:(.text._ZN2cv11_InputArrayD2Ev[_ZN2cv11_InputArrayD5Ev]+0x13): undefined reference to `vtable                                                               for cv::_InputArray'
/tmp/cc0PMDdW.o: In function `cv::_OutputArray::_OutputArray(cv::Mat&)':
main.cpp:(.text._ZN2cv12_OutputArrayC2ERNS_3MatE[_ZN2cv12_OutputArrayC5ERNS_3MatE]+0x23): undefined re                                                              ference to `vtable for cv::_OutputArray'
/tmp/cc0PMDdW.o: In function `cv::_OutputArray::~_OutputArray()':
main.cpp:(.text._ZN2cv12_OutputArrayD2Ev[_ZN2cv12_OutputArrayD5Ev]+0x13): undefined reference to `vtab                                                              le for cv::_OutputArray'
/tmp/cc0PMDdW.o: In function `cv::Mat::~Mat()':
main.cpp:(.text._ZN2cv3MatD2Ev[_ZN2cv3MatD5Ev]+0x39): undefined reference to `cv::fastFree(void*)'
/tmp/cc0PMDdW.o: In function `cv::Mat::release()':
main.cpp:(.text._ZN2cv3Mat7releaseEv[_ZN2cv3Mat7releaseEv]+0x4b): undefined reference to `cv::Mat::dea                                                              llocate()'
collect2: error: ld returned 1 exit status
make: *** [main] Error 1

我不确定我错过了什么。我已经包含了这个简单程序需要编译的所有库。我在网上搜索了类似的错误,我看到的所有答案都建议添加我的 makefile 中已经存在的库。

【问题讨论】:

还将g++ $(INCPATH) $(LIBS) $(LIBPATH) $^ -o $@改写成$(CXX) $(INCPATH) $(LIBPATH) $^ $(LIBS) -o $@ @berak,我很困惑。我以为我是用我的 LIB_PATH 变量来做的。 @Chnossos 非常感谢。这似乎成功了。我会接受你的回答并为这个问题创建一个答案。 真正要记住的是-l 标志必须 .cpp.o 命令行中的文件之后。不要忘记接受您自己的答案以正确关闭此问题。 @Chnossos 再次感谢。再过 20 个小时,我无法接受自己的答案。如果您想从我的答案中写出答案并获得荣誉,我可以删除我的答案。 【参考方案1】:

你的问题是这一行:

g++ $(INCPATH) $(LIBS) $(LIBPATH) $^ -o $@

应该这样重写:

$(CXX) $(INCPATH) $(LIBPATH) $^ $(LIBS) -o $@

包含-l 标志的变量应始终位于命令行中的.cpp.o 文件之后


但你可以做得更好。您的 Makefile 最终应如下所示:

CPPFLAGS    :=  -I../opencv-1/modules/objdetect/include \
                -I../opencv-1/modules/highgui/include \
                -I../opencv-1/modules/imgproc/include \
                -I../opencv-1/modules/core/include \
                -I../opencv-1/modules/imgcodecs/include \
                -I../opencv-1/modules/videoio/include

LDFLAGS     :=  -L../opencv-1/debug/lib

LDLIBS      :=  -lopencv_core -lopencv_videoio -lopencv_highgui \
                -lopencv_imgproc -lopencv_video -lopencv_objdetect

不多也不少。 GNU Make 已经有一个隐含规则将.cpp 文件编译成可执行文件,只需使用内置变量依赖它即可。

注意CPPFLAGS 代表预处理器标志,而不是 c++ 标志。使用CXXFLAGS 提供标志,例如-std-g 标志。

【讨论】:

以上是关于在 Ubuntu 14.04 上从源代码编译时如何链接到 opencv 3.0?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Ubuntu 服务器上从 Shell 运行 Android 模拟器

在 Ubuntu 上从源码编译安装 Python 3.8

如何在 Ubuntu 14.04 LTS 中安装 ia32-libs (Trusty Tahr)

Android编译环境配置(Ubuntu 14.04)

Mono 3.0.1 --> 为 Ubuntu 14.04 LTS (AWS Linux AMI) 编译 xsp 时出错

Ubuntu14.04 + Qt5.7.1(静态编译)