2011-05-30 110 views
8

我覺得整個cmake社區都在拖我。 「教程」或資源對我來說都沒有任何意義。它就像我錯過了一些東西。我認爲最讓我困惑的是語言,我看到的所有教程都沒有像解釋cmake那樣接近於體面地向那些沒有unix並且有經驗的人解釋cmake。有人可以向我解釋這個cmake腳本嗎?

無論如何,我正在使用FireBreath,它廣泛地使用cmake,我想它是我開始計算如何使用它而不是直接更改項目文件的時間。

根的CMakeLists.txt文件包含以下內容:

cmake_minimum_required (VERSION 2.6) 
set (CMAKE_BACKWARDS_COMPATIBILITY 2.6) 

Project(${PLUGIN_NAME}) 

file (GLOB GENERAL RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} 
    [^.]*.cpp 
    [^.]*.h 
    [^.]*.cmake 
    ) 

include_directories(${PLUGIN_INCLUDE_DIRS}) 

# Generated files are stored in ${GENERATED} by the project configuration 
SET_SOURCE_FILES_PROPERTIES(
    ${GENERATED} 
    PROPERTIES 
     GENERATED 1 
    ) 

SOURCE_GROUP(Generated FILES 
    ${GENERATED} 
    ) 

SET(SOURCES 
    ${GENERAL} 
    ${GENERATED} 
    ) 

我真的欣賞,如果有人能解釋每行給我。尤其是${GENERAL}${GENERATED}是。

回答

19

首先,cmake語法非常簡單。它由「命令」和「參數」組成。它很簡單,它需要一段時間才能沉入其中。一切都是「命令(參數)」。此外,命令名稱不區分大小寫。以前,他們必須是全部大寫,但從2.6版(我認爲)並不重要。但是參數區分大小寫。

cmake_minimum_required (VERSION 2.6) 

該命令爲項目設置cmake所需的最低版本。如果當前版本的cmake低於2.6,它將停止處理並報告錯誤。這可以防止支持古代版本的工具。

set (CMAKE_BACKWARDS_COMPATIBILITY 2.6) 

將變量CMAKE_BACKWARDS_COMPATIBILITY設置爲值2.6。這實際上是您提交的CMakeLists.txt文件中的一個小錯誤,因爲CMAKE_BACKWARDS_COMPATIBILITY不應該用於2.6及更高版本。該腳本應該可能使用cmake_policy。這是爲了指定cmake的新版本在面對cmake以前版本中的不一致時應該如何表現。您今天從頭開始編寫的任何腳本都不需要擔心這一點。

Project(${PLUGIN_NAME}) 

將項目名稱設置爲變量PLUGIN_NAME中的值。該值在某些IDE中顯示爲項目名稱。要將值寫入變量,可以使用set(PLUGIN_NAME myName)並讀取使用${}語法的值:"${PLUGIN_NAME}"。某些命令也會寫入變量,但您可以按照與set命令相同的方式使用它們。

file (GLOB GENERAL RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} 
    [^.]*.cpp 
    [^.]*.h 
    [^.]*.cmake 
    ) 

file是一個命令。它的第一個參數GLOB的意思是「返回磁盤上的名稱與我將作爲參數給出的模式匹配的文件」。下一個參數GENERAL是結果存儲的變量,與set一樣,它將結果寫入變量,您可以稍後使用${GENERAL}讀取結果。 RELATIVE和路徑意味着返回相對於該路徑的文件名稱,而不是完整的路徑。因此,而不是「C:\ some \ long \ path \ src \ foo.cpp」或「/home/me/some/path/src/foo.cpp」,您將得到「src \ foo.cpp」或「src/Foo.cpp中」。變量CMAKE_CURRENT_SOURCE_DIR是CMake爲你填充的「魔術變量」,它指向當前正在處理的源目錄的路徑,CMakeLists.txt文件所在的位置。參數的最後一個列表是將要匹配的文件的模式。基本上,任何文件擴展名爲cpp,h或cmake的文件。

include_directories(${PLUGIN_INCLUDE_DIRS}) 

${PLUGIN_INCLUDE_DIRS}中的目錄添加到編譯器搜索的包含文件的目錄中。例如,如果使用gcc進行編譯,這將導致額外的「-I」參數。

# Generated files are stored in ${GENERATED} by the project configuration 

以#開頭的行是註釋。

SET_SOURCE_FILES_PROPERTIES(
     ${GENERATED} 
     PROPERTIES 
      GENERATED 1 
     ) 

文件可以具有與它們關聯的鍵/值對,並且這會影響它們的構建方式。這裏變量${GENERATED}中列出的文件的屬性「GENERATED」設置爲值1.這是什麼意思?那麼,CMake現在知道不要在磁盤上查找文件「$ {GENERATED}」,因爲它們將在另一個構建步驟中創建。在發佈的代碼片段中,沒有人設置變量${GENERATED}。我想它會在項目文件的其他地方設置。不要混淆變量${GENERATED}與屬性GENERATED!這是一個微妙的點,也許變量應該是GENERATED_FILES以避免混淆,即SET_SOURCE_FILES_PROPERTIES(${GENERATED_FILES} PROPERTIES GENERATED 1)

SOURCE_GROUP(Generated FILES ${GENERATED}) 

這將創建一個組,在Visual Studio轉換成一個文件選項卡,名爲「生成」包含在變量${GENERATED}文件。

SET(SOURCES ${GENERAL} ${GENERATED}) 

該行設置的變量來源,無論是在變量${GENERAL}${GENERATED}。之前,我們將${GENERAL}設置爲當前源目錄中的cpp,h和cmake文件的列表。在類似C的僞代碼中,這就像「SOURCES = GENERAL + GENERATED」。作爲實現的細節,值SOURCES實際上是一個列表,其內容由「;」分隔字符。通常這是這樣做的,以便稍後您可以通過僅使用變量${SOURCES}創建庫或可執行文件,而不是隨處重複其他2個變量。

+0

謝謝!我希望我能給你一個以上的投票權。這是一個巨大的幫助。 – 2011-05-30 14:35:36

6

有時,我可以理解你對cmake教程的感受。我建議查看在線文檔和一些cmake項目:例如食人魔,Vtk,Kde。

從你看CMakeLists.txt看來,這個應該由外部CMake項目(帶有add_subdirectory)調用,因爲它引用了變量PLUGIN_NAME,PLUGIN_INCLUDE_DIRS和GENERATED。

回答您的問題:

cmake_minimum_required (VERSION 2.6) 
set (CMAKE_BACKWARDS_COMPATIBILITY 2.6) 
Project(${PLUGIN_NAME}) 

這是爲了準備您的cmakefile,告訴CMake的,它必須是2.6或更高版本,並且你開始一個名稱的項目作爲PLUGIN_NAME變量指定。

file (GLOB GENERAL RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} 
    [^.]*.cpp 
    [^.]*.h 
    [^.]*.cmake 
    ) 

這部分水珠通過電流源目錄(就是你的CMakeLists.txt是),所有收集*的.cpp,* h和* .cmake文件。結果是文件路徑的集合/列表,與當前源目錄相關並存儲在變量GENERAL中。

# Generated files are stored in ${GENERATED} by the project configuration 
SET_SOURCE_FILES_PROPERTIES(
    ${GENERATED} 
    PROPERTIES 
     GENERATED 1 
    ) 

SOURCE_GROUP(Generated FILES 
    ${GENERATED} 
    ) 

顯然,將有一組源文件存儲在變量GENERATED(因此不是GENERAL)中。如果是構建生成的源文件,這些文件不一定在CMake的第一個版本中,CMake需要知道這些文件是否生成。使用set_source_files_properties命令,他們得到「生成」屬性,這是CMake執行正確的依賴性檢查所需的。

SET(SOURCES 
    ${GENERAL} 
    ${GENERATED} 
    ) 

所以現在我們有一組來自文件(GLOB ...)調用的源文件,存儲在變量GENERAL中。我們有一組存儲在其他地方創建的變量GENERATED中的soruce文件。這兩組合併成一個源文件列表並存儲在變量SOURCES中。

在正常情況下我會期待一個add_library電話: add_library($ {PLUGIN_NAME} {來源})

這指定CMake的一個新的圖書館是要建立和從源源文件建立。

相關問題