自学内容网 自学内容网

【Linux】自动化构建工具-make/Makefile

make与Makefile

make:一条命令

makefile/Makefile:一个文件。文件里面写依赖关系与依赖方法

两个搭配使用,完成项目自动化构建。

一、Makefile基本语法

target(目标文件):文件1 文件2(依赖文件列表)//依赖关系
<Tab>gcc -o 欲建立的执行文件 目标文件1 目标文件2///依赖方法

<Tab>必须是隔一个Tab建 。

proc: proc.c
     gcc -o proc proc.c
.PHONY: clean
clean:
     rm -f proc

代码解析: 

proc:目标文件。

proc.c:依赖文件列表。

对于proc:proc.c,冒号左侧是目标文件,右侧是它的依赖文件,所以就可以说它们之间存在一种依赖关系只有 proc.c 存在才可以有 proc。

proc:proc.c下面的语句gcc -o proc proc.c叫做依赖方法。

 .PHONY:表示声明一个伪目标。(类似于关键字)。

clean:伪目标的一个名称。(类似于变量名)。

clean::clean:单独一行表示这一行的依赖关系,没有依赖列表。

 二、make与Makefile基本原理

创建一个proc.c 

创建一个makefile 

 

执行命令 

为什么直接make就出可执行程序了,相反清理文件要make clean?(后面要加clean)

原理:

 1.makefile文件,会被make从上到下开始扫描,第一个目标名,是缺省要形成的。(也就是说直接make就形成)如果想执行其他依赖关系和依赖方法,make name

另外一直输入make,会发现系统提示proc为最新的,而make clean则会一直显示执行依赖方法,如何消除一直make带来的提示呢?此外为什么make clean会一直显示执行依赖方法?

 如何掩盖make带来提示的内容?不想让他一直 make:`proc'

我们在makefile文件中添加一个.PHONY:proc。.PHONY作用让目标文件,对应的依赖方法总是被执行。让依赖方法,忽略时间对比。下面一句不理解没事往下看

其次就是我们可以修改文件,修改文件也能消除一直make带来的提示。文件 = 内容 + 属性

我们可以通过【stat】这个指令来查看源文件和可执行文件的所有属性,不过要观察的还是其中一个叫做ACM时间 

  • Access: 最后一次访问该文件的时间
  • Change:最后一次改变该文件属性或状态的时间
  • Modify:最近一次修改文件内容的时间【比较的是这个时间】

 我们可以对比看:当proc的Modify的时间22:29:01,proc.c的Modify的时间为22:29:37,proc.c的修改时间大于proc,我们再次make,则修改成功。

下面可以通过时间对比可知,只要proc.c的修改时间大于proc。则就可以修改。

为什么一直make clean会一直显示依赖方法? 

因为rm -f本来就不关心时间。所以系统会一直输出rm -f

另外我们每次make后总会显示gcc proc.c -o proc这种的依赖方法,我们如何屏蔽掉呢? 

makefile:命令语句前面+@ 

 语句执行

 

2.make makefile在执行gcc命令的时候,如果发生语法错误,就会终止推导过程        

 假如编译报错,将会终止推导过程,下面的结束编译是不是就没有打印

3.make解释makefile是时候,是会自动推导的。推导过程,不执行依赖方法。直到推导到有依赖文件存在,然后在逆向的执行所有的依赖方法

下面的makefile中,我们找到不到proc.o,则我们就不执行下面的依赖方法,把下面的依赖方法放入到一个栈中,之后我们继续推导发现我们找不到proc.s,则我们继续不执行proc.o:proc.s下面的依赖方法,把下面的依赖方法放入到一个栈中。后面以此类推,一直找到我们能找到的文件proc.c。然后执行后依次出栈 

我们打印一下,来更好的理解 

下面两个makefile文件内容是一样的 

% makefile语法中的通配符

$(bin):类似于解引用 等于proc

$^ 所有依赖文件列表

$@ 目标文件

 %.c 当前目录下所有.c文件,展开到依赖列表中

$< 依赖文件,一个一个的交给gcc -c选项,形成同名的.o文件

4.makefile默认只形成一个可执行程序 

我们如果有两个.c文件需要同时编译,makefile默认只会生成一个可执行程序

 下面我们想要形成code与proc两个可执行程序

下面默认只生成一个proc可执行程序 

 改变方法我们写一下.PHONY:all(.PHONY作用让目标文件,对应的依赖方法总是被执行

这里的目的就是.PHONY:all下面有依赖关系执行目标文件,如果目标文件没有被执行找不到all则先入栈,然后执行下面的语句。最后一下这个all的栈。

我们在all下面的依赖方法写一个echo "heheh"好理解一下 

最后是不是最后打印heheh 


原文地址:https://blog.csdn.net/m0_73911405/article/details/143662084

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!