【问题标题】:Excluding directory somewhere in file structure from cmake sourcefile list从cmake源文件列表中排除文件结构中某处的目录
【发布时间】:2014-06-30 13:22:05
【问题描述】:

在我项目的任何子目录中,都可以在任何地方创建一个名为“hide”的目录,并在其中放置一些代码文件(.c、.cpp、.h、...)。 CMake 将忽略这些文件。我怎样才能做到这一点? 有什么简单方法的建议吗?网上搜了一圈没找到解决办法。

我尝试了什么:

文件和全局

file(GLOB_RECURSE SOURCE_FILES "*.cpp" "*.c")
file(GLOB_RECURSE REMOVE_SOURCES  
  "*/hide/*"
  "${PROJECT_SOURCE_DIR}/CMakeFiles/*"
  "*main.c")
file(GLOB_RECURSE REMOVE_SOURCES "*/hide/*")
list(REMOVE_ITEM SOURCE_FILES ${REMOVE_SOURCES})

如果目录路径已知(对于“CMakeFiles”目录)或文件已知(对于“main.c”文件),则第二行可以正常工作。但如果一个字符串有两个 '*' 则不起作用。对于位于某处的目录,我找不到简单的解决方案。

正则表达式

然后我尝试使用 REGEX。

file(GLOB_RECURSE SOURCE_FILES "*.cpp" "*.c")
string(REGEX REPLACE ";.*/hide/.*;" ";" FOO ${SOURCE_FILES})

因为源文件列表是用分号分隔的,如果上面的行包含字符串'hide',上面的行将把字符串从一个分号移到下一个分号。 该表达式的分号似乎有问题。有任何分号会使命令什么也找不到。

foreach 循环

我尝试了一些 foreach 循环,但无法获得所有“隐藏”目录的列表。

【问题讨论】:

  • 你的问题对我有帮助。

标签: cmake


【解决方案1】:

我想其中一种方法是这样的:

set (EXCLUDE_DIR "/hide/")
file (GLOB_RECURSE SOURCE_FILES "*.cpp" "*.c")
foreach (TMP_PATH ${SOURCE_FILES})
    string (FIND ${TMP_PATH} ${EXCLUDE_DIR} EXCLUDE_DIR_FOUND)
    if (NOT ${EXCLUDE_DIR_FOUND} EQUAL -1)
        list (REMOVE_ITEM SOURCE_FILES ${TMP_PATH})
    endif ()
endforeach(TMP_PATH)

只需在列表中的字符串中搜索/hide/ 子字符串。如果找到子字符串 --- 从列表中删除整个字符串。

请注意,这可能是唯一适用于 Linux 的解决方案。并且可能不适用于旧版本的 CMake(this)。

在上述情况下,您可以执行以下操作:

# try to replace substring with empty string, compare to original:
string (REPLACE ${EXCLUDE_DIR} "" REPLACED_PATH ${TMP_PATH})
string (COMPARE EQUAL ${TMP_PATH} ${REPLACED_PATH} EXCLUDE_DIR_FOUND)

注意:GLOB_RECURSE 被认为是万恶之源。

注意 2: 另一件需要注意的事情 - CMake bug in matching empty variable to string

NOTE3:考虑了gg99的评论

【讨论】:

  • 解决方案有两个问题:1) 行:foreach (TMP_PATH "${SOURCE_FILES}) 有一个 " 导致代码无法工作。2) if 语句不工作,因为 ${EXCLUDE_DIR_FOUND} 等于 -1 in如果找不到字符串,因此该语句始终为真。我只是想知道如何解决这个问题...
  • ...可能是来自 NOTE2 的错误。 (使用 CMake 版本 2.8.9)
  • @Led,不太确定 FIND 返回什么。根据你的观察修复了代码。
  • line list (REMOVE_ITEM ${SOURCE_FILES} ${TMP_PATH}) 实际上应该是:list (REMOVE_ITEM SOURCE_FILES ${TMP_PATH}),即 SOURCE_FILES 周围没有 ${}
【解决方案2】:

找到适合我的解决方案。添加了一个功能,可以轻松排除另一个目录。

# Function:                 EXCLUDE_FILES_FROM_DIR_IN_LIST
# Description:              Exclude all files from a list under a specific directory.
# Param _InFileList:        Input and returned List 
# Param _excludeDirName:    Name of the directory, which shall be ignored.
# Param _verbose:           Print the names of the files handled

FUNCTION (EXCLUDE_FILES_FROM_DIR_IN_LIST _InFileList _excludeDirName _verbose)
  foreach (ITR ${_InFileList})
    if ("${_verbose}")
      message(STATUS "ITR=${ITR}")
    endif ("${_verbose}")

    if ("${ITR}" MATCHES "(.*)${_excludeDirName}(.*)")                   # Check if the item matches the directory name in _excludeDirName
      message(STATUS "Remove Item from List:${ITR}")
      list (REMOVE_ITEM _InFileList ${ITR})                              # Remove the item from the list
    endif ("${ITR}" MATCHES "(.*)${_excludeDirName}(.*)")

  endforeach(ITR)
  set(SOURCE_FILES ${_InFileList} PARENT_SCOPE)                          # Return the SOURCE_FILES variable to the calling parent
ENDFUNCTION (EXCLUDE_FILES_FROM_DIR_IN_LIST)


EXCLUDE_FILES_FROM_DIR_IN_LIST("${SOURCE_FILES}" "/hide/" FALSE)

【讨论】:

    【解决方案3】:

    概括上面提到的函数解决方案,你会得到类似的结果:

    # Remove strings matching given regular expression from a list.
    # @param(in,out) aItems Reference of a list variable to filter.
    # @param aRegEx Value of regular expression to match.
    function (filter_items aItems aRegEx)
        # For each item in our list
        foreach (item ${${aItems}})
            # Check if our items matches our regular expression
            if ("${item}" MATCHES ${aRegEx})
                # Remove current item from our list
                list (REMOVE_ITEM ${aItems} ${item})
            endif ("${item}" MATCHES ${aRegEx})
        endforeach(item)
        # Provide output parameter
        set(${aItems} ${${aItems}} PARENT_SCOPE)
    endfunction (filter_items)
    

    你可以这样使用它:

    file(GLOB_RECURSE MyFunFiles "*.fun")
    filter_items(MyFunFiles ".*NotCool.*")
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-07-27
      • 2011-08-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-29
      • 2015-02-21
      • 2020-08-04
      相关资源
      最近更新 更多