• 嵌入式Linux应用开发基础知识(三)——Makefile入门


    使用keil、mdk、avr等工具开发时,点点鼠标就可以编译了,但是你是否理解它的内部机制呢?它是怎么组织管理程序的?怎么决定编译哪一个文件的?这些其实都是和Makefile息息相关

    一、Makefile作用

    说起作用的话,得看看我们平时怎么使用GCC进行编译,比如我们需要编译main.c和sub.c生成可执行程序test, 那么我们有两种方式进行编译:

    • 方式一: 直接使用gcc -o test main.c sub.c进行编译
    • 方式二:使用gcc -c -o main.o main.c 和gcc -c -o sub.o sub.c生成main.o和sub.o OBJ文件,然后使用gcc -o test main.o sub.o生成可执行文件test

    方式一用于源文件比较少的程序,方式二用于源文件比较多的程序。但是如果源文件很多时,我们一条一条输入命令就变得很不高效。这时我们的Makefile就起作用了。
    Makefile可以根据文件的更新时间选择性的进行执行相应的命令。

    二、Makefile规则

    Makefile的书写框架如下:

    目标1:依赖1 依赖2 ...
    【TAB】命令1
    目标2:依赖3 依赖4 ...
    【TAB】命令2
    ......
    
    • 1
    • 2
    • 3
    • 4
    • 5

    Makefile的执行情况如下:

    • 当"目标文件"不存在或者依赖文件比目标文件更新时间更新时,则执行"命令", 注意如果依赖1和依赖2文件不存在,Makefile会先跳过相关的命令,在下方查找相关依赖文件,如果还是查找不到相关的依赖文件,那么编译报错。

    三、Makefile实验

    源程序如下:
    main.c

    #include <stdio.h>
    #include "sub.h"
    
    int main(int argc, char *argv[])
    {
           int i;
           printf("Main fun!\n");
           sub_fun();
           return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    sub.c

    void sub_fun(void)
    {
           printf("Sub fun!\n");
    }
    
    • 1
    • 2
    • 3
    • 4

    3.1 Makefile文件书写

    Makefile文件我们一般是按照命令的执行顺序进行编写,首先第一行是最后执行的命令,如:
    gcc -o test main.o sub.o 可见目标文件为test 依赖为 main.o sub.o
    则第一部分如下:

    test : main.o sub.o
    	gcc -o test main.o sub.o
    
    • 1
    • 2

    随后部分就是依次生成目标文件
    生成main.o如下:

    main.o : main.c
    	gcc -c -o main.o main.c
    
    • 1
    • 2

    生成sub.o如下:

    sub.o : sub.c
    	gcc -c -o sub.o sub.c
    
    • 1
    • 2

    合并之后的Makefile:

    test : main.o sub.o
    	gcc -o test main.o sub.o
    main.o : main.c
    	gcc -c -o main.o main.c
    sub.o : sub.c
    	gcc -c -o sub.o sub.c
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    Makefile执行过程为,先判断test是否存在,不存在则想执行命令, 发现main.o和sub.o也不存在,,那么会往下查找这两个文件,发现main.o 依赖main.c 那么执行gcc -c -o main.o main.c, 发现sub.o 依赖sub.c 执行gcc -c -o sub.o sub.c, 再返回执行gcc -o test main.o sub.o
    如下图为执行的顺序图
    在这里插入图片描述

    接着我们试图修改main.c,再次编译:
    在这里插入图片描述
    编译过程为判断main.o和sub.o有没有更新,发现main.o依赖main.c, main,c有更新,那么需要执行gcc -c -o main.o main.c, 发现sub.o依赖sub.c, 而sub.c没有更新,那么不执行,再发现main.o有更新了, 那么需要执行gcc -o test main.o sub.o 。

    为了再次验证makefile是不是根据时间来更新的,我们这里使用ls -l查看文件的时间,和使用touch来更新文件时间,重新编译:
    在这里插入图片描述

    和我们想的一样

  • 相关阅读:
    微信聊天功能测试用例
    游戏中的语音聊天方案
    Git 工作流程
    Java 迭代器、Object类、泛型、序列化
    微信小程序-婚礼邀请函页面
    悬浮工具球(仿 iphone 辅助触控)
    无锡设计培训:PLC控制的基本原则
    NumPy 差分、最小公倍数、最大公约数、三角函数详解
    mybatis字段映射的容错性
    量子计算新突破!来源于150年前的思想实验
  • 原文地址:https://blog.csdn.net/FourLeafCloverLLLS/article/details/126185858