Linux下shell脚本/Makefile编写

Linux下shell脚本/Makefile编写
一、基本概念
代码变成可执行文件,叫做编译(compile);先编译这个,还是先编译那个(即编译的安排),叫做构建(build)。
make只是一个指定的Shell命令进行构建的工具,它的规则很简单,你规定要构建哪个文件,它依赖哪些源文件,当那些文件有变动时,如何重新构建它。
二、Makefile文件的格式
1、概述
Makefile文件由一系列规则(rules)构成。每条规则如下

< target >: < prerequisites >
[tab]  < commands > 

上面第一行冒号前面的部分,叫做“目标”(target),冒号后面的部分叫做“前置条件(prerequisites)”,第二行必须由一个tab键起首,后面跟着“命令(commands)”。“目标”时必需的,不可省略;“前置条件”和“命令”都是可选的,但是两者之中必须至少存在一个。
每条规则就明确两件事:构建目标的前置条件是什么,以及如何构建。
2、目标(target)
一个目标(target)就构成一条规则,目标通常是文件名,指明Make命令所要构建的对象,比如aaa.f文件,目标可以是一个文件名,也可以是多个文件名,之间用空格分隔。除了文件名,目标还可以是某个操作的名字,这个称为“伪目标(phony target)”。

clean:
     rm *.o

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

$ make clean

但是如果当前目录中,正好有一个文件叫做clean,那么这个命令不会执行,因为make发现clean文件已经存在,就认为没有必要重新构建了,就不会执行指定的rm命令,为了避免这种情况,可以明确声明clean是“伪目标”,写法如下

.PHONY: clean
clean:
     rm *.o temp

声明clean是“伪目标”之后,make就不会去检查是否存在一个叫clean文件,而是每次运行都执行对应的命令。如果 make命令运行时没有指定目标,默认会执行makefile文件的第一个目标。
3、前置条件(prerequisites)
前置条件通常是一组文件名,之间用空格分隔,它指定了“目标”是否重新构建的判断标准:只要有一个前置文件不存在,或有过更新(前置文件的last-modification时间戳比目标的时间戳新),“目标”就需要重新构建。

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

上面代码中,构建result.txt的前置条件是source.txt。如果当前目录中,source.txt已经存在,那么$ make resule.txt 可以正常运行,否则必须要再写一条规则来生成source.txt。

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

上面代码中,source.txt后面没有前置条件,就意味着它跟其他文件无关,只要这个文件不存在,每次调用$ make source.txt,它都会生成。
4、命令(commands)
命令(commands)表示如何更新目标文件,有一行或多行的Shell命令组成。它是构建“目标”的具体指令,它的运行结果通常就是生成目标文件。
每个命令之前必须有一个tab键,需要注意的是,每行命令在一个单独的Shell中执行,这些Shell之间没有继承关系。

var-lost:
      export foo = bar
      echo “foo=[$$foo]

上面代码执行后($ make ver-lost),取不到foo的值,因为两行命令在两个不同的进程执行。一个解决办法是将两行命令写在一行,中间用分号分隔。

var-kept: 
     export foo = bar: echo “foo = [$$foo]

另一个解决办法是在换行符前加反斜杠转义。

var-kept: 
     export foo = bar : \
     echo “foo = [$$foo]

最后一个办法是加上.ONESHELL:命令

.ONESHELL:
var-kept: 
     export foo = bar : \
     echo “foo = [$$foo]

三、Makefile文件的语法
1、注释,井号(#)在makefile中表示注释。
2、回声(echoing),正常情况下,make会打印每条命令,然后再执行,这就叫回声(echoing)。在命令前加上@,就可以关闭回声。

test:	test:
    #这是测试	    @ #这是测试
    echo AAAA	    @ echo AAAA

3、通配符
通配符用来指定一组符合条件的文件名。例如*,*.sv表示所有后缀名为sv的文件名。
4、模式匹配
Make命令允许对文件名,进行类似正则运算的匹配,主要用到的匹配符是%,可以将大量同类型文件,只用一条规则就完成构建。

%.o: %.c

等同于

f1.o: f1.c
f2.o: f2.c

5、变量与赋值符
1)Makefile允许使用等号自定义变量。

txt = Hello World
test:
     @echo $(txt)

上面代码中,变量txt等于Hello World 。调用时,变量需要放在$()之中。
调用shell变量,需要在美元符号前,再加一个美元符号,这是因为Make命令会对美元符号转义。

test:
   @echo $ $HOME

2)赋值运算
VARIABLE = value #在执行时拓展,允许递归拓展。
VARIABLE : = value #在定义时拓展
VARIABLE + = value #将值追加到变量尾端
6、判断与循环

ifeq ($(CC), gcc)
   libs = $( libs_for_gcc)
else
   libs = $( normal_libs)
endif

7、内置函数
1)shell函数,用来执行shell命令

srcfiles: : = $ ( shell echo src/[00..99].txt)

8、Makefile export
1)在(parent,上层的)makefile中export出来变量,子makefile(sub make)中,是可以访问的。
2)而同一级别的makefile(可通过makefile中内置变量MAKELEVEL查看得知当前makefile的level),是无法通过export来传递变量的,即一个makefile中export出来一个变量,同一级的另外一个makefile中,是无法访问/得到的。
3)makefile中的export是导出变量到子makefile,而目标对应执行的动作中的export,是属于shell中的export,其作用是导出变量到当前shell。此两个export的作用是不同的。
8、补充:
1)shell echo
echo命令是一个内置在Bash中的shell,通常用于shell脚本中以显示消息或输出其他命令的结果。
-n:当指定-n选项时,其后的换行符被抑制;即不会在最后自动换行。
-e:当指定-e选项时,则将解释以下反斜杠转义字符:
2)md5sum [选项] … [文件]
md5sum – 计算检验MD5效验码,md5sum命令采用MD5报文摘要算法(128位)计算和检查文件的校验和。一般来说,安装了Linux后,就会有md5sum这个工具,直接在命令行终端直接运行。
MD5算法常常被用来验证网络文件传输的完整性,防止文件被人篡改。MD5 全称是报文摘要算法(Message-Digest Algorithm 5),此算法对任意长度的信息逐位进行计算,产生一个二进制长度为128位(十六进制长度就是32位)的“指纹”(或称“报文摘要”),不同的文件产生相同的报文摘要的可能性是非常非常之小的。
3)perl -e
可以让perl程序在命令行上运行
4)date +%N
5)注意事项,makefile里的添加的开关选项,要与bsub运行时开关选项最好保持一致,否则可能会导致选项冲突,检查log脚本未运行。
返回纳秒数
6)makefile中“-”的作用,在调用命令时,不加“-”,如果在命令执行后对于的log文件中出现E,makefile则会识别报错,不会执行后续的调用命令;加“-”,如果在命令执行后对于的log文件中出现E,makefile则不会识别报错,执行后续的调用命令。
7)多命令顺序执行连接符:
(1);分号——没有任何逻辑关系的连接符。当多个命令用分号连接时,各命令之间的执行成功与否彼此没有任何影响,都会一条一条执行下去。
(2)|| 逻辑或——当用此连接符连接多个命令时,前面的命令执行成功,则后面的命令不会执行。前面的命令执行失败,后面的命令才会执行。
(3)&& 逻辑与——当用此连接符连接多个命令时,前面的命令执行成功,才会执行后面的命令,前面的命令执行失败,后面的命令不会执行,与 || 正好相反。
(4)| 管道符——当用此连接符连接多个命令时,前面命令执行的正确输出,会交给后面的命令继续处理。若前面的命令执行失败,则会报错,若后面的命令无法处理前面命令的输出,也会报错。

参考文章:
http://www.ruanyifeng.com/blog/2015/02/make.html

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
概述 什么是 makefile?或许很多Windows 的程序员都不知道这个东西,因为那些Windows 的IDE 都为你做了这个工作,但我觉得 要作一个好的和professional 的程序员,makefile 还是要懂。这就好像现在有这么多的HTML 的编辑器,但如果你想成为一个专 业人士,你还是要了解HTML 的标识的含义。特别在Unix 下的软件编译,你就不能不自己makefile 了,会不会makefile, 从一个侧面说明了一个人是否具备完成大型工程的能力。 因为,makefile 关系到了整个工程的编译规则。一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中, makefile 定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复 杂的功能操作,因为makefile 就像一个Shell 脚本一样,其中也可以执行操作系统的命令。 makefile 带来的好处就是——“自动化编译”,一旦好,只需要一个make 命令,整个工程完全自动编译,极大的提高了软件 开发的效率。make 是一个命令工具,是一个解释makefile 中指令的命令工具,一般来说,大多数的IDE 都有这个命令,比如: Delphi 的make,Visual C++的nmake,Linux 下GNU 的make。可见,makefile 都成为了一种在工程方面的编译方法。 现在讲述如何 makefile 的文章比较少,这是我想这篇文章的原因。当然,不同产商的make 各不相同,也有不同的语法, 但其本质都是在“文件依赖性”上做文章,这里,我仅对GNU 的make 进行讲述,我的环境是RedHat Linux 8.0,make 的版本 是3.80。必竟,这个make 是应用最为广泛的,也是用得最多的。而且其还是最遵循于IEEE 1003.2-1992 标准的(POSIX.2)。 在这篇文档中,将以C/C++的源码作为我们基础,所以必然涉及一些关于C/C++的编译的知识,相关于这方面的内容,还请各 位查看相关的编译器的文档。这里所默认的编译器是UNIX 下的GCC 和CC。 关于程序的编译和链接

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值