Подтвердить что ты не робот

Источники из подкаталогов в Makefile

У меня есть библиотека С++, созданная с помощью Makefile. До недавнего времени все источники находились в одном каталоге, а Makefile делал что-то вроде этого

SOURCES = $(wildcard *.cpp)

который работал нормально.

Теперь я добавил некоторые источники, которые находятся в подкаталоге, скажем subdir. Я знаю, что могу это сделать

SOURCES = $(wildcard *.cpp) $(wildcard subdir/*.cpp)

но я ищу способ избежать указания subdir вручную, т.е. сделать wildcard поиск в подкаталогах или создать список подкаталогов и расширить его несколькими функциями wildcard. На данный момент, имея нерекурсивное решение (т.е. Расширяя только первый уровень), будет хорошо.

Я ничего не нашел - лучше всего использовать find -type d, чтобы перечислить подкаталоги, но это похоже на взлом. Есть ли встроенный способ сделать это?

4b9b3361

Ответ 1

Это должно сделать это:

SOURCES = $(wildcard *.cpp) $(wildcard */*.cpp)

Если вы передумаете и хотите получить рекурсивное решение (т.е. на любую глубину), это можно сделать, но оно включает некоторые из более мощных функций Make. Вы знаете, те, которые позволяют вам делать то, что вам действительно не нужно.

EDIT:
Джек Келли отмечает, что $(wildcard **/*.cpp) работает на любой глубине, по крайней мере на некоторых платформах, используя GNUMake 3.81. (Как он это понял, я понятия не имею.)

Ответ 2

Рекурсивные подстановочные знаки могут выполняться исключительно в Make, без вызова оболочки или команды find. Выполнение поиска с использованием только Make означает, что это решение работает и на Windows, а не только на * nix.

# Make does not offer a recursive wildcard function, so here one:
rwildcard=$(wildcard $1$2) $(foreach d,$(wildcard $1*),$(call rwildcard,$d/,$2))

# How to recursively find all files with the same name in a given folder
ALL_INDEX_HTMLS := $(call rwildcard,foo/,index.html)

# How to recursively find all files that match a pattern
ALL_HTMLS := $(call rwildcard,foo/,*.html)

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

Ответ 3

Если вы не хотите использовать рекурсивные make файлы, это может дать вам несколько идей:

subdirs := $(wildcard */)
sources := $(wildcard $(addsuffix *.cpp,$(subdirs)))
objects := $(patsubst %.cpp,%.o,$(sources))

$(objects) : %.o : %.cpp

Ответ 4

Обычная практика заключается в том, чтобы поставить Makefile в каждом поддире с источниками, затем

all: recursive
    $(MAKE) -C componentX
    # stuff for current dir

или

all: recursive
    cd componentX && $(MAKE)
    # stuff for current dir

recursive: true

Возможно, было бы целесообразно установить параметры для каждого Makefile в Makefile.inc в корневой каталог источника. Цель recursive заставляет make перейти в подкаталоги. Убедитесь, что он не перекомпилирует что-либо в целевом объекте, требующем recursive.

Ответ 5

Это побочная заметка и не отвечайте на ваш вопрос, но есть статья "Рекурсивная оценка считается вредной". Это стоит прочитать.

Вот ссылка. http://aegis.sourceforge.net/auug97.pdf

Ответ 6

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

recurfind = $(shell find $(1) -name '$(2)')
SRCS := $(call recurfind,subdir1,*.c) $(call recurfind,subdir2,*.cc) $(call recurfind,subdir2,*.cu) \
        ...