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

时间:2011-12-19 09:43:56

标签: autoconf

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

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

AC_INIT([my program],[999.9.9])

我希望有类似的东西:

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

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

2 个答案:

答案 0 :(得分: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 :(得分:1)

您可以简单地使用本机宏m4_include()(而不是按照 ldav1s 的建议,通过tr调用catm4_esyscmd_s()),< / p>

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

这也是 GNU M4 suggests的官方指南,适用于类似情况:

$ cat examples/incl.m4
⇒Include file start
⇒foo
⇒Include file end
     

[…]

     

includesinclude扩展到以下内容的事实:   文件可用于定义对整个文件进行操作的宏。这里   是一个示例,它定义了“ bar”以扩展到   incl.m4

$ m4 -I examples
define(`bar', include(`incl.m4'))
⇒
This is `bar':  >>bar<<
⇒This is bar:  >>Include file start
⇒foo
⇒Include file end
⇒<<

GNU M4 还提供support for regular expressions,因此,如果要确保版本字符串始终遵循特定的模式–或者VERSION文件包含的文本多于只是版本字符串–您可以使用m4_bregexp()来查找所需内容:

AC_INIT([foo], m4_bregexp(m4_include([VERSION]), [[0-9]+\.[0-9]+\.[0-9]+], [\&]))

这也是最安全的方法,因为如果无法在VERSION文件中找到上述正则表达式,则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_MINORFOO_VERSION_REVISIONconfigure.ac中始终可用。

  

注意NA_宏名称中的NA_DEFINE_SUBSTRINGS_AS()前缀代表“ N ot A utotools”

如果在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)
  

注意:.json文件可能包含逗号和方括号(它们对GNU m4-ish 不太友好),因此需要将其删除/已替换,然后再处理JSON字符串。在上面的代码中,宏m4_unquote()删除了package.json中可能存在的所有第一级方括号-如果后者包含嵌套数组,则必须m4_unquote()对其自身进行最大次数的调用。级别的数组嵌套-宏m4_join()将所有逗号替换为'|'

NA_DEFINE_SUBSTRINGS_AS()宏也接受空参数,因此,如果您愿意,可以将[JSON_ENTRY]参数替换为[],因为您可能永远不会使用JSON源字符串{{ 1}}。

如果您只需要从"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()