qt creator源码全方面分析(3-6)
codeForFamily 人气:0
[TOC]
# qtcreatorplugin.pri
上一节我们介绍了qtcreatorlibrary.pri,现在我们介绍qtcreatorplugin.pri,其实插件的本质也是动态库,所以qtcreatorplugin.pri实现的内容和功能与qtcreatorlibrary.pri差不多。
## 使用实例
和上一节一样,为了分析这个文件,我们也再找个使用该pri的例子,源目录\src\plugins\cppeditor\cppeditor.pro。
```
DEFINES += CPPEDITOR_LIBRARY
include(../../qtcreatorplugin.pri)
...
```
以及依赖项,源目录\src\libs\cplusplus\cppeditor_dependencies.pri。
```
QTC_PLUGIN_NAME = CppEditor
QTC_LIB_DEPENDS += \
extensionsystem \
utils \
cplusplus
QTC_PLUGIN_DEPENDS += \
texteditor \
coreplugin \
cpptools \
projectexplorer
QTC_TEST_DEPENDS += \
qmakeprojectmanager
```
这里我们也可以看见,设置了插件名QTC_PLUGIN_NAME,依赖的库名QTC_LIB_DEPENDS和依赖的插件名QTC_PLUGIN_DEPENDS,这在qtcreator.pri中解析依赖时会用到的。
## 上半部
```
depfile = $$replace(_PRO_FILE_PWD_, ([^/]+$), \\1/\\1_dependencies.pri)
exists($$depfile) {
include($$depfile)
isEmpty(QTC_PLUGIN_NAME): \
error("$$basename(depfile) does not define QTC_PLUGIN_NAME.")
} else {
isEmpty(QTC_PLUGIN_NAME): \
error("QTC_PLUGIN_NAME is empty. Maybe you meant to create $$basename(depfile)?")
}
TARGET = $$QTC_PLUGIN_NAME
plugin_deps = $$QTC_PLUGIN_DEPENDS
plugin_test_deps = $$QTC_TEST_DEPENDS
plugin_recmds = $$QTC_PLUGIN_RECOMMENDS
include(../qtcreator.pri)
defineReplace(dependencyName) {
dependencies_file =
for(dir, QTC_PLUGIN_DIRS) {
exists($$dir/$$1/$${1}_dependencies.pri) {
dependencies_file = $$dir/$$1/$${1}_dependencies.pri
break()
}
}
isEmpty(dependencies_file): \
error("Plugin dependency $$dep not found")
include($$dependencies_file)
return($$QTC_PLUGIN_NAME)
}
# for substitution in the .json
dependencyList =
for(dep, plugin_deps) {
dependencyList += " { \"Name\" : \"$$dependencyName($$dep)\", \"Version\" : \"$$QTCREATOR_VERSION\" }"
}
for(dep, plugin_recmds) {
dependencyList += " { \"Name\" : \"$$dependencyName($$dep)\", \"Version\" : \"$$QTCREATOR_VERSION\", \"Type\" : \"optional\" }"
}
for(dep, plugin_test_deps) {
dependencyList += " { \"Name\" : \"$$dependencyName($$dep)\", \"Version\" : \"$$QTCREATOR_VERSION\", \"Type\" : \"test\" }"
}
dependencyList = $$join(dependencyList, ",$$escape_expand(\\n)")
dependencyList = "\"Dependencies\" : [$$escape_expand(\\n)$$dependencyList$$escape_expand(\\n) ]"
# use gui precompiled header for plugins by default
isEmpty(PRECOMPILED_HEADER):PRECOMPILED_HEADER = $$PWD/shared/qtcreator_gui_pch.h
isEmpty(USE_USER_DESTDIR) {
DESTDIR = $$IDE_PLUGIN_PATH
} else {
win32 {
DESTDIRAPPNAME = "qtcreator"
DESTDIRBASE = "$$(LOCALAPPDATA)"
isEmpty(DESTDIRBASE):DESTDIRBASE="$$(USERPROFILE)\Local Settings\Application Data"
} else:macx {
DESTDIRAPPNAME = "Qt Creator"
DESTDIRBASE = "$$(HOME)/Library/Application Support"
} else:unix {
DESTDIRAPPNAME = "qtcreator"
DESTDIRBASE = "$$(XDG_DATA_HOME)"
isEmpty(DESTDIRBASE):DESTDIRBASE = "$$(HOME)/.local/sharehttps://img.qb5200.com/download-x/data"
else:DESTDIRBASE = "$$DESTDIRBASEhttps://img.qb5200.com/download-x/data"
}
DESTDIR = "$$DESTDIRBASE/QtProject/$$DESTDIRAPPNAME/plugins/$$QTCREATOR_VERSION"
}
LIBS += -L$$DESTDIR
INCLUDEPATH += $$OUT_PWD
# copy the plugin spec
isEmpty(TARGET) {
error("qtcreatorplugin.pri: You must provide a TARGET")
}
PLUGINJSON = $$_PRO_FILE_PWD_/$${TARGET}.json
PLUGINJSON_IN = $${PLUGINJSON}.in
exists($$PLUGINJSON_IN) {
DISTFILES += $$PLUGINJSON_IN
QMAKE_SUBSTITUTES += $$PLUGINJSON_IN
PLUGINJSON = $$OUT_PWD/$${TARGET}.json
} else {
# need to support that for external plugins
DISTFILES += $$PLUGINJSON
}
```
1. 第一部分实现的内容和[qtcreatorlibrary.pri](https://www.cnblogs.com/codeForFamily/p/qt-creator-ide-source-learn-3-5.html)中的一样,
1. 根据pro文件名获取对应的依赖文件,进行包含。这里只是多了个文件存在性判断,以及插件名是否设置判断。
2. 设置插件文件名。
3. 加载qtcreator.pri。
2. 定义了替换函数dependencyName。
代码和[qtcreator.pri](https://www.cnblogs.com/codeForFamily/p/qt-creator-ide-source-learn-3-2.html)文件最后的递归解决插件依赖几乎一样。区别在于这里只分析了当前依赖的插件,而不是继续递归往下。
3. 实现插件元数据的依赖信息替换。
我们在[Plugin Meta Data](https://www.cnblogs.com/codeForFamily/p/qt-creator-ide-source-learn-2-10-3.html)已经介绍过Dependencies键,示例如下:
```json
"Dependencies" : [
{ "Name" : "SomeOtherPlugin", "Version" : "2.3.0_2" },
{ "Name" : "EvenOther", "Version" : "1.0.0" }
]
```
这里很明显,把依赖信息填充到dependencyList对象中。
4. 添加预编译头文件。和[qtcreatorlibrary.pri](https://www.cnblogs.com/codeForFamily/p/qt-creator-ide-source-learn-3-5.html)一样。
5. 设置目标文件夹,并添加库和包含路径。
win32系统下,有两个输出路径,一个为构建目录/lib/qtcreator/plugin,一个为用户路径,譬如C:/Users/codeForFamily/AppData/Local/QtProject/qtcreator/plugins/4.6.2。我们在[Creating Your First Plugin](https://www.cnblogs.com/codeForFamily/p/qt-creator-ide-source-learn-2-10-2.html)的"部署到列表"中就提到过。
6. \*.json.in编译为\*.json
获取插件目录下的json.in文件。其实就是插件元数据的模板。
```
{
\"Name\" : \"CppEditor\",
\"Version\" : \"$$QTCREATOR_VERSION\",
...
$$dependencyList
}
```
并设置QMAKE_SUBSTITUTES对json.in文件进行变量替换,生成json文件。这种用法我们在[qtcreator.pri](https://www.cnblogs.com/codeForFamily/p/qt-creator-ide-source-learn-3-1.html)中已经介绍过。
```
{
"Name" : "CppEditor",
"Version" : "4.6.2",
...
"Dependencies" : [
{ "Name" : "TextEditor", "Version" : "4.6.2" },
{ "Name" : "Core", "Version" : "4.6.2" },
{ "Name" : "CppTools", "Version" : "4.6.2" },
{ "Name" : "ProjectExplorer", "Version" : "4.6.2" },
{ "Name" : "QmakeProjectManager", "Version" : "4.6.2", "Type" : "test" }
]
}
```
该json文件最终输出到OUT_PWD目录,这也是步骤5中为什么要包含OUT_PWD路径的原因。
## 下半部
```
osx {
QMAKE_LFLAGS_SONAME = -Wl,-install_name,@rpath/PlugIns/
QMAKE_LFLAGS += -compatibility_version $$QTCREATOR_COMPAT_VERSION
}
include(rpath.pri)
contains(QT_CONFIG, reduce_exports):CONFIG += hide_symbols
TEMPLATE = lib
CONFIG += plugin plugin_with_soname
linux*:QMAKE_LFLAGS += $$QMAKE_LFLAGS_NOUNDEF
target.path = $$INSTALL_PLUGIN_PATH
INSTALLS += target
TARGET = $$qtLibraryTargetName($$TARGET)
```
这部分内容和[qtcreatorlibrary.pri](https://www.cnblogs.com/codeForFamily/p/qt-creator-ide-source-learn-3-5.html)几乎一样。不再介绍。
## 结果
qtcreatorplugin.pri与[qtcreatorlibrary.pri](https://www.cnblogs.com/codeForFamily/p/qt-creator-ide-source-learn-3-5.html)的主要区别,就在于多了生成dependencyList,以及json.in文件转为json文件这两部分。
------
**`原创造福大家,共享改变世界`**
**`献出一片爱心,温暖作者心灵`**
------
加载全部内容