目录
- 1、基本格式如下:
- 2、GCC编译过程
- 3、Makefile具体流程可参考下图:
- 4、Makefile变量解析![在这里插入图片描述](https://img-blog.csdnimg.cn/50fdafadef79400abea65b64a12f8ec8.png)
- 5、实例
- 项目目录
- 5.1 使用g++直接编译
- 5.2 Version 1
- 5.3 Version 2
- 5.4 Version 3
- 5.5 Version 4
- 6、常见的自动化变量
- 7、参考链接
1、基本格式如下:
targets: prerequisites
command
targets:规则的目标,可以是 Object File(一般称它为中间文件),也可以是可执行文件,还可以是一个标签;
prerequisites:是我们的依赖文件,要生成 targets 需要的文件或者是目标。可以是多个,也可以是没有;
command:make 需要执行的命令(任意的 shell 命令)。可以有多条命令,每一条命令占一行。
2、GCC编译过程
GCC即GNU Compiler Collection。gcc编译过程分为4个阶段:预处理、编译、汇编、链接。
预处理(也称预编译,Preprocessing):头⽂件包含、宏替换、条件编译、删除注释
编译(Compilation):主要进⾏词法、语法、语义分析等,检查⽆误后将预处理好的⽂件编译成汇编⽂件。
汇编(Assembly):将汇编⽂件转换成 ⼆进制⽬标⽂件
链接(Linking):将项⽬中的各个⼆进制⽂件+所需的库+启动代码链接成可执⾏⽂
gcc可以理解为编译管理工具,它会具体调用相关的工具进行执行,具体如下图:
3、Makefile具体流程可参考下图:
4、Makefile变量解析
5、实例
项目目录
项目文件夹hello,及文件main.cpp,factorial.cpp,printhello.cpp,functions.h
hello目录如下
main.cpp
#define _FUNCTIONS_H_
#include <iostream>
#include "functions.h"
using namespace std;
int main()
{
printhello();
cout << "This is main:" << endl;
cout << "The factorial of 5 is:" << factorial(5) << endl;
return 0;
}
printhello.cpp
#include <iostream>
#include "functions.h"
using namespace std;
void printhello()
{
int i;
cout << "Hello World!" << endl;
}
factorial.cpp
#include "functions.h"
int factorial(int n)
{
if (n==1)
return 1;
else
return n * factorial(n-1);
}
functions.h
#ifdef _FUNCTIONS_H_
#define _FUNCTIONS_H_
void printhello();
int factorial(int n);
#endif
5.1 使用g++直接编译
g++ main.cpp factorial.cpp printhello.cpp -o Hello
./Hello
5.2 Version 1
hello: main.cpp printhello.cpp factorial.cpp
g++ -o hello main.cpp printhello.cpp factorial.cpp
5.3 Version 2
CXX = g++
TARGET = hello
OBJ = main.o printhello.o factorial.o
$(TARGET): $(OBJ)
$(CXX) -o $(TARGET) $(OBJ)
main.o: main.cpp
$(CXX) -c main.cpp
printhello.o: printhello.cpp
$(CXX) -c printhello.cpp
factorial.o: factorial.cpp
$(CXX) -c factorial.cpp
5.4 Version 3
CXX = g++
TARGET = hello
OBJ = main.o printhello.o factorial.o
CXXFLAGS = -c -Wall
$(TARGET): $(OBJ)
$(CXX) -o $@ $^
%.o: %.cpp
$(CXX) $(CXXFLAGS) $< -o $@
.PHONY: clean
clean:
rm -f *.o $(TARGET)
5.5 Version 4
CXX = g++
TARGET = hello
SRC = $(wildcard *.cpp)
OBJ = $(patsubst %.cpp, %.o, $(SRC))
CXXFLAGS = -c -Wall
$(TARGET): $(OBJ)
$(CXX) -o $@ $^
%.o: %.cpp
$(CXX) $(CXXFLAGS) $< -o $@
.PHONY: clean
clean:
rm -f *.o $(TARGET)
6、常见的自动化变量
.PHONY,makefile的特殊变量。以clean为例,第一种情况,我们不需要生成"clean"这个文件,另一种情况“clean”目标与文件"clean"重名时,目标不会执行。所以我们需要一个"伪目标"去执行makefile中的“clean”下面的命令。
wildcard,用于防止通配符解析失败。使变量定义时,括号里的通配符仍然生效。
patsubst,用于防止替换文件解析失效。替换文件后缀。
7、参考链接
B站-于仕琪,Makefile 20分钟入门
快乐的学习—Makefile语法详细总结及示例解析