GNU make, как определить путь к файлу или каталогу? - PullRequest
2 голосов
/ 25 февраля 2012

С какого-то пути я использую

PATHS = $(wildcard $(SOME_PATH)/*)

для получения всех подпутей.

Мне нужно знать, файл это или каталог.

Как это сделать в make?

Спасибо.

Ответы [ 5 ]

8 голосов
/ 26 февраля 2012

У Джона Маршалла есть способ, который будет работать, но есть более безопасный способ. Все каталоги всегда имеют одну хорошо известную запись, и это "." Итак, что вам нужно сделать, это:

PATHS := $(wildcard $(SOME_PATH)/*)
DIRS := $(patsubst %/.,%,$(wildcard $(addsuffix /.,$(PATHS))))
FILES := $(filter-out $(DIRS),$(PATHS))

Подстановочный знак будет соответствовать всем каталогам и только каталогам, поскольку только каталоги содержат «.». Это надежно.

Способ Yehnan также работает, но менее эффективен, потому что вы вызываете оболочку для каждого элемента в PATHS. Скорее всего, это не сильно повлияет на ваше время выполнения, но если это можно сделать внутри make, а не с помощью shell, я бы предпочел это. Также это помогает переносимости избежать $ (shell ...).

4 голосов
/ 25 февраля 2012
DIRS  := $(patsubst %/,%,$(filter %/,$(wildcard $(SOME_PATH)/*/)))
FILES := $(filter-out $(DIRS),$(wildcard $(SOME_PATH)/*))

Похоже, что это также может быть сделано только с одним wildcard следующим образом:

ENTRIES := $(wildcard $(SOME_PATH)/*/)
DIRS  := $(patsubst %/,%,$(filter %/,$(ENTRIES)))
FILES := $(filter-out %/,$(ENTRIES))

, но я менее убежден в надежности зависимости от $(wildcard */) для создания записей дляфайлы, поскольку они на самом деле не соответствуют запрошенному шаблону (т. е. такие записи не имеют завершающей косой черты).

GNU Make 3.82 действительно производит такие записи, но это скорее похоже на ошибкучем особенность.

1 голос
/ 25 февраля 2012
PATHS = $(wildcard $(SOME_PATH)/*)
DIRPATHS = $(foreach dir, $(wildcard $(PATHS)/*), $(shell test -d $(dir) && echo $(dir)))
0 голосов
/ 02 декабря 2016

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

FILES := $(shell find $(SOME_PATH) -type -f)

Одним из преимуществ является то, что вы даже можете использовать несколько путей в качестве входных данных (т.е. SOME_PATH).

0 голосов
/ 25 февраля 2012

Код ниже работает по стандартному bash и печатает для каждого найденного элемента, если это каталог:

PATHS=$(wildcard *)
for f in $(PATHS); do \
    if test -d $$f; then echo "$$f: DIR"; fi; \
done
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...