CMake файл (GLOB_RECURSE), чтобы найти один файл на каталог? - PullRequest
0 голосов
/ 06 июня 2019

Я бы хотел пройтись по дереву и получить список максимум из одного файла из каждого каталога. Единственным критерием для выбранных файлов является то, что они соответствуют глобу или шаблону, например "*.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_RECURSE и find_file не подходят для этой задачи, поэтому есть другой подход, который я должен рассмотреть?

Ответы [ 3 ]

1 голос
/ 16 июня 2019

Список, возвращаемый 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.

1 голос
/ 17 июня 2019

Я не уверен, но вы можете создать исполняемый файл для поиска в каталогах командой

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

как в этом примере

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

и вы можете сохранить этот результат в новом файле и включить этот файл, если вам нужна дальнейшая разработка

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

1 голос
/ 11 июня 2019
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()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...