Makefile - компилирует все подкаталоги и выводит .o файлы в отдельный каталог - PullRequest
0 голосов
/ 26 сентября 2018

У меня есть эта команда из моего скрипта bash

find . -type f -name "*.c" -execdir bash -c "f={}; kos-cc $KOS_CFLAGS -c {} -o $PWD/\${f%.c}.o" \;

Его задача - рекурсивно искать в текущем каталоге ($ PWD) файлы .c, компилировать их с помощью моего компилятора "kos-cc" и затем выводитьвсе .o файлы в текущем рабочем каталоге.

Я хочу переместить части моего bash-скрипта в make-файл, и эта строка - последняя, ​​которая озадачивает меня.Я знаю, как создавать правила, которые компилируют файлы c из каталога A и выводят файлы .o в каталог B, но здесь каталог A не всегда одинаков (поскольку мне нужно обрабатывать и подкаталоги).Как мне выполнить эквивалентную задачу в Makefile с помощью правила или команды?

1 Ответ

0 голосов
/ 26 сентября 2018

Это не тривиально, потому что ваши источники находятся в разных каталогах, и простые правила создания шаблонов не могут легко справиться с этим.Но используя немного более продвинутые функции make, может сделать это:

SRC := $(shell find . -type f -name "*.c")
OBJ := $(patsubst %.c,%.o,$(notdir $(SRC)))

.PHONY: all    
all: $(OBJ)

define COMPILE_rule
$$(patsubst %.c,%.o,$$(notdir $(1))): $(1)
    kos-cc $$(KOS_CFLAGS) -c -o $$@ $$<
endef
$(foreach s,$(SRC),$(eval $(call COMPILE_rule,$(s))))

.PHONY: clean
clean:
    rm -f $(OBJ)

Осторожно: у вас может быть несколько исходных файлов с одинаковым базовым именем в разных каталогах.И если это произойдет, вы получите фатальный конфликт имен объектных файлов ...

РЕДАКТИРОВАТЬ (добавить обнаружение конфликтов):

Следующее обнаруживает конфликтные ситуациии выдает ошибку (замените error на warning или info в зависимости от уровня серьезности, который вы назначаете этим конфликтам):

SRC := $(shell find . -type f -name "*.c")
OBJ := $(patsubst %.c,%.o,$(notdir $(SRC)))

ifneq ($(words $(OBJ)),$(words $(sort $(OBJ))))
$(error object file name conflicts detected)
endif

(sort сортирует, а также удаляет дубликаты и words возвращает количество разделенных пробелом слов в строковом параметре).

...