亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Qt高級——QMake用戶指南

發布時間:2020-06-26 10:27:43 來源:網絡 閱讀:20421 作者:天山老妖S 欄目:編程語言

Qt高級——QMake用戶指南

本文翻譯自Qt 4.8官方文檔。

一、QMake使用

QMake提供了一個用于管理應用程序、庫、其它組件的構建過程的面向工程系統。
QMake擴展了每個工程文件的信息,生成一個執行編譯和鏈接過程的必須命令的MakeFile。

1、描述工程

工程文件.pro描述了工程信息。工程文件信息會被qmake用于生成包含構建過程中所需的所有命令的MakeFile。工程文件通常包含一系列頭文件和源文件,通用配置信息以及音樂程序指定的細節,如應用程序的鏈接庫、搜索路徑。
工程文件包含一定數量的不同元素,如注釋、變量聲明、內置函數以及簡單的控制結構。在大多數簡單的工程中,只需要聲明使用簡單配置選項構建工程的源文件和頭文件即可。

2、構建工程

對于簡單的工程,只需要在工程的頂層目錄運行qmake。默認情況下,qmake會生成一個構建工程的MakeFile,此時可以運行平臺相關的make工具構建工程。
qmake也能用于生成工程文件。

3、預編譯頭文件

在大型工程中,可以利用預編譯頭文件的優勢加速構建過程。

二、QMake工程文件

1、工程文件基本元素

工程文件包含qmake構建應用、庫、插件的所有必須信息。工程使用的資源通常使用一系列聲明指定,但支持用于描述不同平臺和環境的不同構建過程的簡單編程結構。
qmake使用的工程文件格式支持簡單和相對復雜的構建系統。簡單工程文件使用直接聲明風格,定義標準變量指明工程需要的頭文件和源文件。復雜工程可能需要使用流控制結構微調構建過程。
工程文件中不同類型的元素如下:
A、變量
工程文件中,變量用于保存字符串列表。簡單工程中,變量會告訴qmake使用的配置選項,提供在構建過程中使用的文件名和路徑。
qmake會在工程文件中查找某些變量,變量的內容將決定哪些內容會生成到MakeFile。例如,HEADERS和SOURCES變量的列表值會告訴qmake相關的頭文件和源文件(工程文件所在目錄)。
變量可以用于存儲臨時的列表值,覆寫存在的列表值或是擴展新的值。下列代碼顯示了如何賦值列表值給變量:
HEADERS = mainwindow.h paintwidget.h
注意:第一種賦值方法只包括同一行指定的值。第二種賦值方法會使用“\”字符分隔列表值的項。
變量的列表值可以使用如下方式擴展:

SOURCES = main.cpp mainwindow.cpp \
          paintwidget.cpp
CONFIG += qt

CONFIG是一個qmake生成MakeFile文件時的特殊變量。
qmake會識別下列變量的值,并描述變量的內容。
CONFIG:通用工程配置選項
DESTDIR:可執行文件或庫文件的輸出目錄
FORMS:由uic處理的UI文件列表
HEADERS:構建工程使用的頭文件列表
QT:Qt相關配置選項
RESOURCES:包含到最終工程的資源文件列表
SOURCES:用于構建工程的源文件列表
TEMPLATE:構建工程的模板,決定構建過程輸出一個應用,一個庫或是一個插件
變量的內容可以通過在變量名稱前加“$$”符號來訪問,用于將一個變量的內容賦值給另一個變量。
TEMP_SOURCES = $$SOURCES
$$操作符可以被擴展用于操作字符串和值列表的內置函數中。
通常,變量用于包含空格分隔符的值列表,但有時需要指定包含空格的值,必須使用雙引號包含。
DEST = "Program Files"
引號內的文本在值列表內作為單個值對待。類似的方法可以用于處理包含空格的路徑,尤其是在Windows平臺定義INCLUDEPATH和LIBS變量。

win32:INCLUDEPATH += "C:/mylibs/extra headers"
unix:INCLUDEPATH += "/home/user/extra headers"

B、注釋
可以在工程文件中增加注釋。注釋需要#符號開頭,直到#所在行結束。

# Comments usually start at the beginning of a line, but they
# can also follow other content on the same line.

為了在變量賦值中包括#,必須使用內置變量LITERAL_HASH。
C、內置函數和控制流
qmake提供了多個內置函數用于處理變量內容。在簡單工程中,最常使用的函數是使用一個文件名作為參數的include函數。在工程文件中,給定文件的內容會被包含在include函數調用的位置。include函數最常用于包含其它工程文件.pro。
include(other.pro)
通過代碼塊作用域可以實現類似編程語言中IF語句的行為,支持條件控制結構。

win32 {
        SOURCES += paintwidget_win.cpp}

只有條件為true時,括號內的賦值才會有效。在這個例子中,特殊變量win32必須被設置。在 Windows平臺上,win32會自動設置。當在其它平臺上,通過運行帶-win32參數選項的qmake可以指定win32。左括號必須與條件在同一行。
使用for函數通過遍歷列表值可以構建一個簡單的循環。下列代碼會在目錄存在的情況下增加目錄到SUBDIRS變量。

EXTRAS = handlers tests docsfor(dir, EXTRAS) {
        exists($$dir) {
        SUBDIRS += $$dir
        }}

對變量進行更復雜的操作可以通過內置函數find、unique、count。內置函數可以提供對字符串、路徑的操作,支持用戶輸入,并調用其它外部工具。

2、工程模板

TEMPLATE變量用于定義構建的工程的類型。如果工程文件中沒有聲明TEMPLATE變量,qmake會默認構建一個應用程序,并生成一個MakeFile文件。
下列時可用工程類型:
app:創建一個構建應用程序的MakeFile
lib:創建一個構建庫的MakeFile
subdirs:創建一個包含使用SUBDIRS變量指定子目錄的規則的MakeFile,每個子目錄必須包含自己的工程文件。
vcapp:創建一個構建應用程序的Visual Studio平臺的工程文件
vclib:創建一個構建庫的Visual Studio平臺的工程文件
vcsubdirs:創建一個在子目錄構建工程的Visual Studio平臺的解決方案文件
當使用subdirs模板時,qmake會生成一個MakeFile檢查每個子目錄,處理查找到的任何工程文件。并且在新生成的MakeFile上運行平臺的make工具。SUBDIRS變量用于包含要處理的子目錄列表。

3、通用配置

CONFIG變量用于指定編譯器使用的選項和屬性以及鏈接庫。CONFIG變量可以增加任何選項,但是本節所述選項會被qmake內部識別。
下列選項控制用于構建工程的編譯器選項:
release:工程使用release模式構建,如果debug也被指定會被忽略。
debug:工程使用debug模式構建
debug_and_release:工程使用debug和release兩種模式構建
debug_and_release_target:工程使用debug和release兩種模式構建,目標會被構建到debug和release兩個目錄下
build_all:如果指定debug_and_release,工程默認使用debug和release兩種模式構建
autogen_precompile_source:自動生成.cpp文件,包含在.pro文件中指定的預編譯頭文件
ordered:當使用subdirs模板時,本選項會指定按照列出的目錄給定的順序處理
warn_on:編譯器會盡可能多輸出警告信息,如果指定warn_off,警告信息會被忽略
warn_off:編譯器盡可能少的輸出警告信息
copy_dir_files:打開要復制目錄安裝規則,而不只復制文件
debug_and_release選項是一個特殊選項,會開啟工程的debug和release兩種版本構建。qmake生成的MakeFile文件會包含兩種版本的構建規則,使用下列方式進行調用:
make all
增加build_all選項到CONFIG變量會生成構建工程的默認規則,并且創建debug和release版本的安裝目標。
注意:CONFIG變量指定每個選項可以用于條件作用域。可以使用CONFIG內置函數測試某個配置選項的表現。下列代碼將展示CONFIG函數作為作用域的條件,測試opengl選項是否在用。

CONFIG(opengl) {
        message(Building with OpenGL support.)} else {
        message(OpenGL support is not available.)}

下列選項會定義構建工程的類型,注意,某些選項只有在特定平臺才會生效。
qt:工程是一個Qt應用程序,會鏈接Qt庫。可以使用QT變量控制應用程序需要的任何附加Qt模塊
thread:工程是一個多線程應用程序
x11:工程是一個X11應用程序或庫
當使用應用程序或庫的工程模板時,很多配置選項用于微調構建過程。例如,如果應用程序使用Qt庫,并且在debug模式構建多線程應用時,工程文件如下:
CONFIG += qt thread debug
注意:必須使用“+=”而不是“=”,否則qmake不會使用Qt配置決定工程需要的設置。

4、聲明Qt庫

如果CONFIG變量包含qt,qmake對Qt應用程序的支持會開啟,這會使微調應用程序的Qt模塊變得可能。用于聲明需要擴展模塊的QT變量可以實現微調。例如,可以使用下列代碼開啟XML和network模塊:

CONFIG += qt
QT += network xml

注意QT默認包含core和gui模塊,上述代碼會增加network和xml模塊到默認值列表。下列代碼將會忽略默認模塊,這會導致應用程序源碼編譯時錯誤。
QT = network xml # This will omit the core and gui modules
如果要不使用gui模塊構建工程,可以使用“-=”排除gui模塊。默認情況下,QT包含core和gui兩個模塊,所以下列代碼會構建一個最小化工程。
QT -= gui # Only the core module is used.
下列選項可以用于QT變量:
Core:QtCore模塊,默認包含
Gui:QtGui模塊,默認包含
Network:QtNetwork模塊
Opengl:QtOpenGL模塊
Sql:QtSql模塊
Svg:QtSvg模塊
Xml:QtXml模塊
Xmlpatterns:QtXmlPatterns
qt3support:Qt3Support模塊
注意,增加opengl選項到QT變量會自動促使相應選項到增加到CONFIG變量。因此,對于Qt應用程序,增加opengl選項到QT和CONFIG變量不是必須的。

5、配置特性

qmake可以使用特性文件.prf文件設置額外的配置特性。這些額外特性常常提供了對構建過程中自定義工具的支持。為了增加特性到構建過程,可以增加特性名稱到CONFIG變量。
例如,qmake可以利用pkg-config支持的外部庫對構建過程進行配置,例如D-Bus或ogg外部庫,代碼如下:

CONFIG += link_pkgconfig
PKGCONFIG += ogg dbus-1

6、聲明第三方庫

如果在工程中使用除Qt支持的庫以外的第三方庫,需要在工程文件中指定。
qmake搜索庫的路徑和要鏈接的特定庫要加入到LIBS變量的列表值中。給出庫本身的路徑,或是指定庫的類unix風格標記和路徑可以優先使用。
例如,下列代碼展示如何指定庫:
LIBS += -L/usr/local/lib -lmath
包含頭文件的路徑可以使用INCLUDEPATH變量指定。

三、QMake命令行使用

當qmake有多個選項在命令行運行,qmake的行為可以被自定義。qmake選項可以微調構建過程,提供有用的診斷信息,并指定工程的目標平臺。

1、語法

qmake的使用采用下列簡單形式:
qmake [mode] [options] files
Qmake支持兩種不同的操作模式:默認模式下,qmake會使用工程文件的信息生成MakeFile文件,但qmake也可以生成工程文件。如果要顯示設置模式,必須在其它所有選項前指定模式。模式有下列兩個選項值:
-makefile:qmake生成MakeFile
-project:qmake生成工程文件,生成的過程文件可能需要編輯。

2、通用選項參數

為了自定義構建過程和覆寫平臺的默認設置,qmake可以在命令行指定一系列參數選項。下列基本選項提供有用的信息,指定qmake輸出的文件的位置,控制輸出到控制臺調試信息的水平。
-help:qmake會回顧特性,給出有用幫助信息
-o file:qmake的輸出會被重定向到file 文件。如果本選項不指定,qmake會根據運行的模式為輸出選擇一個合適的文件名。如果指定了“-”,輸出定向到stdout。
-d:qmake會輸出調試信息
對于每個目標平臺都需要不同構建的有多個子目錄的工程,qmake可以使用下列選項在每個工程文件中設置相應特定平臺的變量。
-unix:qmake運行在unix模式,會使用unix的文件和路徑命名規范,增加對unix的測試會成功,是所有的類unix平臺的默認模式。
-macx:qmake運行在Mac OS X模式,會使用unix的文件和路徑命名規范,增加對macx的測試會成功,是Mac OS X平臺的默認模式。
-win32:qmake運行在win32模式,會使用Windows的文件和路徑命名規范,增加對win32的測試會成功,是Windows平臺的默認模式。
工程使用的模板通常在工程文件中使用TEMPLATE變量設置,可以使用下列選項覆寫或修改:
-t tmpl:qamke會使用tmpl設置TEMPLATE變量,但僅在.pro文件被處理后。
-t prefix:增加前綴prefix到TEMPLATE變量
調整警告信息的水平可以幫助找到工程文件中的問題。
-Wall:qmake會報告已知的所有警告信息
-Wnone:不生成任何警告信息
-Wparser:qmake只會生成解析警告信息,解析警告信息會在解析工程文件過程中提醒開發者常見的陷阱和潛在問題。
-Wlogic:qmake會警告工程文件中的常見陷阱和潛在問題。例如,如果一個文件是否被多次放到文件列表中,或是如果文件沒有找到,qmake會警告。

3、MakeFile模式選項

qmake -makefile [options] files
在makefile模式,qmake會生成用于構建工程的makefile文件。此外,下列選項可以被用于makefile模式中:
-after:qmake會在指定文件后的命令行上處理給定賦值
-nocache:qmake會忽略.qmake.cache文件
-nodepend:qmake不會生成任何依賴信息
-cache file:qmake會使用file作為緩存文件,其它的.qmake.cache文件會被忽略。
-spec spec:qmake會使用spec作為平臺和編譯器信息的路徑,QMAKESPEC變量的值會被忽略。
可以在命令行上進行qmake賦值,賦值會在指定的所有文件處理。例如:
qmake -makefile -unix -o Makefile "CONFIG+=test" test.pro
上述代碼會從使用unix路徑名的test.pro文件生成一個Makefile。但指定選項的很多是默認的,不是必須的。因此,在Unix平臺,上述代碼可以簡化如下:
qmake "CONFIG+=test" test.pro
如果確定變量在指定文件后被處理,可以使用-after選項。當-after選項指定,在-after后的所有命令行的賦值會被延遲到指定文件被解析后進行。

4、工程模式選項

qmake -project [options] files
在project模式下,qmake會生成一個工程文件。可以在project模式下使用下列選項:
-r:qmake會遞歸處理給定的目錄
-nopwd:qmake不會查找當前源碼的工作路徑,只使用指定文件。
在project模式下,files參數是文件或目錄列表。如果指定一個目錄,會被包含到DEPENDPATH變量,相關代碼會包含到生成的工程文件中;如果給定一個文件,會被追加到依賴于擴展的合適變量。例如,UI會被增加到FORMS變量,C++文件會被增加到SOURCES變量。

四、QMake平臺相關事項

很多跨平臺工程使用qmake的基本配置和特性進行處理。在一些平臺上,利用平臺相關特性有時是有用的,甚至是必須的。qmake直到很多特性,這些特性只能通過特定變量訪問,特定變量只在獨立平臺上有效。

1、Mac OS X平臺

本平臺特有的特性包括支持創建通用二進制文件、框架和捆綁包。
A、源包和二進制包
源包中提供的qmake版本與二進制包中提供的配置略有不同,因為它使用了不同的特性規范。源包通常使用macx-g++規范,二進制包通常被配置為使用macx-xcode代碼規范。
每個包的用戶需要使用-spec參數選項調用qmake覆寫配置。例如,在一個工程目錄使用下列命令可以從一個二進制包生成Makefile文件:
qmake -spec macx-g++
B、框架使用
qmake會自動生成鏈接框架的構建規則,這些框架的標準框架路徑在Mac OS X平臺下是/Library/Frameworks/。
除了標準框架目錄之外,需要向構建系統指定目錄,通過增加鏈接器選項到QMAKE_LFLAGS變量可以實現。
QMAKE_LFLAGS += -F/path/to/framework/directory/
框架本身會通過附加-framework選項和框架的名稱被鏈接到LIBS變量。
LIBS += -framework TheFramework
C、創建框架
任何給定的庫項目都可以被配置,以便生成的庫文件放置在準備部署的框架中。通過設置工程使用lib模板,并增加lib_bundle選項到CONFIG變量可以實現。

TEMPLATE = lib
CONFIG += lib_bundle

與庫關聯的數據使用QMAKE_BUNDLE_DATA變量指定。這將保存將使用庫捆綁包進行安裝的項,并且通常用于指定頭文件集合。例如:

FRAMEWORK_HEADERS.version = Versions
FRAMEWORK_HEADERS.files = path/to/header_one.h path/to/header_two.h
FRAMEWORK_HEADERS.path = Headers
QMAKE_BUNDLE_DATA += FRAMEWORK_HEADERS

FRAMEWORK_HEADERS是用戶定義的變量,用于定義使用特殊框架所需的頭文件。追加FRAMEWORK_HEADERS到QMAKE_BUNDLE_DATA變量,確保頭文件信息被增加到所安裝的庫捆綁包的資源集合中。框架的名稱和版本由變量QMAKE_FRAMEWORK_BUNDLE_NAME和QMAKE_FRAMEWORK_VERSION指定,默認情況下,使用TARGET和VERSION變量的值。
D、創建通用二進制包
為了創建應用程序的通用二進制包,需要使用已經配置了-universal選項的Qt版本。
在二進制包中,支持的架構通常在CONFIG變量指定。例如,下列代碼會使qmake生成同時支持PowerPC 和X86架構的通用二進制包的構建規則。
CONFIG += x86 ppc
此外,開發者使用PowerPC平臺需要設置QMAKE_MAC_SDK變量。
E、創建和移動XCode項目
MAC OS X平臺的開發者可以利用qmake對XCode工程文件的支持,通過運行qmake從已有的qmake工程文件生成一個XCode工程。
qmake -spec macx-xcode project.pro
注意:如果工程在磁盤上進行了移動,需要再次運行qmake處理工程文件生成一個XCode工程。
F、同時支持兩種構建目標
要實現同時支持兩個構建目標目前并不可行,因為在概念上,主動構建配置的XCode概念不同于qmake構建目標的概念。
XCode主動構建配置用于修改xcode配置、編譯器選項以及類似的構建選項。不像Visual Studio,XCode不允許基于構建配置是否選擇debug或release來選擇特定的庫文件。Qmake的debug和release設置會控制鏈接到執行文件的庫文件。
目前不可能在qamke生成的XCode工程文件中設置XCode設置中的文件。
此外,所選的主動構建配置存儲在.pbxuser文件中,.pbxuser文件是由XCode在第一次加載中生成的,而不是qamke創建的。

2、Windows平臺

Windows平臺特有的特性包括在部署Visual Studio 2005開發的Qt應用程序時支持創建Visual Studio工程文件和處理清單文件。
A、創建Visual Studio工程文件
使用Visual Studio編寫Qt應用程序的開發人員可以使用Qt商業版提供的Visual Studio集成工具,而不必擔心如何管理項目依賴關系。
但是,某些開發者可能需要導入已經存在的qmake工程到Visual Studio。qmake能夠利用工程文件創建一個包含開發環境所需必須信息的Visual Studio工程。通過設置qmake工程模板為vcapp或vclib可以實現,可以使用命令行進行:
qmake -tp vc
在子目錄遞歸生成.vcproj文件和在主目錄生成文件如下:
qmake -tp vc -r
每次更新工程文件時,需要運行qmake生成一個更新的Visual Studio工程。
注意:如果使用Visual Studio Add-in,可以通過Qt->Import from .pro file菜單項導入.pro文件。
B、Visual Studio 2005 Manifest文件
當部署使用Visual Studio 2005構建的Qt應用程序時,確保應用程序鏈接時創建的Manifest文件被正確處理是必須的。對于生成DLL的工程來說是自動處理的。
移除嵌入在應用程序可執行文件的manifest文件可以使用下列賦值給CONFIG變量完成:
CONFIG -= embed_manifest_exe
移除嵌入在應用程序DLL文件的manifest文件可以使用下列賦值給CONFIG變量完成:
CONFIG -= embed_manifest_dll

3、Symbian平臺

Symbian平臺特有的特性包括處理靜態數據,兼容性,棧和堆大小,編譯器特定選項,應用程序或庫的唯一標識符。
A、處理靜態數據
如果應用程序使用了任何靜態數據,構建系統需要了解這些靜態數據。這是因為Symbian系統會試圖在沒有使用靜態數據的情況下節省內存。
若要指定靜態數據支持,將其添加到項目文件中:
TARGET.EPOCALLOWDLLDATA = 1
默認值為0
B、棧和堆大小
Symbian平臺使用預定義大小的堆棧和堆。如果應用程序超過任一限制,則可能崩潰或無法完成其任務。毫無理由的崩潰常常可以追溯到堆棧和堆大小不足。
堆棧大小具有最大值,而堆大小具有最小值和最大值,均以字節指定。如果內存不可用,則最小值阻止應用程序啟動。最小值和最大值由一個空間分隔。例如:

TARGET.EPOCHEAPSIZE = 10000 10000000
TARGET.EPOCSTACKSIZE = 0x8000

默認值取決于所使用的Symbian SDK的版本,但是,Qt工具鏈將此設置為最大可能值,并且不應該更改此值。
C、編譯器特定選項
通用編譯器選項通常使用QMAKE_CFLAGS和QMAKE_CXXFLAGS變量進行設置。為了設置特定的編譯器選項,可以使用QMAKE_CFLAGS.<compiler>QMAKE_CXXFLAGS.<compiler><compiler>可以是WINSCW架構(仿真器)的CW,或是ARMV5架構(硬件)的ARMCC,或是ARMV5架構(硬件)的GCCE。例如:

QMAKE_CXXFLAGS.CW += -O2
QMAKE_CXXFLAGS.ARMCC += -O0

D、唯一標識符
Symbian應用程序可能有附加的唯一標識符。下面是如何在工程文件中定義唯一標識符。
支持IDS的可用類型有四種:UID2、UID3、SID和VID。它們可以如下指定的:

TARGET.UID2 = 0x00000001
TARGET.UID3 = 0x00000002
TARGET.SID = 0x00000003
TARGET.VID = 0x00000004

如果未指定SID,則默認與UID3值相同。如果未指定UID3,qmake將自動生成適合開發和調試的UID3。應該為要釋放的應用程序手動指定UID3值。
這兒也有一個UID1,但不會被任何應用所涉及。
UID2對于不同類型的文件具有特定的值;例如app/exes總是0x10039 CE。工具鏈將為最常見的文件類型(如EXE/APP和共享庫DLL)設置值。
E、Capability
Capability為應用程序定義額外的特權,例如列出文件系統上的所有文件的能力。Capability在項目文件中定義如下:
TARGET.CAPABILITY += AllFiles
可以通過首先指定所有的能力,然后在它們前面減去不必要的能力來指定哪些能力不具備,例如:
TARGET.CAPABILITY = ALL -TCB -DRM -AllFiles

五、QMake高級功能

1、qmake高級功能簡介

許多qamke工程文件使用varname=values和varname+=values定義的列表來簡單描述工程使用的源文件和頭文件。qamke還提供用于處理變量聲明中提供的信息的其它運算符、函數和作用域。這些高級特性允許從單個工程文件生成多個平臺的MakeFile文件。

2、操作符

在許多工程文件中,賦值操作符“=”和追加操作符“+=”可以用于包含有關工程的所有信息。典型的使用模式是將值列表賦值給變量,并根據各種測試的結果追加更多的值。由于qmake使用默認值定義了某些變量,因此有時需要使用移除操作符“-=”過濾出不需要的值。下面的運算符可以用來操作變量的內容。
賦值操作符“=”用于將一個值賦值給一個變量。
TARGET = myapp
上述代碼會設置TARGET變量的值為myapp,會使用myapp覆寫TARGET變量以前設置的任何值。
追加操作符“+=”用于追加一個新的值到變量的值列表中。
DEFINES += QT_DLL
上述代碼會追加QT_DLL到預處理列表的定義中,以將其放入生成的Makefile文件中。
移除操作符“-=”用于從一個變量的值列表中移除一個值。
DEFINES -= QT_DLL
上述代碼會將QT_DLL從預處理列表的定義中移除,以將其結果放入生成的Makefile文件中。
增加操作符“=”會增加一個值到變量的值列表中,但僅限這個值不存在的情況。“=”操作符胡阻止一個值被多次包含到變量中。
DEFINES *= QT_DLL
上述代碼只有在預處理列表的定義不存在QT_DLL情況下,才會將QTDLL加入,以將其結果放入生成的Makefile文件中。
注意:unique函數也可以確保變量中每個值只包含一個實例。
“~=”操作符可以代替指定的正則表達式匹配的任何值。
`DEFINES ~= s/QT
[DT].+/QT`
上述代碼,值列表中的以QT_D或QT_T開頭放入任何值使用QT替換。
“$$”操作符用于提取變量的內容,用于在變量中傳遞值或是提供給函數使用。

EVERYTHING = $$SOURCES $$HEADERS
message("The project contains the following files:")
message($$EVERYTHING)

3、作用域

作用域與過程化編程語言的IF語句比較類似。如果條件為true,作用域內的聲明會被處理。
A、語法
作用域由一個條件和同一行跟隨的一個左括號,一系列命令和定義,新一行的右括號組成。

<condition> {
        <command or definition>
        ...
}

左括號必須與條件在同一行。作用域可能會被連接多個條件。
B、作用域和條件
條件后面的作用域是一對括號中包含的一系列聲明。例如:

win32 {
        SOURCES += paintwidget_win.cpp}

如果qmake運行在Windows平臺,上述代碼會增加paintwidget_win.cpp源文件到生成的Makefile的源文件列表中。如果qmake運行在其它平臺,定義會被忽略。
在給定作用域使用的條件也可以取反,用于提供一組可替代的聲明,僅在原始條件為false時才被處理。例如,假設想要在除了Windows平臺上的所有平臺上處理某些事務,代碼如下:

!win32 {
        SOURCES -= paintwidget_win.cpp}

作用域可以將嵌套,以組合多個條件。例如,如果想要在某個平臺包含某個特定文件,僅且在調試開啟時處理。代碼如下:

macx {
        debug {
            HEADERS += debugging.h
        }}

為了省去寫很多作用域,可以通過使用“:”嵌套作用域。上述嵌套作用域可以重寫如下:

macx:debug {
        HEADERS += debugging.h}

也可以使用“:”操作符執行單行條件賦值。
win32:DEFINES += QT_DLL
上述代碼只有在Windows平臺才會增加QT_DLL到DEFINES變量。
通常,“:”操作符更像一個邏輯與操作符,用于連接多個條件,并且必須所有條件為true。
“|”操作符的行為像一個邏輯或操作符(OR),連接多個條件,只要求其中一個條件為true。

win32|macx {
        HEADERS += debugging.h}

可以通過使用else作用域來向作用域內的內容提供替代聲明。如果前一個作用域的條件為false,對else作用域進行處理。例如:

win32:xml {
        message(Building for Windows)
     SOURCES += xmlhandler_win.cpp} else:xml {
         SOURCES += xmlhandler.cpp} else {
        message("Unknown configuration")}

C、配置和作用域
存儲在CONFIG變量的值會被qmake特殊處理。每個可能的值都可以作為作用域的條件。例如,CONFIG的值列表可以使用opengl值擴展。
CONFIG += opengl
上述代碼的結果是測試opengl的任何作用域都會被處理,可以利用這個特性給最終的可執行文件一個合適的名稱。

opengl {
        TARGET = application-gl} else {
        TARGET = application}

這個特性使得在不必丟失需要特定配置的所有自定義設置的情況下,就可以很容易地更改工程的配置。上述代碼中,第一個作用域的聲明被處理時,最終的可執行文件是application-gl。但是,如果opengl沒有被指定,第二個作用域的聲明會被處理,最終的可執行文件是application。
由于可以在CONFIG上設置自己的值,這提供了一種便捷的方法去自定義工程文件并微調生成的MakeFile文件。
D、平臺的作用域值
除了在許多作用域條件中使用的win32、macx和unix值之外,還可以使用多種其它內置平臺和編譯器特定值對作用域進行測試。這些都是基于Qt的mkspecs目錄中提供的平臺規范。例如,工程文件中的下列代碼會顯示在用的當前規范和測試linux-g++規范。

message($$QMAKESPEC)
linux-g++ {
        message(Linux)}

只要在mkspecs目錄中存在一個規范,就可以測試任何其他平臺編譯器組合。
在Symbian平臺上,unix作用域為true。

4、變量

在工程文件中使用的很多變量是qmake在生成MakeFile文件時使用的特殊變量,例如,DEFINES,、SOURCES和HEADERS。用戶可以創建自定義變量,當遇到對一個名稱賦值時,qmake會使用給定的名稱創建一個新的變量。例如:
MY_VARIABLE = value
對于自定義的變量,沒有任何使用限制,因為qmake將忽略它們,除非在處理作用域時需要對它們進行評估。
通過變量名使用“$$”前綴可以將一個變量的值賦值給另一個變量。例如:
MY_DEFINES = $$DEFINES
現在MY_DEFINES變量包含工程文件中DEFINES變量在此處中的內容。等效于下列代碼:
MY_DEFINES = $${DEFINES}
第二種寫法允許將變量的內容追加到另一個值,而不必用空格分隔這兩個值。例如,下列代碼會確保最終的可執行文件有一個包含所使用模板的名稱。
TARGET = myproject_$${TEMPLATE}
變量可以用于存儲環境變量的內容。
為了獲取qamke運行時的環境的值,可以使用$$(...)操作符。

DESTDIR = $$(PWD)
message(The project will be installed in $$DESTDIR)

在上述賦值后,當工程文件被處理時,PWD環境變量的值會被讀取。
為了在生成Mafkefile文件時獲取環境變量值的內容,可以使用$(...)操作符。

DESTDIR = $$(PWD)
message(The project will be installed in $$DESTDIR)

DESTDIR = $(PWD)
message(The project will be installed in the value of PWD)
message(when the Makefile is processed.)

在上述代碼中,當工程文件被處理時,PWD的值會被立即讀取,但$(PWD)會在生成的MakeFile文件中被賦值給DESTDIR變量。這使得構建過程更加靈活,只要在處理MakeFile文件時環境變量被正確設置。
特殊的$$[...]操作符被用于訪問Qt構建時的多個配置選項。

message(Qt version: $$[QT_VERSION])
message(Qt is installed in $$[QT_INSTALL_PREFIX])
message(Qt resources can be found in the following locations:)
message(Documentation: $$[QT_INSTALL_DOCS])
message(Header files: $$[QT_INSTALL_HEADERS])
message(Libraries: $$[QT_INSTALL_LIBS])
message(Binary files (executables): $$[QT_INSTALL_BINS])
message(Plugins: $$[QT_INSTALL_PLUGINS])
message(Data files: $$[QT_INSTALL_DATA])
message(Translation files: $$[QT_INSTALL_TRANSLATIONS])
message(Settings: $$[QT_INSTALL_SETTINGS])
message(Examples: $$[QT_INSTALL_EXAMPLES])
message(Demonstrations: $$[QT_INSTALL_DEMOS])

使用這個操作符訪問的變量通常用于使第三方插件與組件集成。例如,如果工程文件中有下列聲明,Qt Designer插件可以與Qt Designer內置插件一起安裝。

target.path = $$[QT_INSTALL_PLUGINS]/designer
INSTALLS += target

5、變量處理函數

qmake提供了一個內置函數的選擇,以允許變量的內容被處理。內置函數處理被提供的參數,將值或值列表作為結果返回。為了將內置函數結果賦值給變量,必須對內置函數使用$$操作符,就像將一個變量的內置賦值給另一個變量一樣。

HEADERS = model.h
HEADERS += $$OTHER_HEADERS
HEADERS = $$unique(HEADERS)

內置函數應該用于操作符的右側。
可以自定義一個函數處理變量內容。自定義函數按如下定義:

defineReplace(functionName){
        #function code}

下列函數使用一個變量作為唯一參數,使用eval內置函數從變量中提取出了一個值列表,并且編輯了值列表。

defineReplace(headersAndSources) {
    variable = $$1
    names = $$eval($$variable)
    headers =
    sources =

    for(name, names) {
        header = $${name}.h
        exists($$header) {
            headers += $$header
        }
        source = $${name}.cpp
        exists($$source) {
            sources += $$source
        }
    }
    return($$headers $$sources)}

6、條件判斷函數

qmake提供了用于編寫作用域時作為條件的內置函數。這些內置函數不會返回一個值,而是指明成功或失敗。

count(options, 2) {
        message(Both release and debug specified.)}

這些內置函數只能用于條件表達式。
可以自定義函數提供作用域的條件。下列代碼用于測試一個列表中的每個文件是否存在,如果所有的文件都存在,返回true;否則返回false。

defineTest(allFiles) {
        files = $$ARGS

        for(file, files) {
            !exists($$file) {
                return(false)
            }
        }
        return(true)}

7、增加新的配置特性

Qmake允許用戶創建自己的特性,增加到工程文件中,通過增加名稱到CONFIG變量的值列表中。

六、QMake預編譯頭文件

1、預編譯頭文件簡介

預編譯頭文件是一些編譯器支持的一種性能特性,用于編譯穩定的代碼體,并將代碼的編譯狀態存儲在二進制文件中。在后續編譯過程中,編譯器將加載存儲狀態,并繼續編譯指定的文件。每個后續編譯速度更快,因為不需要重新編譯穩定的代碼。qmake支持在某些平臺上使用預編譯頭文件(PCH)和構建環境。
Windows平臺:

nmake
Dsp projects (VC 6.0)
Vcproj projects (VC 7.0 & 7.1)

Mac OS X平臺:

Makefile
Xcode

Unix平臺:
GCC 3.4及以上版本

2、增加預編譯頭文件到工程

A、預編譯頭文件的注釋
預編譯頭必須包含在整個工程中穩定和靜態的代碼。典型的PCH如下:

// Add C includes here

#if defined __cplusplus
// Add C++ includes here
#include <stdlib>
#include <iostream>
#include <vector>
#include <QApplication> // Qt includes
#include <QPushButton>
#include <QLabel>
#include "thirdparty/include/libmain.h"
#include "my_stable_class.h"
...
#endif

注意:預編譯頭文件需要從C++包含中分離出C包含,因為C文件的預編譯頭文件可能不包含C++代碼。
B、工程選項
要在工程中使用預編譯頭文件,只需要在工程文件中定義PRECOMPILED_HEADER變量即可。
PRECOMPILED_HEADER = stable.h
qmake會處理其余事情,確保創建和使用預編譯頭文件。開發者不需要在HEADERS中包含預編譯頭文件,因為如果配置支持PCH,qmake會這樣做。
默認情況下,Windows(以及Windows CE)為目標的MSVC和G++規范會通過precompile_header開啟預編譯。
使用precompile_header選項,可以在工程文件中觸發條件代碼塊,以便在使用預編譯頭時添加設置。

precompile_header:!isEmpty(PRECOMPILED_HEADER) {
DEFINES += USING_PCH}

3、注意事項

在某些平臺上,預編譯頭文件的文件名后綴與其他對象文件的文件名后綴相同。例如,下面的聲明可能會導致兩個不同的對象文件生成相同的名稱:

PRECOMPILED_HEADER = window.h
SOURCES            = window.cpp

為了避免像這樣的潛在沖突,確保將預編譯的頭文件賦予不同的名稱是一種很好的工程實踐。

4、工程實例

下列代碼可以在Qt發布版的examples/qmake/precompile目錄下可以找到。
mydialog.ui文件:

<ui version="4.0" >
 <author></author>
 <comment></comment>
 <exportmacro></exportmacro>
 <class>MyDialog</class>
 <widget class="QDialog" name="MyDialog" >
  <property name="geometry" >
   <rect>
    <x>0</x>
    <y>0</y>
    <width>401</width>
    <height>70</height>
   </rect>
  </property>
  <property name="windowTitle" >
   <string>Mach 2!</string>
  </property>
  <layout class="QVBoxLayout" >
   <property name="margin" >
    <number>9</number>
   </property>
   <property name="spacing" >
    <number>6</number>
   </property>
   <item>
    <widget class="QLabel" name="aLabel" >
     <property name="text" >
      <string>Join the life in the fastlane; - PCH enable your project today! -</string>
     </property>
    </widget>
   </item>
   <item>
    <widget class="QPushButton" name="aButton" >
     <property name="text" >
      <string>&Quit</string>
     </property>
     <property name="shortcut" >
      <string>Alt+Q</string>
     </property>
    </widget>
   </item>
  </layout>
 </widget>
 <pixmapfunction>qPixmapFromMimeSource</pixmapfunction>
 <resources/>
 <connections/>
</ui>

stable.h文件:

/* Add C includes here */

#if defined __cplusplus
/* Add C++ includes here */

# include <iostream>
# include <QApplication>
# include <QPushButton>
# include <QLabel>
#endif

myobject.h文件:

#include <QObject>

class MyObject : public QObject
{
public:
    MyObject();
    ~MyObject();
};

myobject.cpp文件:

#include <iostream>
#include <QDebug>
#include <QObject>
#include "myobject.h"

MyObject::MyObject()
    : QObject()
{
    std::cout << "MyObject::MyObject()\n";
}

util.cpp文件:

void util_function_does_nothing()
{
    // Nothing here...
    int x = 0;
    ++x;
}

main.cpp文件:

#include <QApplication>
#include <QPushButton>
#include <QLabel>
#include "myobject.h"
#include "mydialog.h"

int main(int argc, char **argv)
{
    QApplication app(argc, argv);

    MyObject obj;
    MyDialog dialog;

    dialog.connect(dialog.aButton, SIGNAL(clicked()), SLOT(close()));
    dialog.show();

    return app.exec();
}

precompile.pro文件:

TEMPLATE  = app
LANGUAGE  = C++
CONFIG   += console precompile_header

# Use Precompiled headers (PCH)
PRECOMPILED_HEADER  = stable.h

HEADERS   = stable.h \
            mydialog.h \
            myobject.h
SOURCES   = main.cpp \
            mydialog.cpp \
            myobject.cpp \
            util.cpp
FORMS     = mydialog.ui

七、QMake變量

1、QMake變量簡介

QMake的基本行為受定義在工程構建過程中聲明的變量的影響。某些變量用于聲明資源,如每個平臺中通用的頭文件、源文件,其它變量用于定義指定平臺中的編譯器和鏈接器中的行為。
平臺特定變量遵循變量擴展或修改的命名模式,但在其名稱中包含相關平臺的名稱。例如,QMAKE_LIBS用于指定工程需要鏈接的庫的列表,QMAKE_LIBS_X11用于擴展或覆寫這個列表。

2、常用QMake變量

CONFIG
CONFIG變量用于指定工程配置和編譯器選項。CONFIG變量的值會被qmake內部識別并有特殊的意義。
下列CONFIG值用于控制編譯選項:
release:工程會以release模式構建,如果指定了debug,會被忽略。
debug:工程會被debug模式構建
debug_and_release:工程會以debug和release兩種模式構建,會有一些意想不到的副作用。
build_all:如果指定了debug_and_release,工程默認會以debug和release兩種模式構建
ordered:當使用subdirs模板時,本選項指定列出的子目錄會以給出的順序被處理
precompile_header:在工程中支持預編譯頭文件的使用
warn_on:編譯器應該輸出盡可能多的警告信息,如果指定warn_off,本選項會會忽略。
warn_off:編譯器應該輸出盡可能少的警告信息
由于 CONDIG變量中定義debug和release兩個選項時,debug選項會覆蓋release選項,如果想要使用debug和release兩種模式構建工程,使用debug_and_release選項。此時,qmake會生成包含構建兩種版本的規則的MakeFiles,使用make all可以調用。
當鏈接庫時,qmake依賴于底層平臺來了解庫中鏈接的其它庫。但是,如果是靜態鏈接,除非使用下列的CONFIG選項,否則qmake不會得到這些信息。
create_prl:本選項使qmake能夠追蹤這些依賴關系。當本選項開啟,qmake會創建一個以.prl結尾的文件,用于保存有關庫的元信息。
link_prl:當本選項開啟時,qmake會處理所有鏈接到應用程序的庫,并找出他們的元信息。
注意:構建一個靜態庫時,需要使用create_prl;使用一個靜態庫時,需要使用link_prl。

DEFINES
qmake會將DEFINES變量的值作為C編譯器預處理宏(-D)添加。
例如:DEFINES += USE_MY_STUFF QT_DLL

DEPENDPATH
此變量包含要查找依賴關系的所有目錄的列表,會在查找包含文件時候使用。
DESTDIR
指定輸出目標文件的目錄

DESTDIR_TARGET
本變量是由qmake內部設置的,基本是DESTDIR變量加上TARGET變量作為結尾。本變量的值通常由qmake或qmake.conf處理,并且很少需要修改。

DLLDESTDIR
指定dll目標文件拷貝到的地方

FORMS
本變量指定在編譯前,uic要處理的UI文件。為了構建這些UI文件自動增加到工程,需要所有的依賴、頭文件、源文件。

HEADERS
定義工程的頭文件。qmake會為指定頭文件生成依賴信息。如果頭文件中需要moc,qmake也會自動檢測,為了生成和鏈接moc文件,會增加相應的依賴和文件到工程。

HEADERS = myclass.h \
          login.h \
          mainwindow.h

INCLUDEPATH
本變量指定編譯時需要查找搜索的inlucde路徑。
為了指定一個包含空格的路徑,將路徑使用引號括起來。

win32:INCLUDEPATH += "C:/mylibs/extra headers"
unix:INCLUDEPATH += "/home/user/extra headers"

INSTALLS
本變量包含當make install或是類似的安裝過程被執行時,要被安裝的資源列表。INSTALLS值列表中的每個項會通常會使用屬性定義,屬性提供安裝在哪兒的相關信息。
例如,下列代碼target.path定義描述了構建目標被安裝的路徑,增加構建目標到INSTALLS會將構建目標加入要安裝的資源列表中。

target.path += $$[QT_INSTALL_PLUGINS]/imageformats
INSTALLS += target

注意:qmake會忽略可執行文件,如果需要安裝可執行文件,可以取消文件的可執行屬性標識。

LIBS
本變量包含鏈接到工程的庫列表。可以使用Unix平臺-l(library)和-L(library path)的標識,qmake會正確處理Windows和Symbian平臺上的這些庫。例如:

unix:LIBS += -L/usr/local/lib -lmath
win32:LIBS += c:/mylibs/math.lib

注意:在Windows平臺,使用-l選項指定庫會使用最高版本的庫。例如,math3.lib可能會潛在使用,替換math.lib。為了便面這種模糊性,推薦顯示的指定庫,通過使用包含庫文件后綴.lib的文件名。
為了指定包含空格的路徑,將路徑使用引號括起來。

win32:LIBS += "C:/mylibs/extra libs/extra.lib"
unix:LIBS += "-L/home/user/extra libs" -lextra

默認情況下,使用庫前,存儲在LIBS變量中的庫列表會被簡化為唯一名稱的列表。為了改變這種行為,可以使用在CONFIG變量使用no_lflags_merge選項。

MOC_DIR
本變量指定臨時moc文件的存放路徑。例如,

unix:MOC_DIR = ../myproject/tmp
win32:MOC_DIR = c:/myproject/tmp

PRECOMPILED_HEADER
為了加快工程的編譯速度,本變量會為創建一個預編譯頭文件指明一個頭文件。預編譯頭文件目前只支持某些平臺(Windows所有MSVC工程類型, Mac OS X - Xcode, Makefile, Unix - gcc 3.3+版本)。

PWD
本變量指定指向當前文件被解析的目錄的全路徑。為了支持影子構建,編寫工程文件時在源碼樹引用文件時會有用。

OUT_PWD
本變量包含指向生成MakeFile文件的目錄的全路徑

QMAKE
本變量包含qmake程序自己的名字,會放在生成的MakeFile文件中。

QMAKESPEC
當生成MakeFile時,本變量包含qmake配置要使用的名稱。
使用QMAKESPEC環境變量會覆蓋qmake配置。注意,由于qmake讀取工程文件的方式,在工程文件內設置QMAKESPEC變量會沒有效果。

QT
QT變量中存儲的值用于控制工程中使用的Qt模塊。
core:默認包含,QtCore模塊
gui:默認包含,QtGui模塊
network:QtNetwork模塊
opengl:QtOpenGl模塊
phonon:Phonon多媒體框架
sql:QtSql模塊
svg:QtSvg模塊
xml:QtXml模塊
webkit:QtWebkit模塊
默認,QT包含core和gui模塊,在沒有進一步配置的情況下確保構建一個GUI應用程序。
如果想要構建一個沒有QtGui模塊的工程,需要使用“-=”將gui排除。如:
QT -= gui # Only the core module is used
注意:增加opengl選項到QT變量會自動將相應的選項增加到CONFIG變量。因此,對于應用程序來說,不必增加opengl選項到QT和CONFIG兩個變量。

QTPLUGIN
本變量包含靜態插件的名字列表

QT_VERSION
本變量包含當前Qt的版本

QT_MAJOR_VERSION
本變量包含當前Qt版本的主版本號

QT_MINOR_VERSION
本變量包含當前Qt版本的次版本號

RC_FILE
本變量包含應用程序的資源文件的名稱

RESOURCES
本變量包含資源集合文件的名稱(qrc)

SOURCES
本變量包含工程中所有源文件的名稱,如:

SOURCES = myclass.cpp \
        login.cpp \
        mainwindow.cpp

SUBDIRS
此變量與subdirs模板一起使用時,指定包含需要構建的工程部分的所有子目錄或工程文件的名稱。使用此變量指定的每個子目錄必須包含其自己的工程文件。
建議每個子目錄中的工程文件與子目錄本身具有相同的基名,因為這樣可以省略文件名。例如,如果子目錄是myapp,目錄中的工程文件應用命名為myapp.pro。
或者,可以在任何目錄中指定.pro文件的相對路徑。強烈建議只在當前工程的父目錄或其子目錄中指定路徑。例如:

SUBDIRS = kernel \
          tools \
          myapp

如果需要確保子目錄按指定的順序構建,需要在CONFIG 變量增加ordered選項。
CONFIG += ordered
通過修改附加的屬性SUBDIRS的默認行為,支持的附加調節屬性如下:
.subdir:使用指定的子目錄取代SUBDIRS的值
.file:顯示指定子工程的pro文件,不能與修飾符.subdir結合使用
.condition:指定bld.inf定義,如果子工程被構建,必須為true。
.depends:子工程依賴于指定的子工程,只對生成MakeFile的平臺可用。
.makefile:子工程的MakeFile,只對生成MakeFile的平臺可用。
.target:子工程相關的MakeFile目標的基字符串
例如,定義兩個子目錄,它們的值不同于SUBDIRS的值。

SUBDIRS += my_executable my_library
my_executable.subdir = app
my_executable.depends = my_library
my_library.subdir = lib

Visual Studio不支持ordered選項。

TARGET
本變量指定目標文件名稱
TEMPLATE = app
TARGET = myapp
SOURCES = main.cpp
上述代碼會在創建一個可執行文件myapp(Unix)和myapp.exe(Windows)。

TEMPLATE
本變量指定目標文件的名稱。
app :建立一個應用程序的Makefile,是默認值。
lib:建立一個庫的Makefile。
vcapp:建立一個應用程序的Visual Studio項目文件。
vclib:建立一個庫的Visual Studio項目文件。
subdirs:特殊的模板,
TRANSLATIONS
本變量包含翻譯文件(.ts)列表,

VERSION
本變量用于包含應用程序或庫的版本號。

八、QMake函數

1、QMake函數簡介

QMake提供內置函數用于處理變量的內容以及在配置過程中進行測試。處理變量內容的函數通常會返回可賦值給其它變量的值,可以使用$$FuncionName獲取函數的返回值;進行測試的函數通常作為作用域的條件部分使用。

2、替換函數

qmake提供了在配置過程中處理變量內容的函數。這些函數稱為替換函數。通常,替換函數返回可以賦值給其它變量的值。可以通過在函數名稱前使用$$操作符來獲取這些值。

basename(variablename)
返回指定文件的基本文件名

FILE = /etc/passwd
FILENAME = $$basename(FILE) #passwd

dirname(file)
返回指定文件file中的目錄部分

FILE = /etc/X11R6/XF86Config
DIRNAME = $$dirname(FILE) #/etc/X11R6

find(variablename, substr)
在variablename變量的所有值中查找匹配substr字符串的值,substr可能是正則表達式。

join(variablename, glue, before, after)
使用glue連接variablename變量中的值。如果變量的值非空,在值前面加一個前綴before,在值的后面加一個后綴after。Variablename是必須參數,其它參數默認是空字符串。如果需要在glue、before、after中對空格進行編碼,必須對它們使用引號。

member(variablename, position)
返回variablename變量的值列表中position位置的值。如果在指定位置不能找到值項,返回一個空字符串。Variablename是必須參數,如果不指定position參數,position默認為0,返回variablename變量的值列表中的第一個值。

prompt(question)
顯示指定的question,返回一個從stdin讀取的值。

quote(string)
將整個string轉換為單個實體,返回結果。這只是一種把字符串括上雙引號的花樣方法。

replace(string, old_string, new_string)
使用new_string替換在變量string中出現的old_string。如:

MESSAGE = This is a tent.
message($$replace(MESSAGE, tent, test))
sprintf(string, arguments...)

使用逗號分隔的函數參數arguments替換1%——9%,返回處理后的字符串。

unique(variablename)
返回變量中值的鏈表,如果有重復的刪除。

ARGS = 1 2 3 2 5 1
ARGS = $$unique(ARGS) #1 2 3 5

3、測試函數

CONFIG(config)
本函數用來測試放置在CONFIG變量中的變量。這與常規舊式(tmake)作用域相同,但具有附加的優點,可以將第二個參數傳遞給活動配置進行測試。由于CONFIG變量中值的順序是重要的,CONFIG的第二個參數用于指定要考慮的值的集合。例如:

CONFIG = debug
CONFIG += release
CONFIG(release, debug|release):message(Release build!) #will print
CONFIG(debug, debug|release):message(Debug build!) #no print

由于release作為活躍設置, CONFIG用于生成構建文件。在一般情況下,不需要第二個參數,但對于特定的互斥測試,這是非常寶貴的。

contains(variablename, value)
如果variablename變量包含value值,成功;否則,失敗。可以使用作用域檢查此函數的返回值。

contains( drivers, network ) {
        # drivers contains 'network'
        message( "Configuring for network build..." )
        HEADERS += network.h
        SOURCES += network.cpp}

上述代碼只有在drivers變量包含network值的條件下,作用域才會被處理。

count(variablename, number)
如果variablename變量包含指定數量number的值列表,成功;否則,失敗。
本函數用于確保作用域內的聲明僅在變量包含正確數值的情況下才被處理。

options = $$find(CONFIG, "debug") $$find(CONFIG, "release")
count(options, 2) {
        message(Both release and debug specified.)}

error(string)
函數無返回值,用于顯示給定的字符串string給用戶,并退出。只用于不可恢復的錯誤。
error(An error has occurred in the configuration process.)

eval(string)
評估使用qamke語法規則的string字符串的內容,返回true。在string字符串中可以使用定義和賦值來修改現有變量的值或創建新的定義。

eval(TARGET = myapp) {
        message($$TARGET)}

注意:引號可以用來分隔字符串,如果不需要返回值,則可以放棄。

exists(filename)
測試給定文件名的文件是否存在。如果文件存在,函數成功;否則,失敗。如果文件名是一個正則表達式,如果有任何文件匹配成功,則函數執行成功。

exists( $(QTDIR)/lib/libqt-mt* ) 
{
      message( "Configuring for multi-threaded Qt..." )
      CONFIG += thread
}

for(iterate, list)
這個特殊的測試函數將開啟循環,遍歷列表中的所有值,依次對每個值設置迭代。為方便起見,如果列表為1…10,則迭代將遍歷值1到10。
在for循環的條件行后使用else作用域是不允許的。

LIST = 1 2 3
for(a, LIST):exists(file.$${a}):message(I see a file.$${a}!)

message(string)
此函數簡單地將消息寫入控制臺。不像error()函數,本函數允許繼續處理。
message( "This is a message" )
上述代碼會將"This is a message"消息寫入控制臺。引號的使用是可選的。
注意:默認,對于給定項目,qmake生成的每個MakeFile文件都會寫入消息。如果要確保每個項目只顯示一次消息,在構建期間,可以測試build_pass變量,并在相鄰build_pass變量的作用域中過濾出消息。
!build_pass:message( "This is a message" )

include(filename)
將filename指定的文件的內容包含在當前工程所在的點。如果文件已經被包含,函數成功;否則,失敗。被包含的文件要被立即處理。
通過使用此函數作為作用域的條件,可以檢查文件是否被包含。

include( shared.pri )
OPTIONS = standard custom!include( options.pri ) {
        message( "No custom build options specified" )
OPTIONS -= custom}

infile(filename, var, val)
當文件被qmake解析時,如果filename文件包含有val值的var變量,成功;否則,失敗。如果不指定第三個參數val,函數只會測試文件中是否包含var變量。
isEmpty(variablename)
如果variablename變量為空,成功;否則,失敗。等價于count(variablename, 0)。

isEmpty(CONFIG) {
CONFIG += qt warn_on debug}

system(command)
在shell中執行給定的命令command,如果command返回一個0的退出狀態,成功;否則,失敗。
可以使用system函數從command命令獲取stdout和stderr,賦值給變量。如:

UNAME = $$system(uname -s)
contains( UNAME, [lL]inux ):message( This looks like Linux ($$UNAME) to me )

warning(string)
顯示給定的字符串string,總會成功。與message()相同。

packagesExist(packages)
使用PKGCONFIG機制決定在工程解析時是否存在給定的packages。通常用于打開、關閉特性。如:

packagesExist(sqlite3 QtNetwork QtDeclarative) 
{
DEFINES += USE_FANCY_UI
}

九、配置QMake環境

1、屬性

qmake擁有一個持久信息系統,允許在qmake中一次設置變量,以后每次調用qmake時,可以查詢該值。
在qmake中按如下設置變量:
qmake -set VARIABLE VALUE
使用適當的變量和值應該代替VARIABLE和VALUE。
為了從qmake中取出信息,如下:

qmake -query VARIABLE
qmake -query #queries all current VARIABLE/VALUE pairs..

注意:qmake -query只會列出先前使用qmake -set VARIABLE VALUE設置的變量。
屬性信息會被保存到QSetting對象中對象中(意味著它將存儲在不同平臺的不同位置)。由于VARIABLE也可以被版本化,可以在較舊版本的qamke中設置一個值,而較新版本將檢索此值。但是,如果在較新版本的qmake設置VARIABLE,將不能再舊版本使用這個值。通過前綴化qmake的版本到VARIABLE,可以查詢特定版本的變量,代碼如下:
qmake -query "1.06a/VARIABLE"
qmake也有內置屬性的概念,例如可以使用QT_INSTALL_PREFIX屬性查詢這個qmake版本的Qt安裝。
qmake -query "QT_INSTALL_PREFIX"
由于沒有被版本化,內置屬性不能有前綴版本,并且qmake的每個版本都有自己的內置屬性值集合。

QT_INSTALL_PREFIX:Where the version of Qt this qmake is built for resides
QT_INSTALL_DATA - Where data for this version of Qt resides

QMAKE_VERSION:當前qmake的版本
最終,這些值可以在一個工程文件中查詢,使用如下語法:
QMAKE_VERS = $$[QMAKE_VERSION]

2、QMAKESPEC

qmake需要一個平臺和編譯器的描述文件,文件包含很多用于生成MakeFile的默認值。標準的Qt版本帶有很多這類文件,位于Qt安裝目錄的 mkspecs子目錄下。
QMAKESPEC環境變量包含下列的任何值:
指向包含qmake.conf文件的目錄的完整路徑。qmake會打開目錄中的qmake.conf文件。如果文件不存在,qmake會以錯誤退出。
平臺-編譯器組合的名稱。qmake會搜索,當Qt編譯時
QMAKESPEC路徑會自動增加到INCLUDEPATH系統變量。

3、INSTALLS

在Unix上,使用構建工具安裝應用程序和庫是相同的。例如,通過調用make install。qmake有安裝集的概念,。
例如,documentation文件集合使用如下方式描述:

documentation.path = /usr/local/program/doc
documentation.files = docs/*

path成員告訴qmake,文件應該安裝在/usr/local/program/doc路徑,files成員指定要拷貝到安裝目錄下的文件。本例中,docs目錄下的所有文件將被拷貝到/usr/local/program/doc目錄。
一旦安裝集已被完全描述,可以像如下代碼將其添加到安裝列表中:
INSTALLS += documentation
qmake會確保指定的文件被拷貝到安裝目錄。如果需要對安裝過程進行更大的控制,還可以為對象的額外成員提供定義。例如,下列代碼告訴qmake為安裝集執行一系列的命令:
unix:documentation.extra = create_docs; mv master.doc toc.doc
unix作用域確保這些特殊的命令只會在unix平臺下執行。其它平臺適合的命令可以使用其它作用域規則定義。
在執行對象的其他成員中的指令前執行extra成員中指定的命令。
如果追加內置的安裝集到INSTALLS變量,并且不指定files和extra成員,qmake會決定拷貝哪些內容。目前,只支持內置安裝集的是target:

target.path = /usr/local/myprogram
INSTALLS += target

上訴代碼中,qmake知道拷貝哪些內容,自動處理安裝過程。

4、緩存文件

緩存文件是qmake讀取的特殊文件,用于查找不在qmake.conf文件、工程文件或是命令行指定的設置。如果qmake運行時沒有指定-nocache選項,qmake會試圖在當前目錄的上層目錄下查找名稱為.qmake.cache的文件。如果沒有找到,qmake會忽略這個處理步驟。 如果qmake找到一個.qmake.cache文件,qmake會在處理工程文件前首先處理這個文件。

5、庫依賴

經常在鏈接到一個庫時,qmake依賴于底層平臺來了解庫中鏈接的其他庫,并讓平臺將它們拉入。然而,在很多情況下,這是不夠的。例如,當靜態鏈接一個庫時,沒有鏈接到其他庫,因此不會創建與這些庫的依賴關系。但是,后續鏈接到該庫的應用程序需要知道在哪里可以找到靜態庫所需的符號。為了幫助解決這種情況,qmake嘗試在適當的情況下遵循庫的依賴關系,但是必須通過以下兩個步驟明確地啟用該行為。
A、開啟庫自身的依賴追蹤。要做到這點,必須告訴qmake保存庫的有關信息。
CONFIG += create_prl
這只和lib模板有關,其它模板會被忽略。當啟用此選項時,qmake會創建一個在.prl結尾的文件,該文件將保存庫相關的一些元信息。這個元文件就像一個普通的工程文件,但只包含內部變量聲明。可以自由查看該文件,如果刪除該文件,則qmake會知道在需要時重新創建它,即在后續讀取工程文件時,或者如果依賴庫(以下描述)已經發生變化時。在安裝此庫時,通過將其指定為INSTALLS聲明中的目標,qmake將自動將.prl文件拷貝到安裝路徑。
B、在使用靜態庫的應用程序中讀取該元信息。
CONFIG += link_prl
當該選項開啟,qmake會處理由應用程序鏈接的所有庫,并找到它們的元信息。qmake會使用它來確定相關鏈接信息,特別是向應用程序工程文件的DEFINES以及LIBS添加值。一旦qmake處理了該文件,它將查看LIBS變量中新引入的庫,并找到它們的依賴.prl文件,直到所有庫都被解析。此時,MakeFile文件按常規創建,并且庫與應用程序顯式鏈接。
prl文件的內部結構是關閉的,因此后續可以很容易地進行更改。prl文件并不是用來被手工改變的,只能由{qmake Manual#qmake}{qmake}創建,并且不應該在操作系統之間傳輸,由于它們可能包含依賴于平臺的信息。

6、文件擴展

在正常情況下,qmake會嘗試為平臺使用適當的文件擴展名。但是,有時需要重寫每個平臺的默認選項,并顯式定義用于qmake的文件擴展名。這是通過重新定義某些內置變量來實現的;
例如,用于moc文件的擴展可以用工程文件中的以下賦值來重新定義。
QMAKE_EXT_MOC = .mymoc
下列變量可用于重新定義qmake所識別的公共文件擴展名。
QMAKE_EXT_MOC:修改包含的moc文件的擴展
QMAKE_EXT_UI:修改designer UI文件的擴展
QMAKE_EXT_PRL:修改庫依賴文件的擴展
QMAKE_EXT_LEX:修改文件后綴(LEXSOURCES)
QMAKE_EXT_YACC:修改文件后綴(YACCSOURCES)
QMAKE_EXT_OBJ:修改生成的對象文件的后綴
上述所有變量都只接受第一個值,所以必須給它分配一個值,會在整個工程文件中使用。有兩個變量可以接受一個值列表:
QMAKE_EXT_CPP:qmake會將這些后綴的文件解釋為C++源文件 QMAKE_EXT_H:qmake會將這些后綴的文件解釋為C和C++頭文件

7、自定義MakeFile文件輸出

qmake試圖實現跨平臺構建工具所期望的一切。當真的需要運行特定的平臺相關命令時,常常是不太理想的。這可以通過對不同qmake后端的特定指令來實現。
對MakeFile文件輸出的定制是通過對象風格的API實現的,就像在qmake中其它地方發現的那樣。對象是通過指定成員來自動定義的,例如:

mytarget.target = .buildfile
mytarget.commands = touch $$mytarget.target
mytarget.depends = mytarget2
mytarget2.commands = @echo Building $$mytarget.target

上述代碼定義了一個名為mytarget的qmake目標,mytarget目標包含一個名為.buildfile的MakeFile目標,.buildfile使用touch命令依次生成。最終,.depends成員指定mytarget目標依賴于mytarget2。mytarget2是一個偽目標,只定義了一些顯示到控制臺的文本。
最后一步是指示qmake,這個對象是要建立的目標。
QMAKE_EXTRA_TARGETS += mytarget mytarget2
這就是實際構建自定義目標所需做的一切。當然,可能希望將其中一個目標綁定到qmake構建目標。要做到這一點,只需要將MakeFile目標包含到PRE_TARGETDEPS列表中。
下表是QMAKE_EXTRA_TARGETS變量的可用選項的概述。
commands:生成自定義構建目標的命令
CONFIG:自定義構建目標的特定配置選項
depends:自定義目標鎖依賴的現有構建目標
recurse:為了調用子目標的MakeFile文件,當創建MakeFile文件時,指定使用哪些子目標。當CONFIG變量設置了recursive才能使用。
recurse_target:通過MakeFile文件中的子目標MakeFile文件,指定要構建的目標。
target:自定義構建目標創建的文件
CONFIG變量:
recursive:指明MakeFile中要創建的規則,因而會在子目標的MakeFile文件中調用相關目標。默認會為每個子目標創建一個實體。
為了方便起見,還有一種新的編譯器或預處理器的工程定制方法。

new_moc.output  = moc_${QMAKE_FILE_BASE}.cpp
new_moc.commands = moc ${QMAKE_FILE_NAME} -o ${QMAKE_FILE_OUT}
new_moc.depend_command = g++ -E -M ${QMAKE_FILE_NAME} | sed "s,^.*: ,,"
new_moc.input = NEW_HEADERS
QMAKE_EXTRA_COMPILERS += new_moc

通過上面的定義,如果有可用的moc,可以使用moc隨時替換。
在給定的NEW_HEADERS變量的所有參數上執行命令。結果寫到output成員指定文件。這個文件會被增加到工程中的其它源文件。此外,為了生成依賴信息,qmake會執行depend_command命令,也將這些信息放到工程中。
這些命令可以很容易地放入緩存文件中,從而允許后續工程文件向NEW_HEADERS添加參數。
下表概述了QMAKE_EXTRA_COMPILERS變量的可用選項。
commands:用于從輸入產生輸出的命令。
CONFIG:為自定義編譯器指定配置選項
depend_command:指定用于生成輸出依賴項列表的命令。
dependency_type:指定輸出的文件類型,如果它是已知類型(TYPE_C, TYPE_UI, TYPE_QRC),則使用其中的一種類型處理它。
depends:指定輸出文件的依賴
input:包含使用自定義編譯器處理的文件的變量
name:對自定義編譯器所做事情的描述。只用于某些后端
output:自定義編譯器創建的文件名
output_function:指定用于創建文件名的qmake自定義函數
variable_out:應該將從輸出創建的文件添加到變量。
指定到CONFIG選項的成員:
commands:用于從輸入產生輸出的命令。
CONFIG:為自定義編譯器指定配置選項
depend_command:指定用于生成輸出依賴項列表的命令。
dependency_type:指定輸出的文件類型,如果它是已知類型(TYPE_C, TYPE_UI, TYPE_QRC),則使用其中的一種類型處理它。
depends:指定輸出文件的依賴
input:包含使用自定義編譯器處理的文件的變量
name:對自定義編譯器所做事情的描述。只用于某些后端
output:自定義編譯器創建的文件名
output_function:指定用于創建文件名的qmake自定義函數
variable_out:應該將從輸出創建的文件添加到變量。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

津南区| 体育| 雷山县| 资溪县| 阜平县| 龙里县| 宁陕县| 化德县| 陇南市| 安宁市| 永安市| 威信县| 西平县| 航空| 鄄城县| 健康| 繁峙县| 绵竹市| 托克托县| 夏邑县| 绥江县| 霍州市| 远安县| 和田市| 海伦市| 正镶白旗| 昆山市| 绍兴县| 云霄县| 赤水市| 台江县| 浦江县| 和龙市| 右玉县| 沁水县| 佛冈县| 宁明县| 方城县| 吉林省| 施秉县| 浑源县|