MAKEFILE

  • 在Linux中,有一个叫make的东西,就相当于C语言的集成开发环境,我们只需要在make里面创建文件,写代码,make会帮我们管理这些文件

  • 我们创建的项目不叫project,而是称为Makefile,打开一个make源程序包,发现很多Makefile的文件,说明里面有很多的项目

  • 源程序包里面,也有名为makefile的文件(m是小写),两个命名同时存在,这是合理的,在开发一个项目的时候,工程师一般都会命名为Makefile然后打包交给用户,用户觉得某个Makefile需要改动,用户改动后或者新建后的项目定义为makefile,并且在运行时候,先执行makefile,再执行Makefile文件。

  • 快捷操作:

    • vim * -p :可以vim你所创建的文件
      gcc *.c :编译该文件夹下的所有.c文件
      在非插入的模式下:
          x可以删除光标前的内容
          u可以撤销前一个操作
          ctrl+r 反撤销
          yy 复制光标所在一行的内容
          v 进入可视模式,直接移动光标选中内容,按y复制内容,然后按p/P粘贴内容。
          dd 删除一整行的内容
          ggVG:选中全部   y复制   d全部删除
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24

      ### 一、为何使用Makefile

      ![image-20230311145137250](https://gitee.com/zhou-xuezhi/mypic2/raw/master/img/20230311145144.png)

      * 这个树形图展示了一个项目中的层级关系,如果我们需要变动3号文件,会发现,牵一发而动全身,改动一个被迫需要改动一堆,为了解放我们,make中编写Makefile就不再需要考虑这些,你把每个文件的依赖关系以指令的形式说明清楚并且保存下来,改动一个即可,会自动帮你修改关联到的其他文件。

      ***

      ***

      ***

      ### 二、创建相关文件

      #### 1.创建工程文件

      * ```c++
      touch main.c tool1.c tool1.h tool2.c tool2.h
      ls
      gedit main.c tool1.c tool1.h tool2.c tool2.h 或者 vim * -p

      vim * -p 打开该文件下所有文件 gt用于切换文件
      :wqa 可在vim 中方退出所有文件
  • 编写代码

    • tool1.h

      • #ifndef TOOL1_H
        #define TOOL1_H
        
        void mytool1(void);
        
        # endif
        
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10

        * tool2.h

        * ```c++
        #ifndef TOOL2_H
        #define TOOL2_H

        void mytool2(void);

        # endif
    • tool1.c

      • #include <stdio.h>
        #include "tool1.h"
        
        void mytool1()
        {
            printf("tool1 print\n");
        }
        
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11

        * tool2.c

        * ```c++
        #include <stdio.h>
        #include "tool2.h"

        void mytool2()
        {
        printf("tool2 print\n");
        }
    • main.c

      • #include "tool1.h"
        #include "tool2.h"
        
        int main()
        {
            mytool1();
            mytool2();
            return 0;
        }
        
        1
        2
        3
        4
        5

        * 编译代码

        * ```c++
        gcc *.c
    • ls
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16

      * ![image-20230311150527032](https://gitee.com/zhou-xuezhi/mypic2/raw/master/img/20230311150527.png)

      ***

      ***

      #### 2.文件依赖关系

      **.o是可执行文件**

      ```c++
      a.out -> main.o tool1.o tool2.o # 可执行文件a.out依赖于后面的三个执行文件
      main.o -> main.c
      tool1.o -> tool1.c
      tool2.o -> tool2.c


3.编写makefile文件

  • 终端输入:vim makefile
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16

    * makefile文件内容

    * ```c++
    mytool:main.o tool1.o tool2.o
    [TAB键] gcc main.o tool1.o tool2.o -o mytool

    main.o:main.c
    gcc main.c -c -Wall -g -o main.o
    tool1.o:tool1.c
    gcc tool1.c -c -Wall -g -o tool1.o
    tool2.o:tool2.c
    gcc tool2.c -c -Wall -g -o tool2.o

    clean:
    rm *.o mytool -rf
    * 上述文件内容说明了可执行文件,以及其依赖和对应编译过程 * ```c mytool:main.o tool1.o tool2.o # mytool依赖于main.o tool1.o tool2.o三个可执行文件 gcc main.o tool1.o tool2.o -o mytool # gcc使得main.o tool1.o tool2.o 生成可执行文件mytool -o 使得可执行文件命名mytool main.o:main.c # main.o依赖于main.c gcc main.c -c -Wall -g -o main.o # gcc 编译main.c -c(编译) -Wall(显示警告信息) -g(gdb调试) -o(如上) clean: rm *.o mytool -rf # 递归的删除make生成的所有.o文件以及mytool文件
    1
    2
    3
    4
    5



    * ```c
    终端输入:make
    * 显示结果:![image-20230311151934404](https://gitee.com/zhou-xuezhi/mypic2/raw/master/img/20230311151934.png)


4.执行mytool可执行文件

1
./mytool

在终端输入:

1
make clean     #  可将makefile文件中定义 rm *.o mytool -rf指令执行 递归伤处make生成的所有.o文件以及mytool文件


5.makefile第二个版本

利用关键词去替换重复部分减少工工作量,实际过程中操作:$(简写代码)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
OBJS = main.o tool1.o tool2.o
CC = gcc
RM = rm -f

mytool:$(OBJS)
$(CC) $(OBJS) -o mytool

main.o:main.c
$(CC) main.c -c -Wall -g -o main.o
tool1.o:tool1.c
$(CC) tool1.c -c -Wall -g -o tool1.o
tool2.o:tool2.c
$(CC) tool2.c -c -Wall -g -o tool2.o


clean:
$(RM) *.o mytool -r


6.makefile第三个版本

将编译选项定义为CFLAGS代替

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
OBJS = main.o tool1.o tool2.o
CC = gcc
RM = rm -f
CFLAGS += -c -Wall -g

mytool:$(OBJS)
$(CC) $(OBJS) -o mytool

main.o:main.c
$(CC) main.c $(CFLAGS) -o main.o
tool1.o:tool1.c
$(CC) tool1.c $(CFLAGS) -o tool1.o
tool2.o:tool2.c
$(CC) tool2.c $(CFLAGS) -o tool2.o

clean:
$(RM) *.o mytool -r



7.makefile第四个版本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
OBJS = main.o tool1.o tool2.o
CC = gcc
RM = rm -f
CFLAGS += -c -Wall -g

mytool:$(OBJS)
$(CC) $^ -o $@

main.o:main.c
$(CC) $^ $(CFLAGS) -o main.o
tool1.o:tool1.c
$(CC) $^ $(CFLAGS) -o tool1.o
tool2.o:tool2.c
$(CC) $^ $(CFLAGS) -o tool2.o

clean:
$(RM) *.o mytool -r
  • 上述中:

    • mytool:$(OBJS)
          $(CC) $^ -o $@
          
      $^ 代表上述的依赖 $(OBJS)  $@ 代表上述需要生成的目标文件   $(CC) $^ -o $@ 整体意思:GCC将上述需要依赖的文件进行-o生成上一句当中的目标文件
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34

      ***

      ***



      #### 8.第五个版本(重点)

      **将格式一致的部分利用通用公式代替:**

      ```c++
      OBJS = main.o tool1.o tool2.o
      CC = gcc
      RM = rm -f
      CFLAGS += -c -Wall -g

      mytool:$(OBJS)
      $(CC) $^ -o $@

      %.o:%.c
      $(CC) $^ $(CFLAGS) -o $@

      clean:
      $(RM) *.o mytool -r


      # 以下部分都是格式一致:
      main.o:main.c
      $(CC) $^ $(CFLAGS) -o main.o
      tool1.o:tool1.c
      $(CC) $^ $(CFLAGS) -o tool1.o
      tool2.o:tool2.c
      $(CC) $^ $(CFLAGS) -o tool2.o