Makefile是一种用于工程管理的规则,一个工程中的源文件不计其数,如何通过一定的规范来指定哪些源文件需要编译,哪些源文件需要忽略,这一点很重要,Makefile提供了一种很好的工程管理的规则来实现对整个项目的编译和配置,试想而知,当一个工程包含几千个源文件和头文件的时候,你仅仅通过单条的命令一个一个的进行编译将是非常大的工程。
用户只需要通过简单的一句make指令就能实现对这个工程文件的类似一个脚本文件的实现,其基本语法是:
Target:prerequisite
command
Target正如英文的意思指的是目标,prerequisite指的是依赖,command表示的是命令(注意:command前面必须用TAB键分隔,不然将不会成功),Target:prerequisite指定了两者的关系,说明要生成这些目标需要依赖某些文件,所有两者是有联系的。
比如,在开发中,我们会有一些文件,比如main.c、add.c、sub.c ,同时提供其对于的头文件为common.h 、add.h、sub.h
其对应的文件编写如下:
参考代码:https://download.csdn.net/download/qq_40793742/10406919
//---------main.c---------------
#include <stdio.h>
#include "add.h"
#include "sub.h"
void main()
{
int a = 1;
int b = 2;
printf("add is %d\n", add(a,b));
printf("sub is %d\n", sub(a,b));
}
//------------add.c-----------------
#include "add.h"
int add(int x, int y)
{
return x+y;
}
//------------sub.c-----------------
#include "sub.h"
int sub(int x, int y)
{
return x-y;
}
//------------add.h-----------------
#ifndef _ADD_H_
#define _ADD_H_
#include <stdio.h>
int add(int x, int y);
#endif /*_ADD_H_*/
//------------sub.h-----------------
#ifndef _SUB_H_
#define _SUB_H_
#include <stdio.h>
int sub(int x, int y);
#endif /*_SUB_H_*/
生成上述这些文件的TARGET文件,可以通过
方式一:直接生成目标文件 gcc -o TARGET main.c add.c sub.c 最终生成ELF文件 x86 |
方式二:有时候我们还需要产生中间的.o文件以便我们进行分析和链接 在linux下面我们知道,要编译这些文件我们可以分别将这些文件先只编译不链接,生成各自的.o文件 通过gcc -c xxx.c arm-linux-gcc -c *.c (这里的*.c表示任意的.c文件,分开写sub.c main.c add.c) gcc -o TARGET *.o (这里*.表示所有的.o文件 分开写 sub.o main.o add.o) |
方式三:同时也可以创建一个脚本文件来实现上述功能 #vi genbash 编写下面的内容 #!/bin/bash arm-linux-gcc -c *.c gcc -o TARGET *.o
保存后, 通过终端运行 #bash genbash 来生成代码 |
那么运用Makefile会有什么好处呢?
下面分三种情况来说明Makefile的优势
#vi Makefile
下面探讨一下下面三个Makefile程序,实现的功能是一样的,你会选择哪个? //------------------------ TARGET:main.c sub.c add.c rm -f TARGET //------------------------
TARGET:main.o sub.o add.o rm -f *.o TARGET //------------------------ CC := gcc $(CC) -o $@ $^ %.o:%.c$(CC) -c $^ clean: rm -f *.o TARGET
//------------------------ CC := gcc rm -f *.o TARGET //------------------------ |
编写Makefile,通过终端输出make即可实现对所有文件的编译工作,是不是很强大
上面引入的伪目标和
伪目标的格式
.PHONY : NAME
NAME :
Command
可见伪目标和Makefile的规则相似,通过 .PHONY声明它是伪目标,不过现在的编译器做的已经不错了,现在也可以不要加入
.PHONY : NAME也能识别是伪目标。通过伪目标可以方便的实现清除,下载等工作,比如
make clean (清除工作)
make write2sd ( 迅速将文件写到SD卡)
伪目标和Makefile的规则不要的是它不需要依赖关系,这是它俩的区别所在
在第三个Makefile和第四个Makefile中引入的一些变量,其概念如下:
# $@: 目标集合
# $<: 依赖中的第一个
# $^: 所有依赖文件集合
# %.o: 所有的.o
# %.c:所有的.c文件
参考:https://blog.csdn.net/haoel/article/details/2886/ 陈皓 跟我一起写Makefile