Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > GNU toolchain > Как в makefile получить список всех файлов?


Автор: avn 24.3.2014, 13:48
Доброго времени суток!

Такой у меня вопрос.

Я пытаюсь в makefile получить в переменную список всех файлов *.C, *.CPP, *.S в текущей директории и всех поддиректориях. И как-то не могу разобраться в этом...

Т. е. все бы хорошо если бы я получил список всех поддиректорий, их поддиректорий и т. д. - рекурсия. Но, похоже, make не имеет штатных средств.

Я работаю в Windows. Там можно сделать так: dir /A /B /S *.cpp . На выходе шикарный списочек - то, что мне нужно. В Unix, я так понимаю, можно извратиться с ls соответствующим образом (кстати, не получилось - может, кто подскажет?..).

Пытаюсь вписать строку в makefile:

all_files := $(shell dir /A /B /S *.c)

Получаю:

/bin/sh: dir: command not found

Пишу иначе:

all_files := $(shell 'dir /A /B /S *.c')

Получаю:

process_begin: CreateProcess(NULL, "dir /A /B /S *.c", ...) failed.

Как поступить в таком случае? Подскажите, потому что я уже  smile  !

Добавлено через 3 минуты и 11 секунд
Если написать $(shell LS -R), то что-то получается. Но LS -R дает совершенно не тот вывод, что нужно. Мне нужно строго в виде:

FILE.C
DIR1/FILE1.C
DIR1/FILE2.C
DIR1/DIR2/FILE2.C
DIR3/FILE2.C

Наверное, тут как-то можно с foreach чего-нибудь придумать, но я пока застрял...

Автор: avn 24.3.2014, 15:32
Смог решить НЕ-ИДЕАЛЬНО, но работает:

Код


SRC_PATH := 

FILES0 := $(wildcard $(SRC_PATH)*)
FILES1 := $(foreach dir, $(FILES0), $(wildcard $(dir)))
FILES := $(FILES1)
ifdef FILES1
FILES2 := $(foreach dir, $(FILES0), $(wildcard $(dir)/*))
FILES += $(FILES2)
ifdef FILES2
FILES3 := $(foreach dir, $(FILES0), $(wildcard $(dir)/*/*))
FILES += $(FILES3)
ifdef FILES3
FILES4 := $(foreach dir, $(FILES0), $(wildcard $(dir)/*/*/*))
FILES += $(FILES4)
ifdef FILES4
FILES5 := $(foreach dir, $(FILES0), $(wildcard $(dir)/*/*/*/*))
FILES += $(FILES5)
ifdef FILES5
FILES6 := $(foreach dir, $(FILES0), $(wildcard $(dir)/*/*/*/*/*))
FILES += $(FILES6)
ifdef FILES6
FILES7 := $(foreach dir, $(FILES0), $(wildcard $(dir)/*/*/*/*/*/*))
FILES += $(FILES7)
ifdef FILES7
FILES8 := $(foreach dir, $(FILES0), $(wildcard $(dir)/*/*/*/*/*/*/*))
FILES += $(FILES8)
ifdef FILES8
FILES9 := $(foreach dir, $(FILES0), $(wildcard $(dir)/*/*/*/*/*/*/*/*))
FILES += $(FILES9)
ifdef FILES9
FILES10 :=$(foreach dir, $(FILES0), $(wildcard $(dir)/*/*/*/*/*/*/*/*/*))
FILES += $(FILES10)
endif
endif
endif
endif
endif
endif
endif
endif
endif

SRC_CPP := $(sort $(wildcard $(addsuffix .CPP, $(basename $(FILES)))))
SRC_C := $(sort $(wildcard $(addsuffix .C, $(basename $(FILES)))))
SRC_ASM := $(sort $(wildcard $(addsuffix .S, $(basename $(FILES)))))
SRC_H := $(sort $(wildcard $(addsuffix .H, $(basename $(FILES)))))
INCLUDE := $(sort $(dir $(SRC_H)))



Если кто знает более элегантное решение - пишите!

Автор: leniviy 24.3.2014, 15:33
Вообще-то так делать не принято. Принято хардкодить имена файлов в Makefile, а поиском файлов занимается генератор мейкфайла.
Но если очень нужно...

Цитата(avn @  24.3.2014,  13:48 Найти цитируемый пост)
process_begin: CreateProcess(NULL, "dir /A /B /S *.c", ...) failed.

Потому что Не существует "dir.exe". Есть команда "dir" в cmd.exe. Можно так: "$(shell cmd /c dir ...)".

Но лучше использовать встроенные make функции для получения списка файлов в директории (без использования $(shell).

Добавлено через 14 минут и 35 секунд
Если Makefile только 1, есть вариант собрать *.c файлы в текущем каталоге, найти подкаталоги, и для каждого найденного перезапускать $(MAKE) с параметрами -C и -f. Он, если надо, пойдет еще глубже, итд.

Автор: avn 24.3.2014, 16:28
Цитата

"$(shell cmd /c dir ...)".

Не работает - тупо зависает.
Цитата

Но лучше использовать встроенные make функции для получения списка файлов в директории (без использования $(shell).

Вот их-то я и не нашел.
Цитата

Если Makefile только 1, есть вариант собрать *.c файлы в текущем каталоге, найти подкаталоги, и для каждого найденного перезапускать $(MAKE) с параметрами -C и -f. Он, если надо, пойдет еще глубже, итд.

А Вы можете пример привести?

Автор: leniviy 24.3.2014, 17:36
Я так не помню.
Для поиска надо использовать со слэшом на конце, типа: DIRS = $(wildcard */) 
потом каждый из DIRS считать таргетом. как-то так:
Код

$(DIRS):
    $(MAKE) -C %не-помню-переменную-имя-таргета -f $(не-помню-переменную-полный-путь-к-мейкфайлу)

тут должен быть TAB, а не пробелы, но движок форума его порезал


Добавлено @ 17:36
Всё здесь: http://www.gnu.org/savannah-checkouts/gnu/make/manual/make.html#Recursion

Добавлено @ 17:39
Цитата(avn @  24.3.2014,  16:28 Найти цитируемый пост)

Не работает - тупо зависает.

Вероятно, запускает интерактивный. Попробуйте //c (с двумя слэшами). Mingw - он такой

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)