type
status
date
slug
summary
tags
category
icon
password

makefile

实际上就是在学习Makefile脚本语言的语法了
实际上集成开发环境就是含有一个makefile,所以编译的时候很方便
所以说在linux上面开发的时候因为没办法使用keil这个IDE,所以需要编写一个keil的makefile来模拟keil的集成开发环境
说白了makefile就是为了避免很多的重复操作,因为gcc的时候只能把所有文件的名称都打出来,然后再去编译,打一堆文件的名字太麻烦了,所以就使用makefile编写一次,然后就用makefile就好了,就能少打很多东西
在linux下可执行文件的后缀不是exe,而是elf
makefile实际上就是一个脚本,是一个用于编译的脚本

c语言文件的执行过程

实际上都是gcc这个编译器在做的事情,就没必要纠结这个步骤了
  • 预处理:头文件展开,宏定义替换,生成一个.i文件,也就是-E
    • 预处理指令:gcc -E hello.c -o hello.i(里面的-E就是表示预处理,-o表示输出为)
  • 汇编:根据.i文件生成汇编代码.s文件,也就是-S
    • 汇编指令:gcc -S hello.i -o hello.S
  • 编译:根据.s文件生成二进制代码,也就是.o文件,也就是-c
    • 编译指令:gcc -c hello.S -o hello.o
  • 链接:最后将.o文件生成一个可执行文件.elf,也就是-O
    • 链接指令:gcc hello.o -o hello
上面四步可以直接使用一条指令代替,也就是gcc hello.c -o hello,也就是将c文件预处理汇编编译链接为一个可执行文件

makefile的创建

需要先创建一个文本文件,然后将后缀去掉并取名为Makefile

Makefile基本语法

  • #是注释,跟所有的脚本语言都是一样的
  • Makefile的显式规则
    • 格式:目标文件:依赖文件【tab】指令
    • 如将.c文件生成.i文件,那么就应该写作:
    • 第一个目标文件要是最终目标,同样以上面的例子为例,第一个目标文件就应该是hello(因为hello是最终目标),所以上面所有的顺序需要反过来,就像是一个递归的依赖链,如下图:
    • hello:hlloe.o gcc hello.o -o hello hello.o:hlloe.S gcc -c hello.S -o hello.o hello.S:hello.i gcc -S hello.i -o hello.S hello.i:hello.c gcc -E hello.c -o hello.i
      • 因为只知道想要输出什么,所以就只能从下向上找了。所以这个时候如果目录下面是有.o文件的就有可能出错
    • 在Makefile中创建单独的指令(也就是没有目标文件的指令,如在进行预处理等操作之前需要先将已经存在的中间结果以及可执行文件删除,也就是执行rm指令。复习一下,在shell脚本中就是直接可以使用linux命令进行操作的,也就是直接在脚本中使用rm指令),也就是创建一个伪目标
    • 伪目标的Makefile端使用.PHONY来表示(phony本身就是赝品的意思)
      • 伪目标可以使用clear等。伪目标的名称应该是可以自己命名的
        使用伪目标的时候就需要在make后面加上伪目标的名称,这样就能代替在Makefile里面写的指令了
        使用格式如下:
        notion image
        这个clear在Makefile里面就是一个rm指令
        自己使用如下:
        notion image
        notion image
        可以发现实际上伪目标就是可以自己命名的
    • Makefile中也是可以有变量的,下面是有关变量的三个运算符(准确来说是赋值运算符),有点像编程语言里面的全局变量,只不过有一些是常变量,但是有一些就是常变量
      • =:表示的是替换(跟编程语言是一样的)
      • +=:表示的是追加(跟编程语言是一样的)
      • :=:表示的是恒等于(就相当于是一个常量)
    • 实际上使用就相当于是脚本语言里面的变量,使用的时候也是一样的,但是在shell脚本里面变量的使用是用${},但是在Makefile里面变量的使用是$()
      • 也就是在Makefile里面使用变量提高Makefile的可移植性
    • 隐含规则(也就是通配符的一部分):
      • %.c:任意的.c文件
      • %.o:任意的.o文件
      • .c:所有的.c文件
      • .o:所有的.o文件
    • 注意任意的和所有的区别,任意的意思是只有一个文件(也就是从全部里面任意取出来一个,也就相当于是使用%来指代任意一个文件名),但是所有的就是全部的文件(也就是全部的文件)
    • 通配符(剩下的一点关于通配符的规则)
      • $^:表示所有的依赖文件
      • $@:表示所有的目标文件
      • $<:表示所有文件的依赖文件的第一个文件
        notion image
        notion image
        这个通配符的时候是在指令中使用的,以上面的这个例子为例,就是用来在所有的命令里面来代替所有的目标文件和依赖文件的,当然也可以使用变量来实现,但是这个通配符是Makefile自带的(所以这些自带的变量也叫做Makefile中的自动变量)
        所以使用变量替换以及自动变量之后,一个Makefile就是下面这种状态:
        notion image
        自动变量有很多,需要使用的时候再去看就好了
    • Makefile中的函数

    Makefile的使用

    notion image
    使用格式如下,只需要打一个make指令就好了

    Makefile杂记

    notion image
    初次使用的时候需要下载Makefile的脚本解释器Make,然后才能通过make指令运行Makefile。这么看的话make应该也是放在/usr/bin目录下的,所以可以直接执行
    Linux基本使用汇编点灯
    Loading...
    Noah
    Noah
    永远年轻,永远热泪盈眶
    公告
    ❗❗复习笔记问题❗❗
    由于兼容性问题
    导入md文件可能导致了一些格式错误
    🌹如发现格式错误,请联系我~🌹
    🌹如博客内容有误也欢迎指出~🌹