Я следующую структуру папок:Как написать хороший и эффективный Makefile
TOPDIR
|
├── a
│ ├── a.c
│ ├── a.h
│ └── a.mk
├── b
│ ├── b.c
│ ├── b.h
│ └── b.mk
├── c
│ ├── c.c
│ ├── c.h
│ └── c.mk
├── include
│ └── common.h
├── root
│ ├── main.c
│ └── root.mk
└── Makefile
за состоянием
Моя цель, чтобы написать основной Makefile
под TOPDIR
и суб-Makefile, *.mk
в подпункте папке, папка include
содержит некоторые общие определения. root
папка содержит мой основной файл (функция, расположенная здесь). Между тем, в main.c
, он будет вызывать функцию из a.c
и b.c
, c.c
является водитель связаны, и будет вызываться из a.c
и b.c
Проблема
Я написал суб-Makefile, как (я использую один a.mk
для Например, другие такие же, только root.mk
мало отличается):
#MODULE will be modified for each sub folder
MODULE = a
LIB = $(MAKE_DIR)/libs/lib$(MODULE).a
SRCS = $(wildcard *.c)
OBJS = $(patsubst %.c, %.o, $(SRCS))
#generate lib file from obj file
$(LIB): $(OBJS)
@mkdir -p ../libs
@$(AR) cr [email protected] $^
@echo " Archive $(notdir [email protected])"
#compile obj file from source file
$(OBJS): $(SRCS)
@$(CC) $(CFLAGS) -c $^
@echo " CC $(OBJS)"
.PHONY: clean
clean:
@$(RM) -f $(LIB) $(OBJS)
@$(RM) -f *.expand
@echo " Remove Objects: $(OBJS)"
@echo " Remove Libraries: $(notdir $(LIB))"
Я написал root.mk
как:
PROG = ../prog/DEMO
SRCS = $(wildcard *.c)
OBJS = $(patsubst %.c, %.o, $(SRCS))
#generate finial target file for run
$(PROG): $(SRCS)
@mkdir -p ../prog
@$(CC) $^ $(CFLAGS) -Wl,-Map=$(PROG).map $(LIBS) -o [email protected]
@echo " Generate Program $(notdir $(PROG)) from $^"
.PHONY: clean
clean:
@$(RM) -f $(OBJS) $(PROG)
@$(RM) -f *.expand
@$(RM) -rf ../prog ../libs
@echo " Remove Objects: $(OBJS)"
@echo " Remove Libraries: $(notdir $(PROG))"
Я написал главный Makefile
как:
MAKE_DIR = $(PWD)
ROOT_DIR := $(MAKE_DIR)/root
DRV_DIR := $(MAKE_DIR)/driver
INCLUDE_DIR := $(MAKE_DIR)/include
DEBUG_DIR := $(MAKE_DIR)/debug
INC_SRCH_PATH :=
INC_SRCH_PATH += -I$(ROOT_DIR)
INC_SRCH_PATH += -I$(DRV_DIR)
INC_SRCH_PATH += -I$(INCLUDE_DIR)
INC_SRCH_PATH += -I$(DEBUG_DIR)
LIB_SRCH_PATH :=
LIB_SRCH_PATH += -L$(MAKE_DIR)/libs
CC = gcc
LD = ld
#problem happan here, if I change the sequence of LIB,
#during the finial link, it will find some function un-referenced,
#why can I put liba first?
LIBS := -lc -lb -la
CFLAGS :=
CFLAGS += $(INC_SRCH_PATH) $(LIB_SRCH_PATH)
CFLAGS += -Wall -O -ggdb
CFLAGS += -DDEBUG -D_REENTRANT
LDFLAGS :=
export MAKE_DIR CC LD CFLAGS LDFLAGS LIBS LINT INC_SRCH_PATH
all:
@$(MAKE) -C a -f a.mk
@$(MAKE) -C b -f b.mk
@$(MAKE) -C c -f c.mk
@$(MAKE) -C root -f root.mk
.PHONY: clean
clean:
@$(MAKE) -C debug -f debug.mk clean
@$(MAKE) -C driver -f driver.mk clean
@$(MAKE) -C mw -f mw.mk clean
@$(MAKE) -C root -f root.mk clean
Вопрос
В главном
Makefile
, я определить, какиеLIB
файл я буду использовать, если нужно переместить его вroot.mk
для лучше?В суб-Makefile, я не использовал
-MM
для создания файла зависит, если это вызывает проблемы, я не могу изменить последовательность моихlib*
, который я также описанный вMakefile
комментарии.Кажется, моя система makefile НЕ обнаруживает, что я обновляю какой-либо файл head, например, я сначала скомпилировал весь код, а затем я модифицировал один файл head, когда пытаюсь перекомпилировать, ни один источник не скомпилирован
если:
#Automatic dependency magic:
%.d: src/%.c
$(CC) -MM [email protected] $<
-include (MYPROG_OBJECTS:%.o=%.d)
нужно добавить в каждый суб-Makefile?
Всегда стоит читать, когда новый в Makefile. [Recursive make считают вредным] (http://aegis.sourceforge.net/auug97.pdf) – RedX