как пройтись по каталогу и найти все файлы с определенным расширением - PullRequest
2 голосов
/ 28 января 2012

Мне нужно написать сборочный файл перед сборкой, который вызывается отдельно от основного файла сборки. Этот make-файл должен пройтись по каталогу, где он вызывается. В другом файле make под названием 'sources.mk' есть список каталогов с переменной, описывающей каталог:

SUBDIRS := \
. \
directory1 \
directory2 \

Теперь мне нужно запустить цикл по этому списку, и в этом цикле мне нужно вызвать утилиту, которая будет обрабатывать все файлы с расширением 'h'. Я написал это:

include Default/sources.mk

find_files:
    for prefix in $(SUBDIRS); do \
        for file in *.h; do \
            C:/QtSDK/Desktop/Qt/4.7.4/mingw/bin/moc.exe $$prefix/$$file; \
        done \
    done

Команда запуска: make -f premake.mk

Я не описываю ошибки, их много, я пробовал разные make-файлы, но я новичок в этом, и эти попытки потерпели неудачу. Пожалуйста, просмотрите мой код и / или предложите другие методы.

Ответы [ 2 ]

2 голосов
/ 28 января 2012

Ваша проблема, вероятно, заключается в следующем: вы ищете file в *.h в текущем каталоге, а не в подкаталоге. Попробуйте вместо этого:

for prefix in $(SUBDIRS); do \
    for file in $$prefix/*.h; do \
        C:/QtSDK/Desktop/Qt/4.7.4/mingw/bin/moc.exe $$file; \
    done \
done

С учетом вышесказанного, гораздо лучший способ сделать это - использовать make для обработки всех файлов (и решить, нужно ли обрабатывать их все!), Вместо использования явного цикл в правиле. Вы начнете со списка заголовочных файлов, как предполагает ответ Эльдара Абусалимова:

moc_headers := $(wildcard $(SUBDIRS:%=%/*.h))

Внутренняя часть этого манипулирует списком SUBDIRS в форму directory1/*.h, directory2/*.h и т. Д., А затем функция wildcard расширяет все шаблоны *.h.

Затем вы генерируете список выходных файлов из них:

moc_mocfiles := $(patsubst %.h, %_moc.cpp, $(moc_headers))

Этот расширенный список заголовочных файлов directory1/header1.h, directory1/header2.h и т. Д. Заменяет шаблон %.h на %_moc.cpp. (Обратите внимание, что, поскольку все эти имена имеют имя каталога как часть имени, вы не можете легко использовать более распространенный шаблон имени moc_%.h, потому что вы получите moc_directory1/header1.cpp, а не желаемый directory1/moc_header1.cpp. Есть способы обойти это, но легче избежать этой проблемы.) В любом случае, это дает вам список выходных файлов: directory1/header1_moc.cpp, directory1/header2_moc.cpp и т. д.

Теперь, когда у вас есть список выходных файлов, Make знает, как их легко перебрать. Вы просто объявляете этот список как обязательное условие для какой-либо другой цели, которую вы делаете, например:

find_files: $(moc_mocfiles)

И, наконец, вы даете общее правило для создания файла *_moc.cpp из файла *.h:

%_moc.cpp: %.h
     C:/QtSDK/Desktop/Qt/4.7.4/mingw/bin/moc.exe $< -o $@

Там в первой строке указано, «это то, как вы создаете файл, который соответствует шаблону %_moc.cpp, если у вас есть файл, соответствующий шаблону %.h, из которого он будет создан». Во второй строке $< становится входным файлом (файл %.h), а $@ становится выходным файлом. Здесь вы явно указываете moc.exe с опцией -o выплевывать файл с именем %_moc.cpp вместо того, что он использует по умолчанию.

Итак, собрав все это вместе, когда вы сделаете цель find_files, make поймет, что ему нужно внести все эти %_moc.cpp файлы в список moc_mocfiles, и для каждого из них он увидит, что имеет возможное правило, которое подходит, оно увидит, что правило применяется, потому что соответствующий файл %.h существует, и оно будет применять правило.

Это также имеет то преимущество, что, если файл %_moc.cpp уже существует и новее, чем файл %.h, что указывает на то, что он уже обновлен, он не потрудится восстановить его при следующем запуске make , Он будет восстанавливать только файлы, соответствующие %.h файлам, которые вы редактировали.

(О, и еще одна вещь: при вырезании и вставке всех этих вещей из этого ответа, убедитесь, что ваши вкладки находятся в нужных местах!)

1 голос
/ 28 января 2012

Просто используйте встроенную wildcard функцию из GNU Make:

HEADERS := $(wildcard $(SUBDIRS:%=%/*.h))
...