(ubuntu, qt, opencv, jetson nx)编译动态链接库遇坑记录

        由于项目需要,需要在jetson nx的开发板上生成一个动态链接库文件提供给软件测试方在相同平台上进行测试。在整个编译过程中,遇到了很多的坑,在这里记录下来供各位参考。

1、使用g++编译动态链接库

其实编译动态链接库本身并不需要用到qt,利用g++在命令行中就能实现动态链接库的生成。总体的思路主要是:test.cpp --> test.o -->test.so

前者需要先将test.cpp编译成.o文件,示例如下:

g++ -c test.cpp -lib

而后者则需要将.o文件编译为.so文件,示例如下:

g++ -shared -fPIC -o libtest.so test.o

主要两段代码,即可在命令行中实现.so文件的生成。

但是!第一步中配置所需要的lib以及include路径的过程实在太繁琐了,尤其是像opencv这种有自己路径的情况。所以想到了用qt软件中自带的动态库生成方式来生成.so文件,方便快捷。

2、使用qt生成动态链接库

        首先我们打开qt界面,选择新建项目,在项目选择处选择“Library”-->“C++库”。

         接着就是给你的项目取个好听的名字,我们就叫“test”吧,然后根据系统提示进行操作。因为.so文件里可能用不到QtCore模块,所以可以在选择模块时去除。

 最终创建完成的项目如下:

         此时,把左下方的Debug改为Release(个人喜好),右键永久删除“test_global.h”文件,再把“test.h”中的类,以及“test.cpp”中的函数都删了吧。我们重新写。

“test.h”代码如下:

#ifndef TEST_H
#define TEST_H


#endif // TEST_H

 “test.cpp”代码如下:

#include "test.h"




接下来开始写我们自己的代码。本文主要拿opencv作为例子,因此写一个简单的opencv读取以及显示的动态库

“test.cpp”如下:

#include "test.h"


int ReadAndShow(string filename)
{
    Mat img;
    img = imread(filename);
    imshow("img", img);
    waitKey(0);
    return 0;
}

“test.h”如下:

#ifndef TEST_H
#define TEST_H

#include "opencv2/opencv.hpp"
#include <iostream>
using namespace cv;
using namespace std;

int ReadAndShow(string filename);

#endif // TEST_H

随后,需要在“test.pro”中配置opencv路径。

文中示例如下:

#-------------------------------------------------
#
# Project created by QtCreator 2022-04-03T22:40:00
#
#-------------------------------------------------

QT       -= core gui

TARGET = test
TEMPLATE = lib

DEFINES += TEST_LIBRARY

# The following define makes your compiler emit warnings if you use
# any feature of Qt which has been marked as deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS

# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

SOURCES += \
        test.cpp

HEADERS += \
        test.h

unix {
    target.path = /usr/lib
    INSTALLS += target
}


// 上方为系统自动生成,下方为手动加入的路径以及库文件

unix:!macx: LIBS += -L$$PWD/../../../../../usr/local/lib/ -lopencv_highgui \
                    -L$$PWD/../../../../../usr/local/lib/ -lopencv_core \
                    -L$$PWD/../../../../../usr/local/lib/ -lopencv_imgcodecs \
                    -L$$PWD/../../../../../usr/local/lib/ -lopencv_imgproc \


INCLUDEPATH += $$PWD/../../../../../usr/local/include/opencv4
DEPENDPATH += $$PWD/../../../../../usr/local/include/opencv4

万事俱备后,我们点击构建项目,成功编译后会在“build-test-Desktop-Release”文件夹中找到四个文件,分别为:libtest.so, libtest.so.1, libtest.so.1.0, libtest.so.1.0.0。这四个就是生成的库文件了。现在先新建一个项目测试以下库文件能否使用,后面再说说在此过程中遇到的坑。


还是在qt中生成一个项目(此时生成的是qt项目而不是库项目),删除一些不必要的.ui文件等,最终如图,上方的项目是我们编译库时的项目,下方是新建的项目。

         在main.cpp中输入:

#include "test.h"

int main()
{
    // filename根据自己的图片路径进行更改
    string filename = "/home/unique/Pictures/Data_zheng/100um/1.tif";

    ReadAndShow(filename);
    return 0;
}

        在testso.pro文件中加入opencv所需的库文件以及头文件路径,并加入“libtest.so”以及“test.h”的路径。示例如下:

#-------------------------------------------------
#
# Project created by QtCreator 2022-04-03T22:56:10
#
#-------------------------------------------------

QT       += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = testso
TEMPLATE = app

# The following define makes your compiler emit warnings if you use
# any feature of Qt which has been marked as deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS

# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0


SOURCES += \
        main.cpp

// 上方为系统自动生成,下方为需要进行修改的地方
// opencv库文件以及头文件路径
unix:!macx: LIBS += -L$$PWD/../../../../../usr/local/lib/ -lopencv_highgui \
                    -L$$PWD/../../../../../usr/local/lib/ -lopencv_core \
                    -L$$PWD/../../../../../usr/local/lib/ -lopencv_imgcodecs \
                    -L$$PWD/../../../../../usr/local/lib/ -lopencv_imgproc \

INCLUDEPATH += $$PWD/../../../../../../usr/local/include/opencv4
DEPENDPATH += $$PWD/../../../../../../usr/local/include/opencv4


// libtest.so文件以及test.h路径
unix:!macx: LIBS += -L$$PWD/../../build-test-Desktop-Release/ -ltest

INCLUDEPATH += $$PWD/../../test
DEPENDPATH += $$PWD/../../test

        点击构建并运行,即可成功读取并显示图片。

 

3、将库文件拷贝至U盘(遇到的坑)

        前面的流程其实都很容易,针对不同的库,只要配置好不同的路径就可以成功生成.so文件,并且全程图形化选择,摆脱了写Makefile文件的痛苦。但是,在将libtest.so文件拷贝至U盘时却出现了问题。报错如下:

         为啥会出现这样的问题?这涉及到Ubuntu系统的一个软链接与硬链接的关系。经过多方的寻找,终于发现,原来在生成的libtest.so, libtest.so.1, libtest.so.1.0, libtest.so.1.0.0四个文件中,“libtest.so.1.0.0”才是文件的本体,其他都是其软链接。因此,要在其他机器上使用libtest.so文件时,只需将“libtest.so.1.0.0”拷贝至U盘,并复制三个“libtest.so.1.0.0”改名为libtest.so, libtest.so.1, libtest.so.1.0即可在其他机器上顺利使用。

        本篇文章仅作为经验分享,由于本人理论知识与实践经验都有限,只能使用这种笨方法。如果各位有别的好方法,欢迎留言~

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值