【问题标题】:Using bash arithmetic expansion in GNU makefile在 GNU makefile 中使用 bash 算术扩展
【发布时间】:2020-06-27 11:08:18
【问题描述】:

我想在 Makefile 中使用bash 的算术扩展进行二进制操作(Debian 上的 GNU make + bash)。 expr 未涵盖这些内容。我在 Makefile 中需要这个:

$ x=$(( 255 & 2#11110000)); echo $x
240

不起作用的事情:

$ cat Makefile 
all: a b

a: # $ interpreted by make
    x=$(( 255 & 2#11110000)); echo $$x

b: # escaped $
    x=$$(( 255 & 2#11110000)); echo $$x

(a) 显然不起作用,(b) 也不起作用:

$ make b
x=$(( 255 & 2#11110000)); echo $x
/bin/sh: 1: arithmetic expression: expecting EOF: " 255 & 2#11110000"

什么是可能的方法?大量的引用、反引号和转义也没有产生任何结果。

【问题讨论】:

标签: bash gnu-make


【解决方案1】:

添加

SHELL = bash

生成文件

【讨论】:

  • 非常有趣,确实忘记检查/bin/sh 指向的位置。但是dash 也应该支持 arith 扩展?
  • 没有。 dash 是sh (shell) 实用程序的 POSIX 标准的极简实现。它几乎不提供对标准的任何扩展。这是一件好事,因为它使您的脚本更有可能在/bin/sh 不是 bash 的系统上运行。另一方面,Bash 有大量标准中没有的额外功能。扩展算术是这些功能之一。
【解决方案2】:
$ cat Makefile

# Make variable (recommended)
x := $(shell bash -c 'echo $$((255 & 2\#11110000))')
$(info [$x])

# Shell variable (not recommended)
a:
    x=`bash -c 'echo $$((255 & 2#11110000))'`; echo $$x

给予

$ make
[240]
x=`bash -c 'echo $((255 & 2#11110000))'`; echo $x
240

不要忘记# 在 makefile 中引入了注释!

我建议尽可能使用 make 工具而不是 shell 工具。它通常会变得更干净。 (正如@ensc 所说,我确实这样做了——我在我的 makefile 中到处都使用 bash :-)。)

【讨论】:

  • 感谢您还提到了#。很遗憾,make 变量在目标中不起作用,但只能在顶层起作用。
  • @ShiDoiSi 嗯?使变量在 makefile 的每个部分都起作用,包括目标和配方。您确实可以很好地控制使用它们。
  • 嗯,那我还是做错了:目标中的z := $(shell bash -c 'echo $$((255 & 2#11110000))') 行产生gmake: z: Command not found
  • z := … 语法是 make,而不是 bash。看起来您在z 之前有一个制表符,因此 make 认为该行是配方的一部分。配方由 shell 执行。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-08-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-03
相关资源
最近更新 更多