多級目錄makefile例子
阿新 • • 發佈:2019-01-06
先看一下make前後的目錄結構對比
makefile會自動生成需要的資料夾:各個模組下src目錄下的obj、target目錄
各個模組下src/obj負責存放生成的 .o 檔案;
target用於儲存生成的可執行檔案;
lib用於儲存生成的靜態庫(libModuleA.a)和引用的靜態庫檔案(libtest.a);
include資料夾用於儲存引用庫的標頭檔案(test.h);
module_a模組會生成一個靜態庫,在生成可執行檔案時連結這個靜態庫。
a.c中是一個函式實現,a.h中宣告,main.c中呼叫。
main函式會呼叫module_a生成靜態庫中的函式和引用庫中的函式;
以下是各級makefile的實現。
最外層makefile實現:
#最外層的makefile負責建立相關目錄和進入每個子目錄去make #後邊裡目錄要根據前面一個的目錄為基準 SUBDIRS = ./module_a ../main .PHONY:all all: mkdir -p ./target mkdir -p ./module_a/src/obj mkdir -p ./main/src/obj @list='$(SUBDIRS)';for subdir in $$list; do \ cd $$subdir && make; \ done .PHONY:clean clean: @list='$(SUBDIRS)'; for subdir in $$list; do \ echo "Clean in $$subdir";\ cd $$subdir && make clean;\ done rm -rf ./target
module_a目錄下makefile實現:
CC := gcc
CFLAGS := -fPIC
INC_DIR := ./inc
SRC_DIR := ./src
OBJ_DIR := $(SRC_DIR)/obj
INSTALL_LIB_PATH := ../lib
LIB_TARGET := libmoduleA.a
#包含需要的標頭檔案路徑
CFLAGS += -I$(INC_DIR)
#搜尋指定目錄下的所有以.c結尾的檔案(搜尋結果儲存在SOURCE,結果中包含路徑相關資訊)
SOURCE = $(wildcard $(SRC_DIR)/*.c)
#去除結果中的路徑資訊
SOURCER = $(notdir $(SOURCE))
#把.c換成.o
OBJS = $(patsubst %.c,%.o,$(SOURCER))
#把所有.o加上想要的路徑資訊
OBJS := $(foreach X,$(OBJS),$(OBJ_DIR)/$(X))
#OBJS := $(OBJ_DIR)/*.o
#OBJS := $(OBJ_DIR)/a.o \
# $(OBJ_DIR)/main.o
#OBJS := $(foreach x,$(OBJS),$(x).o)
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c
$(CC) $(CFLAGS) -c -o [email protected] $<
#$(TARGET):$(OBJS)
# $(CC) $(CFLAGS) -o $(TARGET_DIR)/[email protected] $(OBJS)
#用.o生成靜態庫檔案.a,並放到指定目錄下
$(LIB_TARGET):$(OBJS)
ar crus $(LIB_TARGET) $^
install -m 0755 $(LIB_TARGET) $(INSTALL_LIB_PATH)
rm -rf $(LIB_TARGET)
.PHONY:clean
clean:
rm -rf $(OBJ_DIR)
rm -rf $(INSTALL_LIB_PATH)/$(LIB_TARGET)
main目錄下makefile實現:
CC := gcc
CFLAGS := -fPIC
INC_DIR := ../module_a/inc ../include
SRC_DIR := ./src
OBJ_DIR := $(SRC_DIR)/obj
TARGET_DIR := ../target
TARGET := main
INSTALL_LIB_PATH := ../lib
#包含所有以.a結尾的檔案
LIB_TARGET := *.a
CFLAGS += -I$(INC_DIR)
SOURCE = $(wildcard $(SRC_DIR)/*.c)
SOURCER = $(notdir $(SOURCE))
OBJS = $(patsubst %.c,%.o,$(SOURCER))
OBJS := $(foreach X,$(OBJS),$(OBJ_DIR)/$(X))
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c
$(CC) $(CFLAGS) -c -o [email protected] $<
#生成可執行檔案
$(TARGET):$(OBJS)
$(CC) -o $(TARGET_DIR)/$(TARGET) $(OBJS) \
$(INSTALL_LIB_PATH)/$(LIB_TARGET)
@echo "------------------------ MAKEFILE COMPLETE -----------------------"
.PHONY:clean
clean:
rm -rf $(OBJ_DIR)