目录
文件结构图
C:\XULF\笔记\TEST3
│ README.txt
│
└─make1
│ main.c
│ main.h
│ main.out
│ makefile
│ run.sh
│
├─driver1
│ │ animal.c
│ │ animal.h
│ │ makefile
│ │
│ ├─cat
│ │ cat.c
│ │ cat.h
│ │
│ ├─dog
│ │ dog.c
│ │ dog.h
│ │
│ └─obj
├─driver2
│ │ birds.c
│ │ birds.h
│ │ makefile
│ │
│ └─obj
└─driver3
│ makefile
│ monkey.c
│ monkey.h
│
└─obj
READEME.txt
make1:makefile的嵌套使用示例,driver1,driver2,driver3分别模拟了不同的驱动程序,每一个driver内部都有一个子makefile,
由顶层makefile调用,生成中间文件供顶层makefile使用,driver2,driver3中生成的中间文件为.o,driver1中由于源文件太多,每一个源文件
又必须只能对应一个.o文件,所以为了顶层makefile简单一点,逻辑上更清晰一点,我把所有的.o文件集中起来生成了一个静态库,供顶层makefile调用
run.sh:为本例程编写的一个shell脚本,需先执行make all 命令调用所有子makefile生成中间文件,再make生成可执行文件,run.sh简化了命令输入
步骤。
make1根目录下的makefile
CLEAN :=make clean
PRJNAME := main
#头文件路径声明,后续如果有新的头文件路径,在这里添加
INCDIRS := driver1 \
driver1/cat \
driver1/dog \
driver2 \
driver3
#源文件路径声明,后续如果有新的源文件路径,在这里添加
#如果驱动目录涉及静态库编入,则不需要在此处添加,转而在“LIBINSTRUCTION”手动添加库包含指令
#此处drver1用的是静态库
SRCDIRS := ./ \
driver2 \
driver3
#-L 指明静态库所在路径,-l指明静态库名字
#静态库的命名规则为lib$(库名).a,所以此处用到的库全称为libanimal.a
LIBINSTRUCTION:=-L ./driver1 -lanimal
#筛选SRCDIRS路径下的所有.c文件,带路径返回
CFILES := $(foreach dir, $(SRCDIRS),$(wildcard $(dir)/*.c))
#所有C文件去路径
CFILENDIR :=$(notdir $(CFILES))
#把去路经后的所有.c后缀变成.o,就成了依赖文件合集
OBJFILES :=$(CFILENDIR:.c=.o)
#匹配每个INCDIRS字符,加 -I 参数返回,字符间以空格分开
INCLUDE := $(patsubst %, -I %, $(INCDIRS))
#告诉makefile,所有的.o文件,如果在当前目录下找不到,按顺序依次去以下目录找
vpath %.o driver1/obj : driver2/obj : driver3/obj
#目标程序
$(PRJNAME).out:$(OBJFILES)
gcc $(INCLUDE) $^ -o $@ $(LIBINSTRUCTION)
#声明main.o的生成方法
#如果不写此方法,makefile利用隐式规则执行的语句为:gcc -c main.c -o main.o 但是隐式规则中没有声明头文件去哪里找,所以必须显式地写出来
#显式写出后正确的makefile执行语句为:gcc -c -I driver1 -I driver2 -I driver3 main.c -o main.o
$(PRJNAME).o:$(PRJNAME).c
gcc -c $(INCLUDE) $^ -o $@
.PHONY:all driver1 driver2 driver3 clean
all : driver1 driver2 driver3
#-s静默输出
driver1:
cd driver1 && $(MAKE) -s
#$(MAKE) -C driver1
driver2:
cd driver2 && $(MAKE) -s
#$(MAKE) -C driver2
driver3:
cd driver3 && $(MAKE) -s
#$(MAKE) -C driver3
clean:
rm -f *.o *.out
cd driver1 && $(CLEAN) -s
cd driver2 && $(CLEAN) -s
cd driver3 && $(CLEAN) -s
make1根目录下的run.sh
#!/bin/bash
make all
make
driver1目录下的makefile
OBJ := obj/
LIBNAME := animal
INCDIRS := ./ \
cat \
dog
SRCDIRS := ./ \
cat \
dog \
CFILES := $(foreach dir,$(SRCDIRS),$(wildcard $(dir)/*.c))
CFILENDIR := $(notdir $(CFILES))
OBJFILES := $(CFILENDIR:.c=.o)
OBJS := $(patsubst %, obj/%, $(OBJFILES))
INCLUDE := $(patsubst %, -I %, $(INCDIRS))
VPATH := $(SRCDIRS)
#生成静态库
lib$(LIBNAME).a:$(OBJS)
ar -rsv $@ $(OBJS)
$(OBJ)%.o:%.c
gcc -c $(INCLUDE) $< -o $@
.PHONY:clean
clean:
rm -rf obj/*.o *.out *.a
driver2目录下的makefile
OBJ := obj/
$(OBJ)birds.o:birds.c
gcc -c $< -o $@
.PHONY:clean
clean:
rm -rf obj/*.o
driver3目录下的makefile
OBJ := obj/
$(OBJ)monkey.o:monkey.c
gcc -c $< -o $@
.PHONY:clean
clean:
rm -rf obj/*.o