当前位置: 首页 > news >正文

Makefile学习(一)- 基础规则

一、简介

        Makefile是一种用于自动化编译和构建程序的配置文件,广泛应用于 C/C++ 等项目的构建过程。它通过定义 “规则” 来指定文件之间的依赖关系和编译命令让make工具能够自动判断哪些文件需要重新编译,从而提高开发效率。      

        核心作用

        自动化构建无需手动输入冗长的编译命令(如 gcc -o program file1.c file2.c ...),只需执行 make 命令即可完成整个项目的编译。

        增量编译只重新编译修改过的文件及其依赖项,而非整个项目,大幅节省时间(尤其适合大型项目)。

        统一管理:将项目的编译规则、依赖关系、清理操作等集中在一个文件中,便于维护。

 Makefile最基本的语法规则为:

目标(target): 依赖(prerequisites)命令(command)
  • 目标:通常是要生成的文件(如可执行文件、.o 目标文件),也可以是 “伪目标”(如 clean,用于定义清理操作)。
  • 依赖:生成目标所需要的文件(如源代码、.h 头文件)。
  • 命令:生成目标的具体操作(如编译命令),必须以 Tab 键开头(不能用空格)。

二、实例

            创建a.c、b.c文件,内容如下:

    ##### a.c#include <stdio.h>extern void func_b(void);int main(void)
    {printf("this is a\r\n");func_b();return 0;
    }
    
    ##### b.c#include <stdio.h>void func_b(void)
    {printf("this is b\r\n");
    }
    

           gcc

            如果不用Makefile文件,可以使用gcc指令进行编译。

    gcc -o test a.c b.c

            可以看到,最终生成的应用程序执行正常。

            这里需要注意的是,实例中只使用了a.c和b.c两个文件,所以使用gcc指令可以直接进行编译。但是一个正常的项目,文件通常有几百上千个文件,如果用gcc指令,那么命令将会非常长,例如gcc -o test a.c b.c c.c d.c..............1000.c。显然这种方式是不现实的。

            第二点,使用gcc将会编译、链接所有的.c文件。如果只修改了一个.c文件,还使用gcc指令的话,将会把所有.c文件重新编译、链接一遍,那么短则半小时,长则几个小时。所以,如果使用gcc指令直接编译,效率是非常低的。所以,这里需要了解另外一个文件“.o”文件

            在 C/C++ 等编译型语言的项目构建流程中,.o 文件处于中间环节生成可执行文件的具体流程如下:源代码(.c/.cpp) → 编译器编译 → 目标文件(.o) → 链接器链接 可执行文件

            Makefile

      接下来,编写Makefile文件来实现上面的功能。

    test: a.o b.ogcc -o test a.o b.oa.o: a.cgcc -o a.o -c a.cb.o: b.cgcc -o b.o -c b.c

            根据Makefile的规则“目标(target): 依赖(prerequisites)”可以看到,目标是“test”依赖“a.o b.o”。而a.0依赖a.c,b.o依赖b.c。当执行make指令的时候,编译器会去对比依赖文件和目标文件的时间。如果依赖比目标新,则会重新生成目标。所以当执行make指令的时候,流程如下:

            生成test目标文件,发现依赖a.o b.o。发现a.o和b.o没有且a.o依赖a.c,b.o依赖b.c。所以会先执行gcc -o a.o -c a.c来生成a.o和b.o。然后执行gcc -o test a.o b.o生成test文件。

            如果又修改了b.c,make时编译器发现b.c比b.o新,所以需要重新执行gcc -o b.o -c b.c。而a.o比a.c新,所以不需要重新gcc -o a.o -c a.c。

            可以看到,最终的可执行文件test运行正常。并且在当前文件夹下生成了a.o和b.o两个中间文件。

            这时候,可能会有疑问,为什么不能这么写呢?

    a.o: a.cgcc -o a.o -c a.cb.o: b.cgcc -o b.o -c b.ctest: a.o b.ogcc -o test a.o b.o

            这样的话,就会先生成.o文件,最后直接再生成可执行文件test。

            真的是这样吗?执行一下。

            发现并没有生成test,而是只生成了a.o。为什么呢?

            Makefile默认将第一个规则的目标作为“默认目标”。上述写法,make会认为a.o就是默认目标,生成a.o后就不会再往下执行了。如果想生成test,必须手动指定目标,执行make test命令,工具才会按照依赖关系先处理a.o和b.o,再生成test。

            按照这个思路,如果想清除生成的文件,可以在Makefile文件中增加如下命令:

    clean:rm -f *.o test

            需要清除是,执行make clean指令。

    http://www.dtcms.com/a/389234.html

    相关文章:

  • 动态代理 设计模式
  • APP小程序被攻击了该如何应对
  • 零基础从头教学Linux(Day 37)
  • ADB 在嵌入式 Linux 系统调试中的应用
  • 7HTMLCSS高级
  • 玩游戏/用设计软件提示d3dcompiler_47.dll缺失怎么修复?5步快速定位问题,高效修复不踩坑
  • HTML应用指南:利用GET请求获取全国宝马授权经销商门店位置信息
  • 《Java网络编程》第一章:基本网络概念
  • Python内存机制全解析:从基础到高级应用
  • Ubuntu24修改ssh端口
  • hadoop实现一个序列化案例
  • DBG数据库加密网关实现mySQL敏感数据动态脱敏与加密全攻略
  • 解决 Vue SPA 刷新导致 404 的问题
  • 大型语言模型 (LLMs) 的演进历程:从架构革命到智能涌现
  • 大语言模型为什么要叫【模型】
  • 教程上新丨ACL机器翻译大赛30个语种摘冠,腾讯Hunyuan-MT-7B支持33种语言翻译
  • 《C++程序设计》笔记
  • NVR接入录像回放平台EasyCVR海康设备视频平台视频监控系统常见故障与排查全解析
  • 半导体制造常提到的Fan-Out晶圆级封装是什么?
  • Qt 系统相关 - 文件
  • P2242 公路维修问题
  • 安装wsl
  • 牛客多校04C :Computational Geometry Problem(p-Dyck路计数)
  • CMake+visual studio 2022 +qt6 , 从Linux平台移植到windows下平台开发
  • 大模型系列——Playwright MCP 可以复用 Chrome 登录态了
  • 三星S25 Edge 与iPhone 17 Air:最新对比
  • 电脑怎么连接wifi?【图文详解】笔记本电脑怎么连接无线wifi?笔记本电脑连不上wifi怎么办?
  • 设计模式-代理模式详解
  • 怎样让AI图生3D更加高质高效
  • Java 集合框架 Set 接口:实现类的底层数据结构与核心特点