将学习makefile的过程记录下,做个笔记,一是加深理解和记忆,二也方便日后遗忘了查找,因为自己也是边学边记录的,难免有很多问题,请多多指正和包涵
因为主要是学习makefile,所以开始只有一个main.c的函数,内容如下:
一.基本的makefile
main.c
#include <stdio.h>
int main(int argc,char** argv)
{
int i = 0;
int sum = 0;
printf("hello\n");
for(;i<10;i++)
{
sum += i;
}
printf("sum=%d\n",sum);
return 0;
}
https://blog.csdn.net/qq_33706673/article/details/78446928
这里不再详细介绍
makefile version1.0
#生成的目标文件是socket,\
依赖文件是main.o
socket:main.o
cc -o socket main.o
#编译main.c文件,生成main.o文件,依赖main.c文件
main.o:main.c
cc -c main.c
#clean命令,rm -rf表示删除时遇到错误(如没有文件等)继续执行
.PHONY:clean
clean:
rm -rf main.o socket
这里的#后面的是注释,如果注释一行写不完,可以用\,然后下一行的也是注释,如第一行
二.makefile中使用变量
上面的是最简单的情况,要是编译的文件比较多的话,可以用变量表示.o文件名称,简化makefile,当然变量不仅仅可以表示.o文件名
假设现在有main.c;test.c;test.h三个文件
/*main.c文件*/
#include <stdio.h>
#include "test.h"
int main(int argc,char** argv)
{
int i = 0;
int sum = 0;
test();
for(;i<10;i++)
{
sum += i;
}
printf("sum=%d\n",sum);
return 0;
}
/*test.c文件*/
#include <stdio.h>
#include "test.h"
void test()
{
printf("这是test.c文件的test函数\n");
}
/*test.h文件*/
void test();
先看没有用到变量正常编译的情况
#生成的目标文件是socket,依赖文件是main.o,test.o
socket:main.o test.o
cc -o socket main.o test.o
#编译main.c文件,生成main.o文件,依赖main.c文件
main.o:main.c
cc -c main.c
#编译test.c文件,生成test.o文件,依赖test.c,test.h
test.o:test.h test.c
cc -c test.c
.PHONY:clean
clean:
rm -rf main.o test.o socket
下面看使用了变量的情况
Makefile version2.1
#用变量object表示main.o和test.o文件
object = main.o test.o
#生成的目标文件是socket,依赖文件是main.o,test.o
socket:$(object)
cc -o socket $(object)
#编译main.c文件,生成main.o文件,依赖main.c文件
main.o:main.c
cc -c main.c
#编译test.c文件,生成test.o文件,依赖test.c,test.h
test.o:test.h test.c
cc -c test.c
.PHONY:clean
clean:
rm -rf $(object) socket
因为上面的文件比较少,所以使用变量的好处不是很明显,文件越多,使用变量的好处越明显,比如
2. 可以做到见名知意的好处
3. 其他。。。
三.Makefile里的打印信息
打印信息有很多的方法,这里只介绍一种,用@echo方式输出打印信息,格式如下:
一般情况下加上冒号比较好,echo执行完后自动换行,不需要加换行字符\n,加了的话相当于换2行
Makefile version3.0
#用变量object表示main.o和test.o文件
object = main.o test.o
#其他变量,做到见名知意
endReleaseFile = socket
#生成的目标文件是socket,依赖文件是main.o,test.o
$(endReleaseFile):$(object)
cc -o $(endReleaseFile) $(object)
@echo "链接main.o test.o,生成目标文件socket\n"
#编译main.c文件,生成main.o文件,依赖main.c文件
main.o:main.c
@echo 编译开始,请稍等... ...
cc -c main.c
@echo "编译main.c结束,生成mian.o,依赖main.c\n"
#编译test.c文件,生成test.o文件,依赖test.c,test.h
test.o:test.h test.c
cc -c test.c
@echo "编译test.c结束,生成test.o,依赖test.c test.h\n"
.PHONY:clean
clean:
rm -rf $(object) socket
@echo "删除main.o test.o socket文件\n"
在打印的时候也可以直接使用变量打印变量的内容
四.Makefile中的编译命令
比如我现在想做几个命令
make c :make clean的简写命令
make r :make rebuild;不管是不是最新的.o和目标文件都强制重新编译
五.Makefile中其他说明
1. linux命令
2. 删除没有的文件时报错
rm命令参数
-r,-R,--recursive
递归地移除目录中的内容。
-f,--force
忽略不存在的文件,并且从不向用户提示。
rm 加上 -f的选项,这样,即使要删除的文件不存在,也不提示报错。
rm 加上 -r的选项,可以递归删除文件夹。
所以一般使用rm -rf命令
3. 目标文件中的.o文件的顺序与下面谁先编译的顺序无关
即这里的test.o和main.o与下面是先编译test.c还是先编译main.c无关