2011-05-30 106 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的一个新的图书馆是要建立和从源源文件建立。

相关问题