学习目的:
掌握源文件在不同文件夹下Makefile文件的编写
掌握每个多级Makefile文件编写
总结:
1- 删除当前文件下的所有.o文件及可执行文件test命令:
find ./ -name "*.o" -exec rm {} \;;rm test
2- 可执行文件名不能和当前路径下的文件夹重名,否则编译出错!!
源文件在不同文件夹
a- 文件分布
ls -R //查看当前文件夹下文件拓扑
由上可知,当前文件夹下有一个Makefile文件、三个文件夹(include、main、test1),这三个文件夹下分别有三个文件:head.h,main.c,test1.c
b- Makefile文件编写
由于源文件和头文件在不同的文件夹,Makefile文件在根目录,所以编写Makefile文件生成对应的.o、可执行文件时要加路径。
注:当使用VPATH时候,对于生成.o的命令一定要使用$^ $@,否则很容一编不过。除了用路径的方式.o文件和.c文件在一块,其余的.o文件都在根路径下(Makefile路径下)
附:如果非得使用路径也可以,对于.c文件使用路径,但.o文件一使用路径就报错,也就是.o文件会生成到根Makefile路径下。
I- 原始版
#Makefile
CC=gcc
CFLAGS=-c -Wall -I include
test:test1/test1.o main/main.o
$(CC) test1/test1.o main/main.o -o test
test1/test1.o:test1/test1.c
$(CC) $(CFLAGS) test1/test1.c -o test1/test1.o
main/main.o:main/main.c
$(CC) $(CFLAGS) main/main.c -o main/main.o
.PHONY:clean
clean:
find ./ -name "*.o" -exec rm {} \;;rm test
II- 自动变量替换
使用自动变量替换后,简化了Makefile脚本,但是还是有路径,看着很长。
#Makefile
CC=gcc
CFLAGS=-c -Wall -I include
test:test1/test1.o main/main.o
$(CC) $^ -o test
test1/test1.o:test1/test1.c
$(CC) $(CFLAGS) $^ -o $@
main/main.o:main/main.c
$(CC) $(CFLAGS) $^ -o $@
.PHONY:clean
clean:
find ./ -name "*.o" -exec rm {} \;;rm test
III- 隐式推导
使用隐式推导后,大大简化了Makefile脚本,但是还是有路径,看着很长。注意生成可执行文件的语句不可以省略!!
#Makefile
CC=gcc
CFLAGS=-c -Wall -I include
test:test1/test1.o main/main.o
$(CC) test1/test1.o main/main.o -o test
.PHONY:clean
clean:
find ./ -name "*.o" -exec rm {} \;;rm test
IV- 加入虚路径VPATCH
文件路径可以用空格、冒号”:“分割开来。
#Makefile
CC=gcc
CFLAGS=-c -Wall -I include
#添加虚路径
VPATH=test1 main include
#这里可以去掉路径了,因为Makefile会去VPATH中查找
test:test1.o main.o
$(CC) $^ -o test
.PHONY:clean
clean:
find ./ -name "*.o" -exec rm {} \;;rm test
不使用隐式推导
#Makefile
CC=gcc
CFLAGS=-c -Wall -I include
VPATH=test1 include main
test:test1.o main.o
$(CC) test1.o main.o -o test
test1.o:test1.c
$(CC) $(CFLAGS) $^ -o $@
main.o:main.c
$(CC) $(CFLAGS) $^ -o $@
.PHONY:clean
clean:
find ./ -name "*.o" -exec rm {} \;;rm test
其他:
1- clean命令
find ./ -name "*.o" -exec rm {} \;;rm test //删除本路径下*.o文件、可执行文件test
/*拆解*/
/*1- 查找.o文件,双引号可以去了*/
find ./ -name "*.o"
/*2- 删除*.o文件*/
find ./ -name "*.o" -exec rm {} \;
/*3- 删除可执行文件及.o文件*/
find ./ -name "*.o" -exec rm {} \;;rm test
2- 编译错误
gcc -c -Wall -I include test1/test1.c -o test1/test1.o
gcc -c -Wall -I include main/main.c -o main/main.o
gcc test1/test1.o main/main.o -o main
/usr/bin/ld: cannot open output file main: Is a directory
collect2: error: ld returned 1 exit status
Makefile:6: recipe for target 'main' failed
make: *** [main] Error 1
上述编译错误是因为,刚开始可执行文件名为main,而在当前文件路径下有个main的文件夹,由于可执行文件名和目录名重复了。所以报错,把可执行文件名改成其他的就好了。