• qt creator源码全方面分析(3-6)


    qtcreatorplugin.pri

    上一节我们介绍了qtcreatorlibrary.pri,现在我们介绍qtcreatorplugin.pri,其实插件的本质也是动态库,所以qtcreatorplugin.pri实现的内容和功能与qtcreatorlibrary.pri差不多。

    使用实例

    和上一节一样,为了分析这个文件,我们也再找个使用该pri的例子,源目录srcpluginscppeditorcppeditor.pro。

    DEFINES += CPPEDITOR_LIBRARY
    include(../../qtcreatorplugin.pri)
    ...
    

    以及依赖项,源目录srclibscpluspluscppeditor_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 SettingsApplication Data"
        } else:macx {
            DESTDIRAPPNAME = "Qt Creator"
            DESTDIRBASE = "$$(HOME)/Library/Application Support"
        } else:unix {
            DESTDIRAPPNAME = "qtcreator"
            DESTDIRBASE = "$$(XDG_DATA_HOME)"
            isEmpty(DESTDIRBASE):DESTDIRBASE = "$$(HOME)/.local/share/data"
            else:DESTDIRBASE = "$$DESTDIRBASE/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中的一样,

      1. 根据pro文件名获取对应的依赖文件,进行包含。这里只是多了个文件存在性判断,以及插件名是否设置判断。

      2. 设置插件文件名。

      3. 加载qtcreator.pri。

    2. 定义了替换函数dependencyName。

      代码和qtcreator.pri文件最后的递归解决插件依赖几乎一样。区别在于这里只分析了当前依赖的插件,而不是继续递归往下。

    3. 实现插件元数据的依赖信息替换。

      我们在Plugin Meta Data已经介绍过Dependencies键,示例如下:

      "Dependencies" : [
                { "Name" : "SomeOtherPlugin", "Version" : "2.3.0_2" },
                { "Name" : "EvenOther", "Version" : "1.0.0" }
      ]
      

      这里很明显,把依赖信息填充到dependencyList对象中。

    4. 添加预编译头文件。和qtcreatorlibrary.pri一样。

    5. 设置目标文件夹,并添加库和包含路径。

      win32系统下,有两个输出路径,一个为构建目录/lib/qtcreator/plugin,一个为用户路径,譬如C:/Users/codeForFamily/AppData/Local/QtProject/qtcreator/plugins/4.6.2。我们在Creating Your First Plugin的"部署到列表"中就提到过。

    6. *.json.in编译为*.json

      获取插件目录下的json.in文件。其实就是插件元数据的模板。

      {
          "Name" : "CppEditor",
          "Version" : "$$QTCREATOR_VERSION",
          ...
          $$dependencyList
      }
      

      并设置QMAKE_SUBSTITUTES对json.in文件进行变量替换,生成json文件。这种用法我们在qtcreator.pri中已经介绍过。

      {
          "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路径的原因。

      image-20200305221549795

    下半部

    
    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几乎一样。不再介绍。

    结果

    qtcreatorplugin.pri与qtcreatorlibrary.pri的主要区别,就在于多了生成dependencyList,以及json.in文件转为json文件这两部分。


    原创造福大家,共享改变世界

    献出一片爱心,温暖作者心灵


  • 相关阅读:
    [转]给定单链表,检测是否有环。如果有环,则求出进入环的第一个节点
    二叉树的后序遍历
    求二叉树叶子节点的个数
    随笔
    两个免费转换视频的软件,实现服务器端Video2FLV
    自制Flash FLV视频播放器
    Flash取得外部WEB参数的方法
    [转]javascript小技巧,超强推荐
    c#设计模式(转)
    ffmpeg和Mencoder使用实例小全
  • 原文地址:https://www.cnblogs.com/codeForFamily/p/qt-creator-ide-source-learn-3-6.html
Copyright © 2020-2023  润新知