天天看點

Qt的.pro工程檔案文法學習

  我們編寫Qt應用程式時,不管使用Qt Creator還是VS或者Eclipse,不管是Qt Widgets還是Qt Quick,總會發現有.pro檔案,我們稱.pro檔案為Qt的工程管理檔案,它存在的目的是列舉工程中包含的源檔案。類似于makefile,一個工程中可以包含一個或多個.pro檔案。是以對于使用Qt的開發人員來說,熟悉.pro工程檔案的文法,懂得閱讀和修改.pro檔案,将有利于對項目工程的檔案組織和管理。

  qmake、.pro檔案、makefile檔案的關系簡單來說就是:

qmake工具使用了與平台無關的.pro檔案生成與平台相關的makefile檔案。

  是以雖然本文标題為.pro檔案文法學習,實際上應該是qmake的文法學習,但是因為IDE把qmake隐藏起來了,我們接觸地更多的是.pro檔案,是以還是使用這樣的标題。

================================

TARGET變量 & TEMPLATE變量 & CONFIG變量:

  首先我們需要知道工程檔案主要分為三種:app(單獨的應用程式)、lib(靜态或動态庫)和subdirs(遞歸編譯)。工程檔案的類型可以使用TEMPLATE變量來指定。

  TARGET是用來定義應用程式的名字的,而程式的擴充名則由TEMPLATE來定義。例如:TARGET = hello,TEMPLATE = app,則在Linux下會生成hello(無字尾的ELF可執行檔案),對應的在Windows下會生成hello.exe。

  TEMPLATE和CONFIG共同定義了目标類型,以下是幾種常見情況:

  • TEMPLATE = app,生成标準程式(注意如果沒有TEMPLATE這一項,那麼預設工程就是app)。
  • TEMPLATE = subdirs,子項目工程模闆,可以用它來建立一個能夠進入特定目錄并且編譯子目錄裡的目标檔案。此時除了TEMPLATE = subdirs,還需要指定SUBDIRS變量,在每個子目錄中,qmake會搜尋以目錄命名的.pro檔案,并且會編譯該工程。
  • TEMPLATE = lib,生成庫檔案,若不指定CONFIG變量,則編譯為共享庫;若CONFIG += staticlib,則編譯為靜态庫;若CONFIG += plugin,則編譯為插件(插件總是動态庫)。

對于app或者lib工程,以下是較常使用的一些變量:

  • TARGET變量:指定可執行檔案或庫的基本檔案名,其中不包含任何的擴充、字首或版本号。(預設的是目前的目錄名)
  • CONFIG變量:指定各種用于工程配置和編譯的參數
  • HEADERS變量:指定工程的C++頭檔案(.h)
  • SOURCES變量:指定工程的C++實作檔案(.cpp)
  • FORMS變量:指定需要uic處理的由Qt設計師生成的.ui檔案
  • RESOURCES變量:指定需要rcc處理的.qrc檔案(資源檔案)
  • LEXSOURCES變量:指定工程的lex源檔案(.l)
  • YACCSOURCES變量:指定工程中的yacc源檔案(.y)
  • DEFINES變量:指定預定義的C++預處理器符号
  • INCLUDEPATH變量:指定C++編譯器搜尋全局頭檔案的路徑
  • LIBS變量:指定工程要連結的庫。庫既可以通過絕對路徑指定,也可以使用源自Unix的-L和-l辨別符來指定(例如:-L/usr/local/lib和-ldb_cxx)
  • QT變量:指定工程所要使用的Qt子產品(預設的是core gui,對應于QtCore和QtGui子產品)
  • VERSION變量:指定目标庫的版本号
  • DESTDIR變量:指定生成的可執行檔案放置的目錄。(預設值是平台相關的,例如在Linux上,值目前目錄;在Windows上,則是指debug或release子目錄)
  • DLLDESTDIR變量:指定目标庫檔案放置的目錄(預設與DESTDIR相同)
  • OBJECTS_DIR變量:指定目标檔案(.o檔案)的存放目錄

.pro檔案中的注釋:

  注釋以井号(#)開頭,在行尾處結束。

.pro檔案中的一個條目的文法通常具有如下形式:

variable = values      

  values是字元串的清單,例如:CONFIG = qt release warn_off,是指将清單 [“qt”, “release”, “warn_off”] 賦給CONFIG變量,注意!它會覆寫CONFIG變量以前設定的各個值。是以我們通常用 += 操作符來擴充變量的值。如:

CONFIG = qt
CONFIG += release
CONFIG      

  同樣,我們也可以用 -= 操作符從目前的變量中移除任意的指定值。如:

CONFIG = qt release warn_off
CONFIG      

會使CONFIG變量的值變成 [“release”, “warn_off”]。

  另外還有 = 操作符和 ~= 操作符。= 操作符在一個變量上添加一個值,但要求被添加的值不在變量的清單上,否則将不做任何事情。例如:

SOURCE *= main.cpp      

這一行将把main.cpp檔案添加到工程中,隻有當它還沒有被添加的情況下才會添加。

最後,~= 操作符使用指定的值替換符合正規表達式的值,這是sed的文法。例如:

SOURCES ~= s/\.cpp\b/.cxx/      

使用.cxx替換SOURCES變量中所有.cpp檔案的擴充名。

  除了使用qmake定義的标準變量外,我們也可以設定任意變量和值,并且可以使用$$varName 或者 $${varName} 文法引用它。例如:

MY_VERSION = 2.0
TARGET = Hello_$${MY_VERSION}      

  使用 $${PWD} 可以擷取目前檔案所在的目錄路徑。

  使用内置函數 $$lower() 可以把字元串轉換為小寫。

  而内置函數$$system() 允許我們從外部應用程式中産生字元串,例如想要确認目前的UNIX版本,可以這樣寫:

OS_VERSION = $$system(uname -r)      

然後,可以在條件中使用結果變量,并與contains()合用:

contains(OS_VERSION, SunOS): SOURCES += mythread_sun.c      

  有時候可能需要在.pro檔案中指定包含空格的檔案名。在這種情況下,隻需要簡單地把檔案名用引号括起來即可。

  當在不同平台上編譯工程時,可能有必要基于平台指定不同的檔案或者不同的參數。qmake的條件判斷文法是:

condition {
    then-case
} else {
    else-case      

condition部分可以是平台名字(例如:win32、unix或者macx),或者更複雜的斷言。then-case和else-case部分使用标準文法為變量指派。例如:

win32 {
    SOURCES += serial_win.cpp
} else {
    SOURCES += serial_unix.cpp
}      

else分支是可選的。為了友善,當then-case部分僅有一條變量指派,而且在沒有else-case分支時,qmake也支援單行形式的文法。例如:

macx: SOURCES += serial_mac.cpp      

  如果有幾個工程檔案需要共享相同的項,則可以把相同的項提取到單獨的檔案中,在各自的.pro檔案中使用include()語句包含它們。例如:

include(../common.pri)      

通常,打算被别的工程檔案所包含的工程檔案會帶有.pri(工程包含)的擴充名。

繼續閱讀