前言
一般对于C语言小项目的我们都是用gcc去编译,但是当我们得项目变大或者很多的文件的时候,如果使用gcc去编译的话就会很麻烦而且花费的时间就会很多,这时就需要一个东西来帮助我们解决这种困境,于是Makefile就出现了。本文适合于小白,没有什么深入,大概能用。(我也是小白,写一下文章记录一下自己的所学,所以有问题麻烦提出,让小白的我学到更多)
一、Makefile
Makefile和Make的区别
Makefile:是一个文件,是我们需要去编写的文件,通常在我们的项目目录下创建一个名字为Makefile的文件。
Make:是一个程序,它是用来解析Makefile文件的,这个程序需要在Linux安装(具体安装方式在Terminal输入make,根据其提示信息进行安装,比较简单,就不说啦)
当我们在项目的路径下输入make,make这个解析器工具就会帮助我们去解析Makefile文件里面的语法,解析出来的语法作用就是编译代码。
make主要就是对于我们项目中的.c文件编译成.o文件,如果我们没有去修改.c文件,那么make在进行第二次或者多次的时候就不会对这个.c文件再进行编译,所以可以节省很多时间。不过,我们项目第一次编译的时候,都是需要全部重新编译的。当我们的所有.c文件都没有修改的时候,输入make在Terminal会出现 ‘main’ is up to date,表示我们得文件没有修改,已经是最新的啦,不用帮助我们编译。
学习Makefile最好了解一下C语言的编译原理,四个步骤(预处理、编译、汇编、链接)。
这个内容可以在我的另一篇文章(动静态库的制作)可以看到。
二、Makefile三个简单的版本
(1)版本1
当我们的项目存在一个.c文件需要编译的时候,在Makefile文件下面的内容如下:(比较拉胯和麻烦,看懂就行,版本3比较常用)
项目目录只有一个hello.c,所以就不展现出来啦。
Makefile代码如下:
hello:hello.o
gcc hello.o -o hello
hello.c:hello.o
gcc -c hello.c -o hello.o
clean:
rm hello.o hello
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import warnings
warnings.filterwarnings('ignore')
import ssl
ssl._create_default_https_context = ssl._create_unverified_context
(2)版本2
当我们的项目存在多个.c文件需要编译的时候,在Makefile文件下面的内容如下:(比较拉胯和麻烦,看懂就行,版本3比较常用)
如图,上面是我们得项目目录里面的所有文件,那么我们得Makefile文件要写内容为:
# '#'注释的标志
# 语法就是 a:b a是目标文件 b是依赖文件
# make 编译的过程是从下面开始编译的,也就是我们需要将生成二进制文件的命令写在最上面
# 生成.o文件的命令放在下面
demo:main.o camera.o common.o music.o photo.o video.o
gcc main.o camera.o common.o music.o photo.o video.o -o demo
main.o:main.c
gcc -c main.c -o main.o
camera.o:camera.c
gcc -c camera.c -o camera.o
common.o:common.c
gcc -c common.c -o common.o
music.o:music.c
gcc -c music.c -o music.o
photo.o:photo.c
gcc -c photo.c -o photo.o
video.o:video.c
gcc -c video.c -o video.o
clean:
rm *.o demo
在Linux上运行的结果如下
输入make之后,make这个工具就会帮助我们解析Makefile里面的内容来帮助我们编译。
再输入make,出现这个回应,说明我们没有再去改动.c文件,所以make不会帮助我们去编译。
输入make clean 可以帮助我们 执行Makefile里面clean这个命令。(clean也称为伪目标,没有依赖文件的就是伪目标)
(3)版本3
这个版本需要会写,比较常用,也比较容易复用,自动化版本。(这个版本里面的内容,小白的我暂时还不会,所以不好讲什么,只是呈现一些代码)
还是上面版本2的项目目录文件,Makefile的内容如下:
SRCS=$(wildcard *.c) #这一步的作用:检索当前路径下所有.c文件的名字存放在变量SRCS 即SRCS用来存放.c文件的名字
OBJS=$(patsubst %.c,%.o,$(SRCS)) # 这一步的作用:把SRCS的所有.c替换成.o,存放在变量OBJS
TARGET=demo
CC=gcc
$(TARGET):$(OBJS)
$(CC) $(OBJS) -o $(TARGET)
#接下来这一步可能比较难理解里面的符号
#里面的符号其实Makefile内置的自动化变量
#至于是啥,我也不会
# ^:表示依赖列表的值
# @:表示目标列表的值
%.o:%.c
$(CC) -c $(^) -o $(@)
clean:
rm $(OBJS) $(TARGET)
效果如下:
总结
本文到这里就结束,没有涉及很深,就是一点点基础,希望能够帮到你。(有用的话记得点赞,互相学习)。