多个makefile构建多个目录的工程文件(大工程基本如此)
通过多个层级的makefile构建整个工程级别的makefile,大工程如果不使用cmake等,基本如此组织,
linux内核也是这样哈
目录树
➜ test_pro3 tree -h
.
├── [4.0K] app_1
│ ├── [ 272] app1.c
│ ├── [ 248] app1.h
│ ├── [ 278] app1_t.c
│ └── [ 283] makefile
├── [4.0K] app_2
│ ├── [ 270] app2.c
│ ├── [ 226] app2.h
│ └── [ 189] makefile
├── [4.0K] app_main
│ ├── [ 353] app_main.c
│ └── [ 201] makefile
├── [1.0K] makefile
└── [4.0K] obj
4 directories, 10 files
顶层的makefile
ROOT_DIR = $(shell pwd)
APP_1_DIR = $(ROOT_DIR)/app_1
APP_2_DIR = $(ROOT_DIR)/app_2
APP_MAIN_DIR = $(ROOT_DIR)/app_main
INC_DIR := $(APP_1_DIR) \
$(APP_2_DIR)
export OBJ_DIR := $(ROOT_DIR)/obj
EXEC = test_app.bin
export DFLAGS ?= # 库的链接参数
export CFLAGS := $(patsubst %, -I %, $(INC_DIR)) # 参数信息
export CROSS_COMPILE ?= # 没有定义交叉编译器时,直接用gcc
export CC := $(CROSS_COMPILE)gcc # 编译器 按需就行
export AR = ${CROSS_COMPILE}ar
export STRIP = ${CROSS_COMPILE}strip
export AS = ${CROSS_COMPILE}as
export LD = ${CROSS_COMPILE}lr
export RANLIB = ${CROSS_COMPILE}ranlib
export NM = ${CROSS_COMPILE}nm
.PHONY : clean all READY BUILD_OBJ BIN_MAKE
all: clean READY BUILD_OBJ BIN_MAKE
READY:
$(info will make project)
mkdir -p $(OBJ_DIR)
BIN_MAKE:
$(CC) $(OBJ_DIR)/*.o -o ${EXEC} $(CFLAGS) $(DFLAGS)
BUILD_OBJ:
make -C $(APP_1_DIR)
make -C $(APP_2_DIR)
make -C $(APP_MAIN_DIR)
clean:
rm -rf $(OBJ_DIR)/*.o $(EXEC)
各个子目录的makefile,都大同小异,只是改下对应的O文件就行
BUILD_OBJ := $(OBJ_DIR)/app1.o \
$(OBJ_DIR)/app1_t.o
.PHONY : all LIB
all: LIB
$(info $(BUILD_OBJ))
LIB: $(BUILD_OBJ)
#可以ar构建静态库
$(info $(BUILD_OBJ))
$(OBJ_DIR)/app1.o: app1.c
$(CC) -c $< -o $@ $(CFLAGS) $(DFLAGS)
$(OBJ_DIR)/app1_t.o: app1_t.c
$(CC) -c $< -o $@ $(CFLAGS) $(DFLAGS)
测试
➜ test_pro3 make
rm -rf /home/zw/test_pro/test_pro3/obj/*.o test_app.bin
will make project
mkdir -p /home/zw/test_pro/test_pro3/obj
make -C /home/zw/test_pro/test_pro3/app_1
make[1]: Entering directory '/home/zw/test_pro/test_pro3/app_1'
/home/zw/test_pro/test_pro3/obj/app1.o /home/zw/test_pro/test_pro3/obj/app1_t.o
gcc -c app1.c -o /home/zw/test_pro/test_pro3/obj/app1.o -I /home/zw/test_pro/test_pro3/app_1 -I /home/zw/test_pro/test_pro3/app_2
gcc -c app1_t.c -o /home/zw/test_pro/test_pro3/obj/app1_t.o -I /home/zw/test_pro/test_pro3/app_1 -I /home/zw/test_pro/test_pro3/app_2
/home/zw/test_pro/test_pro3/obj/app1.o /home/zw/test_pro/test_pro3/obj/app1_t.o
#可以ar构建静态库
make[1]: Leaving directory '/home/zw/test_pro/test_pro3/app_1'
make -C /home/zw/test_pro/test_pro3/app_2
make[1]: Entering directory '/home/zw/test_pro/test_pro3/app_2'
/home/zw/test_pro/test_pro3/obj/app2.o
gcc -c app2.c -o /home/zw/test_pro/test_pro3/obj/app2.o -I /home/zw/test_pro/test_pro3/app_1 -I /home/zw/test_pro/test_pro3/app_2
/home/zw/test_pro/test_pro3/obj/app2.o
make[1]: Leaving directory '/home/zw/test_pro/test_pro3/app_2'
make -C /home/zw/test_pro/test_pro3/app_main
make[1]: Entering directory '/home/zw/test_pro/test_pro3/app_main'
/home/zw/test_pro/test_pro3/obj/app_main.o
gcc -c app_main.c -o /home/zw/test_pro/test_pro3/obj/app_main.o -I /home/zw/test_pro/test_pro3/app_1 -I /home/zw/test_pro/test_pro3/app_2
/home/zw/test_pro/test_pro3/obj/app_main.o
make[1]: Leaving directory '/home/zw/test_pro/test_pro3/app_main'
gcc /home/zw/test_pro/test_pro3/obj/*.o -o test_app.bin -I /home/zw/test_pro/test_pro3/app_1 -I /home/zw/test_pro/test_pro3/app_2
➜ test_pro3 ./test_app.bin
main in
app1_init in
app1_t_init in
app2_init in
各个子目录也可以采用如下的统一的makefile,只需在顶层的clean种调用对应的子目录的clean即可
CUR_DIR = $(shell pwd)
SRC = $(wildcard *.c) # 获取当前目录下的所有.c文件
OBJ := $(patsubst %.c, %.o, $(SRC)) # 将所有的.c文件换成.o文件
BUILD_OBJ := $(CUR_DIR)/$(OBJ)
.PHONY : all clean LIB CPOBJ
all: LIB CPOBJ
$(info $(SRC) $(OBJ))
LIB: $(BUILD_OBJ)
#可以ar构建静态库
$(info $(BUILD_OBJ))
%.o: %.c
$(CC) -c $< -o $@ $(CFLAGS) $(DFLAGS)
CPOBJ:
-cp $(CUR_DIR)/*.o $(OBJ_DIR) -Rdf
clean:
-rm $(CUR_DIR)/*.o -rf
测试
➜ test_pro3 make clean all
make -C /home/zw/test_pro/test_pro3/app_1 clean
make[1]: Entering directory '/home/zw/test_pro/test_pro3/app_1'
app1_t.c app1.c app1_t.o app1.o
rm /home/zw/test_pro/test_pro3/app_1/*.o -rf
make[1]: Leaving directory '/home/zw/test_pro/test_pro3/app_1'
rm -rf /home/zw/test_pro/test_pro3/obj/*.o test_app.bin
will make project
mkdir -p /home/zw/test_pro/test_pro3/obj
make -C /home/zw/test_pro/test_pro3/app_1
make[1]: Entering directory '/home/zw/test_pro/test_pro3/app_1'
app1_t.c app1.c app1_t.o app1.o
gcc -c app1_t.c -o app1_t.o -I /home/zw/test_pro/test_pro3/app_1 -I /home/zw/test_pro/test_pro3/app_2
gcc -c app1.c -o app1.o -I /home/zw/test_pro/test_pro3/app_1 -I /home/zw/test_pro/test_pro3/app_2
/home/zw/test_pro/test_pro3/app_1/ app1_t.o app1.o
#可以ar构建静态库
cp /home/zw/test_pro/test_pro3/app_1/*.o /home/zw/test_pro/test_pro3/obj -Rdf
make[1]: Leaving directory '/home/zw/test_pro/test_pro3/app_1'
make -C /home/zw/test_pro/test_pro3/app_2
make[1]: Entering directory '/home/zw/test_pro/test_pro3/app_2'
/home/zw/test_pro/test_pro3/obj/app2.o
gcc -c app2.c -o /home/zw/test_pro/test_pro3/obj/app2.o -I /home/zw/test_pro/test_pro3/app_1 -I /home/zw/test_pro/test_pro3/app_2
/home/zw/test_pro/test_pro3/obj/app2.o
make[1]: Leaving directory '/home/zw/test_pro/test_pro3/app_2'
make -C /home/zw/test_pro/test_pro3/app_main
make[1]: Entering directory '/home/zw/test_pro/test_pro3/app_main'
/home/zw/test_pro/test_pro3/obj/app_main.o
gcc -c app_main.c -o /home/zw/test_pro/test_pro3/obj/app_main.o -I /home/zw/test_pro/test_pro3/app_1 -I /home/zw/test_pro/test_pro3/app_2
/home/zw/test_pro/test_pro3/obj/app_main.o
make[1]: Leaving directory '/home/zw/test_pro/test_pro3/app_main'
gcc /home/zw/test_pro/test_pro3/obj/*.o -o test_app.bin -I /home/zw/test_pro/test_pro3/app_1 -I /home/zw/test_pro/test_pro3/app_2