编写的Makefile正确姿势

为什么要编写makefile:makefile是指一个工程中的源文件不计其数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的规则来指定哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作,因为 makefile就像一个Shell脚本一样,也可以执行操作系统的命令

一个基本的makefile应该包含哪些功能:生成目标文件,清理临时文件。

1.编写只有main.cpp的makefile

首先写一段测试代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include "iostream"

int find_max(int arr[],int size){
int max = 0;
for(int i = 0; i < size; i++){
if(max < arr[i])
max = arr[i];
}
return max;
}
int main(){
int arr[6] = {1,8,5,9,10,6};
int res = find_max(arr,6);
std::cout<<"the max num = "<<res<<"\n";
return 0;
}



之后编写makefile文件

terminal中输入vim makefile

1
vim makefile

按照makefile的格式输入

1
2
3
4
5
6
main: mian.cpp
g++ main.cpp -o main

clean:
rm *.o

之后赋权运行

1
2
chmod 755 makefile
make

可以看到terminal中输出

1
g++ main.cpp -o main

我们在ls看一下

1
main     main.cpp makefile test

然后依旧是赋权运行

1
2
chmod 755 main
./main

到此,最简单的makefile已经编写完成,当然,实际工程中makefile肯定不会是这么简单的一个源文件的编写,会涉及到不同编译器编译选项多个源文件多个目标文件的makefile。因此,下面依依进行讲解

不同编译器,不同编译选项,多个源文件makefile编写

编写测试文件

main.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include "iostream"
#include "find_min.hpp"

int find_max(int arr[],int size){
int max = 0;
for(int i = 0; i < size; i++){
if(max < arr[i])
max = arr[i];
}
return max;
}
int main(){
int arr[6] = {1,8,5,9,10,6};
int res_max = find_max(arr,6);
std::cout<<"the max num = "<<res_max<<"\n";
int res_min = find_min(arr,6);
std::cout<<"the min num = "<<res_min<<"\n";
return 0;
}

find_min.hpp

1
2
#include "iostream"
int find_min (int arr[],int size);

find_min.cpp

1
2
3
4
5
6
7
8
9
10
11
#include "find_min.hpp"

int find_min (int arr[],int size){
int min = INT_MAX;
for(int i = 0; i < size; i++){
if(arr[i] < min)
min = arr[i];
}
return min;
}

我们先以正常的方式生成目标文件并运行

1
2
g++ main.cpp find_min.cpp -o main
./main

可以得到如下结果

1
2
the max num = 10
the min num = 1

之后我们编写相应的makefile

1
2
3
4
5
6
main: main.cpp find_min.o
g++ main.cpp find_min.o -o main

find_min.o:
g++ -c find_min.cpp
clean: rm *.o

make后terminal输出如下结果

1
2
g++ -c find_min.cpp
g++ main.cpp find_min.o -o main

ls查看生成文件

1
find_min.cpp find_min.hpp find_min.o   main         main.cpp     makefile

之后我们定义编译器和编译选项

1
vim makefile

修改成如下

1
2
3
4
5
6
7
8
9
10
11
translater = g++
opt_c = -c
opt_o = -o

main: main.cpp find_min.o
$(translater) main.cpp find_min.o $(opt_o) main

find_min.o:
$(translater) $(opt_c) find_min.cpp
clean:
rm *.o main

之后运行

1
make clean

输出如下

1
rm -rf *.o main

我们ls看一下

1
find_min.cpp find_min.hpp main.cpp     makefile

可以看见.o和main文都被删除

之后我们在运行make输出

1
g++ main.cpp find_min.o -o main

多个.cpp文件生成一个main文件

编写测试文件

find_arr.hpp

1
2
3
#include "iostream"
int find_arr (int arr[],int size);

find_arr.cpp

1
2
3
4
5
6
7
8
9
#include"find_arr.hpp"

int find_arr (int arr[],int size){
for(int i = 0; i < size; i++)
std::cout<<arr[i]<<"\t";
std::cout<<"\n";
return 0;
}

main.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include "iostream"
#include "find_min.hpp"
#include "find_arr.hpp"

int find_max(int arr[],int size){
int max = 0;
for(int i = 0; i < size; i++){
if(max < arr[i])
max = arr[i];
}
return max;
}
int main(){
int arr[6] = {1,8,5,9,10,6};
int res_max = find_max(arr,6);
std::cout<<"the max num = "<<res_max<<"\n";
int res_min = find_min(arr,6);
std::cout<<"the min num = "<<res_min<<"\n";
find_arr(arr,6);
return 0;
}

修改makefile

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
translater = g++
opt_c = -c
opt_o = -o

main: main.cpp find_min.o find_arr.o
$(translater) main.cpp find_min.o find_arr.o $(opt_o) main

find_min.o:
$(translater) $(opt_c) find_min.cpp

find_arr.o:
$(translater) $(opt_c) find_arr.cpp

clean:
rm -rf *.o main

make运行结果

1
2
3
g++ -c find_min.cpp
g++ -c find_arr.cpp
g++ main.cpp find_min.o find_arr.o -o main

ls查看

1
2
find_arr     find_arr.hpp find_min.cpp find_min.o   main.cpp
find_arr.cpp find_arr.o find_min.hpp main makefile

生成多个目标文件的makefile编写

首先编写测试文件

find_arr.hpp

1
2
#icnlude "iostream"
int find_arr (int arr[].int size);

find_arr.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include"find_arr.hpp"

int find_arr (int arr[],int size){
for(int i = 0; i < size; i++)
std::cout<<arr[i]<<"\t";
std::cout<<"\n";
return 0;
}

int main(){
int arr[] = {1,2,3,4,5};
find_arr(arr,5);
return 0;
}

修改makefile

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
translater = g++
opt_c = -c
opt_o = -o

all: main find_arr

find_arr:
$(translater) find_arr.cpp $(opt_o) find_arr
main: main.cpp find_min.o
$(translater) main.cpp find_min.o $(opt_o) main

find_min.o:
$(translater) $(opt_c) find_min.cpp
clean:
rm -rf *.o main

make一下输出

1
2
3
g++ -c find_min.cpp
g++ main.cpp find_min.o -o main
g++ find_arr.cpp -o find_arr

结尾

常用的makefile编写已经掌握,此文用于记录echo的学习历程。