make
внутри и вне себя обрабатывает цели каталога точно так же, как цели файлов. Таким образом, легко написать такие правила:
outDir/someTarget: Makefile outDir
touch outDir/someTarget
outDir:
mkdir -p outDir
Единственная проблема в том, что временная метка каталогов зависит от того, что сделано с файлами внутри. Для приведенных выше правил это приводит к следующему результату:
$ make
mkdir -p outDir
touch outDir/someTarget
$ make
touch outDir/someTarget
$ make
touch outDir/someTarget
$ make
touch outDir/someTarget
Это определенно не то, что вы хотите. Всякий раз, когда вы касаетесь файла, вы также касаетесь каталога. А так как файл зависит от каталога, файл, следовательно, устарел, и его приходится перестраивать.
Однако вы можете легко разорвать этот цикл, указав , заставляя make игнорировать метку времени каталога . Это делается путем объявления каталога как предварительного заказа только для заказа:
# The pipe symbol tells make that the following prerequisites are order-only
# |
# v
outDir/someTarget: Makefile | outDir
touch outDir/someTarget
outDir:
mkdir -p outDir
Это правильно дает:
$ make
mkdir -p outDir
touch outDir/someTarget
$ make
make: 'outDir/someTarget' is up to date.
TL; DR:
Напишите правило для создания каталога:
$(OUT_DIR):
mkdir -p $(OUT_DIR)
И цели для содержимого внутри зависят только от порядка в каталоге:
$(OUT_DIR)/someTarget: ... | $(OUT_DIR)