《跟我一起写Makefile》记录(一)

声明:本文记录本人看网络上关于Makefile的文档《跟我一起写Makefile》(陈皓 写),其中主要讲述了GUN Make 自动化编译工具的运用。本人以linux/C++角度学习Make,博文中加入了一些我个人的一些理解。

1.编译、链接、中间文件、库文件

编译: 将C++源码 使用g++编译器 生成 .o 文件的过程称为编译。
链接: 将多个.o文件 生成一个可执行程序的过程称为链接。
中间文件: 从源代码 到最后的可执行文件中间的 文件形态称为中间文件。比较典型的有.o 文件
库文件: 将多个.o 文件进行打包,以便于在生成可执行程序时,不需要显示的将每个.o文件的名字都打出来。

2.Make 执行规则

file1:main.h
#pragma once
void print_hello();
void print_nihao();

file2:main.cpp
#include <iostream>
#include "main.h"
int main()
{
    print_hello();
    print_nihao();
    return 0;
}

file3:print_hello.cpp
#include <iostream>
using namespace std;
void print_hello()
{
    cout << "hello3" << endl;
}

file4:print_nihao,cpp
#include <iostream>
using namespace std;
void print_nihao()
{
    cout << "nihao" << endl;
}
file5:makefile

main:main.o print_hello.o print_nihao.o                     #规则1
    g++ -o main main.o print_hello.o print_nihao.o          #command1
main.o:main.cpp                                             #规则2
    g++ -c -o main.o main.cpp                               #command2
print_hello.o:print_hello.cpp                               #规则3
    g++ -c -o print_hello.o print_hello.cpp                 #command3
print_nihao.o:print_nihao.cpp                               #规则4
    g++ -c -o print_nihao.o print_nihao.cpp                 #command4

以上面的简单代码举例:

  • (1)首先make会在当前文件夹中去找 Makefile 或者 makefile文件,作为make的执行文件

  • (2) 在make找到其执行的文件后,make会在文件中寻找第一个需要生成的目标文件,作为最终执行的目标。(上述示例中的main会作为最终目标)

  • (3) 如果main 文件存在且依赖文件存在
    make会检查 依赖文件(.o文件) 和 生成依赖文件的 依赖文件(cpp文件)的时间戳
    如果cpp 文件比.o文件的时间戳新,那么make会依据时间戳会执行command2 command3 command4其中的某些,重新生成.o 文件。这就导致 生成main文件的依赖文件的时间戳比main文件的时间戳更新,于是执行command1 重新生成main 文件。如果*.o 文件是最新的,那么make回去检查 main 文件和*.o文件的时间戳,如果main文件也是最新的,那么make什么也不做。如果main文件不是最新的,那么会执行comman1 重新生成 main文件。

  • (4) 如果 main文件存在且依赖文件不存在
    首先,make 会寻找生成 main.o 的规则 ,找到了规则2, 然后会执行command2,于是生成了main.o。接着,make 会寻找生成 print_hello.o 的规则,找到了规则3,然后执行command3,生成了print_hello.o。最后,make 会寻找生成 print_nihao.o 的规则,找到了规则4,然后执行command4,生成了print_nihao.o。

  • (5) 如果main 文件不存在 但是依赖文件存在
    make会检查 依赖文件(.o文件) 和 生成依赖文件的 依赖文件(cpp文件)的时间戳,如果cpp 文件比.o文件的时间戳新,那么make会依据时>间戳会执行command2 command3 command4其中的某些,重新生成.o 文件。这就导致 生成main文件的依赖文件的时间戳比main文件的时间戳更新,于是执行command1 重新生成main 文件。

  • (6)如果main 文件不存在 且依赖文件不存在
    首先,make 会寻找生成 main.o 的规则 ,找到了规则2, 然后会执行command2,于是生成了main.o。接着,make 会寻找生成 print_hello.o 的规则,找到了规则3,然后执行command3,生成了print_hello.o。最后,make 会寻找生成 print_nihao.o 的规则,找到了规则4,然后执行command4,生成了print_nihao.o。

总之,无论最终的目标的依赖文件是否存在,make都会层层的检查依赖关系的时间戳。

3、make引入变量

为了便于 相同批量的 .o 文件的名字 多次使用,可以在make中使用变量,make中变量名对于大小写不敏感。

#举例
#原始写法
main:main.o a.o b.o c.o
	g++ -o main main.o a.o b.o c.o
	
#定义变量后的写法
obj = main.o a.o b.o c.o
main:$(obj)
	g++ -o main $(obj) 
make引入变量的好处:
  • 避免批量的名字 写多次
  • 当批量名字需要追加时 只需要改动一个位置

4. make的自动推导

  • (1)make看到.o文件,会自动的将.cpp文件加到依赖关系中。
  • (2)当将.o文件对应的.cpp 文件添加到依赖关系后,make会自动的推导出 .cpp 生成 .o的命令:
cc -o x -c x.cpp

因此我们可以将make的规则 简化。(不需要再写其依赖的源文件,也不需要在写生成.o的命令)
于是我们例子中的代码可以简化为:

file5:makefile

main:main.o print_hello.o print_nihao.o                     #规则1
    g++ -o main main.o print_hello.o print_nihao.o          

规则2、规则3、规则4、规则5 make会自动的推导出来。make 的这种自动推导的规则被称为隐晦规则

5、 伪目标

make可以定义伪目标,伪目标类似于C语言中的label, 只有显示的声明生成该目标,make才会执行生成该目标的命令。在makefile中通常要有一个clean伪目标,用于清空编译过程中生成的中间文件,通常的写法如下:

.PHONY:clean
clean:
	-rm -rf *.o main

注意:

  • rm 前的-号是指 忽略发生的问题,继续执行。
  • clean目标有一个不成文的规定,一般clean目标放在makefile文件的最末尾。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值