When M4 encounters ‘$’ within a macro definition, followed immediately by a character it recognizes (‘0’...‘9’, ‘#’, ‘@’, or ‘*’), it will perform M4 parameter expansion. This happens regardless of how many layers of quotes the parameter expansion is nested within, or even if it occurs in text that will be rescanned as a comment.
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
On the other hand, since autoconf generates shell code, you often want to output shell variable expansion, rather than performing M4 parameter expansion. To do this, you must use M4 quoting to separate the ‘$’ from the next character in the definition of your macro. If the macro definition occurs in single-quoted text, then insert another level of quoting; if the usage is already inside a double-quoted string, then split it into concatenated strings.
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
Posix states that M4 implementations are free to provide implementation extensions when ‘${’ is encountered in a macro definition. Autoconf reserves the longer sequence ‘${{’ for use with planned extensions that will be available in the future GNU M4 2.0, but guarantees that all other instances of ‘${’ will be output literally. Therefore, this idiom can also be used to output shell code parameter references:
define([first], [${1}])first ⇒${1}
Posix also states that ‘$11’ should expand to the first parameter concatenated with a literal ‘1’, although some versions of GNU M4 expand the eleventh parameter instead. For portability, you should only use single-digit M4 parameter expansion.
With this in mind, we can explore the cases where macros invoke macros...