8.使用M4编程
Autoconf在两个层面上编写:1、M4sugar,提供比纯M4编程更加方便的宏;2、M4sh,提供专用于生成shell脚本的宏。
8.1 M4 的引用¶
Autoconf的使用者可以跳过这一部分,宏编写者必须阅读。M4 Qutation。
每次宏展开时,都会去除一层引用。
8.1.3 引用和参数¶
在M4的一个宏定义中,遇到了$(‘0’...‘9’, ‘#’, ‘@’, or ‘*’)
,会执行M4的参数展开。不管有多少层嵌套引用,甚至是注释都会执行。
define([none], [$1]) #会导致扩展
⇒
define([one], [[$1]]) #当作文本处理
⇒
define([two], [[[$1]]]) #当作[文本]处理
⇒
define([comment], [# $1]) #注释
⇒
define([active], [ACTIVE])
⇒
none([active])
⇒ACTIVE
one([active])
⇒active
two([active])
⇒[active]
comment([active])
⇒# active
想要打破这一规则需要这样使用:
define([single], [a single-quoted $[]1 definition])
⇒
define([double], [[a double-quoted $][1 definition]])
⇒
single
⇒a single-quoted $1 definition
double
⇒a double-quoted $1 definition
warning:M4扩展一个宏之后,结果文本会被立即进行宏扩展和引用删除。例:
car([int tab[10];])
⇒int tab10;
car([[int tab[10];]])
⇒int tab[10];
第一个扩展的结果是int tab[10];
,但是经过引用删除之后,去除了引用符号;
第二个扩展的结果是[int tab[10];]
,经过引用删除之后,还会保留内部的引用符号。
8.1.6 特殊字符替换¶
编写Autoconf宏的时候可能需要特殊字符,但是使用标准的引用规则会很困难。
还有,少量的M4sugar内部使用了特殊字符,如果宏参包含了-=<{(
or )}>=-
,它们可能不会正常工作。
替换规则:
- @<:@ - [
- @:>@ - ]
- @S|@ - $
- @%:@ - #
- @{:@ - (
- @:}@ - )
- @&t@ - Expands to nothing
AC_ARG_ENABLE(
[ovirt-vmconsole],
[AS_HELP_STRING(
[--disable-ovirt-vmconsole],
[disable ovirt-vmconsole integration @<:@default=no@:>@]
)],
,
[enable_ovirt_vmconsole="yes"]
)
8.2 使用 autom4te¶
除了Autoconf本身,Autoconf套件包括M4sugar, M4sh, and Autotest,很大程度上依赖M4。
8.3 使用 M4 的语法¶
保留了m4_
开头的宏命名空间。
8.3.1 重定义M4宏¶
除了几个例外,所有的M4本地宏都被重命名为m4_
开头。
下面这些宏没有改变:
m4_builtin
m4_changecom
m4_changequote
m4_debugfile
m4_debugmode
m4_decr
m4_define
m4_divnum
m4_errprint
m4_esyscmd
m4_eval
m4_format
m4_ifdef
m4_incr
m4_index
m4_indir
m4_len
m4_pushdef
m4_shift
m4_substr
m4_syscmd
m4_sysval
m4_traceoff
m4_traceon
m4_translit
下面的有轻微的不同:
m4_include (file)¶
m4_sinclude (file)¶
跟m4内置的宏类似,但是会对多次引入文件发出警告。
m4_include([m4/ax_python_module.m4])