作者:billy
版權聲明:著作權歸作者所有,商業轉載請聯繫作者獲得授權,非商業轉載請註明出處
QBS簡介
QBS(Qt Build Suite)同 qmake、cmake 之類一樣都是構建工具。QBS 號稱是下一代的構建工具(博主的理解上一代是基於 makefile 的構建工具)。根據官網介紹,Qbs 極有可能會替代 qmake 成爲 Qt 6.0 的構建系統,與 qmake 相比,Qbs 提供了更快構建速度,以及更多的特性。
和qmake不一樣,qbs沒有綁定Qt版本,它從項目文件的高級項目描述中生成一個正確的編譯表(依賴表)。而傳統的MakeFile生成工具比如qmake和CMake生成了makefile文件,然後將實際的命令留給make或者ninja這樣的工具去執行。Qbs的另一方面就是充當了並行生成與直接調用編譯器、連接器以及其他工具的角色,非常像SCons和Ant做的事情。
Declarative語言
qbs的語法是一個簡化版本的qml,提供了對IDE友好的軟件項目的展示。它同樣提供了自由使用任何JavaScript表達式進行屬性綁定的支持。
萬事從 “Hello world” 開始,我們創建一個最基礎的程序來看下 qbs 如何構建項目:
consoleApplication: true 代表了這是一個控制檯程序。
files: “main.cpp” 則列出了源文件(不僅僅只是 C++頭文件和源文件)
多個文件時:files: [“foo.h”, “foo.cpp”, “main.cpp”]
fileTagsFilter: “application” 代表的意思就是 CppApplication 的 type 屬性爲 “application”, CppApplication 是一個可執行程序,常用的類型還有 dynamiclibrary(動態庫)、staticlibrary 靜態庫。
Group 將一組在某些行爲上是一樣的文件組合成一組,比如某些將安裝到同一目錄下的文件。
Group 分組的對象是文件,如果 Group 項內沒有指定有效文件,那麼這個 Group 是會被忽略的。
Group 項指定文件可以用 files 屬性或 fileTagsFilter 屬性,這兩個屬性是互斥的只能用其一。
files: 指定文件列表。
fileTagsFilter: 指定文件標記名,通過標記名來匹配文件。
qbs Property Documentation
-
architecture : string
目標平臺的處理器體系結構。
未定義表示目標平臺獨立於體系結構(例如clr或jvm),此屬性通常在配置文件中設置。
常用值爲:“x86”、“x86_64”和“arm”,默認:未定義。 -
architectures : stringList
產品將爲其構建的體系結構。
默認值:Android上是[armv5te],與蘋果平臺上的xcode相同,否則等同於[qbs.architecture]。 -
buildVariant : string
構建模式的名稱。
可能的值是“debug”和“release”。如果 qbs.configurationname 爲“release”,則默認爲“release”,否則爲“debug”。 -
buildVariants : stringList
構建模式的名稱列表。
默認值:相當於[qbs.buildvariant]。 -
debugInformation : bool
是否生成調試信息。
默認值:對於調試版本爲true,否則爲false。 -
enableDebugCode : bool
是否在產品中啓用調試功能。不要與生成調試符號或代碼優化級別混淆。
通常,此屬性對 debug 啓用,對 release 禁用。
默認值:對於調試版本爲true,否則爲false。 -
hostOS : stringList
此屬性由QBS內部設置,並指定OS QBS正在運行。
此屬性的可能值是TargetOS的值,即使其中某些值可能不受支持,默認:未定義。 -
hostPlatform : string
主機平臺,注:不要使用此屬性。
默認:自動確定。 -
install : bool
是否安裝某組文件。
此屬性通常設置在組項中,以將多個文件標記爲可安裝。
注意:啓用此屬性的項目將自動接收文件標記“installable”。這對於編寫與包裝相關的規則很有用,默認值:false -
installDir : string
產品或組文件的安裝目錄。
此屬性的值是相對於InstallPrefix的路徑,默認:未定義 -
installPrefix : string
全局安裝前綴。它隱式地預加在installdir的所有值之前。
此屬性本身的值在安裝上下文中相對於InstallRoot,默認:[] -
installRoot : string
全局安裝根目錄。
在安裝上下文中,它隱式地預加了installPrefix的所有值。
注意:此屬性與InstallDir和InstallPrefix有根本不同,因爲它對正在構建的代碼不可見。實際上,install根目錄通常只是用於打包二進制文件的臨時位置,因此不應假定它們在運行時位於該位置。出於同樣的原因,通常不從項目文件中設置此屬性。默認值:/install-root -
installSourceBase : string
要安裝的本地文件的基目錄。
從installdir中指定的目標目錄路徑中省略源基目錄。
默認:要安裝的當前文件的目錄,相對於產品的源目錄。 -
nullDevice : string
與空設備對應的平臺特定文件路徑。
默認值:在Windows上爲“nul”,在Unix上爲/dev/null。 -
optimization : string
所有工具鏈都應執行的一般優化類型。
允許值爲:
“fast”
“none”
“small”
默認值:調試版本爲“none”,發佈版本爲“fast”。 -
pathListSeparator : string
環境變量或其他上下文中使用的路徑列表的平臺特定分隔符。
在Windows上默認爲“;”,在Unix上默認爲“:”。 -
profiles : stringList
構建產品的配置文件。
對於這裏列出的每個概要文件,將根據各自概要文件中設置的屬性構建一個產品實例。
默認值:[project.profile] -
shellPath : path
與命令行解釋器對應的平臺特定文件路徑。
在Windows上,這是保存在comspec環境變量(通常是c:/windows/system32/cmd.exe)中的cmd.exe的路徑,在類Unix平臺上,這是/bin/sh。
默認值:Windows上"%COMSPEC%",Unix上“bin/sh” -
sysroot : string
目標平臺的sysroot。
此屬性通常設置在用於交叉編譯的配置文件中。默認:未定義 -
targetOS : stringList
指定要爲其生成項目的操作系統。
使用此屬性在條件中測試特定OS或OS系列。請勿爲此目的使用TargetPlatform。
可能的值包括“bsd”、“darwin”和“unix”中的一個或多個,以及targetform的可能值。
默認:未定義 -
targetPlatform : stringList
要爲其生成項目的操作系統。
此屬性通常設置在配置文件中或特定產品中,目標操作系統始終是已知的(例如以本機代碼編寫的Apple Watch應用程序)。通常應將此屬性視爲只寫,並避免使用它來測試當前目標操作系統。
可能的值包括以下一個或多個:
"aix"
"android"
"freebsd"
"haiku"
"hpux"
"hurd"
"integrity"
"ios"
"ios-simulator"
"linux"
"lynx"
"macos"
"netbsd"
"openbsd"
"qnx"
"solaris"
"tvos"
"tvos-simulator"
"vxworks"
"watchos"
"watchos-simulator"
"windows"
默認:未定義
-
toolchain : stringList
工具鏈的屬性用於構建。
典型值包括“llvm”,以及toolchaintype的可能值。默認:未定義 -
toolchainType : string
工具鏈用於構建。
通常應將此屬性視爲只寫,並避免使用它來測試當前的工具鏈。
典型值包括:“gcc”、“clang”、“mingw”、“msvc”和“xcode”。
默認:自動確定。 -
[read-only] configurationName : string
當前生成配置的名稱。
構建配置是通過命令行參數config設置的。默認:“default” -
[read-only] hostOSBuildVersion : string
主機操作系統的內部版本。
目前,僅爲Windows和Apple平臺定義,默認:未定義
在Windows上,這是4位或5位Windows內部版本號,相當於versionPatch。
在蘋果平臺上,這是蘋果版本控制方案中的標準版本號。例如,“13C64”。 -
[read-only] hostOSVersion : string
主機操作系統版本。
目前,僅爲Windows和Apple平臺定義, 默認:未定義
由兩個或三個由點分隔的數字組成。例如,“10.9”或“6.3.9600”。 -
[read-only] hostOSVersionParts : list
主機操作系統版本列表。
例如,Windows8.1(版本6.3.9600)對應的值爲[6,3,9600],默認:[] -
[read-only] hostOSVersionMajor : int
主機操作系統主版本。
默認值:hostoVersionParts[0] -
[read-only] hostOSVersionMinor : int
主機操作系統次版本。
默認值:hostosVersionParts[1] -
[read-only] hostOSVersionPatch : int
主機操作系統修補程序級別。
默認值:hostosVersionParts[2] -
[read-only] version : string
QBS版本號。例如,“1.4.1”。 -
[read-only] versionMajor : int
QBS的主要版本號。 -
[read-only] versionMinor : int
QBS的次要版本號。 -
[read-only] versionPatch : int
QBS的補丁版本號。
Group QML Type
-
condition : bool
確定組中的文件是否實際視爲項目的一部分。默認值:true -
excludeFiles : list
從文件列表中減去的文件列表。使用通配符時很有用。默認:一個空的列表 -
fileTags : list
要附加到組文件的文件標記列表。然後可以用一個規則來匹配它們。
注意:文件標記器從不應用於設置了此屬性的文件。默認:一個空的列表 -
fileTagsFilter : list
要匹配的artifact.filetags列表。
此組中設置的任何屬性都將應用於產品的工件,其文件標記與此處列出的標記匹配。
組的file tags屬性指定的文件標記將添加到匹配的項目中。此屬性與文件互斥。
默認:一個空的列表 -
files : list
組中的文件。與FileTagsFilter互斥。
使用包含組項的文件的父目錄解析相對路徑。但是,如果prefix屬性設置爲絕對路徑,則該路徑將成爲基目錄。默認:一個空的列表 -
filesAreTargets : bool
如果此屬性爲true且組位於模塊中,則組中的文件將不會成爲依賴於模塊的產品的源工件。相反,它們被視爲產品的目標工件。也就是說,它們將與依賴模塊的產品中的規則的inputsFromDependencies文件標記列表相匹配。默認值:false -
name : string
組的名稱。不在內部使用;主要用於IDE。
默認值:“Group x”,其中x是產品中所有組中的唯一數字。 -
overrideTags : bool
確定如何處理同時在產品(或父組,如果有)和組的頂級列出的文件上的標記。
如果此屬性爲真,則通過組設置的文件標記將替換通過產品或父組設置的標記。如果爲假,則將組標記添加到父標記中。如果設置了FileTagsFilter,則忽略此屬性。默認值:true -
prefix : string
用於預處理所有文件的字符串。允許斜槓並具有目錄語義。
默認值:父組的前綴(如果存在),否則爲空。
案例
通常我們使用Group 指定安裝文件的目標目錄。
要安裝一組文件,請將該組的 qbs.install 屬性設置爲true,qbs.installdir 的值指定文件安裝目錄的路徑。可以將所有安裝目錄的基目錄指定爲 qbs.installPrefix 的值。
例如,以下屬性指定在Windows和Linux上安裝一組QML文件和應用程序可執行文件的位置:
Application {
name: "myapp"
Group {
name: "Runtime resources"
files: "*.qml"
qbs.install: true
qbs.installDir: condition: qbs.targetOS.contains("unix")
? "share/myapp" : "resources"
}
Group {
name: "The App itself"
fileTagsFilter: "application"
qbs.install: true
qbs.installDir: "bin"
}
qbs.installPrefix: condition: qbs.targetOS.contains("unix")
? "usr/local" : "MyApp"
}
在Windows上,qml文件最終將安裝在myapp\resources中,應用程序可在myapp\bin中執行。
在Linux上,qml文件將安裝在/usr/local/share/myapp中,可執行文件將安裝在/usr/local/bin中。
前景
這是一個試驗性質的項目,用來試驗不同編譯工具概念。qmake仍然會存在很長一段時間,並且沒人會強迫誰去使用qbs,或者其它任何編譯工具。儘管在某些時候我們肯定會嘗試將qbs作爲Qt自身的編譯系統來使用。
通用元編譯工具,比如CMake或者GNU Autotools的用戶也許注意到了,嚴謹來說,qbs與跨平臺編譯工具相比有一個關鍵部分的缺失:適應宿主環境,就是所謂的配置檢查。當前,qbs仍然需要一個外部的配置腳本來生成一個JSON格式的文件,從而能被qbs調用。但是這終究不是一個長久的解決方法。關鍵點在於使配置測試像其他模塊一樣可用。其實現當然不止包括了Declarative,還包含了一些JavaScript代碼。