有人可以向我解释这个cmake脚本吗?

时间:2011-05-30 06:35:02

标签: cmake firebreath

我觉得整个cmake社区都在拖着我。没有任何“教程”或资源对我有意义。就像我错过了一些东西。我觉得最让我感到困惑的是语言,我所看到的任何一个教程都没有给那些没有unix和体验经验的人解释cmake。“/ p>

无论如何,我正在使用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}

2 个答案:

答案 0 :(得分: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”的文件选项卡,其中包含变量${GENERATED}中的文件。

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

此行将变量SOURCES设置为变量${GENERAL}${GENERATED}中的任何变量。之前我们将${GENERAL}设置为当前源目录中的cpp,h和cmake文件列表。在类似C的伪代码中,这就像“SOURCES = GENERAL + GENERATED”。作为实现的细节,值SOURCES实际上是一个列表,其内容由“;”分隔。字符。通常这样做是为了以后您可以通过使用变量${SOURCES}创建库或可执行文件,而不是在任何地方重复其他2个变量。

答案 1 :(得分: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所在的目录)并收集ALL * .cpp,* .h和* .cmake文件。结果是文件路径的设置/列表,相对于当前源目录的resepct,存储在变量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命令,它们获得“generated”属性,这是CMake执行正确的依赖性检查所需的。

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

所以现在我们有一组来自文件(GLOB ...)调用的源文件,存储在变量GENERAL中。我们有一组存储在变量GENERATED中的soruce文件,这些文件是在其他地方创建的。这两个集合组合成一个源文件列表并存储在变量SOURCES中。

在正常情况下我会期待一个add_library调用:     add_library($ {PLUGIN_NAME} {SOURCES})

这指定Cmake要从SOURCES中的源文件创建和构建新库。