翻譯|使用教程|編輯:鮑佳佳|2021-05-19 11:41:34.540|閱讀 1486 次
概述:一年半前,Qt做出了一個重大決定,開始使用CMake來構建Qt 6。做出此決定的主要原因是用戶反饋。大多數Qt用戶希望更輕松地將他們的Qt項目與其他軟件集成在一起。
# 界面/圖表報表/文檔/IDE等千款熱門軟控件火熱銷售中 >>
Qt自帶集成開發環境(IDE),名為Qt Creator。它可以在Linux、OS X和Windows上運行,并提供智能代碼完成、語法高亮、集成幫助系統、調試器和剖析器集成,還集成了所有主要的版本控制系統(如git、Bazaar)。除了Qt Creator外,Windows上的開發人員還可以使用Qt的Visual Studio插件。也可以使用其他的IDE(如KDE上的KDevelop)。但當然絕不是必須使用任何IDE。
一年半前,Qt做出了一個重大決定,開始使用CMake來構建Qt 6。做出此決定的主要原因是用戶反饋。大多數Qt用戶希望更輕松地將他們的Qt項目與其他軟件集成在一起。根據當時的研究,CMake顯然是Qt用戶中最常用的構建工具-除了qmake。此外,遷移到CMake還為我們提供了擺脫內部構建工具維護負擔的機會。
比決定更大的是遷移到CMake所需的工作。現在,基本的遷移工作已經完成,現在該分享我們的發現了。
盡管已被許多項目很好地建立和使用,但CMake缺少了先前Qt構建工具所支持的一些關鍵功能。這就是為什么我們與Kitware合作消除障礙并改善CMake的原因,從而使Qt項目和更大的CMake社區受益。
由于各種因素,構建Qt很復雜:
讓我們看一下Qt的構建工具開關引起或影響的CMake改進。
Qt相關組件:
預編譯頭
在C ++項目中,可能會一遍又一遍地包含相同的頭文件。對于庫頭尤其如此。如果工具鏈支持,則可以通過預編譯頭文件來加快編譯速度。
在最長的時間內,CMake并未為此提供現成的支持。但是,在網上搜索代碼片段以啟用CMake中的預編譯頭的日子已經過去。從CMake 3.16開始,使用該target_precompile_headers命令可以添加要預編譯的頭文件列表。
Unity構建
另一種加快編譯速度的方法是unity builds。這就是多名技術--它也被稱為巨型構建、合并構建和單一編譯單元。
這種技術創建了一個包含所有其他源文件的源文件,并且只編譯這一個源文件。
#include "source_file1.cpp"
#include "source_file2.cpp"
/*...*/
#include "source_file8.cpp"
所有源文件的包含文件僅被處理一次,所有內容都以一個翻譯單元結束,并且優化器對項目具有全局視圖。
但是,并非每個C ++項目都可以不加修改地利用統一構建。
depfile支持AUTOMOC + Ninja
長期以來,人們一直在抱怨CMake的AUTOMOC,它會不必要地運行,或者在再次調用moc時無法正確檢測到。原因之一是moc輸出的確切依賴關系對于AUTOMOC是不可見的。
從Qt 5.15開始,moc學會了寫出準確的文件,這些文件構成了moc輸出的依賴性。CMake 3.17學會了讀取moc的depfiles并將其用于Ninja生成器。
總結一下:使用Ninja生成器的Qt> = 5.15和CMake> = 3.17時,AUTOMOC知道正確的依賴項,可以在正確的時間重新運行moc。
Ninja Multi-Config
在Windows和macOS上,傳統上Qt是用兩種配置(調試和發布)構建的,但在一個構建目錄中。
直到版本3.17引入了一個名為“ Ninja Multi-Config”的新生成器后,CMake才提供實現此目的的方法,該生成器可以一次構建多個配置。
iOS多架構構建
適用于iOS的Qt提供了模擬器和設備版本,該版本將針對實際目標構建的Qt與針對iOS模擬器構建的Qt相結合。盡管CMake 3.17引入了Ninja Multi-Config,但它的iOS支持尚未為iOS多體系結構構建做好準備。
CMake 3.18解決了這個問題,我們可以很高興地為模擬器和設備進行構建。
文件(配置)
在Qt構建中,在配置時會生成大量帶有動態創建內容的文件。configure_file但是,該命令僅使用輸入文件,不使用字符串。
解決此問題的一種方法是讓輸入文件只有一個變量
--conf-file-content.txt.in--
@my-conf-file-content@
然后像這樣調用configure_file
set(my-conf-file-content "This is the generated content!")
configure_file("my-conf-file-content.txt.in" "output.txt" @ONLY)
在CMake 3.18中,我們可以輕松實現相同目標:
file(CONFIGURE OUTPUT "output.txt" CONTENT "This is the generated content!")
評估!與功能同盟!
在Qt構建中,我們用盡了CMake語言作為實際編程語言執行的能力。不僅應該由用戶調用CMake函數,而且在引擎蓋下還有更復雜的設備。
讓我們煩惱的一件事是,不可能動態調用函數。在qmake中,可以調用在變量中定義的函數,并且Qt5版本廣泛使用此功能。
f = message
$${f}("Hello World!")
有多種方法可以使此工作在CMake中進行,包括生成一個隨后包含的文件,但是特別是在Windows上,這將極大地減慢項目配置步驟。
CMake 3.18隨附cmake_language(EVAL)用于評估CMake代碼并cmake_language(CALL)調用宏或函數。
set(f "message")
cmake_language(CALL ${f} STATUS "Hello World!")
cmake_language(EVAL CODE "${f}(\"Hello World!\")")
稍后致電-延遲的代碼
同樣,qmake功能啟發了CMake命令。
在QMake項目中,可以編寫CONFIG += foo,然后在mkspecs/features/foo.prf處理實際的項目文件后加載。
這對于面向用戶的API尤其有用。假設您正在為Android創建一個項目。
qt_add_executable(MyApp)
set_property(MyApp TARGET PROPERTY QT_ANDROID_EXTRA_LIBS SuperDuperLib)
qt_finalize_executable(MyApp)
該qt_finalize_executable調用將根據目標的屬性為目標生成適當的部署設置。如果用戶忘記致電qt_finalize_executable,則不會生成部署設置,也不會出現錯誤或警告。
但是,如果用戶擺脫了打電話的負擔,那會不會很棒qt_finalize_executable?在CMake 3.19中,Qt構建利用了新命令cmake_language(DEFER CALL)。這樣一來,就可以在定義的時間調用函數,例如,在評估當前目錄的項目文件之后。
不同目錄范圍的源文件上的屬性
在某些地方,我們為模塊創建目標,然后在子目錄中將源文件添加到該目標。這樣可以使源文件的名稱與CMakeLists.txt文件保持接近。
但是,無法在這些位置指定每個源文件的屬性-我們必須進入層次結構的頂層才能進行設置。我們并不經常這樣做,但是有時在開發過程中會出現這種情況,以允許根據選項設置在編譯時選擇實驗功能。
在CMake 3.18中,set_source_files_properties學會了在不同目錄范圍內設置屬性:
該DIRECTORY選項獲取指向處理后的源目錄的路徑的列表,并TARGET_DIRECTORY獲取目標的列表,這些目標的源目錄將用作設置源文件屬性的作用域列表。
get_property()并且get_source_file_property()還具有相同的新參數,除了只能指定一個值而不是列表。
add_custom_command DEPFILE支持Makefile
CMake 3.20將為Unix Makefile生成器提供depfile支持。這也是將moc生成的depfile用于Makefile的前提。
====================================================
想要了解或購買Qt正版授權的朋友,歡迎
Qt技術交流群現已開通,QQ搜索群號“765444821”或者掃描下方二維碼即可加入
本站文章除注明轉載外,均為本站原創或翻譯。歡迎任何形式的轉載,但請務必注明出處、不得修改原文相關鏈接,如果存在內容上的異議請郵件反饋至chenjj@fc6vip.cn
文章轉載自: