Linux项目自动化构建工具-make/Makefile

Linux项目自动化构建工具-make/Makefile

Linux项目自动化构建工具-make/Makefile_第1张图片


每博一文案

人生路漫漫,越长大,越明白,每个人的路都是漫长而又艰辛的

无论我们有多累,我们都无路可退。就像马丁说的那样,每一个强大的人都曾咬牙

度过一段,没人帮忙,没人支持,没人嘘寒问暖的自己。过去了,这就是你的成人礼,过不去

求饶了,这就是你的无底洞,我们都要熬过一段灰暗,孤独,无人能懂的岁月里,别无他法,谁也无法逃避。

蔡康永曾说,人生前期越是嫌麻烦,越是懒得学习,后来就越可能错过让你,心动的人和事。

错过新风景,生活有太多的磨难和挫折,但那些打不倒我们的,将会让我们变得更加强大,尝遍人生百味的我们,将会更加生动而干劲。

​ —————— 一禅心灵庙语


文章目录

  • Linux项目自动化构建工具-make/Makefile
    • 每博一文案
    • make/Makefike 介绍
    • 使用make命令,一键编译
    • 项目清理
    • ”依赖关系“与 “依赖方法”
    • 优化
    • 原理:
    • 最后:


make/Makefike 介绍

会不会写makefile ,从一个侧面说明了一个人是否具备完成大型工程的能力
一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中,makefile 定义了一系列的规
则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功
能操作
makefile 带来的好处就是——“自动化编译” ,一旦写好,只需要一个make 命令,整个工程完全自动编译,
极大的提高了软件开发的效率。
make 是一个命令工具 ,是一个解释makefile 中指令的命令工具,一般来说,大多数的IDE都有这个命令,
比如:Delphi的make,Visual C++的nmake,Linux下GNU的make。可见,makefile都成为了一种在工
程方面的编译方法。
make是一条命令,makefile是一个文件,两个搭配使用,完成项目自动化构建


使用make命令,一键编译

首先我们创建一个C程序项目:

[linux@localhost dir]$ touch main.c
[linux@localhost dir]$ touch mytest.c
[linux@localhost dir]$ touch mytest.h

main.c 文件内容

#include"mytest.h"

int main()
{
 
  show();   
  return 0;
}

mytest.h 文件的内容

pragma once    
    
#include                                                                     
extern void show();    
    

mytest.c 文件内容

#include"mytest.h"    
    
void show()    
{    
    
  int i  = 0;                                                                                                                  
  for(;i < 10; i++)    
  {    
    printf("hello %d\n",i);    
    
  }    
    
}  

创建 Makefile文件 : 在该项目,文件夹中创建 makefile 或者是 Makefile 文件名的大小写无关,因为 Linux 是不区分大小写的

[linux@localhost dir]$ touch Makefile

Linux项目自动化构建工具-make/Makefile_第2张图片


编写Makefile文件内容

mybin:mytest.c main.c
	gcc mytest.c main.c -o mybin

Linux项目自动化构建工具-make/Makefile_第3张图片

编写好 Makefile 内容后,就可以直接使用 make命令 ,就会自动一键,编译生成可执行程序了

[linux@localhost dir]$ make

从下图中我们可以看到,当我们使用 make命令 ,就自动执行了,我们在 Makefile 文件中所写的 脚本内容:gcc mytest.c main.c -o mybin ,生成了,可执行程序 mybin ,对于该脚本的作用以及详细信息,大家可以移步到:

Linux编译器-gcc的使用

Linux项目自动化构建工具-make/Makefile_第4张图片

运行看看

[linux@localhost dir]$ ./mybin

Linux项目自动化构建工具-make/Makefile_第5张图片


项目清理

工程是需要被清理的,我们还可以编写一个清理项目的
clean 这种,没有被第一个目标文件直接或间接关联,那么它后面所定义的命令将不会被自动执行,不
过,我们可以显示要make执行。即命令——“make clean”,以此来清除所有的目标文件,以便重编译。脚本内容,打开 Makefile 写入如下:内容

mybin:mytest.c main.c    
  gcc mytest.c main.c -o mybin    
.PHONY:clean    
clean:    
  rm -f mybin  

Linux项目自动化构建工具-make/Makefile_第6张图片


编写好后,就可以使用命令 make clean 清除项目了

[linux@localhost dir]$ make clean

从图下,我们可以看到当我们,使用 make clean 命令的时候,执行了 我们在 Makefile 中编写的脚本:rm -f mybin 强制删除 mybin 文件,

Linux项目自动化构建工具-make/Makefile_第7张图片


”依赖关系“与 “依赖方法”

Makefile 主要是由 “依赖关系"“依赖方法” 所对应的,缺一不可, 编写:Makefile ,本质上是在编写依赖关系和依赖方法

Linux项目自动化构建工具-make/Makefile_第8张图片


mybin:mytest.c main.c    
  gcc mytest.c main.c -o mybin    
.PHONY:clean    
clean:    
  rm -f mybin  
 
//
解析:
mybin 是为目标文件 :冒号后面的为 依赖关系 main.c mytest.c ,就是mybin目标文件(可执行程序)的产生需要对应的源文件,不然没有源文件,又如何生成 mybin目标文件(可执行程序)	,注意语法细节:要顶格写入
	gcc mytest.c main.c -o mybin  为依赖方法,就是如何通过依赖关系中的(main.c mytest.c)文件,生成,产生,目标文件mybin, 注意语法细节:要以Tab键开头,不可以是空格这是语法规定,依赖关系与依法方法之间不可以有空行的存在,必须相互紧挨着
.PHONY: 可以理解成是 Makefile的关键字,凡是被.PHONY:clean(伪目标),总是会被执行的,达到无障碍运行,记住一点就是 (伪目标)可以无障碍运行,
clean 是目标文件
      rm -f mybin 依赖方法,强制删除文件(mybin)

Linux项目自动化构建工具-make/Makefile_第9张图片


这里解释一下:.PHONY:的总是被执行

当我们已经产生了目标文件 比如这里的 mybin ,可我们还是继续使用 make 命令想要继续产出的时候,不会执行了,报出 make: `mybin’ is up to date. 以是最新的了,该make 命令被迫,不执行了,

Linux项目自动化构建工具-make/Makefile_第10张图片


而我们多次使用被 .PHONY 修饰的 clean(伪目标) 命令就不会被停止,可以一直使用,就算我们删除的文件不存在了,也还是会执行的,如下图:

Linux项目自动化构建工具-make/Makefile_第11张图片


我们的 mybin 也是可以被 .PHONY修饰的,从而达到 make的无障碍运行的 操作如下:

.PHONY:mybin                                                                           mybin:mytest.c main.c    
  gcc mytest.c main.c -o mybin    
.PHONY:clean    
clean:    
  rm -f mybin 

Linux项目自动化构建工具-make/Makefile_第12张图片


Linux项目自动化构建工具-make/Makefile_第13张图片


问题 : 为什么 不要让 make 被修饰 .PHONY 成伪目标

因为,对于项目而言,一般都是比较大的,完整编译一次,可能需要消耗 1~3 个小时,大一点的话,可能更多,成本太大了,太消耗时间了,所以不建议 被 .PHONY ,修饰,而清除项目,就不需要了,这么多时间成本,而且可能一次没有清除干净,需要多次清除。


问题: 为什么 编译使用 make命令 就可以了,不需要带选项标签,而清除项目,却需要make clean 带上标签

因为命令 默认是从上往下执行的,默认make 执行第一个语句的,所以不需要带上标签,而我们的清除项目,clean 命令,不是位于第一个语句,所以需要使用到 标签,跳转到相对应的位置 make clean


优化

大家发现没有,如果使用上述的方式,编写的Makefile 依赖关系和依赖方法,太过于死板了,如果项目中的依赖关系的文件,太多了的话,我们需要一个一个的输入,难免会输错,而且一旦在项目中我们添加了,对应的依赖关系中的文件,我们又要对 Makefile 内容上做修改,太麻烦了,有没有什么,一劳永逸的方法,当然,是用的,我们可以使用上 通配符以及一些特殊的符号,代替大量重复类似的文件上的操作

mybin:main.o mytest.o    
  gcc $^ -o $@    
%.o:%.c    
  gcc -c $<    
.PHONY:clean    
clean:    
  rm -f *.o mybin 

Linux项目自动化构建工具-make/Makefile_第14张图片


试试看

[linux@localhost dir]$ make 

Linux项目自动化构建工具-make/Makefile_第15张图片


[linux@localhost dir]$ ./mybin

Linux项目自动化构建工具-make/Makefile_第16张图片


[linux@localhost dir]$ make clean

Linux项目自动化构建工具-make/Makefile_第17张图片


解析

mybin:main.o mytest.o    
  gcc $^ -o $@    
%.o:%.c    
  gcc -c $<    
.PHONY:clean    
clean:    
  rm -f *.o mybin
mybin 目标文件
main.o mytest.o 依赖关系,生成目标文件(mybin)所依赖的源文件 main.o mytest.o
	$^ 表示依赖文件列表中的:冒号右侧的源文件(main.o mytest.o)
	$@ 表示代指目标文件(mybin)
	gcc $^ -o $@ 依赖方法,生成目标文件(mybin),在这里就等于是 gcc main.o mytest.o -o mybin
	%.c  依赖关系表示当前目录下的所有后缀为.c文件
	%.o 目标文件表示当前目录下的所有后缀为.o 文件,就是依赖关系中的.c 文件产生的.o 目标文件
	$< 表示在依赖关系中的%.c的源文件,用 gcc 进行汇编成同名的.o 文件
	gcc -c $< 依赖方法表示使用 gcc 依赖关系中的%.c的源文件对进行汇编生成同名的.o文件(%.o目标文件),因为 gcc -c 没有重定向默认是创建同名的.o二进制目标文件,在这里等于是 gcc -c main.c mytest.c
	.PHONY:clean(伪目标) 表示无障碍运行
	clean 表示目标文件
	*.o 通配符,表示当前目录下的所有以.o 为后缀的文件
	rm-f *.o mybin  表示强制删除当前目录下的以.o为后缀的文件以及名为mybin的文件 
	

Linux项目自动化构建工具-make/Makefile_第18张图片


原理:

make是如何工作的,在默认的方式下,也就是我们只输入 make 命令。那么

make 会在当前目录下找名字叫 “Makefile" 或**“makefile”** 的文件,如果找到了,它会找文件中的第一个目标文件(target), 在上面的例子中,它会找到 ”mybin" 这个文件,并把这个文件作为最终的目标文件,

如果 “mybin" 文件不存在,或是 ”mybin" 所依赖的后面的 main.c mybin.c 文件的文件修改时间比 ”mybin“ 这个文件新(可以用touch测试),那么 ,它就会执行后面所定义的命令来生成 mybin 这个目标文件。

如果**”mybin"** 所依赖的**“main.c mybin.c"** 文件不存在,那么 make 会在当前文件中找目标为 main.c mybin.c 文件的依赖性,如果找到了,则再根据那一个规则生成 ”main.c mybin.c 文件(这有点像一个堆栈的过程)

当然,如果你的C文件,和H文件都是存在的,于是make 会生成main.o mybin.o 文件,然后再用 maIn.o mybin.o 文件声明make 的终极任务,也就是执行文件 mybIn

这就是整个 make 的依赖性,make 会一层一层地去找文件之间的依赖关系,直到最终编译出第一个目标文件,在找寻的过程中,如果出现错误,比如:最后被依赖的文件找不到,那么make 就会直接退出,并报错,而对于所定义的命令的错误,或是编译不成功,make 根本不会理会

make 只管文件的依赖性,即使如果在我找了依赖关系之后,冒火后面的文件还是否存在,那么对不起,我就不工作了。


其中大家如果不理解的 gcc 的使用,大家可以移步到: Linux编译器-gcc的使用

最后:

限于自身水平,其中存在的错误,希望大家给予指教,韩信点兵——多多益善,谢谢大家,后会有期,江湖再见!


你可能感兴趣的:(Linux,linux,自动化,c++,服务器,后端)