【问题标题】:source_group CMake command isn't workingsource_group CMake 命令不起作用
【发布时间】:2015-07-27 11:46:21
【问题描述】:

我不理解 CMakeLists.txt 中的 source_group 命令。 当我这样做时,它会起作用:

file(GLOB INPUT_HEAD    KeyBoard.h Mouse.h)
source_group("Header Files\\Input" FILES ${INPUT_HEAD})

但这不起作用:

file(GLOB SHADERS ../Shaders/*.txt)
source_group("Source Files\\Shaders" FILES ${SHADERS})

关于如何解决这个问题的任何建议? (我已经阅读了这个命令的文档,我不明白为什么这个不起作用)

【问题讨论】:

    标签: cmake


    【解决方案1】:

    您需要在实际目标中使用这些文件。例如,它们必须在add_libraryadd_executable 语句中使用,然后它们将位于该项目的文件夹中。另外,我使用 ''/'' 而不是 \\ 作为分隔符。您可能还想使用set_property(GLOBAL PROPERTY USE_FOLDERS ON) 将预定义的 cmake 项目放入他们自己的解决方案文件夹中。

    【讨论】:

    • 啊.. 但是着色器文件既不是库也不是可执行文件。我应该如何继续将这些文件包含在 Visual Studio 项目中?我应该让它们保持原样并强制用户在单独的文本编辑器中打开它们吗?
    • 只要它们没有使 Visual Studio 尝试构建它们的扩展名,我就会尝试将所有文​​件包含在一个目标中,因为我喜欢在使用来源。我只是把它们放在一个单独的文件夹中。我没有遇到扩展名冲突的问题,但如果你这样做,我认为应该有一些 source property 可以设置(符号或语言)以防止文件被 VS 解释。
    • 除非它是一个错误,否则在 source_group 调用中,“/”斜杠的行为与“\\”不同,至少在 Visual Studio 中是这样。使用“/”会生成一个名为“top/middle/bottom”的顶级过滤器,而“\\”会给出“top”,其中包含“middle”,其中包含“bottom”。
    【解决方案2】:

    自 CMake 3.8 以来有一个新命令可以根据相对于特定路径的文件夹结构自动过滤文件。

    这是一个小例子,其中 SRC_BUILD_FILES 是一个包含您要过滤的所有文件的集合。过滤相对于某个基本路径发生,在此示例中使用 CMAKE_CURRENT_SOURCE_DIR 设置,但它可以是任何文件夹。 PREFIX 名称(此处为:Implementation)可以根据您的喜好设置,并将包含过滤后的集合。

        source_group(TREE "${CMAKE_CURRENT_SOURCE_DIR}"
             PREFIX "Implementation"
             FILES ${SRC_BUILD_FILES})
    

    因此无需在 cmake 脚本中通配或手动重新迭代文件夹名称。

    【讨论】:

      【解决方案3】:

      在现代 CMake 中,您主要使用目标,以下函数可能有用:

      function (target_source_group)
        set (_options
          GROUP_INTERFACE_SOURCES
          )
        set (_multi_value_args
          # Required
          TARGET
          ROOT_DIR
          )
        set (_one_value_args
          PREFIX
          )
      
        cmake_parse_arguments (i
          "${_options}" "${_one_value_args}" "${_multi_value_args}" ${ARGN})
      
        # Check inputs
      
        foreach (_target IN LISTS i_TARGET)
          if (i_GROUP_INTERFACE_SOURCES)
            get_target_property (_target_sources ${_target} INTERFACE_SOURCES)
          else ()
            get_target_property (_target_sources ${_target} SOURCES)
          endif ()
      
          # Remove sources to be installed
          set (_source_to_install_regex
            "(\\$<INSTALL_INTERFACE:([^>;<$]+)>)")
      
          string (REGEX REPLACE
            "${_source_to_install_regex}"
            ""
            _sources_to_build
            "${_target_sources}")
      
          # Remove remaining ";"s. It seems safer to do it this way rather than include
          # them in _source_to_install_regex
          string (REGEX REPLACE
            "[;]+"
            ";"
            _sources_to_build
            "${_sources_to_build}")
      
          # Extract sources to be built
          set (_source_to_build_regex
            "\\$<BUILD_INTERFACE:([^>;<$]+)>")
      
          string (REGEX REPLACE
            "${_source_to_build_regex}"
            "\\1"
            _sources_to_build
            "${_sources_to_build}")
      
          foreach (_root IN LISTS i_ROOT_DIR)
            set (_sources_under_root_regex
              "${_root}/[^>;<$]+")
      
            string (REGEX MATCHALL
              "${_sources_under_root_regex}"
              _sources_under_root
              "${_sources_to_build}")
      
            source_group (
              TREE    "${_root}"
              FILES   ${_sources_under_root}
              PREFIX  "${i_PREFIX}"
              )
          endforeach ()
        endforeach ()
      endfunction (target_source_group)
      

      【讨论】:

      • 只是想知道。 string(GENEX_STRIP &lt;string&gt; &lt;output_variable&gt;) 可以替换那些正则表达式吗?
      猜你喜欢
      • 2019-05-26
      • 1970-01-01
      • 2017-01-22
      • 1970-01-01
      • 1970-01-01
      • 2013-06-26
      • 1970-01-01
      • 2014-09-28
      • 1970-01-01
      相关资源
      最近更新 更多