Приветствую.
Есть следующая структура каталогов:
.
├── interrupts
│ ├── handlers
│ │ ├── file.a65
│ │ └── Makefile // Вложенный
│ └── Makefile // Вложенный
├── defines.mk
├── common.mk
└── Makefile // Корневой
В первую очередь, файл defines.mk:
PROJECT_NAME = xxx
PROG_AS ?= ca65
PROG_LD ?= ld65
PROG_DOX ?= doxygen
PROG_RM ?= rm -f
PROG_MV ?= mv -f
PROG_MKDIR ?= mkdir -p
PROG_FIND ?= find
PROG_MAKE ?= make
DIR_BUILD ?= build
Файл common.mk
TARGET_SUBMAKE = $(shell \
$(PROG_FIND) \
. \
-mindepth 2 \
-type f \
-name Makefile \
-printf '%h\n' \
)
TARGET_SRC = $(shell \
$(PROG_FIND) \
. \
-maxdepth 1 \
-type f \
-name '*.a65' \
-printf '%f\n' \
)
TARGET_OBJ = $(patsubst \
%.a65, \
$(DIR_BUILD)/$(PROJECT_NAME)/%.o, \
$(TARGET_SRC) \
)
.PHONY: all $(PROJECT_NAME) $(TARGET_SUBMAKE)
$(DIR_BUILD)/$(PROJECT_NAME)/%.o : %.a65
$(PROG_MKDIR) \
$(DIR_BUILD)/$(PROJECT_NAME)
$(PROG_AS) \
-o $@ \
$<
$(TARGET_SUBMAKE):
$(PROG_MAKE) \
-C $@ \
MAKEFILE_DEF=$(MAKEFILE_DEF) \
MAKEFILE_COMMON=$(MAKEFILE_COMMON) \
DIR_BUILD=$(DIR_BUILD)
$(PROJECT_NAME): $(TARGET_SUBMAKE) $(TARGET_OBJ)
all: $(PROJECT_NAME)
Корневой Makefile
MAKEFILE_DEF := $(CURDIR)/defines.mk
MAKEFILE_COMMON := $(CURDIR)/common.mk
include $(MAKEFILE_DEF)
include $(MAKEFILE_COMMON)
.PHONY: doc clean
all: doc
doc:
$(PROG_DOX) Doxygen
clean:
$(PROG_RM) $(DIR_BUILD)/$(PROJECT)/*.o
Вложенные Makefile (все одинаковые)
include $(MAKEFILE_DEF)
include $(MAKEFILE_COMMON)
Итак, в чём вопросы:
1
Оно сейчас работает. Но меня не устраивает, что оно на каждый файл вызывает создание целевого каталога (см.
$(DIR_BUILD)/$(PROJECT_NAME)/%.o : %.a65
$(PROG_MKDIR) \
$(DIR_BUILD)/$(PROJECT_NAME)
...
). Что я пытался сделать:
а) Вынести mkdir в отдельный сегмент и вызывать как $(DIR_BUILD)/$(PROJECT_NAME)/%.o : %.a65 | build-dir
б) Вынести mkdir в отдельный сегмент и вызывать тут: $(PROJECT_NAME): build-dir $(TARGET_SUBMAKE) $(TARGET_OBJ)
Оба варианта приводят к тому, что при вызове корневого make
он просто создаёт директорию и даже не пытается заходить в дочерние Makefile
.
2
Приветствуется общая критика. Я не эксперт в make
, соответственно буду рад услышать, что я делаю не так.
P.S. Сразу уточню насчёт build директории. «Корневой» makefile на самом деле тоже не корневой и его вызывают выше с
DIR_BUILD := $(CURDIR)/build
make -C code/xxx DIR_BUILD=$(DIR_BUILD)