从cmake源文件列表中删除文件结构中的某个目录

时间:2014-06-30 13:22:05

标签: cmake

在我的项目的任何子目录中,都可以创建一个名为“隐藏”的目录。并将一些代码文件(.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'文件),第2行可以正常工作。但如果有两个' *'它就不起作用。一个字符串。我找不到位于某处的目录的简单解决方案。

正则表达式

然后我尝试了REGEX。

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

因为源文件列表以分号分隔,所以上面的行应该将字符串从一个分号移到下一个分号,以防它包含字符串' hide'。 表达式似乎与分号有问题。任何分号都会使命令找不到任何内容。

foreach循环

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

3 个答案:

答案 0 :(得分:4)

我想,其中一种方式就是这样:

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(< 2.8.5,根据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

答案 1 :(得分: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)

答案 2 :(得分:0)

概括上面提到的功能解决方案,你会得到类似的东西:

# 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.*")