Linux-make

工程管理器make的使用

代码编程可执行文件,叫做编译(compile);在一个项目中,先编译这个,还是先编译那个(即编译的安排),叫做构建(build)。

make是最常用的构建工具,诞生于1977年,主要用于C语言想项目。

实际上,任何只要某个文件发生变化,就要重现构建的项目都可以用make构建。

make的概念

make: 制作。比如,要做出文件a.txt,就可以执行:

make a.txt

make本身不知道如何做出a.txt,需要告知make如何调用其它命令完成这个目标。

比如,假设文件a.txt依赖于b.txt和c.txt,是后面两个文件连接(cat命令)的产物。那么,make需要知道下面的规则:
这种规则make本身是不知道的,需要人为地区定义一些规则来进行一系列的操作。

a.txt: b.txt c.txt
    cat b.txt c.txt > a.txt

也就是,make a.txt这条命令的背后实际分为两步:

确认b.txt和c.txt必须已经存在;

使用cat命令将两个文件进行合并,输出为新的文件。

像这样的规则,需要写在一个名为Makefile的文件中,make命令依赖这个文件进行构建

Makefile也可以写成makefile,或者用命令行参数指定为其它文件名:

make -f rules.txt [命令]
make --file=rules.txt [命令]

当把文件写入到Makefile中的时候不需要加上述的参数,所以常规用的时候都要写到Makefile中。

make [命令] //就可以进行使用

make只是一个根据指定的Shell命令进行构建的工具。

Makefile的文件格式

Makefile文件由一系列规则构成。每条规则的形式如下:

<target>: <prerequisites>
[tab] <command> // 这里的tab键必须是tab键,不可以用相等长度的空格进行替代。
目标: 前置条件
[必须有个table键] <命令>

“目标”是必须的;“前置条件”和“命令”是可选的,但两者必存其一。可以没有前置条件或者没有命令,但是至少要有其中的一个。

明确:构建目标的前置条件是什么,以及如何构建。当前置条件和目标都存在的时候,在执行命令之前要保证前置条件必须成立。
在这里插入图片描述
在这里插入图片描述

目标(target)

一个目标(target)构成一个规则。目标通常是文件名,指明命令所要构建的对象,比如a.txt。
目标可以是一个文件名,也可以是多个文件名,之间用空格分隔。
除了文件名,目标还可以是某个操作的名字,这称之为“伪目标”(phony target)。

clean://这里的clean就是目标。
    rm *.o

上面代码的目标是clean,不是一个文件名,是一个操作的名字,属于“伪目标”,作用是删除文件。

make clean

在这里插入图片描述
在这里插入图片描述

在当前目录下有文件名为clean的文件的时候,该命令会又二义性,为了避免这种情况,可以声明clean是“伪目标”:

.PHONY: clean
clean:
    rm *.o

在这里插入图片描述

声明clean是“伪目标”之后,make不会去检查是否存在一个叫做clean的文件,而是每次运行都执行对应的命令。

如果make命令运行时没有指定目标,默认会执行Makefile文件的第一个目标

前置条件

前置条件通常是一组文件名,之间用空格分开,它指定了目标是否重新构建的判断标准:只要有其中的任何一个文件不存在,或者更新过,目标就需要重新构建。

result: source.txt
	cp source.txt result.txt

在这里插入图片描述

构建result.txt文件的前提就是source.txt文件已经存在,make才可以正常运行,否则,就必须要写一条规则用来生成source.txt文件。
当没有source.txt的时候运行报错
在这里插入图片描述

source.txt:
    echo “this is the source” > source.txt

在这里插入图片描述
当前置条件中的source.txt不存在的时候就先创建一个source.txt。
在这里插入图片描述

source.txt没有前置条件,意味着跟其它文件无关,只要source.txt不存在,每次调用make source.txt,都会生成source.txt。

如果连续执行两次make result.txt。
第一次会先创建source.txt,再创建result.txt。
第二次执行,make发现source.txt没有更新,就会不执行任何操作。

命令(command)

表示如何更新目标文件,由一行或多行Shell命令组成
是构建“目标”的具体指令;
结果通常是生成目标文件。
每行命令之前必须有一个tab键。如果想用其它键,可以用内置变量.RECIPEPREFIX声明。(注意是每一行命令之前都要有一个tab)一般情况下用不到,用tab键即可。

.RECIPEPREFIX=>
all:
>echo 123
//用.RECIPEPREFIX指定大于号(>)替代tab键。

在这里插入图片描述

每行命令都是在一个单独运行的Shell中执行的,这些Shell间没有继承关系。

var:
    export foo=bar
    echo “foo=[$$foo]// 美元符号在Makefile中是一个转义符。

在这里插入图片描述
在这里插入图片描述
可以看出来在前一句定义的变量在后一句没有继承。
解决方法:

;

将多行shell命令写到同一行内,每一条的命令之间都用;进行分割。
在这里插入图片描述

\

在每一行的shell命令的下面都加上;以示改行命令的结束,之后再在每一行的命令的最后加上\以示之后的命令与该命令之间的继承关系。“\”只是起到了转意的作用。
在这里插入图片描述
相对于第一种方法来说就是可读性比较强。

.ONESHELL

在之前用.ONESHELL:声明一下
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值