溫馨提示×

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

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Qt高級(jí)——QMake用戶指南

發(fā)布時(shí)間:2020-06-26 10:27:43 來(lái)源:網(wǎng)絡(luò) 閱讀:20416 作者:天山老妖S 欄目:編程語(yǔ)言

Qt高級(jí)——QMake用戶指南

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

一、QMake使用

QMake提供了一個(gè)用于管理應(yīng)用程序、庫(kù)、其它組件的構(gòu)建過(guò)程的面向工程系統(tǒng)。
QMake擴(kuò)展了每個(gè)工程文件的信息,生成一個(gè)執(zhí)行編譯和鏈接過(guò)程的必須命令的MakeFile。

1、描述工程

工程文件.pro描述了工程信息。工程文件信息會(huì)被qmake用于生成包含構(gòu)建過(guò)程中所需的所有命令的MakeFile。工程文件通常包含一系列頭文件和源文件,通用配置信息以及音樂程序指定的細(xì)節(jié),如應(yīng)用程序的鏈接庫(kù)、搜索路徑。
工程文件包含一定數(shù)量的不同元素,如注釋、變量聲明、內(nèi)置函數(shù)以及簡(jiǎn)單的控制結(jié)構(gòu)。在大多數(shù)簡(jiǎn)單的工程中,只需要聲明使用簡(jiǎn)單配置選項(xiàng)構(gòu)建工程的源文件和頭文件即可。

2、構(gòu)建工程

對(duì)于簡(jiǎn)單的工程,只需要在工程的頂層目錄運(yùn)行qmake。默認(rèn)情況下,qmake會(huì)生成一個(gè)構(gòu)建工程的MakeFile,此時(shí)可以運(yùn)行平臺(tái)相關(guān)的make工具構(gòu)建工程。
qmake也能用于生成工程文件。

3、預(yù)編譯頭文件

在大型工程中,可以利用預(yù)編譯頭文件的優(yōu)勢(shì)加速構(gòu)建過(guò)程。

二、QMake工程文件

1、工程文件基本元素

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

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

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

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

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

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

為了在變量賦值中包括#,必須使用內(nèi)置變量LITERAL_HASH。
C、內(nèi)置函數(shù)和控制流
qmake提供了多個(gè)內(nèi)置函數(shù)用于處理變量?jī)?nèi)容。在簡(jiǎn)單工程中,最常使用的函數(shù)是使用一個(gè)文件名作為參數(shù)的include函數(shù)。在工程文件中,給定文件的內(nèi)容會(huì)被包含在include函數(shù)調(diào)用的位置。include函數(shù)最常用于包含其它工程文件.pro。
include(other.pro)
通過(guò)代碼塊作用域可以實(shí)現(xiàn)類似編程語(yǔ)言中IF語(yǔ)句的行為,支持條件控制結(jié)構(gòu)。

win32 {
        SOURCES += paintwidget_win.cpp}

只有條件為true時(shí),括號(hào)內(nèi)的賦值才會(huì)有效。在這個(gè)例子中,特殊變量win32必須被設(shè)置。在 Windows平臺(tái)上,win32會(huì)自動(dòng)設(shè)置。當(dāng)在其它平臺(tái)上,通過(guò)運(yùn)行帶-win32參數(shù)選項(xiàng)的qmake可以指定win32。左括號(hào)必須與條件在同一行。
使用for函數(shù)通過(guò)遍歷列表值可以構(gòu)建一個(gè)簡(jiǎn)單的循環(huán)。下列代碼會(huì)在目錄存在的情況下增加目錄到SUBDIRS變量。

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

對(duì)變量進(jìn)行更復(fù)雜的操作可以通過(guò)內(nèi)置函數(shù)find、unique、count。內(nèi)置函數(shù)可以提供對(duì)字符串、路徑的操作,支持用戶輸入,并調(diào)用其它外部工具。

2、工程模板

TEMPLATE變量用于定義構(gòu)建的工程的類型。如果工程文件中沒有聲明TEMPLATE變量,qmake會(huì)默認(rèn)構(gòu)建一個(gè)應(yīng)用程序,并生成一個(gè)MakeFile文件。
下列時(shí)可用工程類型:
app:創(chuàng)建一個(gè)構(gòu)建應(yīng)用程序的MakeFile
lib:創(chuàng)建一個(gè)構(gòu)建庫(kù)的MakeFile
subdirs:創(chuàng)建一個(gè)包含使用SUBDIRS變量指定子目錄的規(guī)則的MakeFile,每個(gè)子目錄必須包含自己的工程文件。
vcapp:創(chuàng)建一個(gè)構(gòu)建應(yīng)用程序的Visual Studio平臺(tái)的工程文件
vclib:創(chuàng)建一個(gè)構(gòu)建庫(kù)的Visual Studio平臺(tái)的工程文件
vcsubdirs:創(chuàng)建一個(gè)在子目錄構(gòu)建工程的Visual Studio平臺(tái)的解決方案文件
當(dāng)使用subdirs模板時(shí),qmake會(huì)生成一個(gè)MakeFile檢查每個(gè)子目錄,處理查找到的任何工程文件。并且在新生成的MakeFile上運(yùn)行平臺(tái)的make工具。SUBDIRS變量用于包含要處理的子目錄列表。

3、通用配置

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

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

下列選項(xiàng)會(huì)定義構(gòu)建工程的類型,注意,某些選項(xiàng)只有在特定平臺(tái)才會(huì)生效。
qt:工程是一個(gè)Qt應(yīng)用程序,會(huì)鏈接Qt庫(kù)。可以使用QT變量控制應(yīng)用程序需要的任何附加Qt模塊
thread:工程是一個(gè)多線程應(yīng)用程序
x11:工程是一個(gè)X11應(yīng)用程序或庫(kù)
當(dāng)使用應(yīng)用程序或庫(kù)的工程模板時(shí),很多配置選項(xiàng)用于微調(diào)構(gòu)建過(guò)程。例如,如果應(yīng)用程序使用Qt庫(kù),并且在debug模式構(gòu)建多線程應(yīng)用時(shí),工程文件如下:
CONFIG += qt thread debug
注意:必須使用“+=”而不是“=”,否則qmake不會(huì)使用Qt配置決定工程需要的設(shè)置。

4、聲明Qt庫(kù)

如果CONFIG變量包含qt,qmake對(duì)Qt應(yīng)用程序的支持會(huì)開啟,這會(huì)使微調(diào)應(yīng)用程序的Qt模塊變得可能。用于聲明需要擴(kuò)展模塊的QT變量可以實(shí)現(xiàn)微調(diào)。例如,可以使用下列代碼開啟XML和network模塊:

CONFIG += qt
QT += network xml

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

5、配置特性

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

CONFIG += link_pkgconfig
PKGCONFIG += ogg dbus-1

6、聲明第三方庫(kù)

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

三、QMake命令行使用

當(dāng)qmake有多個(gè)選項(xiàng)在命令行運(yùn)行,qmake的行為可以被自定義。qmake選項(xiàng)可以微調(diào)構(gòu)建過(guò)程,提供有用的診斷信息,并指定工程的目標(biāo)平臺(tái)。

1、語(yǔ)法

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

2、通用選項(xiàng)參數(shù)

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

3、MakeFile模式選項(xiàng)

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

4、工程模式選項(xiàng)

qmake -project [options] files
在project模式下,qmake會(huì)生成一個(gè)工程文件??梢栽趐roject模式下使用下列選項(xiàng):
-r:qmake會(huì)遞歸處理給定的目錄
-nopwd:qmake不會(huì)查找當(dāng)前源碼的工作路徑,只使用指定文件。
在project模式下,files參數(shù)是文件或目錄列表。如果指定一個(gè)目錄,會(huì)被包含到DEPENDPATH變量,相關(guān)代碼會(huì)包含到生成的工程文件中;如果給定一個(gè)文件,會(huì)被追加到依賴于擴(kuò)展的合適變量。例如,UI會(huì)被增加到FORMS變量,C++文件會(huì)被增加到SOURCES變量。

四、QMake平臺(tái)相關(guān)事項(xiàng)

很多跨平臺(tái)工程使用qmake的基本配置和特性進(jìn)行處理。在一些平臺(tái)上,利用平臺(tái)相關(guān)特性有時(shí)是有用的,甚至是必須的。qmake直到很多特性,這些特性只能通過(guò)特定變量訪問,特定變量只在獨(dú)立平臺(tái)上有效。

1、Mac OS X平臺(tái)

本平臺(tái)特有的特性包括支持創(chuàng)建通用二進(jìn)制文件、框架和捆綁包。
A、源包和二進(jìn)制包
源包中提供的qmake版本與二進(jìn)制包中提供的配置略有不同,因?yàn)樗褂昧瞬煌奶匦砸?guī)范。源包通常使用macx-g++規(guī)范,二進(jìn)制包通常被配置為使用macx-xcode代碼規(guī)范。
每個(gè)包的用戶需要使用-spec參數(shù)選項(xiàng)調(diào)用qmake覆寫配置。例如,在一個(gè)工程目錄使用下列命令可以從一個(gè)二進(jìn)制包生成Makefile文件:
qmake -spec macx-g++
B、框架使用
qmake會(huì)自動(dòng)生成鏈接框架的構(gòu)建規(guī)則,這些框架的標(biāo)準(zhǔn)框架路徑在Mac OS X平臺(tái)下是/Library/Frameworks/。
除了標(biāo)準(zhǔn)框架目錄之外,需要向構(gòu)建系統(tǒng)指定目錄,通過(guò)增加鏈接器選項(xiàng)到QMAKE_LFLAGS變量可以實(shí)現(xiàn)。
QMAKE_LFLAGS += -F/path/to/framework/directory/
框架本身會(huì)通過(guò)附加-framework選項(xiàng)和框架的名稱被鏈接到LIBS變量。
LIBS += -framework TheFramework
C、創(chuàng)建框架
任何給定的庫(kù)項(xiàng)目都可以被配置,以便生成的庫(kù)文件放置在準(zhǔn)備部署的框架中。通過(guò)設(shè)置工程使用lib模板,并增加lib_bundle選項(xiàng)到CONFIG變量可以實(shí)現(xiàn)。

TEMPLATE = lib
CONFIG += lib_bundle

與庫(kù)關(guān)聯(lián)的數(shù)據(jù)使用QMAKE_BUNDLE_DATA變量指定。這將保存將使用庫(kù)捆綁包進(jìn)行安裝的項(xiàng),并且通常用于指定頭文件集合。例如:

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變量,確保頭文件信息被增加到所安裝的庫(kù)捆綁包的資源集合中。框架的名稱和版本由變量QMAKE_FRAMEWORK_BUNDLE_NAME和QMAKE_FRAMEWORK_VERSION指定,默認(rèn)情況下,使用TARGET和VERSION變量的值。
D、創(chuàng)建通用二進(jìn)制包
為了創(chuàng)建應(yīng)用程序的通用二進(jìn)制包,需要使用已經(jīng)配置了-universal選項(xiàng)的Qt版本。
在二進(jìn)制包中,支持的架構(gòu)通常在CONFIG變量指定。例如,下列代碼會(huì)使qmake生成同時(shí)支持PowerPC 和X86架構(gòu)的通用二進(jìn)制包的構(gòu)建規(guī)則。
CONFIG += x86 ppc
此外,開發(fā)者使用PowerPC平臺(tái)需要設(shè)置QMAKE_MAC_SDK變量。
E、創(chuàng)建和移動(dòng)XCode項(xiàng)目
MAC OS X平臺(tái)的開發(fā)者可以利用qmake對(duì)XCode工程文件的支持,通過(guò)運(yùn)行qmake從已有的qmake工程文件生成一個(gè)XCode工程。
qmake -spec macx-xcode project.pro
注意:如果工程在磁盤上進(jìn)行了移動(dòng),需要再次運(yùn)行qmake處理工程文件生成一個(gè)XCode工程。
F、同時(shí)支持兩種構(gòu)建目標(biāo)
要實(shí)現(xiàn)同時(shí)支持兩個(gè)構(gòu)建目標(biāo)目前并不可行,因?yàn)樵诟拍钌希鲃?dòng)構(gòu)建配置的XCode概念不同于qmake構(gòu)建目標(biāo)的概念。
XCode主動(dòng)構(gòu)建配置用于修改xcode配置、編譯器選項(xiàng)以及類似的構(gòu)建選項(xiàng)。不像Visual Studio,XCode不允許基于構(gòu)建配置是否選擇debug或release來(lái)選擇特定的庫(kù)文件。Qmake的debug和release設(shè)置會(huì)控制鏈接到執(zhí)行文件的庫(kù)文件。
目前不可能在qamke生成的XCode工程文件中設(shè)置XCode設(shè)置中的文件。
此外,所選的主動(dòng)構(gòu)建配置存儲(chǔ)在.pbxuser文件中,.pbxuser文件是由XCode在第一次加載中生成的,而不是qamke創(chuàng)建的。

2、Windows平臺(tái)

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

3、Symbian平臺(tái)

Symbian平臺(tái)特有的特性包括處理靜態(tài)數(shù)據(jù),兼容性,棧和堆大小,編譯器特定選項(xiàng),應(yīng)用程序或庫(kù)的唯一標(biāo)識(shí)符。
A、處理靜態(tài)數(shù)據(jù)
如果應(yīng)用程序使用了任何靜態(tài)數(shù)據(jù),構(gòu)建系統(tǒng)需要了解這些靜態(tài)數(shù)據(jù)。這是因?yàn)镾ymbian系統(tǒng)會(huì)試圖在沒有使用靜態(tài)數(shù)據(jù)的情況下節(jié)省內(nèi)存。
若要指定靜態(tài)數(shù)據(jù)支持,將其添加到項(xiàng)目文件中:
TARGET.EPOCALLOWDLLDATA = 1
默認(rèn)值為0
B、棧和堆大小
Symbian平臺(tái)使用預(yù)定義大小的堆棧和堆。如果應(yīng)用程序超過(guò)任一限制,則可能崩潰或無(wú)法完成其任務(wù)。毫無(wú)理由的崩潰常常可以追溯到堆棧和堆大小不足。
堆棧大小具有最大值,而堆大小具有最小值和最大值,均以字節(jié)指定。如果內(nèi)存不可用,則最小值阻止應(yīng)用程序啟動(dòng)。最小值和最大值由一個(gè)空間分隔。例如:

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

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

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

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

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

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

五、QMake高級(jí)功能

1、qmake高級(jí)功能簡(jiǎn)介

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

2、操作符

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

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

3、作用域

作用域與過(guò)程化編程語(yǔ)言的IF語(yǔ)句比較類似。如果條件為true,作用域內(nèi)的聲明會(huì)被處理。
A、語(yǔ)法
作用域由一個(gè)條件和同一行跟隨的一個(gè)左括號(hào),一系列命令和定義,新一行的右括號(hào)組成。

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

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

win32 {
        SOURCES += paintwidget_win.cpp}

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

!win32 {
        SOURCES -= paintwidget_win.cpp}

作用域可以將嵌套,以組合多個(gè)條件。例如,如果想要在某個(gè)平臺(tái)包含某個(gè)特定文件,僅且在調(diào)試開啟時(shí)處理。代碼如下:

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

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

macx:debug {
        HEADERS += debugging.h}

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

win32|macx {
        HEADERS += debugging.h}

可以通過(guò)使用else作用域來(lái)向作用域內(nèi)的內(nèi)容提供替代聲明。如果前一個(gè)作用域的條件為false,對(duì)else作用域進(jìn)行處理。例如:

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

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

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

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

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

只要在mkspecs目錄中存在一個(gè)規(guī)范,就可以測(cè)試任何其他平臺(tái)編譯器組合。
在Symbian平臺(tái)上,unix作用域?yàn)閠rue。

4、變量

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

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

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

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.)

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

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])

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

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

5、變量處理函數(shù)

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

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

內(nèi)置函數(shù)應(yīng)該用于操作符的右側(cè)。
可以自定義一個(gè)函數(shù)處理變量?jī)?nèi)容。自定義函數(shù)按如下定義:

defineReplace(functionName){
        #function code}

下列函數(shù)使用一個(gè)變量作為唯一參數(shù),使用eval內(nèi)置函數(shù)從變量中提取出了一個(gè)值列表,并且編輯了值列表。

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、條件判斷函數(shù)

qmake提供了用于編寫作用域時(shí)作為條件的內(nèi)置函數(shù)。這些內(nèi)置函數(shù)不會(huì)返回一個(gè)值,而是指明成功或失敗。

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

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

defineTest(allFiles) {
        files = $$ARGS

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

7、增加新的配置特性

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

六、QMake預(yù)編譯頭文件

1、預(yù)編譯頭文件簡(jiǎn)介

預(yù)編譯頭文件是一些編譯器支持的一種性能特性,用于編譯穩(wěn)定的代碼體,并將代碼的編譯狀態(tài)存儲(chǔ)在二進(jìn)制文件中。在后續(xù)編譯過(guò)程中,編譯器將加載存儲(chǔ)狀態(tài),并繼續(xù)編譯指定的文件。每個(gè)后續(xù)編譯速度更快,因?yàn)椴恍枰匦戮幾g穩(wěn)定的代碼。qmake支持在某些平臺(tái)上使用預(yù)編譯頭文件(PCH)和構(gòu)建環(huán)境。
Windows平臺(tái):

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

Mac OS X平臺(tái):

Makefile
Xcode

Unix平臺(tái):
GCC 3.4及以上版本

2、增加預(yù)編譯頭文件到工程

A、預(yù)編譯頭文件的注釋
預(yù)編譯頭必須包含在整個(gè)工程中穩(wěn)定和靜態(tài)的代碼。典型的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

注意:預(yù)編譯頭文件需要從C++包含中分離出C包含,因?yàn)镃文件的預(yù)編譯頭文件可能不包含C++代碼。
B、工程選項(xiàng)
要在工程中使用預(yù)編譯頭文件,只需要在工程文件中定義PRECOMPILED_HEADER變量即可。
PRECOMPILED_HEADER = stable.h
qmake會(huì)處理其余事情,確保創(chuàng)建和使用預(yù)編譯頭文件。開發(fā)者不需要在HEADERS中包含預(yù)編譯頭文件,因?yàn)槿绻渲弥С諴CH,qmake會(huì)這樣做。
默認(rèn)情況下,Windows(以及Windows CE)為目標(biāo)的MSVC和G++規(guī)范會(huì)通過(guò)precompile_header開啟預(yù)編譯。
使用precompile_header選項(xiàng),可以在工程文件中觸發(fā)條件代碼塊,以便在使用預(yù)編譯頭時(shí)添加設(shè)置。

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

3、注意事項(xiàng)

在某些平臺(tái)上,預(yù)編譯頭文件的文件名后綴與其他對(duì)象文件的文件名后綴相同。例如,下面的聲明可能會(huì)導(dǎo)致兩個(gè)不同的對(duì)象文件生成相同的名稱:

PRECOMPILED_HEADER = window.h
SOURCES            = window.cpp

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

4、工程實(shí)例

下列代碼可以在Qt發(fā)布版的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變量簡(jiǎn)介

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

2、常用QMake變量

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

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

DEPENDPATH
此變量包含要查找依賴關(guān)系的所有目錄的列表,會(huì)在查找包含文件時(shí)候使用。
DESTDIR
指定輸出目標(biāo)文件的目錄

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

DLLDESTDIR
指定dll目標(biāo)文件拷貝到的地方

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

HEADERS
定義工程的頭文件。qmake會(huì)為指定頭文件生成依賴信息。如果頭文件中需要moc,qmake也會(huì)自動(dòng)檢測(cè),為了生成和鏈接moc文件,會(huì)增加相應(yīng)的依賴和文件到工程。

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

INCLUDEPATH
本變量指定編譯時(shí)需要查找搜索的inlucde路徑。
為了指定一個(gè)包含空格的路徑,將路徑使用引號(hào)括起來(lái)。

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

INSTALLS
本變量包含當(dāng)make install或是類似的安裝過(guò)程被執(zhí)行時(shí),要被安裝的資源列表。INSTALLS值列表中的每個(gè)項(xiàng)會(huì)通常會(huì)使用屬性定義,屬性提供安裝在哪兒的相關(guān)信息。
例如,下列代碼target.path定義描述了構(gòu)建目標(biāo)被安裝的路徑,增加構(gòu)建目標(biāo)到INSTALLS會(huì)將構(gòu)建目標(biāo)加入要安裝的資源列表中。

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

注意:qmake會(huì)忽略可執(zhí)行文件,如果需要安裝可執(zhí)行文件,可以取消文件的可執(zhí)行屬性標(biāo)識(shí)。

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

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

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

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

默認(rèn)情況下,使用庫(kù)前,存儲(chǔ)在LIBS變量中的庫(kù)列表會(huì)被簡(jiǎn)化為唯一名稱的列表。為了改變這種行為,可以使用在CONFIG變量使用no_lflags_merge選項(xiàng)。

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

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

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

PWD
本變量指定指向當(dāng)前文件被解析的目錄的全路徑。為了支持影子構(gòu)建,編寫工程文件時(shí)在源碼樹引用文件時(shí)會(huì)有用。

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

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

QMAKESPEC
當(dāng)生成MakeFile時(shí),本變量包含qmake配置要使用的名稱。
使用QMAKESPEC環(huán)境變量會(huì)覆蓋qmake配置。注意,由于qmake讀取工程文件的方式,在工程文件內(nèi)設(shè)置QMAKESPEC變量會(huì)沒有效果。

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

QTPLUGIN
本變量包含靜態(tài)插件的名字列表

QT_VERSION
本變量包含當(dāng)前Qt的版本

QT_MAJOR_VERSION
本變量包含當(dāng)前Qt版本的主版本號(hào)

QT_MINOR_VERSION
本變量包含當(dāng)前Qt版本的次版本號(hào)

RC_FILE
本變量包含應(yīng)用程序的資源文件的名稱

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

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

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

SUBDIRS
此變量與subdirs模板一起使用時(shí),指定包含需要構(gòu)建的工程部分的所有子目錄或工程文件的名稱。使用此變量指定的每個(gè)子目錄必須包含其自己的工程文件。
建議每個(gè)子目錄中的工程文件與子目錄本身具有相同的基名,因?yàn)檫@樣可以省略文件名。例如,如果子目錄是myapp,目錄中的工程文件應(yīng)用命名為myapp.pro。
或者,可以在任何目錄中指定.pro文件的相對(duì)路徑。強(qiáng)烈建議只在當(dāng)前工程的父目錄或其子目錄中指定路徑。例如:

SUBDIRS = kernel \
          tools \
          myapp

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

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

Visual Studio不支持ordered選項(xiàng)。

TARGET
本變量指定目標(biāo)文件名稱
TEMPLATE = app
TARGET = myapp
SOURCES = main.cpp
上述代碼會(huì)在創(chuàng)建一個(gè)可執(zhí)行文件myapp(Unix)和myapp.exe(Windows)。

TEMPLATE
本變量指定目標(biāo)文件的名稱。
app :建立一個(gè)應(yīng)用程序的Makefile,是默認(rèn)值。
lib:建立一個(gè)庫(kù)的Makefile。
vcapp:建立一個(gè)應(yīng)用程序的Visual Studio項(xiàng)目文件。
vclib:建立一個(gè)庫(kù)的Visual Studio項(xiàng)目文件。
subdirs:特殊的模板,
TRANSLATIONS
本變量包含翻譯文件(.ts)列表,

VERSION
本變量用于包含應(yīng)用程序或庫(kù)的版本號(hào)。

八、QMake函數(shù)

1、QMake函數(shù)簡(jiǎn)介

QMake提供內(nèi)置函數(shù)用于處理變量的內(nèi)容以及在配置過(guò)程中進(jìn)行測(cè)試。處理變量?jī)?nèi)容的函數(shù)通常會(huì)返回可賦值給其它變量的值,可以使用$$FuncionName獲取函數(shù)的返回值;進(jìn)行測(cè)試的函數(shù)通常作為作用域的條件部分使用。

2、替換函數(shù)

qmake提供了在配置過(guò)程中處理變量?jī)?nèi)容的函數(shù)。這些函數(shù)稱為替換函數(shù)。通常,替換函數(shù)返回可以賦值給其它變量的值。可以通過(guò)在函數(shù)名稱前使用$$操作符來(lái)獲取這些值。

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可能是正則表達(dá)式。

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

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

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

quote(string)
將整個(gè)string轉(zhuǎn)換為單個(gè)實(shí)體,返回結(jié)果。這只是一種把字符串括上雙引號(hào)的花樣方法。

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

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

使用逗號(hào)分隔的函數(shù)參數(shù)arguments替換1%——9%,返回處理后的字符串。

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

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

3、測(cè)試函數(shù)

CONFIG(config)
本函數(shù)用來(lái)測(cè)試放置在CONFIG變量中的變量。這與常規(guī)舊式(tmake)作用域相同,但具有附加的優(yōu)點(diǎn),可以將第二個(gè)參數(shù)傳遞給活動(dòng)配置進(jìn)行測(cè)試。由于CONFIG變量中值的順序是重要的,CONFIG的第二個(gè)參數(shù)用于指定要考慮的值的集合。例如:

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

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

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

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

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

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

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

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

eval(string)
評(píng)估使用qamke語(yǔ)法規(guī)則的string字符串的內(nèi)容,返回true。在string字符串中可以使用定義和賦值來(lái)修改現(xiàn)有變量的值或創(chuàng)建新的定義。

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

注意:引號(hào)可以用來(lái)分隔字符串,如果不需要返回值,則可以放棄。

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

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

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

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

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

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

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

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

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

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

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

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

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

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

九、配置QMake環(huán)境

1、屬性

qmake擁有一個(gè)持久信息系統(tǒng),允許在qmake中一次設(shè)置變量,以后每次調(diào)用qmake時(shí),可以查詢?cè)撝怠?br/>在qmake中按如下設(shè)置變量:
qmake -set VARIABLE VALUE
使用適當(dāng)?shù)淖兞亢椭祽?yīng)該代替VARIABLE和VALUE。
為了從qmake中取出信息,如下:

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

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

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:當(dāng)前qmake的版本
最終,這些值可以在一個(gè)工程文件中查詢,使用如下語(yǔ)法:
QMAKE_VERS = $$[QMAKE_VERSION]

2、QMAKESPEC

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

3、INSTALLS

在Unix上,使用構(gòu)建工具安裝應(yīng)用程序和庫(kù)是相同的。例如,通過(guò)調(diào)用make install。qmake有安裝集的概念,。
例如,documentation文件集合使用如下方式描述:

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

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

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

上訴代碼中,qmake知道拷貝哪些內(nèi)容,自動(dòng)處理安裝過(guò)程。

4、緩存文件

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

5、庫(kù)依賴

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

6、文件擴(kuò)展

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

7、自定義MakeFile文件輸出

qmake試圖實(shí)現(xiàn)跨平臺(tái)構(gòu)建工具所期望的一切。當(dāng)真的需要運(yùn)行特定的平臺(tái)相關(guān)命令時(shí),常常是不太理想的。這可以通過(guò)對(duì)不同qmake后端的特定指令來(lái)實(shí)現(xiàn)。
對(duì)MakeFile文件輸出的定制是通過(guò)對(duì)象風(fēng)格的API實(shí)現(xiàn)的,就像在qmake中其它地方發(fā)現(xiàn)的那樣。對(duì)象是通過(guò)指定成員來(lái)自動(dòng)定義的,例如:

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

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

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

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

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI