说明
make1~make3都是完成的一样的工程编译内容,但是目录结构不一样,3个makefile完成的任务都是编译三个可执行文件,语法为:all:prog1 prog2 prog3<换行>.PHONY:all。即,先告诉makefile all目标有三个依赖,然后再告诉makefile all不是目标,是一个伪目标,所以all的三个依赖也不是依赖,会被当成三个目标按顺序生成。
目录结构
make1:所有的工程文件都会被分类放在单独的文件夹中,每个文件夹中有该单个工程的源文件和头文件。makefile在顶级目录。
make2:所有的源文件和头文件都放在了不同的文件夹中,所有源文件在src中,所有头文件在headers中。
make3:只有头文件放在了headers中,其他的所有源文件和makefile放在顶层目录。
异同点:
make2和make3目录结构类似但是make2的makefile却多了很多内容的原因是原来make2中目标生成包含了makefile的隐式规则,例如:“prog1: prog1.o utils.o”,这句话告诉makefile生成prog1需要先生成prog1.o uils.o这两个文件,makefile就会在同级目录去找这两个文件,找不到再根据写出来的规则生成它,但是如果没有写出它的生成规则,那么makefile就会执行隐式规则,即按照他原来的名字去找.c和.h,在同级目录调用gcc生成他:gcc prog1.c prog1.h -o prog1.o,但是gcc找不到prog1.h和prog1.c,所以这个时候就必须手动编写所有.o的生成方法,告诉gcc :.c文件和.h文件在哪里找。
VPATH的作用应该是告诉makefile源文件去哪里找,但是不能按照这个规则去找头文件,make1中不用额外告诉gcc头文件在哪里找的原因应该是makefile已经告诉了gcc源文件在哪里,所以根据隐式规则,生成.o文件的gcc 应该是这样的: gcc ./progFolder/prog1.c -o prog1.o,然后gcc会根据.c文件在他的同级目录寻找.h文件。
Tips:
- gcc -o的作用是取别名,gcc -c的作用是生成.o文件,即只编译,不链接。
- 目标名,中间文件名不要和文件夹名一样,不然make clean 的时候会误删文件夹。
目录结构图
C:TEST1
│
│ 说明.docx
│
├─make1
│ │ makefile
│ │
│ ├─prog1Folder
│ │ prog1.c
│ │ prog1.h
│ │
│ ├─prog2Folder
│ │ prog2.c
│ │ prog2.h
│ │
│ ├─prog3Folder
│ │ prog3.c
│ │ prog3.h
│ │
│ ├─sort
│ │ sort.c
│ │ sort.h
│ │
│ └─utils
│ utils.c
│ utils.h
│
├─make2
│ │ makefile
│ │ prog1
│ │ prog2
│ │ prog3
│ │
│ ├─headers
│ │ prog1.h
│ │ prog2.h
│ │ prog3.h
│ │ sort.h
│ │ utils.h
│ │
│ └─src
│ prog1.c
│ prog2.c
│ prog3.c
│ sort.c
│ utils.c
│
└─make3
│ makefile
│ prog1.c
│ prog2.c
│ prog3.c
│ sort.c
│ utils.c
│
└─headers
prog1.h
prog2.h
prog3.h
sort.h
utils.h
make1里的makefile:
VPATH=prog1Folder:prog2Folder:prog3Folder:sort:utils
all:prog1 prog2 prog3
.PHONY:all clean
prog1: prog1.o utils.o
cc -o prog1 prog1.o utils.o
prog2: prog2.o
cc -o prog2 prog2.o
prog3: prog3.o utils.o sort.o
cc -o prog3 prog3.o utils.o sort.o
clean:
rm -rf *.o *.h.gch prog1 prog2 prog3 *.out
make2里的makefile:
INCLUDES=-I headers
#VPATH=src
all:prog1 prog2 prog3
.PHONY:all clean
prog1: prog1.o utils.o
cc $(INCLUDES) -o prog1 prog1.o utils.o
prog2: prog2.o
cc $(INCLUDES) -o prog2 prog2.o
prog3: prog3.o utils.o sort.o
cc $(INCLUDES) -o prog3 prog3.o utils.o sort.o
prog1.o:
cc $(INCLUDES) -c -o prog1.o ./src/prog1.c
prog2.o:
cc $(INCLUDES) -c -o prog2.o ./src/prog2.c
prog3.o:
cc $(INCLUDES) -c -o prog3.o ./src/prog3.c
utils.o:
cc $(INCLUDES) -c -o utils.o ./src/utils.c
sort.o:
cc $(INCLUDES) -c -o sort.o ./src/sort.c
clean:
rm -rf *.o *.h.gch prog1 prog2 prog3 *.out
make3里的makefile:
INCLUDES=-I headers
all:prog1 prog2 prog3
.PHONY:all clean
prog1:
cc $(INCLUDES) -o prog1 prog1.c utils.c
prog2:
cc $(INCLUDES) -o prog2 prog2.c
prog3:
cc $(INCLUDES) -o prog3 prog3.c utils.c sort.c
clean:
rm -rf *.o *.h.gch prog1 prog2 prog3 *.out