当前位置:首页 » 《随便一记》 » 正文

Linux项目自动化构建工具-make/Makefile (●‘◡‘●)_sjp11的博客

14 人参与  2021年11月10日 12:03  分类 : 《随便一记》  评论

点击全文阅读


目录

1.为什么要使用make

2.makefile的基本语法与变量


1.为什么要使用make

假设我们的执行文件里面包含2个源文件,分别是main.c ,  test.c ,

 如果想要这个程序运行起来,那么就需要先编译:

# 先对源文件进行编译,产生test.o,main.o文件
[sjp@iZwz97d32td9ocseu9tkn4Z ~]$ gcc -c test.c  
[sjp@iZwz97d32td9ocseu9tkn4Z ~]$ gcc -c main.c

# 将test.o main.o文件进行链接,将生成的可执行程序文件定为mytest
[sjp@iZwz97d32td9ocseu9tkn4Z ~]$ gcc test.o main.o -o mytest
[sjp@iZwz97d32td9ocseu9tkn4Z ~]$ ./mytest <==> 执行可执行文件 结果如下
hello sjp
hello sjp
hello sjp
hello sjp
hello sjp
hello sjp

编译过程需要进行好多操作,如果有更多的源文件,那么我们就需要输入更多 gcc -c 源文件  的操作,而且如果要对源文件进行重新编译,则上诉的操作需要在操作一遍,光是找出这些命令就够烦人了,那么有没有一个步骤就完成上面所有操作?make就可以帮我们完成以上所有的操作。

我必须先说明的是make是一条命令。makefile文件

要想使用make这条命令,就需要在当前目录下创建一个makefile或者Makefile文件,内容如下:

1 mytest:main.o test.o
  2   gcc -o mytest main.o test.o # 前面的空格必须以【Tab】键开头
  3 
  4 main.o:main.c
  5   gcc -c main.c                                                                                                                         
  6 test.o:test.c
  7   gcc -c test.c                                                     

当我们执行make指令后,make会去当前目录下去makefile或Makefile文件,并根据makefile或Makefile中的内容去执行相关的命令

[sjp@iZwz97d32td9ocseu9tkn4Z ~]$ make 
gcc -c main.c
gcc -c test.c
gcc -o mytest main.o test.o
# 不修改源文件中的任何内容,再执行make指令,则不会再继续对源文件进行编译
[sjp@iZwz97d32td9ocseu9tkn4Z ~]$ make 
make: `mytest' is up to date.

我们只写了mytest需要的目标文件,结果make会主动的去判断每个目标文件相关的源代码文件,并直接进行编译,最后在执行链接的操作

编译完成后,如果我们再去修改源文件中的代码,那么make会主动的去判断哪一个源目标文件被修改了,并仅重新编译该文件, 如此这样,可以节省很多的编译时间,某些程序在进行编译操作时,会消耗很多的cpu资源。

例如:我们将test.c中的代码修改了一下,那么我们在执行一次make命令,则只会重新编译更新test.c文件产生test.o文件不会对main.c文件进行重新编译,最后再将main.o和test.o重新链接,

[sjp@iZwz97d32td9ocseu9tkn4Z ~]$ make
gcc -c test.c
gcc -o mytest main.o test.o

执行make命令后,没有将main.c重新编译。 

总结make的好处:

  • make可以简化编译所需要执行的命令。
  • 若在编译完成后,修改了某个源文件中的内容,我们再执行make命令,则make只会去编译更新那个被修改的源文件,其它的目标文件不会被修改。
  • 最后可以依照依赖性来更新执行文件

2.makefile的基本语法与变量

基本的makedile规则:

目标:依赖文件列表  

<Tab>依赖方法

第一行 为依赖关系。

例如;

1 mytest:main.o test.o
2   gcc -o mytest main.o test.o # 前面的空格必须以【Tab】键开头
                                         

mytest:main.o test.o 是依赖关系

上面中的第一行中的mytest是目标main.o test.o是依赖文件

gcc -o mytest main.o test.o 是生成mytest文件的方法,也就是依赖方法。

mytest依赖main.o和test.o的链接才能生成mytest

如果我们想要一个命令直接清理掉所有的目标文件(.o文件)与执行文件(.exe文件),那么我可以需要建立clean目标,如下:

  1 mytest:main.o test.o
  2   gcc -o mytest main.o test.o
  3 
  4 main.o:main.c
  5   gcc -c main.c
  6 test.o:test.c
  7   gcc -c test.c
  8 
  9 .PHONY:clean
 10 clean:
 11   rm -f test.o  main.o mytest    

其中.PHONY是修饰clean的,使clean可以一直重复使用,当然.PHONY:clean去掉也是可以的。

当我们要将生成的test.o main.o mytest删掉时,用make clean命令即可。

[sjp@iZwz97d32td9ocseu9tkn4Z ~]$ make clean 
rm -f test.o  main.o mytest 

在makefile文件中重复的变量有很多,那么我们是否可以将它们简化呢?

例子;

 1 mytest:main.o test.o
 2   gcc -o mytest main.o test.o

上面的命令可以改成:

  1 mytest:main.o test.o
  2   gcc -o $@ $^ 

$@:表示目标,代表上面的 mytest 

$^:表示依赖文件列表中的所有依赖文件。代表上面的 main.o test.o

当我们执行make,效果是一样的,如下:

[sjp@iZwz97d32td9ocseu9tkn4Z ~]$ make
gcc -c main.c
gcc -c test.c
gcc -o mytest main.o test.o

使用$^好处:

如果是依赖文件列表中有几十个文件甚至更多,那么在依赖方法中直接使用$^可以直接取代依赖文件列表中所有的文件,不需要将所有的依赖文件一 一列出来 所以使用$^是非常方便的。

使用$^和$@的好处:

如果我们修改(删除,添加)依赖关系中的目标或依赖列表中的依赖文件时,我们可以不用修改(删除添加)依赖方法中的文件

make和makefile说完之后,我们还需要解决一个问题。

问题:

我们知道,生成可执行文件有两种方法:

方法一;将源文件进行编译并链接形成可执行文件,没有保存其中的编译产生的目标文件(.o文件)。如下;

gcc main.c test.c -o mytest  直接将main.c和test.c文件编译并链接形成mytest文件,没有保存其中编译产生的目标文件(.o文件)

方法二:将源文文件进行编译产生目标文件,将它保存下来,然后再将目标文件进行链接。

gcc -c test.c

gcc -c main.c

gcc test.o main.o -o mytest

先将test.c main.c 编译产生目标文件(.o文件),然后再将目标文件进行链接。

请问方法二相对于方法一有什么优势?

方法二是将目标文件给保存起来,我们生成可执行文件时,将目标文件链接起来,如果我们其中有一个文件修改了代码后,我们只需要

对被修改的源文件进行编译即可,不用再将所有的源文件进行编译。例如:如果有一个项目有100多个源文件,如果我们将它编译链接后

形成可执行程序后,发现功能并没有符合我们的预期,我们在将其中的几个源文件进行修改,那么我们只需要对那几个被修改的源文件

再进行编译即可,而方法一由于没有保存相关的目标文件,就需要将所有的源文件进行再一次编译。而将所有的源文件在一次编译可能

需要等上几个小时等,所以为了能减少时间,我们在编译的时候需要将其目标文件进行保存。

好啦,今天的分享就到这里了,如果这篇文章帮到你的话,记得给笔者一个赞哦,关注我,我将不断分享知识出来,感谢你的支持。

记得点个赞哦(●'◡'●)。


点击全文阅读


本文链接:http://zhangshiyu.com/post/30732.html

文件  编译  源文件  
<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

关于我们 | 我要投稿 | 免责申明

Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1