【问题标题】:Can someone explain this cmake script to me?有人可以向我解释这个 cmake 脚本吗?
【发布时间】:2011-05-30 06:35:01
【问题描述】:

我觉得整个 cmake 社区都在欺骗我。 “教程”或资源对我来说没有任何意义。就像我错过了什么。我认为最让我困惑的是语言,而且我所见过的教程中没有一个能像向几乎没有 unix 和 make 经验的人解释 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 firebreath


    【解决方案1】:

    首先,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
    

    以 # 开头的行是 cmets。

    SET_SOURCE_FILES_PROPERTIES(
           ${GENERATED}
           PROPERTIES
               GENERATED 1
           )
    

    文件可以有与之关联的键/值对,这会影响它们的构建方式。这里变量${GENERATED} 中列出的文件将属性“GENERATED”设置为值1。这是什么意思?好吧,CMake 现在知道不要在磁盘上查找文件“${GENERATED}”,因为它们将在另一个构建步骤中创建。在发布的 sn-p 中,没有人设置变量 ${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})
    

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

    【讨论】:

    • 谢谢!我希望我能给你一个以上的赞成票。这是一个巨大的帮助。
    【解决方案2】:

    有时,我能理解您对 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}
        )
    

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

    在正常情况下,我希望 add_library 调用: add_library(${PLUGIN_NAME} {SOURCES})

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

    【讨论】:

      猜你喜欢
      • 2014-10-13
      • 1970-01-01
      • 2017-09-02
      • 1970-01-01
      • 2011-07-14
      • 2010-10-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多