有人能给我解释一下这个cmake脚本吗?

有人能给我解释一下这个cmake脚本吗?,cmake,firebreath,Cmake,Firebreath,我觉得整个cmake社区都在欺骗我。这些“教程”或资源对我来说毫无意义。我好像错过了什么。我认为最让我困惑的是语言,而且我所看到的教程中没有一本能够很好地向几乎没有unix经验的人解释cmake 无论如何,我正在与FireBreath合作,它广泛地使用cmake,我认为是时候开始考虑如何使用它,而不是直接更改项目文件了 根CMakeLists.txt文件包含以下内容: cmake_minimum_required (VERSION 2.6) set (CMAKE_BACKWARDS_COMPAT

我觉得整个cmake社区都在欺骗我。这些“教程”或资源对我来说毫无意义。我好像错过了什么。我认为最让我困惑的是语言,而且我所看到的教程中没有一本能够很好地向几乎没有unix经验的人解释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}
是什么。

首先,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文件中的一个小错误,因为2.6及以上版本不应使用CMAKE_向后兼容。脚本可能应该使用
cmake\u策略
。这是为了指定较新版本的cmake在遇到以前版本的cmake中的不一致时应如何运行。今天,您从头开始编写的任何脚本都不需要担心这一点

Project(${PLUGIN_NAME})
将项目名称设置为变量
PLUGIN\u name
中的任意值。该值在某些IDE中显示为项目名称。要将值写入变量,可以使用
set(PLUGIN\u NAME myName)
,要读取值,可以使用
${}
语法:
“${PLUGIN\u NAME}”
。有些命令也会写入变量,但使用方法与
set
命令相同

file (GLOB GENERAL RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
     [^.]*.cpp
     [^.]*.h
     [^.]*.cmake
     )
文件
是一个命令。它的第一个参数
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\u INCLUDE\u DIRS}
中的目录添加到编译器搜索的INCLUDE文件中。例如,如果使用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}
与生成的属性混淆!这是一个微妙的点,可能变量应该是
生成的\u文件
以避免混淆,即
设置\u源文件\u属性(${GENERATED\u FILES}属性生成1)

这将创建一个组,该组在Visual Studio中转换为一个名为“Generated”的文件选项卡,其中包含变量
${Generated}
中的文件

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

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

有时,我可以理解您对cmake教程的感受。我建议看一下在线文档和一些cmake项目:例如Ogre、Vtk、Kde

从您的CMakeLists.txt的外观来看,这一个似乎应该由外部CMake项目(带有add_子目录)调用,因为它引用了变量PLUGIN_NAME、PLUGIN_INCLUDE_DIRS和GENERATED

回答您的问题:

cmake_minimum_required (VERSION 2.6)
set (CMAKE_BACKWARDS_COMPATIBILITY 2.6)
Project(${PLUGIN_NAME})
这将准备cmake文件,告诉cmake它必须是2.6版或更高版本,并且您正在使用PLUGIN_name变量中指定的名称启动项目

file (GLOB GENERAL RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
    [^.]*.cpp
    [^.]*.h
    [^.]*.cmake
    )
此部分通过当前源目录(cmakelists.txt所在的目录)进行全局搜索,并收集所有*.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 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}
    )