使用makefile管理工程
工程文件结构如下:
.
├── bsp
│ ├── makefile
│ ├── spi
│ │ ├── makefile
│ │ ├── spi.c
│ │ └── spi.h
│ └── uart
│ ├── makefile
│ ├── uart.c
│ └── uart.h
├── interface
│ ├── interface.h
│ └── makefile
├── main
│ ├── main.c
│ ├── main.h
│ └── makefile
├── makefile
├── obj
│ └── makefile
└── os
├── makefile
└── os.c
工程管理时,需要一个主makefile,主makefile调用子文件夹下的makefile。
主makefile如下:
# $^ 代表所有的依赖文件
# $@ 代表目标文件
# $< 代表第一个依赖文件
# = 引用此变量时是最后一次赋值
# := 引用变量时使用当前变量值
# ?= 引用变量时,如果变量已被初始化,则不重新赋值,否则重新赋值
# .PHONY
TARGET := app
OBJDIR := obj
CC := gcc
ROOT_DIR := $(shell pwd)
export CC OBJDIR ROOT_DIR
SUB_DIR := $(filter-out $(OBJDIR),$(filter $(shell ls),$(shell ls -l | grep ^d)))
CUR_C_SRC := $(wildcard *.c)
OBJS := $(patsubst %.c,$(OBJDIR)/%.o,$(CUR_C_SRC))
all:$(SUB_DIR) $(OBJS) $(TARGET)
$(SUB_DIR):print
make -C $@
ifneq ($(CUR_C_SRC),$(OBJS))
$(OBJDIR)/%.o:%.c
$(CC) -c $< -o $@
endif
$(TARGET):
make -C $(OBJDIR)
.PHONY:clean
clean:
@rm -rf $(OBJDIR)/*.o $(TARGET)
.PHONY:print
print:
@echo subdir = $(SUB_DIR)
@echo curcfile = $(CUR_C_SRC)
@echo objs = $(OBJS)
除了obj目录,其他子文件夹下的makefile都一样,如下:
# $^ 代表所有的依赖文件
# $@ 代表目标文件
# $< 代表第一个依赖文件
# = 引用此变量时是最后一次赋值
# := 引用变量时使用当前变量值
# ?= 引用变量时,如果变量已被初始化,则不重新赋值,否则重新赋值
# .PHONY
SUB_DIR := $(filter $(shell ls),$(shell ls -l | grep ^d))
CUR_C_SRC := $(wildcard *.c)
OBJS := $(patsubst %.c,%.o,$(CUR_C_SRC))
CC := gcc
all:$(SUB_DIR) $(OBJS)
$(SUB_DIR):print
make -C $@
ifneq ($(CUR_C_SRC),$(OBJS))
%.o:%.c
$(CC) -c $< -o $(ROOT_DIR)/$(OBJDIR)/$@
endif
.PHONY:clean
clean:
@rm -rf $(OBJS) $(TARGET)
.PHONY:print
print:
@echo subdir = $(SUB_DIR)
@echo curcfile = $(CUR_C_SRC)
obj目录下的makefile如下:
# $^ 代表所有的依赖文件
# $@ 代表目标文件
# $< 代表第一个依赖文件
# = 引用此变量时是最后一次赋值
# := 引用变量时使用当前变量值
# ?= 引用变量时,如果变量已被初始化,则不重新赋值,否则重新赋值
# .PHONY
TARGET := app
OBJS := $(wildcard *.o)
$(TARGET):$(OBJS)
$(CC) $^ -o $(ROOT_DIR)/$@