qt module制作

最近在研究qt 的mqtt,看到官方demo的pro文件有些生疏,研究了下 是qtmodule的写法;

 

搬运过来如下:(大概有个概念即可,凑乎看看~)

制作Qt Module 的总结

注意:本文档中代码用蓝色标识,以csystem代码库为例讲述。

1、代码结构

根目录:stem

一级目录:stem rpmupstream

stem:是存放源码的目录,名字可以随意;

rpm:是放置spec文件和patch文件的目录;

upsteam:是用于放置随着QT版本升级所需的东西。

二级目录:.qmake.conf stem.prosrc sync.profile 〔examples testsconfig.tests〕

.qmake.conf:定义模块开始制作的标志,及加载qt_build_config和当前的QT版本号,内容如下:

 

load(qt_build_config)

 

MODULE_VERSION =$$QT_VERSION

stem.pro:加载configure和qt_parts

load(configure)

 

# FIXME: This causes tests to be installed (if examplesare installed as well),

# which is needed to run some tests because they arebroken.

CONFIG += ordered

 

load(qt_parts)

src:放置源码

sync.profile:定义生成模块的源码和模块路径和生成模块时用到的qt模块等,内容如下:

%modules = ( # path to module namemap

"QtStem" => "$basedir/src/stem",//生成的QT模块的名字,后面的路径是生成模块的源码路径

);

%moduleheaders = ( # restrict the module headers to thosefound in relative path

);

# Module dependencies.

# Every module that is required to build this moduleshould have one entry.

# Each of the module version specifiers can take one ofthe following values:

# - A specific Gitrevision.

# - any git symbolic ref resolvable from the module'srepository (e.g. "refs/heads/master" to track masterbranch)

# - an empty string to use the same branch under test(dependencies will become "refs/heads/master" if we are in themaster branch)

#

�pendencies = (

"qtbase" => "",

"qtxmlpatterns" => "",

);

〔config.tests:〕这个目录可有可无,主要目的是在编译之前进行一些编译链接的测试。如在pro中,有 CONFIG += link_pkgconfig PKGCONFIG +=bluez 这样的编译链接存在,可以在制作模块之前,进行一些链接验证,这种情况下,可以将bluez的链接测试放在这里,具体的做法如下:

1)在config.tests里面创建bluez文件夹,里面包含两个文件:bluez.promain.cpp ;

bluez.pro的代码如下:

TEMPLATE = app

 

CONFIG += link_pkgconfig

PKGCONFIG += bluez

 

TARGET = bluez

 

SOURCES += main.cpp

main.cpp的代码如下:

#include

 

int main()

{

return 0;

}

 

2)在pro中添加编译,这时的pro文件代码如下:

load(configure)

qtCompileTest(bluez)

 

# FIXME: This causes tests to be installed (if examplesare installed as well),

# which is needed to run some tests because they arebroken.

CONFIG += ordered

 

load(qt_parts)

三级目录:src.prostem

src.pro:代码如下:

TEMPLATE = subdirs

CONFIG += ordered

 

SUBDIRS += stem

stem:这是在pro中QT +=名字,这个名字和stem是相对应的。

四级目录:公有.h文件.cpp文件和私有.h文件.cpp文件,以及pro文件

pro文件的大致结构是:

 

QT += core dbus networkgui

TARGET = QtSystem //生成的模块名字

SOURCES += \

PUBLIC_HEADERS +=

PRIVATE_HEADERS +=

HEADERS += $$PUBLIC_HEADERS $$PRIVATE_HEADERS\

load(qt_module) //这个必须存在

2、编译过程

1)exportQTDIR=/usr/share/qt5

导入qt,因为在后续的过程中,可能用到qt的一些pri或是其他模块文件

2)touch.git

这个必须做,只有执行了这步,才可以在/include/QtSystem里面生成相应的模块库以及headers.pri,否则只能生成QtSystemDepends一个文件。

3)qmake 〔CONFIG+=ofono CONFIG+=nox11optionCONFIG+=upower〕

4)make

3、编译后的正确生成文件

在一级目录里面会多三个文件夹:include libmkspecs

include:只包含了生成的模块名的文件夹:QtStem

QtStem中包含了:QtStem、QtStemDepends、QtStemVersion、headers.pri、qtstemversion.h、5.3.0

QtSystem包含了所有的头文件的名字,如下面所示:

#ifndefQT_QTSTEM_MODULE_H

#defineQT_QTSTEM_MODULE_H

#include

#include "cbatteryinfo.h"

#include "mainpage.h"

#include"qtstemversion.h"

#endif

QtStemDepends这个文件是根据stem.pro中QT+= 生成的,内容如下所示:

#include

#include

#include

#include

QtStemVersion包含了记录版本号的头文件的名字,内容如下所示:

#include"qtstemversion.h"

headers.pri记录了这个文件夹中包含的所有文件信息,内容如下所示:

SYNCQT.HEADER_FILES = 所有头文件的名称和../../include/QtStem/qtstemversion.h../../include/QtStem/QtStem

SYNCQT.HEADER_CLASSES =../../include/QtStem/QtStemVersion

SYNCQT.PRIVATE_HEADER_FILES = 所有私有头文件的名称

SYNCQT.QPA_HEADER_FILES =

SYNCQT.INJECTIONS =

qtstemversion.h记录版本信息,内容如下所示:

 

#ifndefQT_QTSTEM_VERSION_H

#defineQT_QTSTEM_VERSION_H

 

#define QTSTEM_VERSION_STR"5.3.0"

 

#define QTSTEM_VERSION0x050300

 

#endif //QT_QTSTEM_VERSION_H

5.3.0这个以版本号命名的文件夹,里面包含了所有的私有头文件

lib目录下面存在三种文件:

cmake目录下面存放着一些制作模块过程中用到的.cmake文件,如:Qt5StemConfig.cmake和Qt5StemConfigVersion.cmake

pkgconfig目录下存放着生成的pc文件,内容大致如下所示:

prefix=/usr

exec_prefix=${prefix}

libdir=${prefix}/lib

includedir=${prefix}/include/qt5

 

 

Name: Qt5 Stem

Description: Qt Stemmodule

Version: 5.3.0

Libs: -L${libdir}-lQt5Stem

Libs.private: -lfontconfig -L/usr/lib -lQt5Network-lQt5DBus -lQt5Gui -lQt5Core -lpthread-lGLESv2

Cflags: -I${includedir}/QtStem-I${includedir}

Requires: Qt5Core Qt5Gui Qt5DBusQt5Network

剩下的就是生成的一些libQt5Stem.la、libQt5Stem.prl和libQt5Stem.so文件

mkspec中存在两个文件夹:modulesmodules-inst

modules中存在一个qt_lib_stem.pri文件,内容如下所示:

QT_MODULE_BIN_BASE = /home/xx/rpmbuild/SOURCES/stem-5.3.0.sky21/stem/bin

QT_MODULE_INCLUDE_BASE = /home/xx/rpmbuild/SOURCES/stem-5.3.0.sky21/stem/include

QT_MODULE_IMPORT_BASE = /home/xx/rpmbuild/SOURCES/stem-5.3.0.skyt21/stem/imports

QT_MODULE_QML_BASE = /home/xx/rpmbuild/SOURCES/stem-5.3.0.sky21/stem/qml

QT_MODULE_LIB_BASE = /home/xx/rpmbuild/SOURCES/stem-5.3.0.sky21/stem/lib

QT_MODULE_HOST_LIB_BASE = /home/xx/rpmbuild/SOURCES/stem-5.3.0.sky21/stem/lib

QT_MODULE_LIBEXEC_BASE = /home/xx/rpmbuild/SOURCES/stem-5.3.0.sky21/stem/libexec

QT_MODULE_PLUGIN_BASE = /home/xx/rpmbuild/SOURCES/stem-5.3.0.sky21/stem/plugins

include(/home/xx/rpmbuild/SOURCES/stem-5.3.0.sky21/stem/mkspecs/modules-inst/qt_lib_stem.pri)

include(/home/xx/rpmbuild/SOURCES/stem-5.3.0.sky21/stem/mkspecs/modules-inst/qt_lib_stem_private.pri)

modules-inst中包含两个文件:qt_lib_stem.priqt_lib_stem_private.pri

qt_lib_stem.pri的内容如下所示:

QT.stem.VERSION = 5.3.0

QT.stem.MAJOR_VERSION = 5

QT.stem.MINOR_VERSION = 3

QT.stem.PATCH_VERSION = 0

QT.stem.name = QtStem

QT.stem.libs =$$QT_MODULE_LIB_BASE

QT.stem.rpath = /usr/lib

QT.stem.includes = $$QT_MODULE_INCLUDE_BASE$$QT_MODULE_INCLUDE_BASE/QtStem

QT.stem.bins =$$QT_MODULE_BIN_BASE

QT.stem.libexecs =$$QT_MODULE_LIBEXEC_BASE

QT.stem.plugins =$$QT_MODULE_PLUGIN_BASE

QT.stem.imports =$$QT_MODULE_IMPORT_BASE

QT.stem.qml =$$QT_MODULE_QML_BASE

QT.stem.depends = core gui dbusnetwork

QT.stem.module_config =

QT.stem.DEFINES =QT_SYSTEM_LIB

QT_MODULES += stem

qt_lib_stem_private.pri的内容如下所示:

QT.stem_private.VERSION =5.3.0

QT.stem_private.MAJOR_VERSION =5

QT.stem_private.MINOR_VERSION =3

QT.stem_private.PATCH_VERSION =0

QT.stem_private.name =QtStem

QT.stem_private.libs =$$QT_MODULE_LIB_BASE

QT.stem_private.includes =$$QT_MODULE_INCLUDE_BASE/QtStem/5.3.0$$QT_MODULE_INCLUDE_BASE/QtStem/5.3.0/QtStem

QT.stem_private.depends =stem

QT.stem_private.module_config = internal_moduleno_link

4spec文件

下面提供一个现成的spec文件,一起分析一下。和上面设置中相对应的stem.spec,具体内容如下所示:

Name: stem//文件名字,需要修改

Summary: Qt Stemmodules

Version: 5.3.0.sky21//以本地QT版本相对应,设置版本号

Release:1%{?dist}.14.3

Group:System/Libraries

License: LGPLv2.1 with exception orGPLv3

URL: //....

Source0:%{name}-%{version}.tar.bz2

BuildRequires: qt5-qtcore-devel//编译依赖需要修改

BuildRequires:qt5-qtgui-devel

BuildRequires:qt5-qtnetwork-devel

BuildRequires:qt5-qtsql-devel

BuildRequires:qt5-qtdbus-devel

BuildRequires:qt5-qtxml-devel

BuildRequires:qt5-qttest-devel

BuildRequires:qt5-qtopengl-devel

BuildRequires:qt5-qtdeclarative-devel

BuildRequires:qt5-qtdeclarative-qtquick-devel

BuildRequires:qt5-qmake

BuildRequires:fdupes

BuildRequires:pkgconfig(libudev)

BuildRequires:pkgconfig(bluez)

 

�scription//模块描述

Qt is a cross-platform application and UIframework. Using Qt, you can

write web-enabled applications once anddeploy them across desktop,

mobile and embedded systems without rewritingthe source code.

.

This package contains the Qt stemmodules

 

 

%package -n qt5-qtstem//最后生成的rpm包

Summary: Qt steminfo

Group:Stem/Libraries

Requires(post):/sbin/ldconfig

Requires(postun):/sbin/ldconfig

 

�scription -nqt5-qtstem

Qt is a cross-platform application and UIframework. Using Qt, you can

write web-enabled applications once anddeploy them across desktop,

mobile and embedded systems without rewritingthe source code.

.

This package contains the Qt StemInfomodule

%package -nqt5-qtstem-devel

Summary: Qt stem info - developmentfiles

Group:Development/Libraries

Requires: qt5-qtstem =%{version}-%{release}

 

�scription -nqt5-qtstem-devel

Qt is a cross-platform application and UIframework. Using Qt, you can

write web-enabled applications once anddeploy them across desktop,

mobile and embedded systems without rewritingthe source code.

.

This package contains the Qt StemInfodevelopment files

 

 

 

%prep//解压,打patch的过程

%setup -q -n%{name}-%{version}/stem

 

%build//编译的过程,做对应的修改

exportQTDIR=/usr/share/qt5

touch.git

qmake -qt=5 CONFIG+=ofono CONFIG+=nox11optionCONFIG+=upower

make%{?_smp_mflags}

 

%install//安装的过程,如果按上面生成的结构,一般不需要特别修改

rm -rf%{buildroot}

%qmake5_install

#Remove unneeded .la files

rm -f %{buildroot}/%{_libdir}\1/" {}\;

 

�upes%{buildroot}/%{_includedir}

 

 

 

 

#### Pre/Postsection

 

%post -nqt5-qtstem

/sbin/ldconfig

%postun -nqt5-qtstem

/sbin/ldconfig

 

 

#### Filesection

 

 

%files -n qt5-qtstem// 打包的过程

�fattr(-,root,root,-)

%{_libdir}/libQt5Stem.so.5

%{_libdir}/libQt5Stem.so.5.*

 

%files -nqt5-qtstem-devel

�fattr(-,root,root,-)

%{_libdir}/libQt5Stem.so

%{_libdir}/libQt5Stem.prl

%{_libdir}/pkgconfig/Qt5Stem.pc

%{_includedir}/qt5/QtStem/

%{_datadir}/qt5/mkspecs/modules/qt_lib_stem.pri

%{_datadir}/qt5/mkspecs/modules/qt_lib_stem_private.pri

%{_libdir}/cmake/Qt5Stem/

 

 

5、总结

按照上面给出的代码结构,构建自己的qt模块生成代码库。严格按照编译过程给出的步骤,验证一下自己生成的模块的正确性。如果验证完成,修改spec文件,生成相应的rpm包。

可能存在的问题:

1)编译没问题,可是生成的include/模块名/里面之包含了一个文件,里面的头文件都没有。可能的原因是在编译的过程中,没有运行touch.git这个步骤;

2)生成的模块没问题,安装后,导入使用的时候,如:在测试pro中QT+= 模块名字,可是在具体使用到某个函数的时候,提示:

qflashtest.o: In function`QFlashTest::QFlashTest(QObject*)':

qflashtest.cpp:(.text+0x3c):undefined reference to `QFlash::QFlash(QObject*)'

qflashtest.o: In function`QFlashTest::turnOn()':

qflashtest.cpp:(.text+0x21c):undefined reference to `QFlash::turnOn()'

qflashtest.o: In function`QFlashTest::turnOff()':

qflashtest.cpp:(.text+0x44c):undefined reference to `Qflash::turnOff()'这样的错误,原因是:在你的源码中,头文件没有按规范的格式书写。

3)关于qt模块生成中源码的规范:

必须有一个*global.h的文件,下面以stem中的为例:stemglobal.h,内容如下:

#ifndefCSTEMGLOBAL_H

#defineCSTEMGLOBAL_H

 

#include

 

#ifndefQT_STATIC

#ifdefined(QT_BUILD_SYSTEMINFO_LIB)

#define Q_EXPORTQ_DECL_EXPORT

#else

#define Q_EXPORTQ_DECL_IMPORT

#endif

#else

#define Q_EXPORT

#endif

 

#endif //CSTEMGLOBAL_H

 

具体到某一个头文件的时候,如qflash.h,内容如下所示:

#ifndef QFLASH_H

#define QFLASH_H

 

#include"cstemglobal.h"

 

#include

 

 

QT_BEGIN_NAMESPACE

 

class Q_EXPORTQFlash : publicQObject

{

Q_OBJECT

public:

explicit QFlash(QObject *parent =0);

~QFlash();

 

 

Q_INVOKABLE voidturnOn();

 

 

Q_INVOKABLE voidturnOff();

};

 

QT_END_NAMESPACE

#endif // QFLASH_H

 

对应的cpp文件

#include

#include

#include

#include "qflash.h"

 

QT_BEGIN_NAMESPACE

 

QFlash::QFlash(QObject *parent):QObject(parent)

{

 

}

 

QFlash::~QFlash()

{

 

}

 

void QFlash::turnOn()

{

 

}

 

void QFlash::turnOff()

{

 

}

 

QT_END_NAMESPACE

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值