【问题标题】:Embedding bash script into makefile将 bash 脚本嵌入到 makefile
【发布时间】:2019-05-01 15:18:41
【问题描述】:

我想在 makefile 中包含一些条件语句:

SHELL=/bin/bash
all: 
        $(g++ -Wall main.cpp othersrc.cpp -o hello)
        @if [[ $? -ne -1 ]]; then \
          echo "Compile failed!"; \
          exit 1; \
        fi

但是得到一个错误:

/bin/bash: -c: line 0: 需要条件二元运算符 /bin/bash: -c:第 0 行:-1' /bin/bash: -c: line 0:if [[ -ne -1 ]] 附近的语法错误;然后 \' makefile:3: 目标 'all' 的配方失败 make: *** [all] 错误 1

如何解决?

【问题讨论】:

  • 确认,不!如果 g++ 失败,Make 的通常行为是让 g++ 写入其错误消息然后中止。看起来您正试图抑制正常行为并将几乎无用的错误消息写入错误的输出流!只需调用 g++,让它自己编写错误信息,然后让 make 检查返回值并中止。
  • @williampursell 错误消息不会被禁止
  • 我似乎没有必要通过设置SHELL = /bin/bash 来限制makefile 的可移植性,这样您就可以使用[[ ... ]] 表单条件......为什么不使用POSIX sh-compliant if [ $$? -eq 0 ]; ... 而不是麻烦重置SHELL

标签: linux bash ubuntu gcc makefile


【解决方案1】:

请注意,makefile 配方的每一行都在不同的 shell 中运行,因此上一行的 $? 不可用,除非您使用 .ONESHELL 选项。

没有.ONESHELL 的修复:

all: hello
.PHONY: all

hello: main.cpp othersrc.cpp
    g++ -o $@ -Wall main.cpp othersrc.cpp && echo "Compile succeeded." || (echo "Compile failed!"; false)

.ONESHELL:

all: hello
.PHONY: all

SHELL:=/bin/bash
.ONESHELL:

hello:
    @echo "g++ -o $@ -Wall main.cpp othersrc.cpp"
    g++ -o $@ -Wall main.cpp othersrc.cpp
    if [[ $$? -eq 0 ]]; then
        echo "Compile succeded!"
    else
        echo "Compile failed!"
        exit 1
    fi

当需要将$ 传递到shell 命令时,它必须在makefile 中引用为$$(基本上,make 向您收取一美元的费用)。因此$$?

【讨论】:

  • 酷!但是我怎么能实现“else”分支呢?说,我想输出“dd.mm.yyyy hh:mm:ss 成功”
  • @amplifier 为您添加了另一个分支。
  • 看来唯一的选择是使用逻辑运算符。但是对于更复杂的场景,是否可以在 makefile 中使用 bash,或者还有另一种选择,比如让 sh 脚本调用 make?我只是在学习 linux 脚本
  • @amplifier 为您添加了条件版本。
  • 如果你使用 .ONESHELL 你不需要反斜杠。如果您不想使用 .ONESHELL (请注意,仅在 GNU make 4.0 及更高版本中可用)然后使用反斜杠就足够了,您不需要 .ONESHELL (但您还必须添加 ; ` to the end of the g++` 行)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-21
  • 2011-06-01
  • 2023-03-07
  • 2021-12-07
相关资源
最近更新 更多