Autoconf:如何在字符串中获取程序输出并检查该字符串中是否存在另一个字符串

Autoconf : How to get program output in a string and check if another string is present in that

我正在 Python 中开发 Qt 应用程序。它使用需要编译的资源文件。我正在使用 autotools 来管理我的项目的编译和安装。

现在,为了使资源文件能够被应用程序使用,需要使用特定版本的编译程序(pyrcc)对其进行编译。我可以通过将 pyrcc -version 的输出放在 configure.ac 中的变量中来获取版本。但是,我不知道如何检查字符串 pyrcc5 是否存在于输出中。如果它不存在,我想告诉用户他的 PyRCC 程序版本错误,并中止 configure.

此外,我想避免程序输出需要额外的变量,而是像这样(伪代码):

if "pyrcc5" not in output of "pyrcc -version":
    say "pyrcc has wrong version"
    exit 1

我该怎么做?

在为 Autoconf 编写 configure.ac 时,请始终记住您基本上是在编写 shell 脚本。 Autoconf 提供了大量的宏,可以为您提供很大的影响力,但您通常至少可以了解基本的“我如何在 Autoconf 中执行 X?”的概念。通过询问“我将如何在便携式 shell 脚本中执行 X?”来提问?

特别是对于...

I would like to avoid the need of an extra variable for the program output, but instead do it like this (Pseudo code):

if "pyrcc5" not in output of "pyrcc -version":
    say "pyrcc has wrong version"
    exit 1

...用于此类任务的可移植 shell 脚本的常用工具是 grep,而且令人高兴的是,将其应用于任务的最简单方法不需要中间变量。例如,这完全实现了您的伪代码(没有向控制台发出任何无关的消息):

if ! pyrcc -version | grep pyrcc5 >/dev/null 2>/dev/null; then
  echo "pyrcc has wrong version"
  exit 1
fi

pyrcc -version 的输出通过管道传输到 grep,并依赖于 grep 当且仅当它找到任何匹配项时以成功状态退出。

事实上,您可以将其准确地放入 configure.ac,但

会更符合习惯
  • 使用通常的 Autoconf 机制定位 pyrccgrep,并使用以这种方式发现的版本;
  • 使用 Autoconf AS_IF 宏来编写 if 结构,而不是按字面写;
  • 使用标准的 Autoconf 机制发出“正在检查...”消息并报告其结果;和
  • 使用标准的 Autoconf 机制输出失败消息并终止。

当然,所有这些都使上述内容变得相当复杂,但也更加灵活和便携。它可能看起来像这样:

AC_ARG_VAR([PYRCC], [The name or full path of pyrcc. Version 5 is required.])

# ...

AC_PROG_GREP
AC_CHECK_PROGS([PYRCC], [pyrcc5 pyrcc], [])
AS_IF([test "x${PYRCC}" = x],
  [AC_MSG_ERROR([Required program pyrcc was not found])])

# ...

AC_MSG_CHECKING([whether ${PYRCC} has an appropriate version])
AS_IF([! pyrcc -version | grep pyrcc5 >/dev/null 2>/dev/null], [
  AC_MSG_RESULT([no])
  AC_MSG_ERROR([pyrcc version 5 is required, but ${PYRCC} is a different version])
], [
  AC_MSG_RESULT([yes])
])

除了可移植性和传统的 Autoconf 进度消息传递之外,这还使构建器能够将特定的 pyrcc 可执行文件指定为 configure(通过在其环境中设置变量 PYRCC ), 在 configure 的帮助文本中记录,并将 PYRCC 导出为 make 变量。

哦,我也用 pyrcc5 的名字偷偷检查了 pyrcc,虽然我不知道这在实践中是否有用。

最终结果看起来不再像我首先提供的 shell 脚本片段,我同意。但同样,纯 shell 脚本片段可以按原样使用,而且,完全自动没收的版本直接从纯脚本派生。