用CMake 構建Qt 項目

譯:用CMake構建Qt項目
作者: Johan Thelin  譯者:賴敬文
原鏈接:http://developer.qt.nokia.com/quarterly/view/using_cmake_to_build_qt_projects
翻譯來源:http://blog.csdn.net/jingwenlai_scut
         QtSDK中已經包含了QMake用於處理跨平臺的編譯問題。然而,還存在其它編譯工具,比如autotools,SCons和CMake.這些工具滿足不同的需求,比如外部依賴。
        當KDE項目從使用Qt3升級到使用Qt4時,整個項目將構建工具從autotools轉而使用CMake.這使得CMake在Qt開發世界中在用戶數以及功能支持和質量上佔有了特殊的位置。從開發過程來看,QtCreator從1.1開始支持CMake (從1.3開始支持Microsoft的開發工具集).
1.一個基本的例子
           在本文中我們將只關注CMake本身,並且指出如何將它與Qt結合起來。首先,我們看一個簡單但典型的基於CMake的項目。從下面的列表可以看出,這個工程包括一些源代碼及文本文件。
$ ls
CMakeLists.txt
hellowindow.cpp
hellowindow.h
main.cpp
          最基本的,CMakeLists.txt文件將QMake需要使用到的工程文件替換了。如果需要編譯這個工程,可以創建一個build目錄,並在其內使用cmake及make來編譯。
$ mkdir build
$ cd build
$ cmake .. && make
         創建一個build目錄的原因是我們想達到”out-of-source”編譯的目的,即我們可以把編譯過程中產生的中間文件與源代碼隔離開來。當然,用qmake也可以做到這一點,但是需要做額外的一些步驟,但CMake可以很容易得做到這一點。


CMake 正在編譯一個基本的項目

CMake中使用的參數代表指CMakeLists.txt文件所在的目錄。這個CMakeLists.txt文件控制了整個編譯的過程。爲了更徹底地理解它,我們用以下這個圖來看看整個編譯的流程。下面這張圖表明用戶編寫的文件(源代碼,頭文件,.ui文件,.qrc文件)在編譯過程中是如何被Qt的工具進行處理,並整合到整個編譯流程中的。因爲qmake是用於處理這個流程的,它隱藏了這個流程中的很多細節。




Qt編譯系統
         當使用CMake的時候,這些中間過程必須要顯式地進行處理。這也就是說,在頭文件中如果有使用Q_OBJECT宏的話,則這個文件需要被moc進行處理,.ui文件也必須要由uic處理,.qrc文件需要由rcc程序處理。
在上面的例子中,我們簡化了這些步驟,我們只需要處理包含了Q_OBJECT宏的頭文件。也就是說,我們需要用moc對helloworld.h文件進行處理。與此工程相對應的CMakeLists.txt文件如下:
                PROJECT(helloworld)
                FIND_PACKAGE(Qt4 REQUIRED)
        上述兩句的意思指定義此工程爲helloworld,並且讓cmake自動去尋找Qt4,下面,我們需要用SET命令把需要定義的頭文件與cpp文件等串起來.
              SET(helloworld_SOURCES main.cpp hellowindow.cpp)
              SET(helloworld_HEADERS hellowindow.h)
爲了調用moc程序,需要使用 QT4_WRAP_CPP宏。 定義如下:
                QT4_WRAP_CPP(helloworld_HEADERS_MOC ${helloworld_HEADERS})
這一步的作用實際上與在命令行中使用
                $moc –o helloworld_moc.h helloworld.h
是類似的,上述的helloworld_HEADERS_MOC只是爲了後續使用而取的名字。
          爲了編譯這個Qt工程,需要包含Qt的庫文件目錄並且包含一些定義:
                 INCLUDE(${QT_USE_FILE})
                 ADD_DEFINITIONS(${QT_DEFINITIONS})
最後,CMake需要知道最終應用程序的名字以及加入鏈接庫來生成它。這個在cmake中可以很方便地使用ADD_EXECUTABLE 和     TARGET_LINK_LIBRARIES. 因此,在CMakeLists.txt中加入如下:
                       ADD_EXECUTABLE(helloworld ${helloworld_SOURCES}
                                                              ${helloworld_HEADERS_MOC})
                       TARGET_LINK_LIBRARIES(helloworld ${QT_LIBRARIES})
             重新回顧上述CMakeLists.txt, 你會覺得相對於qmake來說,要多寫一些配置,這實際上已經大大簡化了,因爲cmake並不是如qmake一樣專爲Qt而使用。
2.加入更多的Qt元素
          從上面的最基本的例子繼續,我們再在加入資源文件及UI文件。在上述的例子中增加了hellowindow.ui及images.qrc文件,相應的CMakeLists.txt增加以下的內容:
                                      SET(helloworld_SOURCES main.cpp hellowindow.cpp)
                                      SET(helloworld_HEADERS hellowindow.h)
                                      SET(helloworld_FORMS hellowindow.ui)
                                      SET(helloworld_RESOURCES images.qrc)
.qrc文件及.ui文件通過宏 QT4_WRAP_UI 和 QT4_ADD_RESOURCES進行處理。這些宏與QT4_WRAP_CPP的宏的作用是一樣的,實際上都是在編譯過程中調用相應的應用程序對其進行處理。即針對.qrc文件通過調用rcc程序對其處理,對.ui文件通過調用uic程序對其處理。對CMakeLists.txt增加內容如下:
                                     QT4_WRAP_CPP(helloworld_HEADERS_MOC ${helloworld_HEADERS})
                                     QT4_WRAP_UI(helloworld_FORMS_HEADERS ${helloworld_FORMS})
                                     QT4_ADD_RESOURCES(helloworld_RESOURCES_RCC ${helloworld_RESOURCES})
同樣地,這些中間生成的文件在最終生成應用程序的時候需要用到,因此,add_executable修改如下:
                                    ADD_EXECUTABLE(helloworld ${helloworld_SOURCES}
                                    ${helloworld_HEADERS_MOC}
                                    ${helloworld_FORMS_HEADERS}
                                    ${helloworld_RESOURCES_RCC})
           在編譯之前,還有一個問題要處理,如上所述,我們要進行的是在源代碼之外 的編譯,因此,這些生成的中間文件都會在build目錄下,這樣的話,編譯器則不能定位由uic程序產生的諸如ui_hellowindow.h等文件。所以,我們需要把build目錄添加到包含目錄中,如下:
                                      INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})
加入這一行之後,所以中間生成的文件都會被包含在include路徑中。
3.更多Qt 模塊
           目前爲止,我們均只依賴於QtCore和QtGui模塊。如果需要引用其它模塊,cmake需要顯式地開啓它。通過set命令將特定的模塊設置爲TRUE則可。例如,如果要在程序中使用OpenGL的支持,則需要在CMakeLists.txt中使用如下這一行:
                                     SET(QT_USE_QTOPENGL TRUE)
其它較常用的模塊包括:
                                     QT_USE_QTNETWORK
                                     QT_USE_QTOPENGL
                                     QT_USE_QTSQL
                                     QT_USE_QTXML
                                     QT_USE_QTSVG
                                     QT_USE_QTTEST
                                     QT_USE_QTDBUS
                                     QT_USE_QTSCRIPT
                                     QT_USE_QTWEBKIT
                                     QT_USE_QTXMLPATTERNS
                                     QT_USE_PHONON
此外,還有其它的宏可以用,具體地可參見cmake/share/Modules/FindQt4.cmake
4.獲益與複雜性的平衡
         如上可以看到,使用cmake並不如qmake輕鬆,但是cmake提供了更多的功能。最顯著的獲益是cmake支持”out-of-source”編譯,這可能會更改使用習慣,但是這樣做使得對源代碼的版本跟蹤變得更加方便。
          同樣地,使用cmake的另外一個好處是不只是針對Qt,cmake使得添加額外的庫的支持變得更加容易,比如,針對不同的平臺,鏈接不同的庫或者是將Qt與其它庫一起使用以構建較大型的程序,此時cmake的優勢開始顯現。
          其它的強大的功能是具有了在一次設置的過程中產生不同版本的應用程序的能力,也就是說,針對一個單一的配置文件,可以產生多種不同的編譯過程。
           Cmake與qmake之間的選擇其實很簡單,對於只使用Qt的項目,qmake是個很好的先把。而當編譯的需求超過了qmake的處理能力或者使用qmake配置變得很複雜時,cmake可以替代它。   
發佈了24 篇原創文章 · 獲贊 38 · 訪問量 16萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章