从configure.ac中的文件中读取版本号

问题描述 投票:11回答:2

由于某些原因,我在纯文本文件而不是configure.ac中定义项目版本号。我想创建一个语句来读取版本号并在编译期间存储它。

现在我的configure.ac看起来像这样:

AC_INIT([my program],[999.9.9])

我希望有类似的东西:

AC_INIT([my program],[ $(cat VERSION) ])

这当然不会工作。这里的诀窍是什么? (我知道我失去了一些便携性 - 我现在不在乎)。谢谢!

autoconf
2个回答
22
投票

尝试:

AC_INIT([my program], m4_esyscmd([tr -d '\n' < VERSION]))

编辑了评论中建议的修复程序。

我还能够使用以下方法删除不可移植的tr调用:

AC_INIT([my program], [m4_translit(m4_esyscmd([cat VERSION]),m4_newline)])

这似乎同样有效,恩里科在下面的评论中提出的解决方案也是如此:

AC_INIT([my program], [m4_esyscmd_s([cat VERSION])])

1
投票

您可以简单地使用原生宏m4_include()(而不是按照ldav1s的建议通过tr调用catm4_esyscmd_s()),

AC_INIT([foo], m4_normalize(m4_include([VERSION])))

这也是GNU M4 qazxsw poi针对类似案例的官方指南:

suggests

[…]

$ cat examples/incl.m4 ⇒Include file start ⇒foo ⇒Include file end include扩展到文件内容的事实可用于定义对整个文件进行操作的宏。这是一个例子,它定义'sinclude'以扩展到bar的内容:

incl.m4

GNU M4还提供$ m4 -I examples define(`bar', include(`incl.m4')) ⇒ This is `bar': >>bar<< ⇒This is bar: >>Include file start ⇒foo ⇒Include file end ⇒<< ,因此如果您想确保版本字符串始终遵循特定模式 - 或者如果support for regular expressions文件包含的文本多于版本字符串 - 您可以使用VERSION查找您要查找的内容:

m4_bregexp()

这也是最安全的方法,因为如果在AC_INIT([foo], m4_bregexp(m4_include([VERSION]), [[0-9]+\.[0-9]+\.[0-9]+], [\&])) 文件中找不到上面的正则表达式,VERSION的第二个参数只会扩展为空字符串,并且Autoconf会抛出以下错误消息:

AC_INIT()

调用error: AC_INIT should be called with package and version arguments 来处理m4_bregexp()文件内容有用的典型情况是,当它包含三个数字版本字符串(VERSION)时,你只想要一个两个数字的字符串(MAJOR.MINOR.REVISION)作为你的扩展MAJOR.MINOR宏。

如果您熟悉正则表达式并捕获括号,并且希望能够执行更复杂的任务,那么我已经编写了这个通用的可变参数宏(您可以将其粘贴到AC_PACKAGE_VERSION的开头),

configure.ac

可以用来做:

dnl  NA_DEFINE_SUBSTRINGS_AS(string, regexp, macro0[, macro1[, ... macroN ]])
dnl  ***************************************************************************
dnl
dnl  Searches for the first match of `regexp` in `string`. For both the entire
dnl  regular expression `regexp` (`\0`) and each sub-expression within capturing
dnl  parentheses (`\1`, `\2`, `\3`, ... , `\N`) a macro expanding to the
dnl  corresponding matching text will be created, named according to the
dnl  argument `macroN` passed. If a `macroN` argument is omitted or empty, the
dnl  corresponding parentheses in the regular expression will be considered as
dnl  non-capturing. If `regexp` cannot be found in `string` no macro will be
dnl  defined. If `regexp` can be found but some of its capturing parentheses
dnl  cannot, the macro(s) corresponding to the latter will be defined as empty
dnl  strings.
dnl
dnl  Source: https://github.com/madmurphy/not-autotools
dnl
dnl  ***************************************************************************
AC_DEFUN([NA_DEFINE_SUBSTRINGS_AS], [
    m4_if(m4_eval([$# > 2]), [1], [
        m4_if(m4_normalize(m4_argn([$#], $*)), [], [],
            [m4_bregexp([$1], [$2], [m4_define(m4_normalize(m4_argn([$#], $*)), \]m4_if([$#], [3], [&], m4_eval([$# - 3]))[)])])
        m4_if(m4_eval([$# > 3]), [1], [NA_DEFINE_SUBSTRINGS_AS(m4_reverse(m4_shift(m4_reverse($@))))])
    ])
])

所以宏NA_DEFINE_SUBSTRINGS_AS( m4_include([VERSION]), [\([0-9]+\)\s*\.\s*\([0-9]+\)\s*\.\s*\([0-9]+\)], [FOO_VERSION_STRING], [FOO_VERSION_MAJOR], [FOO_VERSION_MINOR], [FOO_VERSION_REVISION] ) AC_INIT([foo], FOO_VERSION_MAJOR[.]FOO_VERSION_MINOR[.]FOO_VERSION_REVISION) FOO_VERSION_MAJORFOO_VERSION_MINOR总是在FOO_VERSION_REVISION内可用。

注意:configure.ac宏名称中的NA_前缀代表“Not Autotools”。

如果在NA_DEFINE_SUBSTRINGS_AS()文件中找不到上面的正则表达式,VERSION安全地不会定义相应的宏名称。这允许为此特定情况生成错误(必须在NA_DEFINE_SUBSTRINGS_AS()之后立即粘贴以下行):

AC_INIT()

因为它可以看起来像读取一个简单的m4_ifndef([FOO_VERSION_STRING], [AC_MSG_ERROR([invalid version format in `VERSION` file])]) 文件一样微不足道,如果你想从VERSION文件中检索版本字符串,事情变得更加棘手。在这里,package.json宏可以派上用场:

NA_DEFINE_SUBSTRINGS_AS()

注意:NA_DEFINE_SUBSTRINGS_AS( m4_join([|], m4_unquote(m4_include([package.json]))), ["?version"?:\s*"?\s*\(\([0-9]+\)\s*\.\s*\([0-9]+\)\s*\.\s*\([0-9]+\)\)\s*"?], [JSON_ENTRY], [FOO_VERSION_STRING], [FOO_VERSION_MAJOR], [FOO_VERSION_MINOR], [FOO_VERSION_REVISION] ) AC_INIT([foo], FOO_VERSION_MAJOR[.]FOO_VERSION_MINOR[.]FOO_VERSION_REVISION) 文件可能包含逗号和方括号(对GNU m4-ish不太友好),在处理JSON字符串之前需要删除/替换这些文件。在上面的代码中,宏.json删除了m4_unquote()中可能存在的所有第一级方括号 - 如果后者包含嵌套数组,则package.json必须在数组嵌套的最大级别上调用多次 - 然后宏m4_unquote()替换所有逗号与m4_join()

'|'宏也接受空参数,所以如果你愿意,你可以用NA_DEFINE_SUBSTRINGS_AS()替换[JSON_ENTRY]参数,因为你可能永远不会使用JSON源字符串[]

如果您只需要从"version": "999.9.9"文件中检索完整版本字符串,但不需要使用package.jsonFOO_VERSION_MAJORFOO_VERSION_MINOR,则可以删除上面正则表达式中的一些捕获括号,如下例所示:

FOO_VERSION_REVISION

为了完整性,由于最后一个示例只有一个要捕获的字符串,因此也可以在不使用NA_DEFINE_SUBSTRINGS_AS( m4_join([|], m4_unquote(m4_include([package.json]))), ["?version"?:\s*"?\s*\([0-9]+\.[0-9]+\.[0-9]+\)\s*"?], [], [FOO_VERSION_STRING] ) AC_INIT([foo], FOO_VERSION_STRING) 的情况下重写它:

NA_DEFINE_SUBSTRINGS_AS()
© www.soinside.com 2019 - 2024. All rights reserved.