前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Linux项目自动化构建工具-make/Makefile

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

作者头像
南桥
发布2024-02-18 08:45:35
1240
发布2024-02-18 08:45:35
举报
文章被收录于专栏:南桥谈编程南桥谈编程

前言

makefile有什么用?本篇文章小编将详细介绍

会不会写makefile,从侧面说明一个人具不具备完成大型工程的能力

一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作

makefile带来的好处就是——“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率。

make是一个命令工具,是一个解释makefile中指令的命令工具,一般来说,大多数的IDE都有这个命令,比如:Delphi的make,Visual C++的nmake,Linux下GNU的make。可见,makefile都成为了一种在工程方面的编译方法。

make是一条命令,makefile是一个文件,两个搭配使用,完成项目自动化构建。

快速见识一下

实例代码:

首先创建一个code.c文件,在该文件中写一个测试代码

代码语言:javascript
复制
 #include<stdio.h>

 int main()
 {
   printf("hello gwj!\n");                                                                                                               
   return 0;
 }

创建一个makefile文件:

使用vim指令,进入makefile

使用如下代码:

代码语言:javascript
复制
mytest:code.c
   gcc -o mytest code.c

保存并退出

使用make指令,可直接生成mytest运行文件

清除操作:

进入makefile文件,使用如下指令:

代码语言:javascript
复制
.PHONY:clear
 clear:
   rm -f mytest  

保存并退出后,使用make clear指令可删除mytest运行文件

以上代码实例快速感受一下make指令

说明原理

make是一条命令,makefile是一个文件,两个搭配使用,完成项目自动化构建。

依赖关系和依赖方法

mytest:code.c称之为依赖关系

mytest是目标文件,使用make命令后,生成的运行文件叫mytest

code.c是依赖文件列表,如果有多个时使用空格符隔开,例如:code.c code1.c code2.c code3.c

gcc -o mytest code.c称之为依赖关系,前面必须是Tab键开头,不能是四个空格

此时,makefile写好之后,运行make,会在当前目录里找makefile,读取makefile里的内容,根据依赖关系去形成目标文件。如何去形成呢?根据gcc这样的一个依赖方法形成。 换句话来说就是,make会读取makefile里面的内容

如何理解依赖关系和依赖方法

- 什么是依赖关系?? 在大学,到了月底,身为尾款人的你打电话给你爹要点生活费:“爹,我是你儿子!” 这句话中,“我是你儿子”表明了两人的关系,表明你需要依赖于你爹,这就是一个依赖关系。

- 什么是依赖方法?? 此时呢,你爹就把电话挂了,心想:是我儿子就是我儿子呗,有病吧。现实生活中,光有依赖关系没有用,需要表明你想做什么,此时你又把电话打回去:“我没有生活费啦,给我打钱!” 这里的要钱就是表明了依赖方法

项目清理

clear是一个种特殊的依赖关系,clear也是目标文件,只不过后面什么都不跟

rm -f mytest是依赖方法,是删除文件

如何理解.PHONY:

在读取makefile文件内容时,是从上往下读取,默认认形成第一个目标文件

习惯上把形成可执行程序放在上面,make就可以直接形成

在编译时,默认情况下,如果可执行程序是最新的了,make就不会再去编译,如果就想让编译这个操作总是可以被执行,使用.PHONY:XXX,这里的XXX对应的方法总是可以被执行的。

一般清理项目会总是执行,因此习惯上会有:.PHONY:clear

为什么makefile对最新的可执行程序默认不想重新生成

如果项目种存在很多个源文件,如果在这些源文件中只进行了很小的改变,如果去把所有的源文件重新编译一遍,会带来很大的效率延缓,效率很低。更重要的是,如果每次都重新编译,源代码可能都没有改,重新去编译效率会很低。

这要做的主要目的是提高编译效率。

makefile怎么知道程序需要重新编译?

Modify是修改时间,可执行文件和源代码文件最近修改时间不可能一样 因为永远是先写源代码,即使修改代码,也是先修改,再形成可执行程序。

因此,makefile只需对比可执行文件最近修改时间和源文件最近修改时间,如果可执行文件最近修改时间新,就不需要重新编译;如果源文件最近修改时间新,就需要重新编译。

如果被.PHONY:修饰,就忽略了时间,于是可以总是被执行

我们想需要的makefile

代码语言:javascript
复制
code.exe:code.c
  gcc -o $@ $^

可以理解为取内容,@表示目标文件,^表示依赖文件 @表示取code.exe文件,

make时会自动替换成gcc -o code.exe code.c

make会根据文件的依赖关系,进行自动推导,帮助我们执行所有相关依赖方法。当前的依赖关系如果不存在,就将当前依赖关系入栈,如果下一个依赖关系存在导致当前依赖关系存在,则当前依赖关系出栈,这里就相当于一个递归。

最终需要的目标文件一定要在第一个,后面的可以乱

我们自己在使用makefile时没必要像上述代码那样写,没必要纠结那么多选项,直接可以这样写:

代码语言:javascript
复制
code.exe:code.c
  gcc -o $@ $^

使用变量替换:

代码语言:javascript
复制
  1 bin=code.exe
  2 src=code.c
  3 
  4 $(bin):$(src)
  5   gcc -o $@ $^
  6 .PHONY:
  7 clean:
  8   rm -f $(bin)

此时照样可以编译,在makefile中是可以定义变量的

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2024-02-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 快速见识一下
  • 说明原理
    • 依赖关系和依赖方法
      • 如何理解依赖关系和依赖方法
        • 项目清理
          • 如何理解.PHONY:
          • 为什么makefile对最新的可执行程序默认不想重新生成
          • makefile怎么知道程序需要重新编译?
          • 我们想需要的makefile
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档