天天看點

Qt-QMake官方使用手冊(翻譯)本文翻譯自Qt 4.8官方文檔。

本文翻譯自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選項指定庫會使用最高版本的庫。例如,math2.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:應該将從輸出建立的檔案添加到變量

繼續閱讀