【譯文】Mastering CMake(chapter 2)Getting Started

第二章 開始

2.1 獲取並在您的計算機上安裝CMake

在使用CMake之前,您需要在您的系統上安裝或構建CMake二進制安裝文件。 在許多系統中,您可能會發現CMake已經安裝,或者可以使用系統的標準軟件包管理工具進行安裝。 Cygwin,Debian,FreeBSD,Mac OS X Fink等等都有CMake發行版。 如果您的系統沒有CMake包,您可以在www.cmake.org上找到針對大多數常見體系結構的CMake預編譯。 如果您沒有爲您的系統預編譯找到二進制文件,那麼您可以從源代碼構建CMake。 要構建CMake,您需要一個c ++編譯器。

UNIX和Mac的安裝

如果你的系統提供CMake安裝包作爲其標準軟件包之一,請按照系統的軟件包安裝說明進行安裝。 如果你的系統沒有CMake安裝包,或者有一個過時的CMake版本,你可以從www.cmake.org下載預編譯的二進制文件。這個二進制文件是tar格式。 tar文件包含一個README文件和一個封閉的tar文件。 README文件包含封裝的tar文件中包含的文件清單以及一些說明。安裝只需將附帶的tar文件解壓到目標目錄(通常是/usr/local)。 但是,它可以是任何目錄,並且不需要root權限來進行安裝。

Windows二進制安裝

CMake有一個NullSoft安裝文件可以從www.cmake.org下載。 要安裝此文件,只需在要運行CMake的Windows計算機上運行可執行文件即可。 安裝後,您將能夠從開始菜單運行CMake。

2.2 自己建立CMake

如果您的系統不能使用二進制文件,或者如果二進制文件不是你希望使用的CMake版本,則可以從源代碼構建CMake。 您可以按照www.cmake.org上的說明獲取CMake源代碼。 一旦你有源代碼,它可以用兩種不同的方式建立。 如果您的系統上有一個CMake版本,則可以使用它來構建其他版本的CMake。 一般來說,CMake的當前開發版本總是可以從以前的CMake版本開始構建。 這是在大多數Windows系統上如何構建新版本的CMake。
構建CMake的第二種方法是運行其構建腳本。你需要改變目錄到你的CMake源代碼目錄並輸入

./bootstrap
make
make install
  • 1
  • 2
  • 3

make install步驟是可選的,因爲CMake可以直接從build目錄運行。 在UNIX上,如果您不使用GNU C++編譯器,則需要告訴引導程序腳本使用哪個編譯器。 這是通過在運行引導之前設置環境變量cxx來完成的。 如果您需要在編譯器中使用任何特殊標誌,請設置CXXFLAGS環境變量。 例如,在帶有7.3X編譯器的SGI上,你可以這樣編譯CMake:

cd CMake 
(setenv CXX CC; setenv CXXFLAGS "-LANG:std";./bootstrap) 
make 
make install
  • 1
  • 2
  • 3
  • 4

2.3 基本CMake用法和語法

使用CMake很簡單。 構建過程是通過創建一個或多個CMakeLists文件(實際上是CMakeLists.txt,但本指南將在大多數情況下脫離擴展)控制在項目的每個目錄中。 CMakeLists文件應該包含CMake簡單語言的項目描述。 語言表達爲一系列命令。 每個命令按照它在CMakeLists文件中出現的順序進行評估。 這些命令的形式

command (args ... ) 
  • 1

其中command是命令,args是由空格分隔的參數列表。 (帶有嵌入式空格的參數應該用雙引號。)從版本2.2開始,CMake對命令名不區分大小寫。所以在你看到命令的地方你可以使用COMMAND或者Command。較早版本的CMake只接受大寫命令。

CMake支持可以是字符串或字符串列表的簡單變量。變量是使用$ {VAR}語法引用的。可以使用set命令將多個參數組合到一個列表中。所有其他命令展開列表,就好像它們已經通過空白分隔傳遞到命令一樣。例如,set(Foo a b c)將導致將變量Foo設置爲abc,並且如果將Foo傳遞給另一個命令command($ {Foo}),它將等同於命令(a b c)。如果你想把一個參數列表傳遞給一個命令,就好像它是一個參數一樣,只需雙引號即可。例如oomrnand(”$ {Foo}”)將被調用,只傳遞一個相當於command(”a b c”)的參數。

系統環境變量和Windows註冊表值可以直接在CMake中訪問。要訪問系統環境變量,使用語法$ ENV {VAR}。 CMake還可以使用[HKEY_CURRENT_USER\\ Software \\ pathl \\ path2; key]形式的語法在許多命令中引用註冊表項,其中路徑是從註冊表樹和鍵構建的。

2.4 CMake的Hello World

對於初學者,讓我們考慮最簡單的CMakeLists文件。 要從一個源文件編譯一個可執行文件,CMakeLists文件將包含兩行:

project(Hello)
add executable(Hello Hello.c)
  • 1
  • 2

要構建Hello這個可執行文件,請遵循如何運行CMake(參見第2.5節)中描述的過程來生成Makefiles或Microsoft項目文件。 project命令指示生成的工作區的名稱應該是什麼,add_executable命令將可執行目標添加到生成過程。 這就是這個簡單的例子。 如果您的項目需要幾個文件,這也很容易,只需修改添加可執行文件行,如下所示。

    add executable (Hello Hello.c File2.c File3.c File4.c)
  • 1

add_executable只是CMake中的衆多命令之一。 考慮下面更復雜的例子。

cmake_minimum_required (2.6) 
project (HELLO) 

set (HELLO_SRCS Hello.c File2.c File3.c) 

if (WIN32) 
    set (HELLO_SRCS ${HELLO_SRCS} WinSupport.c) 
else ()     
    set (HELLO_SRCS ${HELLO_SRCS} UnixSupport.c) 
endif () 

add_executable (Hello ${HELLO_SRCS}) 

# look for the Tcl library
find_library(TCL_LIBRARY
    NAMES tcl tc184 tc183 tc182 tc180 
    PATHS /usr/lib /usr/local/lib 
    ) 
if (TCL_LIBRARY) 
    target linklibrary (Hello $ {TCL_LIBRARY}) 
endif ()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

在這個例子中,set命令用於將源文件分組到一個列表中。 if命令用於判斷是否將WinSupport.c或UnixSupport.c添加到此列表中。 最後,add_executable命令用於使用變量HELLO_SRCS中列出的文件構建可執行文件。 find_library命令以幾個不同的名字和幾個不同的路徑查找Tcl庫。 if命令檢查TCL_LIBRARY是否被找到,是否將其添加到Hello可執行目標的鏈接行。 請注意使用#字符表示註釋行。 從#到行尾的所有字符都被認爲是一部分註釋。

2.5 如何運行CMake?

一旦CMake安裝在您的系統上,使用它來建立一個項目很容易。 CMake在構建項目時使用了兩個主目錄:源目錄和二進制目錄。 源目錄是您的項目的源代碼所在的位置。 這也是CMakeLists文件被找到的地方。 二進制目錄是你希望CMake放置生成的目標文件,庫和可執行文件的位置。 通常CMake不會將任何文件寫入源目錄,只有二進制目錄。 如果你想要你可以設置源和二進制目錄是一樣的。 這被稱爲源代碼內部構建,而不同於它的是不同的外部構建。

CMake支持所有操作系統上的源碼內部和源碼外部構建。 這意味着您可以完全地在源代碼樹之外配置你的構建,這樣可以非常容易地刪除構建生成的所有文件。 讓構建樹不同於源代碼樹也使得對於單個源代碼樹進行多個構建變得容易。 當你想要有不同的選項,但只有一個源代碼的副本,這是很有用的。 現在讓我們考慮使用基於Qt的GUI和命令行界面來運行CMake的細節。

運行CMake的Qt界面

CMake包含一個由Clinton Stimpson開發的基於Qt的用戶界面,可以在大多數平臺上使用,包括UNIX,Mac OS X和Windows。 這個接口包含在CMake源代碼中,但是你需要在你的系統上安裝Qt來構建它。

這裏寫圖片描述
Figure 1 - Qt based CMake GUI

在Windows上,可執行文件被命名爲cmake-gui.exe,並且應該位於 開始菜單中的Program Files下 。 在你的桌面上也可能有一個快捷方式,或者如果你從源代碼構建CMake,它將在build目錄中。 對於UNIX和Mac用戶,可執行文件被命名爲cmake-gui,可以在安裝CMake可執行文件的位置找到。可以看到類似於圖1所示的GUI。前兩個條目是源代碼和二進制目錄。 它們允許您指定源代碼的位置,以及要生成的二進制文件的位置。 你應該先設置這兩個值。 如果您指定的二進制目錄不存在,它將爲您創建。 如果二進制目錄已經被CMake配置,那麼它會自動設置源碼樹。

中間區域是你可以爲構建過程指定不同選項的位置。更高級的變量可能被隱藏,但是如果從視圖下拉菜單中選擇“Advanced View”,則可以看到這些變量。您可以通過在搜索框中輸入全部或部分名稱來搜索中間區域的值。這可以方便地找到大型項目中的特定設置或選項。窗口的底部區域包括“配置”和“生成”按鈕以及進度條和可滾動輸出窗口。

一旦你指定了源代碼和二進制目錄,你應該點擊配置按鈕。這將導致CMake從源代碼目錄中讀取CMakeLists文件,然後更新緩存區域以顯示項目的任何新選項。如果你是這個二進制文件目錄上首次運行cmake,它會提示你確定你想要使用什麼生成器, 如圖2所示。這個對話框也會顯示選項,用來定製和調整這次構建你想使用的編譯器 。

這裏寫圖片描述
Figure 2 - Selecting a Generator

第一次配置後,您可以根據需要調整緩存設置,然後再次單擊配置按鈕。 由配置過程創建的新值將被標記爲紅色。 爲了確保你已經看到了所有可能的值,你應該點擊配置,直到沒有值是紅色的,並且你對所有的設置感到滿意。 一旦你完成配置,點擊生成按鈕,這將生成合適的文件。

確保你的環境適合運行cmake-gui是非常重要的。如果您使用的是Visual Studio等IDE,那麼你的環境將設置正確。如果您正在使用NMake或MinGW,那麼您需要確保編譯器可以從你的環境運行。您可以直接爲您的編譯器設置所需的環境變量,也可以使用已經設置好的shell。例如,Microsoft Visual Studio在開始菜單上有一個用於創建Visual Studio命令提示符的選項。這將打開一個命令提示符窗口,其中已經爲Visual Studio設置了其環境。如果你想使用NMake Makefiles,你應該從這個命令提示符運行cmake-gui。同樣的方法適用於MinGW,你應該從MinGW shell中運行cmake-gui,在它的路徑中有一個工作的編譯器。

當cmake-gui完成時,它將在您指定的二進制目錄中生成構建文件。如果選擇Visual Studio作爲生成器,則創建一個MSVC工作區(或解決方案)文件。這個文件的名字是基於你在CMakeLists文件開頭的PROJECT命令中指定的項目的名字。對於許多其他生成器類型,生成Makefile文件。此過程的下一步是使用MSVC打開工作區。一旦打開,該項目就可以以Microsoft Visual C ++的正常方式構建。 ALL BUILD目標可用於構建包中的所有庫和可執行文件。如果您正在使用Makefile構建類型,則可以通過對生成的Makefiles運行make或nmake來構建。

運行cmake Curses界面

在大多數UNIX平臺上,如果支持curses庫,CMake提供一個名爲ccmake的可執行文件。 這個接口是一個基於終端的文本應用程序,非常類似於基於Qt的GUI。 要運行ccmake,將目錄(cd)更改爲要放置二進制文件的目錄。 這可以是我們所說的源代碼構建的源代碼相同的目錄,也可以是您創建的新目錄。 然後運行ccmake,在命令行中輸入源目錄的路徑。 對於源代碼內部使用“.” 爲源目錄。 這將啓動文本界面,如圖3所示(在這種情況下,緩存變量來自VTK,大多數都是自動設置的)。

這裏寫圖片描述
Figure 3 - ccmake running on UNIX

窗口底部顯示簡要說明。 如果你點擊“c”鍵,它將配置項目,你應該總是在更改緩存中的值之後進行配置,要改變值,使用箭頭鍵選擇緩存條目,然後使用回車鍵來編輯它們。 值會隨着回車鍵一起切換,一旦你設定了所有的值,你可以點擊“g”鍵來生成Makefile並退出,也可以點擊“h”來獲得幫助,“q”退出 ,“t”切換查看高級緩存條目。 在UNIX平臺上的CMake使用的兩個例子遵循一個名爲Hello的helloworld項目。 在第一個示例中,執行源碼內部構建。

cd Hello 
ccmake 
make 
  • 1
  • 2
  • 3

在第二個示例中,執行源碼外部構建。

mkdir Hello-Linux 
cd Hello-Linux 
ccmake .. /Hello 
make 
  • 1
  • 2
  • 3
  • 4

從命令行運行CMake

在命令行中,CMake可以作爲交互式問答模式運行,也可以作爲非交互式程序運行。 要以交互模式運行,只需將“-i”選項傳遞給CMake。 這將導致CMake向您要求項目緩存文件中的每個條目的值。 CMake將提供合理的默認值,就像基於GUl和curses的接口一樣。 當不再有任何問題要求時,該過程停止。 下面提供了一個使用CMake交互模式的例子。

$ cmake -i -G "NMake Makefiles" .. /CMake 
Would you like to see advanced options? [No]: 
Please wait while cmake processes CMakeLists.txt files .... 

Variable Name: BUILD TESTING 
Description: Build the testing tree. 
Current Value: ON 
New Value (Enter to keep current value): 

Variable Name: CMAKE INSTALL PREFIX 
Description: Install path prefix, prepended onto install directories. 
Current Value: C:/Program Files/CMake 
New Value (Enter to keep current value):

Please wait while cmake processes CMakeLists.txt files .... 

CMake complete, run make to build project.
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

如果項目有很少或沒有選項,使用CMake在非交互模式下建立一個項目是一個簡單的過程。 對於像VTK這樣的大型項目,推薦使用ccmake,cmake-i或者cmake-gui。 要使用非交互式CMake構建項目,請首先將目錄更改爲要放置二進制文件的位置。 對於源碼內部構建,然後運行cmake。 並使用-D標誌傳入任何選項。 對於源碼外部構建,除了運行cmake,還提供源代碼的路徑作爲參數,這個過程是一樣的。 然後鍵入make,你的項目應該編譯。 有些項目也會有安裝目標,你可以輸入make install來安裝它們。

爲CMake指定編譯器

在某些系統上,可能有多個編譯器可供選擇,或者編譯器可能處於非標準位置。 在這些情況下,您將需要指定到您的編譯器所在的位置 。 有三種方法來指定位置; 生成器可以指定編譯器,可以設置環境變量,也可以設置緩存條目。 一些生成器綁定了特定的編譯器,例如Visual Studio 6生成器始終使用Microsoft Visual Studio 6編譯器。 對於基於Makefile的生成器,CMake會嘗試一個通常的編譯器列表,直到找到一個可用的編譯器。 該列表可以在文件中找到:

Modules/CMakeDeterminCCompiler.cmake and
Modules/CMakeDetermineCXXCompiler.cmake
  • 1
  • 2

這些列表可以通過 CMake運行之前設置的環境變量來搶佔。 CC環境變量指定C編譯器,而cxx環境變量指定C ++編譯器。 您可以通過使用DCMAKE_CXX_COMPILER = cl直接在命令行上指定編譯器。 如果沒有設置,CMake會嘗試下面的編譯器列表:

c++ g++ CC aCC cl bcc xlC.
  • 1

一旦CMake運行並選擇了一個編譯器,您可以通過更改緩存條目CMAKE_CXX_COMPILER和CMAKE_C_COMPILER來更改選擇,但是不建議這樣做。 這樣做的問題是您正在配置的項目可能已經在編譯器上運行了一些測試,並且已經確定了它支持什麼。 更改編譯器通常不會導致這些測試重新運行,從而導致錯誤的結果。 如果您必須更改編譯器,請從空的二進制目錄開始。 編譯器和鏈接器的標誌也可以通過設置環境變量來改變。 設置LDFLAGS將初始化鏈接標誌的緩存值,而CXXFLAGS和CFLAGS將分別初始化CMAKE _ CXX_FLAGS和CMAKE_C_FLAGS。

依賴性分析

CMake爲C和C++源代碼文件提供了強大的內置依賴分析功能。 CMake對Fortran和Java依賴的支持也有限。由於集成開發環境(IDE)支持和維護依賴信息,所以CMake跳過這個構建系統的步驟。但是,Makefile中有一個make程序不知道如何自動計算並保持最新的依賴信息。對於這些構建,CMake會自動計算C,C++和Fortran文件的依賴信息。這些依賴關係的生成和維護都是由CMake自動完成的。一旦項目最初由CMake配置,用戶只需要運行make,CMake就可以完成其餘的工作。 CMake的依賴完全支持多處理器系統的並行構建。

雖然用戶不需要知道CMake是如何工作的,但查看項目的依賴關係信息文件可能是有用的。每個目標的信息存儲在四個文件中,分別叫depend.make,flags.make,build.make和DependInfo.emake。depend.make使所有目標文件的依賴信息存儲在目錄中。 flags .make包含用於此目標的源文件的編譯flags。如果他們改變,那麼文件將被重新編譯。 DependInfo.emake用來保持最新的依賴信息,並且包含關於什麼文件是項目的一部分以及它們在哪些語言中的信息。最後,構建依賴關係的規則被存儲在build.make中 。如果依賴關係已經過期,那麼將重新計算該目標的所有依賴關係,從而使依賴關係信息保持最新。

2.6 編輯CMakeLists文件

CMakeLists文件幾乎可以在任何文本編輯器中編輯。一些編輯器(如Notepad ++)帶有內置的CMake語法突出顯示和縮進支持。對於像Emacs或Vim CMake這樣的編輯器,包括縮進和語法突出顯示模式。這些可以在源代碼分發的Docs目錄中找到,或者從CMake網站下載。文件cmake-mode.el是Emacs模式,cmake-indent.vim和cmakesyntax.vim被Vim使用。在Visual Studio中,CMakeLists文件被列爲項目的一部分,您可以通過雙擊來編輯它們。在任何支持的生成器(Makefiles,Visual Studio等)中,如果編輯CMakeLists文件並重建,則會有一些規則自動調用CMake來根據需要更新生成的文件(例如Makefile或項目文件)。這有助於確保生成的文件始終與您的CMakeLists文件同步。

由於CMake計算並維護依賴關係信息,所以在CMake上make或者運行IDE 生成文件時,CMake可執行文件必須始終可用(儘管它們不必在PATH中)。這意味着如果一個CMake輸入文件在磁盤上發生變化,您的編譯系統將自動重新運行CMake並生成最新的編譯文件。出於這個原因,您通常不應該使用CMake生成Makefile或項目,並將它們移動到沒有安裝CMake的另一臺機器上。

2.7 設置CMake的初始值

雖然CMake在交互模式下運行良好,但有時您需要設置緩存條目而不運行GUI。 這在設置每晚儀表板時很常見,或者您將創建許多具有相同緩存值的構建樹。 在這些情況下,CMake緩存可以通過兩種不同的方式進行初始化。 第一種方法是使用DCACHE _ VAR:TYPE = VALUE參數在CMake命令行上傳遞緩存值。 例如,考慮一下UNIX機器的夜間儀表板腳本:

#!/bin/tcsh 

cd ${HOME} 

# wipe out the old binary tree and then create it again 
rm -rf Foo-Linux 
mkdir Foo-Linux
cd Foo-Linux 

# run cmake to setup the cache 
cmake -DBUILD TESTING:BOOL=ON <etc ... > .. /Foo

# generate the dashboard 
ctest -0 Nightly 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

Windows上的批處理文件可以使用相同的想法。 第二種方法是使用CMake的-c選項創建一個要加載的文件。 在這種情況下,而不是使用-D選項來設置緩存,而是通過由CMake解析的文件來完成。 這個文件的語法是標準的CMakeLists語法,通常只是一系列的設置命令,例如:

#Build the vtkHybrid kit. 
set (VTK USE HYBRID ON CACHE BOOL "doc string")
  • 1
  • 2

在某些情況下,可能會有已經存在的緩存,並且您想要強制設置緩存值。 例如,即使用戶以前運行CMake並將其關閉,你也想要打開Hybrid。 那你可以這樣做:

#Build the vtkHybrid kit always. 
set (VTK USE HYBRID ON CACHE BOOL "doc" FORCE)
  • 1
  • 2

另一個選擇是你想設置並且之後隱藏這些選項,以便用戶以後不會再調整。 這可以使用以下命令完成:

#Build the vtkHybrid kit always and don't distract 
#the user by showing the option. 
set (VTK USE HYBRID ON CACHE INTERNAL "doc" FORCE) 
mark as advanced (VTK USE HYBRID)
  • 1
  • 2
  • 3
  • 4

您可能會試圖直接編輯緩存文件,或者通過給項目初始化緩存文件來“初始化”項目。 這可能不起作用,並可能在未來導致更多的問題。 首先,CMake緩存的語法可能會改變。 其次,緩存文件中有完整的路徑,使得它們不適合在二叉樹之間移動。 所以如果你想初始化一個緩存文件,可以使用上面描述的兩種標準方法之一。

2.8 建設你的項目

運行CMake後,您的項目將準備好建立。 如果您的目標生成器基於Makefiles,那麼您可以通過將目錄更改爲二叉樹並鍵入make(或適當的gmake或nmake)來構建項目。 如果爲Visual Studio等IDE生成文件,則可以啓動IDE,將項目文件加載到該文件中,然後像平常一樣進行構建。

另一個選擇是從命令行使用CMake的-build選項。 這個選項只是一個簡單的方法,允許你從命令行建立你的項目,即使這需要啓動一個IDE。 -build選項包括:

Usage: cmake --build <dir> [options] [-- [native-options]] Options: 
<dir>           = Project binary directory to be built.
--target <tgt>  = Build <tgt> instead of default targets. 
--config <cfg>  = For multi-configuration tools, choose <cfg>.
--clean-first   = Build target 'clean' first, then build. 
                  (To clean only, use --target 'clean'.) 
--              = Pass remaining options to the native tool.
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

因此,即使您使用Visual Studio作爲您的生成器,如果您願意,也可以通過命令行鍵入以下內容來構建您的項目。

cmake --build <your binary dir>
  • 1

這就是爲簡單的項目安裝和運行CMake。 在下面的章節中,我們將更加詳細地考慮CMake,以及如何在更復雜的軟件項目中使用它。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章