Archive:Development/Tutorials/CMake (zh TW)

From KDE TechBase

Template:I18n/Language Navigation Bar (zh TW)

介紹

CMake 讀取指令檔並且為執行平臺的原生構建系統產生輸入檔。它可以生成 GNU Makefiles、KDevelop 專案檔、XCode 專案檔以及 Visual Studio 專案檔。

CMake 是自由軟體並在 BSD 授權下發佈。它是由Kitware 公司開發。

您可以在TechBase 上的 CMake 頁面找到更多 CMake 相關的資訊。

為什麼使用 CMake?

CMake 是 KDE 4 發行的官方工具,是在2006年3月所決定的。相較過去的 KDE 工具 automake 和 unsermake,技術上的不同點有:

  • CMake 是獨立於 KDE 開發,它也可以被用於其它專案
  • 編譯時間更快,主要是因為沒有使用libtool
  • 建構檔更容易編寫

如何使用 CMake 編譯 KDE

取得和安裝CMake

Linux、BSD 和其他 Unix 系統

這裡取得最新的 CMake 穩定版。

下載完成後,解壓並編譯:

$ mkdir cmake-build
$ cd cmake-build
$ ../bootstrap
$ make
$ make install

預設情況下,會安裝 CMake 在 /usr/local。所以請確定 /usr/local/bin 在您的執行路徑(execute path)中。想要改變安裝路徑(例如 debian 中改為 /usr),請在 bootstrap 指令中加入 '--prefix=PATH' 選項。

如果你想使用目前的開發版本,請依循這裡的說明。

Windows

這裡取得最新的 CMake 穩定版。

下載完成後,執行 cmake 安裝程式。

預設將安裝 CMake 在 C:\Program Files\CMake 2.8。所以請確定 <installpath>\bin 在你的執行路徑中。

如果你想使用目前的開發版本,請依循這裡的說明。

執行 CMake

Linux、BSD 和其他 Unix 系統

你必須執行 CMake 來為你的系統生成建構檔。CMake支援 in-source 和 out-of-source 建構,不過目前 KDE 預設禁用 in-source 建構。

假設你在 ~/src/kdelibs/ 中有 kdelibs/,那麼,輸入:

$ ls
kdelibs/
$ mkdir kdelibs-build
$ cd kdelibs-build
$ cmake ../kdelibs

這會在 kdelibs-build/中生成建構 kdelibs/ 的 Makefiles。

Windows

你必須執行 CMake 來為你的系統生成建構檔。CMake支援 in-source 和 out-of-source 建構,不過目前 KDE 預設禁用 in-source 建構。

假設你在 c:\daten\kde4 中有 kdelibs\,那麼,輸入:

c:\daten\kde4> cd kdelibs\win
c:\daten\kde4> cmake
c:\daten\kde4> make 
c:\daten\kde4> make install
c:\daten\kde4> cd ..
c:\daten\kde4> mkdir kdelibs-build
c:\daten\kde4> cd kdelibs-build
c:\daten\kde4\kdelibs-build> cmake ..\kdelibs

這樣就在 kdelibs-build\中生成建構 kdelibs\ 的 Makefiles。想了解更多關於在 Windows 編譯KDE 的資訊,請閱讀KDE on Windows

KDevelop 3 專案檔

If you prefer project files for KDevelop 3 (which will basically be Makefiles accompanied by some extra files for KDevelop), run it like this:

$ cmake ../kdelibs -GKDevelop3

Use 'cmake -h' to find out which generators CMake supports and the other options.

CMake 和 Qt4

為了定位 Qt 4,CMake 會在你的執行路徑中搜尋 qmake。CMake 會使用 QTDIR 環境變數。所以請確定在執行路徑中找到的第一個 qmake 就是你希望使用的。

更多細節

當 CMake 執行完成後,它會生成一個「CMakeCache.txt」檔案。這個檔案包含了所有 CMake 在你的系統上偵測到的設定。如果你希望在其他生成器(generators)上執行 CMake,或你希望 CMake 重新偵測系統,請刪除這個檔案。

如果有些東西你知道它在哪,但 CMake 沒有偵測到,你可以手動的告訴 CMake 到哪裡去找它。CMake 使用變數儲存這些資訊。這些變數快取在前面提到的 CMakeCache.txt中。有3個選項可以手工調整這些變數:

  • 透過命令列告訴 CMake 正確值:cmake ../kdelibs -DNAME_OF_THE_VARIABLE=value
  • 使用 ccmake,它提供了一個基於滑鼠的 GUI 來調整 CMake 變數(執行:ccmake ../kdelibs)
  • 直接編輯 CMakeCache.txt(不建議)

你至少應該執行一次「ccmake ../kdelibs」,這樣你對 CMake 使用那些變數會有個印象。按「T」查看「advanced」變數。如果有些東西 CMake 沒有找到,啟動 ccmake 並手動調整它。

命令列變數

一些你可能希望設定的命令列變數:

  • CMAKE_INSTALL_PREFIX:cmake ../kdelibs -DCMAKE_INSTALL_PREFIX=/opt/kde4 相當於 ./configure --prefix=/opt/kde4
  • CMAKE_BUILD_TYPE:決定你想要的建構方式。你可以選擇「debugfull」、「Debug」、「Profile」、「RelWithDebInfo」和「Release」。預設是用「RelWithDebInfo」。更多細節說明請參考CMake 建構方式頁面。
  • KDE4_BUILD_TESTS=ON: creates Makefiles with build test programs and also provides 'test' targets
  • KDE4_TEST_OUTPUT=xml: Unit tests using the QTestLib framework will create xml formatted logfiles.
  • KDE4_DISABLE_MULTIMEDIA=ON: Build KDE without any multimedia (audio and video) support.
  • BUILD_foo=OFF: disables the build for the project in subdirectory 'foo'.
  • WITH_foo: there are several options, e.g. WITH_CUPS or WITH_Jasper. If you disable them, cmake will not even try to find this package. If it is enabled, cmake will try to find it. If it fails with this, you can still adjust it manually as described above.

環境變數

如果你安裝標頭檔或函式庫在非標準位置,CMake沒法找到(例如 Mac OSX 下安裝 fink 到 /sw),那麼就請設定下面這些環境變數。This can be also very useful e.g. if you install kdesupport to ~/install/kdesupport . Despite the similar naming convention, these will not work as arguments on the cmake command line:

  • CMAKE_INCLUDE_PATH,例如 export CMAKE_INCLUDE_PATH=/sw/include
  • CMAKE_LIBRARY_PATH,例如 export CMAKE_LIBRARY_PATH=/sw/lib
  • CMAKE_PROGRAM_PATH,例如 export CMAKE_LIBRARY_PATH=/sw/bin

With CMake 2.6.0 and above the same effect can be achieved by setting just one variable:

  • CMAKE_PREFIX_PATH,例如 export CMAKE_PREFIX_PATH=/sw


關於變數的更多資訊,請參考這個 cmake.org wiki 網頁

更進一步

如果 cmake 以「Generating done」結束,那表示沒有錯誤,但如果以「Configuring done」結束,那表示有錯誤需要修正。cmake 成功結束後,執行你的建構工具(如 make、KDevelop、XCode 或 MSVC)來建構它。等到完成後執行「make install」。

如果你得到類似下面的錯誤提示:

CMake Error: This project requires some variables to be set,
and cmake can not find them.
Please set the following variables:
X11_XTest_LIB (ADVANCED)

那表示你可能缺少函式庫(或其他相依套件)。在 cmake/modules 目錄中搜尋 cmake 無法找到的變數來確定是缺少哪個函式庫。在上面的例子中,會是:

find_library(X11_XTest_LIB Xtst ${X11_LIB_SEARCH_PATH})

這裡缺少的函式庫是 Xtst。你必須找到它(也許是透過安裝 libXtst-devel 函式庫)並再次執行 cmake。

使用 CMake 在簡單的應用程式中

這是最簡單的 CMakeLists.txt:

add_executable(hello main.cpp)

這將從 main.cpp 原始碼檔案建立一個叫「hello」(Windows下叫「hello.exe」)的執行檔。你可以根據自己的需要混合 C 和 C++ 檔案。在同一個 CMakeLists.txt 也可以有多個執行檔和函式庫。同一個原始碼檔案可以用於多個目標,每個目標可以獨立其他目標編譯。CMake 語言最重要的部分可能是變數:

set( MY_SOURCES main.cpp widget.cpp)
message(STATUS "my sources: ${MY_SOURCES}")

使用 SET() 指令來設定變數的值。如果你列出了一個以上的字串,變數會是一個列表,由一列分號隔開的字串組成。如果您只設定一項,那麼就只有一個值。可以透過 ${VAR} 獲得變數的值。您可以使用 FOREACH() 來反覆運算一份列表:

foreach(next_ITEM ${MY_SOURCES})
   message(STATUS "next item: ${next_ITEM}")
endforeach(next_ITEM ${MY_SOURCES})

CMake 中的指令是不分大小寫的,但變數名和參數名是區分大小寫的。

您還可以測試各式各樣的東西:

if (UNIX)
   message(STATUS "This is UNIX (including OS X and CygWin)")
endif (UNIX)

if (MSVC)
   set(MY_SRCS ${MY_SRCS} winextra.cpp)
endif (MSVC)

在第二個例子中,你可以看到如何將項目附加到列表中。

在 cmake Wiki 中有一份使用 cmake 建構 KDE 4 軟體的教學,推薦閱讀。

使用 CMake 在 KDE 專案中

這是一份建構小型 KDE 4 專案的基本 CMakeList 檔:

project( kde4project )
find_package( KDE4 REQUIRED )
include_directories( ${KDE4_INCLUDES} )

set( KDE4ProjectSources kde4mainapp.cpp someclass.cpp someotherclass.cpp )

kde4_add_executable( kde4project ${KDE4ProjectSources} )

target_link_libraries( kde4project ${KDE4_KDEUI_LIBS} ${KDE4_KPARTS_LIBS} )

install( TARGETS kde4project  ${INSTALL_TARGETS_DEFAULT_ARGS} )

target_link_libraries 包含連結到您的程式的開發庫。比如說,你想要連結 libtidy-devel,你的函式庫的檔名可能叫做 /usr/local/lib/libtidy.a。還要加上 -ltidy 讓 gcc 呼叫。在這裡,請加入 tidy 到您的target_link_libraries。可能的話,請使用預先定義的變數或巨集,如 ${KDE4_KDEUI_LIBS}。

install (TARGETS 是最後安裝目標的位置。如果你沒有這行,就無法使用 make install。

KDE 特定的變數、巨集和其他有用的資訊,可以在KDE 的 CMake 附加元件頁面找到。

擴展 CMake

CMake 可以使用 cmake 腳本擴展。CMake 帶有大量的腳本,在 UNIX 下,這些腳本預設安裝在 /usr/local/share/CMake/Modules/。KDE 函式庫也在 share/apps/cmake/modules/ 安裝了一些CMake 模組。這些檔案位置會優先於系統全域的 CMake 模組路徑。

偵測軟體套件可以使用 FindFOO.cmake,更多資訊請見這裡

你還可以在 CMake 中編寫巨集。他們非常強大,可以滿足你建構軟體中所有的需求,但他們並不適合作為一般目的程式語言。

轉換基於 autotools 的 KDE 軟體使用 CMake

In kdesdk/cmake/ you can find a script am2cmake . This is a ruby script, so you need to have ruby installed. Run am2cmake in the toplevel directory of your sources:

$ cd src/mykooltool/
$ am2cmake --kde4

Don't forget the switch "--kde4", otherwise it won't generate files suitable for KDE 4 software. The converted files 'may' work as they are, but complicated projects will require some additional editing.

You may have to:

  • add more include direcories, using INCLUDE_DIRECTORIES()
  • add more link libraries, using TARGET_LINK_LIBRARIES()
  • add some compile switches, using ADD_DEFINITIONS()
  • add some "configure" checks, see How To Do Platform Checks and How To Find Installed Software
  • take special care of former libtool convenience libraries. They are not supported by cmake, instead there will be a file ConvenienceLibs.cmake created. In this file you will find for every convenience lib a variable, which contains all source files of this convenience lib. For the targets which linked to this convenience lib, just add the variable to the sources.
  • a file AdditionalInfo.txt will be created. There you will see all *.in and *.in.in files of your project. The stuff done in these files will have to be converted manually to cmake.