1. shell 相关

1.1 默认 shell

Makefile 所使用的命令是由 shell 命令行组成,他们是一条一条执行的。

多个命令之间要使用分号隔开,Makefile 中的任何命令都要以 tab 键开始。

多个命令行之间可以有空行和注释行,在执行规则时空行会被自动忽略。

通常系统中可能存在不同的 shell 。但是 make 处理 Makefile 过程时,如果没有明确的指定,那么对所有规则中的命令行的解析使用 bin/sh 来完成。

如:

all:echo $(SHELL)

执行 make 之后结果

wohu@ubuntu:~/cpp/func$ make
echo /bin/sh
/bin/sh
wohu@ubuntu:~/cpp/func$

1.2 执行 shell

语法:

$(shell <shell command>)

它的作用就是执行一个 shell 命令, 并将 shell 命令的结果作为函数的返回.

作用和 <shell command> 一样, ` 是反引号

all:echo $(shell pwd)

执行 make 结果:

wohu@ubuntu:~/cpp/func$ make
echo /home/wohu/cpp/func
/home/wohu/cpp/func
wohu@ubuntu:~/cpp/func$

2. 命令回显

通常 make 在执行命令行之前会把要是执行的命令行输出到标准输出设备。我们称之为 “回显”,如果规则的命令行以字符 @ 开始,则 make 在执行的时候就不会显示这个将要被执行的命令。

示例:

all:@echo $(SHELL)

执行 make 之后结果

wohu@ubuntu:~/cpp/func$ make
/bin/sh
wohu@ubuntu:~/cpp/func$

在执行命令之前没有字符 @,那么 make 的输出将是 /bin/sh

Makefile 中书写 shell 命令时可以加 2 种前缀 @-, 或者不用前缀。3 种格式的 shell 命令区别如下:

  • 不用前缀:输出执行的命令以及命令执行的结果, 出错的话停止执行
  • 前缀 @ : 只输出命令执行的结果, 出错的话停止执行
  • 前缀 - : 命令执行有错的话, 忽略错误, 继续执行

3. make 的参数

  • -n 或者是 --just-print ,执行时只显示所要执行的命令,但不会真正的执行这个命令,其中包括了使用的 @ 字符开始的命令,通常用于检查编写的 Makefile 内容;
  • -s 或者是 --slient 则是禁止所有的执行命令的显示,就好像所有的命令行都使用 @ 开始一样;

4. 命令的执行

当规则中的目标需要被重建的时候,此规则所定义的命令将会被执行,如果是多行的命令,那么每一行命令将是在一个独立的子 shell 进程中被执行。

因此,多命令行之间的执行命令时是相互独立的,相互之间不存在交互。

Makefile 中书写在同一行中的多个命令属于一个完整的 shell 命令行,书写在独立行的一条命令是一个独立的 shell 命令行。

因此:在一个规则的命令中命令行 cd 改变目录不会对其后面的命令的执行产生影响。就是说之后的命令执行的工作目录不会是之前使用 cd 进入的那个目录。如果达到这个目的,就不能把 cd 和其后面的命令放在两行来书写。而应该把这两个命令放在一行上用分号隔开。这样才是一个完整的 shell 命令行。

all:cd /home/wohu/cpp/func;\pwd ; \ls

执行 make 结果

wohu@ubuntu:~/cpp/func$ make
cd /home/wohu/cpp/func;\
pwd ; \
ls
/home/wohu/cpp/func
demo.cpp  demo.h  Makefile
wohu@ubuntu:~/cpp/func$

如果想把一个完整的 shell 命令行书写在多行上,需要使用反斜杠 \ 来对处于多行的命令进行连接,表示他们是一个完整的 shell 命令行。

5. 并发执行命令

GNU make 支持同时执行多条命令。通常情况下,同一时刻只有一个命令在执行,下一个命令只有在当前命令结束之后才能够开始执行。不过可以通过 make 命令行选项 -j 或者 --jobs 来告诉 make 在同一时刻可以允许多条命令同时执行。

如果选项 -j 之后存在一个整数,其含义是告诉 make 在同一时刻可以允许同时执行的命令行的数目。这个数字被称为 job slots。当 -j 选项中没有出现数字的时候,使用默认的 job solts,值为 1,表示 make 将串行的执行规则的命令(同一时刻只能由一条命令被执行)。

并行执行命令所带来的问题是显而易见的:

  • 多个同时执行的命令的输出信息将同时被输出到终端。当出现错误时很难根据一大堆凌乱的信息来区分那条命令执行错误;
  • 在同一时刻可能会存在多个命令执行的进程同时读取到标准输入,但是对于标准输入设备来说,在同一时刻只能存在一个进程访问它。就是说在某个时间点,make 只能保证此刻正在执行的进程中的一个进程读取标准输入流。而其他的进程键的标准输入流将设置为无效。因此在此一时刻多个执行命令的进程中只有一个进程获得标准输入,而其他的需要读取标准输入流的进程由于输入流无效而导致致命的错误。

浅显易懂 Makefile 入门 (08)— 默认 shell (/bin/sh)、命令回显、make参数(-n 只显示命令但不执行,-s 禁止所有回显)、单行命令、多行命令、并发执行相关推荐

  1. linux shell bin sh,linux shell中#bin/sh的理解

    摘要 腾兴网为您分享:linux shell中#bin/sh的理解,支付旭尊,小熊到家,天天美剧,淘金宝等软件知识,以及维棠flv视频软件,usb抓包工具,红警2无敌,ucbug造梦西游4,壁纸工作室 ...

  2. 在运行makefile文件的时候遇到 /bin/sh: 1: XXXXX: not found问题解决

    解决方案 1.命令行操作可以正常操作,在makefile操作出现 /bin/sh: 1: XXXXX: not found 问题: 2.先  which  XXXXX 找到命令绝对路径: 3.在mak ...

  3. 浅显易懂 Makefile 入门 (10)— 嵌套执行 make、export 的使用

    1. 嵌套执行 make 在一个大的工程文件中,不同的文件按照功能被划分到不同的模块中,每个模块可能都会有自己的编译顺序和规则,如果在一个 Makefile 文件中描述所有模块的编译规则,就会很乱,执 ...

  4. 浅显易懂 Makefile 入门 (03)— 目标文件搜索(VPATH 和 vpath 的区别和使用)、隐含规则

    1. 目标文件搜索(VPATH和vpath) 如果需要的文件是存在于不同的路径下(即源文件与 Makefile 文件不在同一个路径下),在编译的时候就用到了 Makefile 中为我们提供的目录搜索文 ...

  5. 浅显易懂 Makefile 入门 (01)— 什么是Makefile、为什么要用Makefile、Makefile规则、Makefile流程如何实现增量编译

    1. 什么是 Makefile Makefile 文件描述了 Linux 系统下 C/C++ 工程的编译规则,它用来自动化编译 C/C++ 项目.一旦写编写好 Makefile 文件,只需要一个 ma ...

  6. 浅显易懂 Makefile 入门 (12)— Makefile 常见的错误信息

    1. 常见的错误信息 make 执行过程中所产生错误并不都是致命的,特别是在命令行之前存在 -.或者 make 使用 -k 选项执行时. make 执行过程的致命错误都带有前缀字符串 ***.错误信息 ...

  7. 浅显易懂 Makefile 入门 (09)— include 文件包含、MAKECMDGOALS

    1. include文件包含 当 make 读取到 include 关键字的时候,会暂停读取当前的 Makefile,而是去读 include 包含的文件,读取结束后再继读取当前的 Makefile ...

  8. 浅显易懂 Makefile 入门 (07)— 其它函数(foreach 、if、call、origin )

    1. foreach 函数 foreach 函数定义如下: $(foreach <var>,<list>,<text>) 函数的功能是:把参数 <list&g ...

  9. 浅显易懂 Makefile 入门 (06)— 文件名操作函数(dir、notdir、suffix、basename、addsuffix、addperfix、join、wildcard)

    编写 Makefile 的时候,很多情况下需要对文件名进行操作.例如获取文件的路径,去除文件的路径,取出文件前缀或后缀等等. 注意:下面的每个函数的参数字符串都会被当作或是一个系列的文件名来看待. 1 ...

最新文章

  1. IIS 5.0 和 6.0 的 ASP.NET 应用程序生命周期
  2. c#中不同类中变量的引用方法
  3. DisplayMetrics
  4. 老旧计算机升级云桌面,哇哦!PC机房轻松升级云课堂 ,PC利旧方案看我的!
  5. Android --- RecyclerViwe中使用SnapHelper报错:“An instance of OnFlingListener already set.”
  6. python spearman相关系数_Python spearman相关系数不匹配 .
  7. ajax数据字符串拼接,ajax请求到后台数据,前台不用拼接字符串,一样显示到页面...
  8. oracle java 绑定变量的值_Oracle SQL调优之绑定变量用法简介
  9. 通过动态获取cookie爬取国家企业信用信息公司系统
  10. 加密原理公钥私钥CA
  11. Nice,涨薪近40%
  12. mysql optimizertrace_MySQL 调优 | OPTIMIZER_TRACE详解
  13. java正则学习笔记
  14. 几款主流的 Python IDE
  15. 拓端tecdat|R语言做复杂金融产品的几何布朗运动的模拟
  16. 数学模型——人口增长模型(基于python)
  17. java 实现屏幕录像_用JAVA捕获屏幕、屏幕录像、播放
  18. 关于onclick=open([Object obj],[Object obj])的问题
  19. 天融信上网行为管理如何做短信验证?
  20. Win7的资源管理器打不开

热门文章

  1. HJ75 公共字符串计算
  2. Python 将字符串转为字典
  3. python 网络编程之Socket通信案例消息发送与接收
  4. 【Sql Server】DateBase-SQL调整
  5. 分布式训练使用手册-paddle 数据并行
  6. java中调用python
  7. Pytorch的默认初始化分布 nn.Embedding.weight初始化分布
  8. viterbi维特比算法和隐马尔可夫模型(HMM)
  9. 堆栈,数据,文本,heap,bss,text data,stack
  10. 编写可调模板并使用自动调谐器