QT之proc工程檔案詳解
一、簡介
*.pro檔案是Qt在建立專案時生成的專案檔案,它支援跨平臺。*.pro格式檔案包含的內容有臨時工程檔案、原始碼檔案、專案庫檔案等。在QT中,有一個工具qmake可以生成一個Makefile檔案,它就是由*.pro檔案生成而來的。下面詳細介紹*.pro檔案的寫法。
使用過Linux下的Makefile的人都知道,Makefile中的賦值運算子有如下四個:
= := += ?=
其區別如下:
- = :最基本的賦值,前面變數的值將會是整個Makefile展開後的最終值;
- := : 覆蓋之前的值,前面變數的值取決於“:=”語句所在Makefile中的位置;
- += : 新增等號後面的值;
- ?= : 如果沒有被賦值過就賦予等號後面的值。
對於本文將要介紹的*.pro檔案而言,常用的是“=”和“+=”兩個。一般而言,“=”使用在變數第一次定義的時候,而“+=”使用在前面已經定義了該變數,當前只是對其進行拓展。*.pro中很多的變數是系統中使用的環境變數,因此本文推薦使用“+=”。
如果要移除某個設定或者原始碼,可以使用“-=”。
下面我將*.pro的內容分為註釋、模板引數、路徑引數、檔案引數、配置引數、變數的使用等幾個方面進行介紹。
二、註釋
在*.pro檔案中,註釋都是從#開始,一直到本行結束。*.pro中沒有多行註釋的方法。
三、模板引數
模版變數告訴qmake為這個應用程式生成哪種Makefile,其定義格式如下:
TEMPLATE = app
下面是可供使用的模版選擇:
- app :建立一個應用程式的Makefile,這是預設值;
- lib : 建立一個庫的Makefile;
- vcapp : 建立一個應用程式的VisualStudio專案檔案;
- vclib : 建立一個庫的VisualStudio專案檔案;
- subdirs : 這是一個特殊的模版,它可以建立一個能夠進入特定目錄並且為一個專案檔案生成Makefile並且為它呼叫make的Makefile。
其中app和lib對應到類Linux作業系統,而vcapp和vclib對應到Windows系統。
四、路徑引數
通過*.pro檔案,我們將我們的原始碼檔案、標頭檔案、資原始檔等分類、分模組進行存放,只需要根據專案的具體情況,配置對應的路徑資訊即可;同時還可以配置使目標檔案、中間檔案、生成的可執行檔案的存放到指定的路徑。
4.1 指定應用程式存放路徑
DESTDIR變數用於指定整個工程編譯之後,生成的可執行程式所存放的路徑,格式如下:
DESTDIR += ./bin
當然,對於開發階段和釋出階段,我們也可以指定不同的存放路徑,方法如下:
Debug:DESTDIR += ./dbg_bin Release:DESTDIR += ./rls_bin
4.2 指定目標檔案存放路徑
通過OBJECTS_DIR變數,我們可以指定C++原始碼編譯生成的目標檔案(obj)存放的路徑:
OBJECTS_DIR += ./Obj
4.3 指定ui_*.h檔案存放路徑
通過UI_DID變數,我們可以指定uic命令處理*.ui檔案生成的ui_*.h檔案的存放路徑:
UI_DIR += forms
4.4 指定qrc_*.h檔案存放路徑
通過RCC_DIR變數,我們可以指定rcc命令處理*.qrc檔案生成的qrc_*.h檔案的存放路徑:
RCC_DIR += ./tmp
4.5 指定Q_OBJECT檔案存放路徑
所謂的Q_OBJECT檔案,是指含有Q_OBJECT的標頭檔案經過moc命令處理之後的檔案。通過MOC_DIR變數可以指定其存放路徑:
MOC_DIR += ./tmp
MOC_DIR用於指定moc命令將含有Q_OBJECT的標頭檔案轉換成標準的*.h檔案的存放路徑。
4.6 指定編譯時的依賴路徑
DEPENDPATH += . forms include qrc sources
DEPENDPATH用於指定程式編譯時,所依賴庫的路徑地址,路徑之間使用空格隔開。
4.7 指定程式包含的標頭檔案路徑
INCLUDEPATH += . include
INCLUDEPATH用於指定程式編譯時,編譯器搜尋標頭檔案的路徑。
五、檔案引數
通過*.pro檔案,我們可以動態新增程式原始碼檔案、標頭檔案,資原始檔等,也可以動態新增一個模組到工程;同時還可以指定原始碼檔案的編碼方式,指定依賴的庫檔案,指定生成的目標檔案等。
5.1 指定C++程式原始檔
通過SOURCES變數可以指定C++實現原始檔:
SOURCES = *.cpp SOURCES += *.cpp
若有多個原始檔,則使用空格分開,如:
SOURCES = 1.cpp 2.cpp 3.cpp。
或者每一個檔案被列在一個分開的行裡面,通過反斜線另起一行,比如:
SOURCES = 1.cpp \ 2.cpp \ 3.cpp
或者繁瑣的單獨地列出每一個檔案,比如:
SOURCES = 1.cpp SOURCES += 2.cpp SOURCES += 3.cpp
5.2 指定C++程式標頭檔案
標頭檔案通過HEADERS變數指定C++標頭檔案:
HEADERS = *.h HEADERS += *.H
列出原始檔的任何一個方法對標頭檔案也都適用。
5.3 指定原始碼檔案編碼方式
CODECFORSRC = GBK
CODECFORSRC變數可以指定原始碼中字串的編碼方式。
5.4 指定*.ui設計檔案
FORMS += forms/painter.ui
FORMS變數用於指定工程中包含的*.ui設計檔案。指定需要uic處理的*.ui檔案。
5.5 指定*.icns設計檔案
RC_FILE += xxx.icns
RESOURCES用於指定工程中包含的*.icns設計檔案。
5.6 指定*.qrc資原始檔
RESOURCES += qrc/painter.qrc
RESOURCES用於指定工程中包含的資原始檔,即指定需要rcc處理的*.qrc檔案。
5.7 指定編譯時依賴的庫檔案
LIBS += -lmath -lpthread -l*
LIBS用於指定編譯工程時要連結的庫檔案,可以在其中加入-L指定庫檔案的路徑。針對除錯版本和釋出版本,有不同依賴庫的,可以使用如下方法進行區分:
Release:LIBS += -L folderPath//release版本引入的lib檔案路徑 Debug:LIBS += -L folderPath//debug版本引入的lib檔案路徑
5.8 指定生成目標檔名
TARGET = filename
TARGET用於指定生成的應用程式的名稱。如果不設定該條目,目標名會被自動設定為跟專案檔案一樣的名稱。
六、配置引數
6.1 配置引數
CONFIG用來告訴qmake關於應用程式的配置資訊,包括工程配置和編譯引數,以下是常用的工程配置和編譯引數:
- qt :告訴qmake這個應用程式是使用Qt來連線編譯的;這也就是說qmake在連線和為編譯新增所需的包含路徑的時候會考慮到Qt庫;
- debug : 編譯有除錯資訊的可執行檔案或者庫檔案;
- release : 編譯不具有除錯資訊的可執行檔案或者庫檔案,如果同時指定debug release時,只有debug有效;
- warn_on :告訴qmake要把編譯器設定為輸出警告資訊的;
- warn_off :關閉大量的警告資訊,預設是開啟的;
- dll : 動態編譯庫;
- staticlib :靜態編譯庫;
- plugin : 編譯一個外掛;
- console : 應用程式需要寫控制檯。
我們常用的CONFIG變數為:
CONFIG += qt warn_on release
或者定義為:
CONFIG = qt CONFIG += release CONFIG += warn_off
6.2 編譯引數
我們也可以通過DEFINES引數,定義預編譯器的編譯選項,從而在*.h和*.cpp檔案中通過#ifdefine或#ifndef更改程式的編譯方式。比如:
DEFINES += DIALOG_H
這將在對應的dialog.h/cpp檔案中被使用,比如將dialog這個模組新增到工程中。
七、變數的訪問
在*.pro檔案裡,可以使用{varName}來訪問自己定義的變數,比如:
MyVersion = 1.2 FILE = 1.cpp TARGET = improve$${MyVersion} SOURCES = $$FILE
*.pro檔案裡,訪問環境變數的用法是:$(varName);*.pro檔案裡,訪問Qt配置引數的用法是:$$[varName]。
八、平臺相關性
有時為了保證不同平臺的相容性,需要針對不同的平臺新增設定條件。這可以根據qmake所執行的平臺來使用相應的作用域來進行處理。比如為windows平臺新增的依賴平臺的檔案的簡單作用域如下:
win32 { SOURCES += hello_win.cpp }
或者;
win32:SOURCES += hello_win.cpp
這樣如果qmake執行在Windows上,它就會把hello_win.cpp新增到原始檔列表中;而如果qmake執行在其他平臺上的時候,它就會很簡單的把這部分內容忽略。
九、生成Makefile
當你已經建立好你的專案檔案,生成Makefile就很容易了,你所要做的就是先到你所生成的專案檔案那裡然後輸入:
qmake -o Makefile hello.pro
對於VisualStudio的使用者,qmake也可以生成“*.dsp”檔案,例如:
qmake -tvcapp -o hello.dsp hello.pro
十、其他
10.1 如果一個檔案不存在,停止qmake
如果某個檔案不存在的時候,你也許不想生成一個Makefile。我們可以通過使用exists()函式來檢查一個檔案是否存在。我們可以通過使用error()函式把正在執行的qmake停下來。這和作用域的工作方式一樣,只要簡單地用這個函式來替換作用域條件,比如對main.cpp檔案的檢查為:
!exists( main.cpp ){ error(“No main.cpp file found”) }
使用“!”來否定這個測試,比如:如果檔案存在,exists(main.cpp)是真,如果檔案不存在,!exists(main.cpp)是真。
10.2 檢查多於一個的條件
假設你使用Windows並且當你在命令列執行你的應用程式的時候,你想能夠看到qDebug()語句。除非你在連編你的程式的時候使用console設定,否則你不會看到輸出。我們可以很容易地把console新增到CONFIG行中,這樣在Windows下,Makefile就會有這個設定。但是如果告訴你我們只是想在當我們的應用程式執行在Windows下並且當debug已經在CONFIG行中的時候,新增console,這就需要兩個巢狀的作用域:只要生成一個作用域,然後在它裡面再生成另一個。把設定放在最裡面的作用域,比如:
win32 { debug { CONFIG += console } }
巢狀作用域可以使用冒號連線起來,比如:
win32:debug{ CONFIG += console }