您好,登錄后才能下訂單哦!
----------------------------------------------------------------
網頁版課程源碼 提取碼:1uy7
引言
----------------------------------------------------------------
上一節我們介紹了pri文件的作用與使用方法,在項目開發尤其是大型項目開發中,pri文件的使用是非常重要的。當我們開展不同的項目開發時,這些項目有非常多的配置項都是完全一樣的。因此,建立一套完整的pri體系變得非常重要。
?
正文
----------------------------------------------------------------
??? 一般情況下,我們會建立一套常用的pri文件,他們各自負責不同的功能,比如有的負責處理編譯選項;有的負責處理目錄設置。為了方便,我們把這些不同的pri整合成一個文件來介紹,當然,大家也可以根據需要把這個文件拆成不同的pri文件。
??? 注:本節的內容默認您的項目使用gcc編譯器。
??? 直接給出gui_base.pri文件:
?
代碼清單02-06-01
1.?? 2.?? 3.?? 4.?? 5.?? 6.?? 7.?? 8.?? 9.?? 10.? ? 11.? ? 12.? ? 13.? ? 14.? ? 15.? ? 16.? ? 17.? ? 18.? ? 19.? ? 20.? ? 21.? ? 22.? ? 23.? ? 24.? ? 25.? ? 26.? ? 27.? ? 28.? ? 29.? ? 30.? ? 31.? ? 32.? ? 33.? ? 34.? ? 35.? ? 36.? ? 37.? ? 38.? ? 39.? ? 40.? ? 41.? ? 42.? ? 43.? ? 44.? ? 45.? ? 46.? ? 47.? ? 48.? ? 49.? ? 50.? ? 51.? ? 52.? ? 53.? ? 54.? ? 55.? ? 56.? ? 57.? ? 58.? ? 59.? ? 60.? ? 61.? ? 62.? ? 63.? ? 64.? ? 65.? ? 66.? ? 67.? ? 68.? ? 69.? ? 70.? ? 71.? ? 72.? ? 73.? ? 74.? ? 75.? ? 76.? ? 77.? ? 78.? ? 79.? ? 80.? ? 81.? ? 82.? ? 83.? ? 84.? ? 85.? ? 86.? ? 87.? ? 88.? ? 89.? ? 90.? ? 91.? ? 92.? ? 93.? ? 94.? ? 95.? ? 96.? ? 97.? ? 98.? ? 99.? ? 100. 101. 102. 103. 104. 105. 106. 107. 108. 109. 110. 111. 112. 113. 114. 115. 116. 117. 118. 119. 120. 121. 122. 123. 124. 125. 126.? | ########################################################################### # 注意:此文件用于放置本次課程各子項目的公共設置, # 在各子項目的 QT 工程文件中通過 include 語句包含該pri文件。 # 需要提前定義如下系統環境變量: # TRAINDEVHOME? ?根目錄: ?其下是bin、lib、src等子目錄。 # TRAINBUILDTYPE 編譯版本: debug|release|all # TRAINBUILDBIT ?編譯位數: 32|64 ########################################################################### ? # 需先通過環境變量 TRAINDEVHOME 指定開發目錄 # 由于 isEmpty 函數不能直接對環境變量進行判斷,所以先將其放入一個臨時變量中 DEVHOME = $$(TRAINDEVHOME) isEmpty(DEVHOME) { ??? error('TRAINDEVHOME'環境變量必須被定義.) } # 設置變量:系統執行文件路徑、庫文件路徑、臨時文件生成路徑、頭文件包含路徑 TRAIN_BIN_PATH = $$(TRAINDEVHOME)/bin TRAIN_LIB_PATH = $$(TRAINDEVHOME)/lib TRAIN_OBJ_PATH = $$(TRAINDEVHOME)/obj TRAIN_SRC_PATH = $$(TRAINDEVHOME)/src TRAIN_UIC_PATH = $$(TRAINDEVHOME)/obj/uic TRAIN_INCLUDE_PATH = $$(TRAINDEVHOME)/include ? # 設置所引用的庫文件的路徑 QMAKE_LIBDIR *= $$TRAIN_LIB_PATH ? DEPENDPATH *=? .\ ??????? $$TRAIN_INCLUDE_PATH ??????? INCLUDEPATH *=? .\ ??????? $$TRAIN_INCLUDE_PATH ? ########################################################################## # # 不同平臺的編譯器設置 # ########################################################################## # 獲取編譯 Qt 的編譯器類型 TRAIN_QMAKESPEC = $$(QMAKESPEC) ? #UNIX + gcc下聲明使用預編譯頭文件 #GCC 3.4 及以后版本支持預編譯頭文件 unix{ ??? contains( ? TRAIN_QMAKESPEC, g++ ) { ??????? CONFIG ? *= precompile_header ??? } } #WIN32下聲明使用預編譯頭文件 win32{ ??? CONFIG ? *= precompile_header ??? ??? # 去掉 strcpy 等編譯警告 ??? QMAKE_CXXFLAGS ? *= -wd4996 } ? #UNIX下編譯設置 unix{ ??? DEFINES ? *= unix __unix? } ? #WIN32下編譯設置 win32{ ??? DEFINES *= WIN32 } ? #激活 STL、RTTI、EXCEPTIONS 支持 CONFIG *= stl exceptions rtti #激活多線程、編譯警告 CONFIG *= thread warn_on ? # 不同編譯版本相關的配置 BUILDTYPE = $$(TRAINBUILDTYPE) equals(BUILDTYPE,debug){ ??? CONFIG ? += debug ??? CONFIG ? -= release } equals(BUILDTYPE,release){ ??? CONFIG ? += release ??? CONFIG ? -= debug } equals(BUILDTYPE,all){ ??? CONFIG ? -= debug ??? CONFIG ? -= release ??? CONFIG ? += debug_and_release build_all } ? # 指定代碼中宏定義 debug_and_release { ??? CONFIG(debug, ? debug|release) { ??? ??? DEFINES += TRAIN_DEBUG ??? } ??? CONFIG(release, ? debug|release) { ??? ??? DEFINES += TRAIN_RELEASE ??? } } else { ??? debug: ? DEFINES += TRAIN_DEBUG ??? release: ? DEFINES += TRAIN_RELEASE } ? # 配置系統使用的編譯位數類型 BUILDBIT = $$(TRAINBUILDBIT) ? # 不同編譯版本相關的配置 equals(BUILDBIT,32){ ??? # 擴展 32 位配置項 ??? CONFIG ? *= x86 ??? DEFINES ? *= TRAIN_32 } equals(BUILDBIT,64){ ??? # 擴展 64 位配置項 ??? CONFIG ? *= x64 ??? DEFINES ? *= TRAIN_64 } ? # 指定不同編譯版本中間文件目錄 debug_and_release { ??? CONFIG(debug, ? debug|release) { ??? ??? TRAIN_OBJ_PATH = $$TRAIN_OBJ_PATH/debug ??? } ??? CONFIG(release, ? debug|release) { ??? ??? TRAIN_OBJ_PATH = $$TRAIN_OBJ_PATH/release ??? } } else { ??? debug:TRAIN_OBJ_PATH ? = $$TRAIN_OBJ_PATH/debug ??? release:TRAIN_OBJ_PATH ? = $$TRAIN_OBJ_PATH/release } |
??? 下面我們來詳細介紹一下這個pri文件。
?
1,開頭的聲明
??? 首先,在pri文件開頭有一個聲明,指明了需要創建的環境變量。也就是說,這個pri文件依賴于環境變量值,當然,您也可以選擇不用環境變量,而是通過修改pri文件中的相關內容來改變這些設置,但是使用環境變量會方便一些,因為不用每次都修改這個pri文件。
??? 這個pri文件用到的環境變量有3個,分別是:
??? 1)? TRAINDEVHOME
用來描述項目的根目錄,目錄結構如下:
$TRAINDEVHOME
------bin????????? 編譯好的運行程序所在目錄
------lib????????? 編譯好的lib文件所在目錄
------include????? 公共頭文件目錄,其下可以再分子目錄
------src????????? 源代碼根目錄
------temp????? ??? 臨時文件目錄
?
2)? TRAINBUILDTYPE?
編譯版本,取值:
debug?????? 編譯debug版本
release???? 編譯release版本
all???????? 同時編譯debug、release版本,即兩個版本都編譯。
?
3)? TRAINBUILDBIT??
編譯位數,取值:
32????????? 編譯成32位程序
64????????? 編譯成64位程序
?
??? 當然了,QTDIR、QMAKESPEC是安裝完Qt后必不可少的環境變量,本文不再贅述。
?
2,環境變量檢查
1.?? ? ? 2.?? ? ? 3.?? ? ? 4.?? ? ? | DEVHOME = $$(TRAINDEVHOME) isEmpty(DEVHOME) { ??? error('TRAINDEVHOME'環境變量必須被定義.) } |
通過Qt的isEmpty()函數判斷環境變量是否存在,如果為空,則輸出錯誤信息并退出。
??? 因為isEmpty()只能使用自定義變量而無法使用環境變量,因此我們先定義了DEVHOME這個變量并賦值為環境變量值,然后用它進行判斷。
?
3,公共目錄
1.?? ? ? 2.?? ? ? 3.?? ? ? 4.?? ? ? 5.?? ? ? 6.?? ? ? 7.?? ? ? 8.?? ? ? 9.?? ? ? 10.? ? 11.? ? 12.? ? 13.? ? 14.? ? 15.? ? 16.? ? | # 設置變量:系統執行文件路徑、庫文件路徑、臨時文件生成路徑、頭文件包含路徑 TRAIN_BIN_PATH = $$(TRAINDEVHOME)/bin TRAIN_LIB_PATH = $$(TRAINDEVHOME)/lib TRAIN_OBJ_PATH = $$(TRAINDEVHOME)/obj TRAIN_SRC_PATH = $$(TRAINDEVHOME)/src TRAIN_UIC_PATH = $$(TRAINDEVHOME)/obj/uic TRAIN_INCLUDE_PATH = ? $$(TRAINDEVHOME)/include ? # 設置所引用的庫文件的路徑 QMAKE_LIBDIR *= $$TRAIN_LIB_PATH ? DEPENDPATH *=? .\ ??????? $$TRAIN_INCLUDE_PATH ??????? INCLUDEPATH *=? .\ ??????? $$TRAIN_INCLUDE_PATH |
??? 這里定義了可執行程序目錄等路徑,都依賴于TRAINDEVHOME環境變量,如果您不想用環境變量,可以使用自定義變量來替換(需要注意自定義變量的語法跟環境變量不同)。
??? 上述變量都是公共路徑設置。在pro中引用本pri文件后,還可以繼續對這些變量值進行引用加工(比如繼續追加目錄層級),從這些變量的名稱就可以對其用途略知一二,現在我們分別看一下。
表02-06-01
關鍵字 | 含義 |
TRAIN_BIN_PATH | 編譯完成的可執行程序的存放路徑 |
TRAIN_LIB_PATH | 編譯完成的lib文件的存放路徑 |
TRAIN_OBJ_PATH | 編譯產生的臨時文件的根目錄 |
TRAIN_SRC_PATH | 源代碼的根目錄 |
TRAIN_UIC_PATH | 編譯ui文件產生的臨時文件根目錄(它是TRAIN_OBJ_PATH目錄的子目錄) |
TRAIN_INCLUDE_PATH | 項目的公共include目錄 |
QMAKE_LIBDIR | Qt關鍵字 設置所引用的庫文件的路徑。比如,編譯某個exe時如果用到了dll文件,那么這個變量用來告訴編譯器到哪個目錄去找所需的lib文件。 |
DEPENDPATH | Qt關鍵字 用來指明所依賴的頭文件路徑 |
INCLUDEPATH | Qt關鍵字 用來告訴編譯器頭文件的搜索目錄。 這樣的話,在源代碼中引用頭文件時,就可以直接寫文件名或者相對路徑,比如: ??? #include "header.h" ??? #include "base/basedll/header.h" 此處的目錄是相對于INCLUDEPATH,也就是: ??? $INCLUDEPATH/base/basedll/header.h |
??????? ???
4,編譯器設置
1.?? ? ? 2.?? ? ? 3.?? ? ? 4.?? ? ? 5.?? ? ? 6.?? ? ? 7.?? ? ? 8.?? ? ? 9.?? ? ? 10.? ? 11.? ? 12.? ? 13.? ? 14.? ? 15.? ? 16.? ? | # 獲取編譯 Qt 的編譯器類型 TRAIN_QMAKESPEC ? = $$(QMAKESPEC) ? #UNIX ? + gcc下聲明使用預編譯頭文件 #GCC ? 3.4 及以后版本支持預編譯頭文件 unix{ ??? contains( TRAIN_QMAKESPEC, g++ ) { ??????? CONFIG *= precompile_header ??? } } #WIN32下聲明使用預編譯頭文件 win32{ ??? CONFIG *= precompile_header ??? ??? # 去掉strcpy等編譯警告 ??? QMAKE_CXXFLAGS *= -wd4996 } |
本部分內容用來處理預編譯頭文件的內容。gcc3.4及以后的版本支持預編譯頭文件,因此為了判斷gcc編譯器,我們使用了Qt的contains()函數。該函數也無法識別環境變量,因此我們定義了變量TRAIN_QMAKESPEC。 當unix(linux也走pri中的unix分支)的編譯器為gcc時,CONFIG配置項就增加了預編譯頭文件的支持:
CONFIG *= precompile_header
windows下(pri中的win32分支,win32是Qt的關鍵字)默認提供預編譯頭文件支持,因此無條件增加precompile_header的選項。
為了消除strcpy造成的4996編譯警告,我們增加如下語句:
??? QMAKE_CXXFLAGS *= -wd4996
?
5,宏定義
1.?? ? ? 2.?? ? ? 3.?? ? ? 4.?? ? ? 5.?? ? ? 6.?? ? ? 7.?? ? ? 8.?? ? ? 9.?? ? ? | #UNIX下編譯設置 unix{ ??? DEFINES ? *= unix __unix? } ? #WIN32下編譯設置 win32{ ??? DEFINES *= WIN32 } |
在代碼中,我們經常需要判斷當前運行程序的操作系統類型,因此需要預先定義操作系統類型宏,上述代碼就給出了在unix以及windows下的定義操作系統類型宏的方法,使用了DEFINES語法,這樣在源代碼中,我們就可以直接使用這些宏進行判斷了。本部分內容在上節進行過講解,這里不再展開。
?
6,激活stl、rtti、exceptions支持
1.?? ? ? 2.?? ? ? | #激活 STL、RTTI、EXCEPTIONS 支持 CONFIG *= stl exceptions rtti |
??? 如果您使用stl庫,那么請激活stl支持。
??? 如果您使用異常處理,那么請激活exceptions。
??? 如果您需要運行時類型識別,那么請激活rtti。
??? 這些選項都是CONFIG配置項,可以單獨配置。
?
7,激活多線程,編譯
1.?? ? ? 2.?? ? ? | #激活多線程、編譯警告 CONFIG *= thread warn_on |
如果您的項目中用到多線程,請激活thread。因為本pri文件是公共pri,所以如果您的某個子模塊用不到多線程支持,您可以在子模塊的pro中禁用多線程,方法是在子模塊的pro中使用如下語句:
CONFIG -= thread
?
8,編譯成debug版還是release版本
1.?? ? ? 2.?? ? ? 3.?? ? ? 4.?? ? ? 5.?? ? ? 6.?? ? ? 7.?? ? ? 8.?? ? ? 9.?? ? ? 10.? ? 11.? ? 12.? ? 13.? ? 14.? ? 15. | # 不同編譯版本相關的配置 BUILDTYPE = $$(TRAINBUILDTYPE) equals(BUILDTYPE,debug){ ??? CONFIG ? += debug ??? CONFIG ? -= release } equals(BUILDTYPE,release){ ??? CONFIG ? += release ??? CONFIG ? -= debug } equals(BUILDTYPE,all){ ??? CONFIG ? -= debug ??? CONFIG ? -= release ??? CONFIG ? += debug_and_release build_all } |
??? 如果需要對我們的程序進行調試,我們會選擇debug版本,因為debug版的程序含有很多調試信息,而如果我們需要發布版則使用release版本,因為它的執行效率更高運行更快。此處我們使用了Qt的equals()函數來判斷編譯版本。同樣這個函數也不識別環境變量,因此我們定義了BUILDTYPE變量來進行判斷。請注意,equals()函數中的第二個參數中的debug、release只是個字符串,下列語句中的debug、release才是Qt的關鍵字。
CONFIG+=debug
??? CONFIG -= release
???
9,程序運行時如何區分debug版還是releaes版
??? 有時候,我們在程序運行過程中,需要知道自己是debug版還是release版,該怎么做呢?
1.?? ? ? 2.?? ? ? 3.?? ? ? 4.?? ? ? 5.? ? ?? 6.?? ? ? 7.?? ? ? 8.?? ? ? 9.?? ? ? 10.? ? 11.? ? 12.? ? | # 指定代碼中宏定義 debug_and_release ? { ??? CONFIG(debug, debug|release) { ??? ??? ? DEFINES += TRAIN_DEBUG ??? } ??? CONFIG(release, debug|release) { ??? ??? ? DEFINES += TRAIN_RELEASE ??? } } ? else { ??? debug: DEFINES += TRAIN_DEBUG ??? release: DEFINES += TRAIN_RELEASE } |
??? 上述語法是分支判斷語法,其{}前面的字符串是CONFIG的配置項,比如此處的debug_and_release。我們使用上述方法得知當前編譯版本并定義了相關的宏TRAIN_DEBUG、TRAIN_RELEASE。這樣在源代碼中就可以直接用這兩個宏來區分debug版與release版本了。請大家務必注意下列代碼的語法:
??? CONFIG(debug, debug|release)
??? 上述語句用來判斷是否正在編譯debug版本。
??? CONFIG(release, debug|release)
??? 上述語句用來判斷是否正在編譯release版本。
?
??? 而下面的語句用來區分debug編譯分支和release編譯分支,方法是在debug或者release后使用冒號(:)。
debug: DEFINES += TRAIN_DEBUG
release: DEFINES += TRAIN_RELEASE
???
10,程序運行時如何區分32位程序還是64位程序
??? 程序運行的時候,有可能需要知道自己被編譯成了32位還是64位,方法如下:
1.?? ? ? 2.?? ? ? 3.?? ? ? 4.?? ? ? 5.?? ? ? 6.?? ? ? 7.?? ? ? 8.?? ? ? 9.?? ? ? 10.? ? 11.? ? 12.? ? 13.? ? 14.? ? | # 配置系統使用的編譯位數類型 BUILDBIT = $$(TRAINBUILDBIT) ? # 不同編譯版本相關的配置 equals(BUILDBIT,32){ ??? # ? 32 位配置項 ??? CONFIG ? *= x86 ??? DEFINES ? *= TRAIN_32 } equals(BUILDBIT,64){ ??? # ? 64 位配置項 ??? CONFIG ? *= x64 ??? DEFINES ? *= TRAIN_64 } |
??? 方法與區分debug版本還是release版本類似,因此不再詳述。
?
11,區分debug版本、release版本的臨時文件
??? 編譯程序時,編譯同一個項目的debug版本與release版本會產生不同的臨時文件,我們當然不希望這些臨時文件會相互覆蓋,因此我們需要為它們指定不同的目錄。
1.?? ? ? 2.?? ? ? 3.?? ? ? 4.?? ? ? 5.?? ? ? 6.?? ? ? 7.?? ? ? 8.?? ? ? 9.?? ? ? 10.? ? 11.? ? 12.? ? | # 指定不同編譯版本中間文件目錄 debug_and_release { ??? CONFIG(debug, ? debug|release) { ??? ??? TRAIN_OBJ_PATH = $$TRAIN_OBJ_PATH/debug ??? } ??? CONFIG(release, ? debug|release) { ??? ??? TRAIN_OBJ_PATH = $$TRAIN_OBJ_PATH/release ??? } } else { ??? debug:TRAIN_OBJ_PATH ? = $$TRAIN_OBJ_PATH/debug ??? release:TRAIN_OBJ_PATH ? = $$TRAIN_OBJ_PATH/release } |
??? 從上述代碼可以看出,debug版本與release版本產生的臨時文件分別存放到obj下面的debug目錄、release目錄,這樣就不會相互覆蓋了。
?
結語
----------------------------------------------------------------
??? 本節詳細介紹了如何為項目引入pri體系并且使它正常運轉起來。本文提到的pri使用了比較多的配置項,大家可以根據個人的需求調整其中的配置項。但是其中最常被修改的可能也就下面3個:
TRAINDEVHOME?? 根目錄,其下是bin、lib、src等子目錄。
TRAINBUILDTYPE 編譯版本: debug|release|all
TRAINBUILDBIT? 編譯位數: 32|64
??? 原因就是使用者可能根據自己的項目需求創建了不同的環境變量名(比如不是TRAINDEVHOME,而是SOURCEHOME),或者干脆不用環境變量僅僅使用自定義變量。如果僅僅使用自定義變量,那么就需要將本pri中所有使用環境變量的地方改成使用自定義變量,而且一定要注意自定義變量的使用語法跟環境變量不同:
??? 環境變量: $$(環境變量名)
變量:???? $$變量名
??? 如果使用自定義變量,那么請注意項目的pro文件中,如果要引用該pri文件,那么也要進行相應修改:
代碼清單02-06-01
myprogram.pro
1.?? ? ? 2.?? ? ? | PRI_FILE_PATH = ../../ include ($$PRI_FILE_PATH/src/gui_base.pri) |
?
??? 本節內容比較多,請大家慢慢消化。如果還是不知道該怎樣使用pri文件,請學習下節內容開始練手吧。
----------------------------------------------------------------
《Qt入門與提高-GUI產品開發》目錄請添加鏈接描述
上一節:KS02-05 pri 文件有啥用?
下一節:KS03-01 怎樣實現國際化
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。