1. 程式人生 > >qt creator原始碼全方面分析(3-6)

qt creator原始碼全方面分析(3-6)

[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/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](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檔案這兩部分。 ------ **`原創造福大家,共享改變世界`** **`獻出一片愛心,溫暖作者心靈`**