CMake文件(GLOB_RECURSE)在每个目录中查找一个文件?

时间:2019-06-06 14:06:19

标签: cmake

我想走一棵树,最后得到一个列表,其中每个目录最多包含一个文件。所选文件的唯一条件是它们与glob /模式匹配,例如“ *.txt”。

如果还不是隐式的,我需要算法来返回稳定的结果。

例如给定一棵看起来像这样的树:

a/some/entry/foo.html
a/some/entry/foo.txt
a/some/entry/bar.txt
a/some/entry/baz.txt
a/some/entry/baz.bmp
a/some/boo.bat
a/some/boo.txt
a/some/bat.txt
a/other/path/far.txt
a/other/path/faz.txt

一个可以接受的结果是:

"a/some/entry/bar.txt a/other/path/far.txt a/some/boo.txt"

GLOB_RECURSEfind_file似乎不适合执行此任务,所以我应该考虑另一种方法吗?

3 个答案:

答案 0 :(得分:1)

SET(resultfilelist "")
FILE(GLOB_RECURSE children LIST_DIRECTORIES true "${CMAKE_CURRENT_SOURCE_DIR}/a/*")
FOREACH(child ${children})
    IF(IS_DIRECTORY ${child})
      #message("Processing ${child}")
      FILE(GLOB txtfiles LIST_DIRECTORIES false ${child}/*.txt)
      list(LENGTH txtfiles txtfilessize)
      IF(${txtfilessize} GREATER 0)
        list(GET txtfiles 0 txtfilesfirst)
        #message("Text file is  ${txtfilesfirst}")
        LIST(APPEND resultfilelist ${txtfilesfirst})
      ENDIF()
    ENDIF()
ENDFOREACH()

FOREACH(child ${resultfilelist})
 message("Text file is  ${child}")
ENDFOREACH()

答案 1 :(得分:1)

file (GLOB_RECURSE ...返回的列表是所需结果的超集。因此,一种可能的解决方案是仅选择每个目录返回的第一个匹配项来对返回的列表进行后期处理。

以下CMake函数概述了必要的步骤:

function (glob_recurse_first _globbingExpression _resultVar)
    file (GLOB_RECURSE _pathList "${_globbingExpression}")
    # canonical order
    list (SORT _pathList)
    # filter first match from each directory
    set (_firstMatched "")
    set (_latestDir "//")
    foreach (_path IN LISTS _pathList)
        get_filename_component(_dir "${_path}" DIRECTORY)
        if (NOT "${_dir}" STREQUAL "${_latestDir}")
            list (APPEND _firstMatched "${_path}")
            set (_latestDir "${_dir}")
        endif()
    endforeach()
    set (${_resultVar} ${_firstMatched} PARENT_SCOPE)
endfunction()

该功能可以通过以下方式使用:

glob_recurse_first("a/*.txt" _fileList)
foreach (_file ${_fileList})
    message (STATUS "${_file}")
endforeach()

遍历表达式"a/*.txt"将保留目录.txt中带有扩展名a的所有文件及其所有子目录。

结果变量_fileList包含绝对路径,a中每个子目录都有一个文件。

答案 2 :(得分:1)

我不确定,但是您可以创建一个可执行文件来通过命令搜索目录

$ grep -R version | awk -F: '/CMake.*:/ {print $1}'

像这个例子

https://unix.stackexchange.com/a/105342

,您可以将结果保存到新文件中,如果需要进一步开发,可以包含此文件

https://stackoverflow.com/a/17655165/914284