多个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
posted @ 2023-01-05 09:29  tccxy  阅读(560)  评论(0编辑  收藏  举报