由于某些原因,我在纯文本文件而不是configure.ac中定义项目版本号。我想创建一个语句来读取版本号并在编译期间存储它。
现在我的configure.ac看起来像这样:
AC_INIT([my program],[999.9.9])
我希望有类似的东西:
AC_INIT([my program],[ $(cat VERSION) ])
这当然不会奏效。这里的诀窍是什么? (我知道我失去了一些便携性 - 我现在不在乎)。谢谢!
答案 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
调用cat
或m4_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
[…]
include
和sinclude
扩展到以下内容的事实: 文件可用于定义对整个文件进行操作的宏。这里 是一个示例,它定义了“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_MAJOR
,FOO_VERSION_MINOR
和FOO_VERSION_REVISION
在configure.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.json
,FOO_VERSION_MAJOR
和FOO_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()