Unresolved directive in attributes.adoc - include::acl_attributes.adoc[] Unresolved directive in attributes.adoc - include::aml_attributes.adoc[] Unresolved directive in attributes.adoc - include::attributes/sh.adoc[]

1. Shell library

1.1. The gatbps_csf variable

Shell
gatbps_csf=…​
$gatbps_readonly gatbps_csf

The gatbps_csf variable holds a sed script that can be used to help perform command substitutions that only remove a single trailing newline character instead of as many trailing newline characters as possible.

The following code sets dir to an absolute path to the current working directory with correct behavior even if the path ends with one or more newline characters:

dir=`pwd && echo x` || exit $?
dir=`eval LC_ALL=C "${SED:-sed}" '"${gatbps_csf?}"' <<EOF
${dir?}
EOF
` || exit $?
eval dir="${dir?}"

1.2. The gatbps_quote function

Shell
gatbps_quote [<arg>...]

The gatbps_quote function quotes the input as a portably quoted shell word.

The algorithm is as follows:

  1. Replace every ' character with '\''.

  2. Prepend a ' character to the result.

  3. Append a ' character to the result.

The input is the space-separated concatenation of the arguments. If no arguments are given, the input is read from standard input in CSF form instead. The output is always written to standard output in CSF form.

1.3. The gatbps_readonly variable

The gatbps_readonly variable can be used to make a variable readonly and can be overridden to become a noop instead.

2. Autoconf library

Macro parameters are generally notated with one or more pairs of <> brackets, where \(n\) pairs of brackets means the parameter will be expanded exactly \(n - 1\) times during rescanning after the macro call is expanded. In other words, the argument written in the call will be expanded exactly \(n\) times: once during argument collection, and \(n - 1\) times during rescanning.

Example 1.
configure.ac
AC_INIT([[example]], 1)
AM_INIT_AUTOMAKE([foreign])

m4_include([gatbps.ac])

m4_pushdef([f1], [[$1]])          dnl would be notated as f1(<x>)
m4_pushdef([f2], [$1])            dnl would be notated as f2(<<x>>)
m4_pushdef([f3], [m4_expand($1)]) dnl would be notated as f3(<<<x>>>)

m4_pushdef([x], [y])

[printf '%s\n'] 'f1(x)';       dnl prints y
[printf '%s\n'] 'f2(x)';       dnl prints y
[printf '%s\n'] 'f3(x)';       dnl prints y

[printf '%s\n'] 'f1([x])';     dnl prints x
[printf '%s\n'] 'f2([x])';     dnl prints y
[printf '%s\n'] 'f3([x])';     dnl prints y

[printf '%s\n'] 'f1([[x]])';   dnl prints [x]
[printf '%s\n'] 'f2([[x]])';   dnl prints x
[printf '%s\n'] 'f3([[x]])';   dnl prints y

[printf '%s\n'] 'f1([[[x]]])'; dnl prints [[x]]
[printf '%s\n'] 'f2([[[x]]])'; dnl prints [x]
[printf '%s\n'] 'f3([[[x]]])'; dnl prints x

m4_popdef([x])

m4_popdef([f3])
m4_popdef([f2])
m4_popdef([f1])

m4_syscmd([>Makefile.am])
AC_CONFIG_FILES([Makefile])
AC_OUTPUT
Output
$ autoreconf -i -f && ./configure
...
y
y
y
x
y
y
[x]
x
y
[[x]]
[x]
x
...

Optional macro parameters are notated with a trailing ? character and are always the trailing parameters of the macro. If an optional parameter is given, all optional parameters to its left must also be given.

2.1. The GATBPS_ARG_WITH_ENUM macro

Autoconf
m4_include([gatbps.ac])

GATBPS_ARG_WITH_ENUM(
  <message>,
  <name>,
  <option>,
  <default>,
  <values>)

2.2. The GATBPS_ARG_WYNA macro

Autoconf
m4_include([gatbps.ac])

GATBPS_ARG_WYNA(
  <option>,
  <yes_description>,
  <no_description>,
  <auto_description>,
  <prerequisites>?)

2.3. The GATBPS_BEFORE macro

Autoconf
m4_include([gatbps.ac])

GATBPS_BEFORE(
  <current_macro>,
  <subsequent_macro>)

2.4. The GATBPS_BUG macro

Autoconf
m4_include([gatbps.ac])

GATBPS_BUG(<message>)

2.5. The GATBPS_DEDUCE_WYNAS macro

Autoconf
m4_include([gatbps.ac])

GATBPS_DEDUCE_WYNAS()

2.6. The GATBPS_DEFINE_UNIQUE macro

Autoconf
m4_include([gatbps.ac])

GATBPS_DEFINE_UNIQUE(
  <name>,
  <body>?)

The GATBPS_DEFINE_UNIQUE macro defines <name> as a macro that expands to <body>. If <name> is already defined as a macro, an error occurs.

2.7. The GATBPS_FINISH_WYNA macro

Autoconf
m4_include([gatbps.ac])

GATBPS_FINISH_WYNA(
  <message>,
  <name>,
  <option>?)

If <option> is omitted, it is taken to be <message>. In this case, <message> itself must be the option name.

2.8. The GATBPS_PUSH_VAR macro

Autoconf
m4_include([gatbps.ac])

{acl_GATBPS_PUSH_VAR}(<name>, <value>)

The {acl_GATBPS_PUSH_VAR} macro saves the current value of the shell variable <name> onto a stack and updates <name> to <value>. The most recent saved value of <name> can later be restored or discarded by calling the {acl_GATBPS_POP_VAR} or {acl_GATBPS_KEEP_VAR} macros.

If <name> was unset, its unset-ness is saved onto the stack, not an empty value. In this case, restoring the saved value will unset <name>, not set it to an empty value.

Each <name> gets its own stack.

2.9. The GATBPS_POP_VAR macro

Autoconf
m4_include([gatbps.ac])

{acl_GATBPS_POP_VAR}(<name>)

2.10. The GATBPS_KEEP_VAR macro

Autoconf
m4_include([gatbps.ac])

{acl_GATBPS_KEEP_VAR}(<name>)

2.11. The GATBPS_CHECK macro

Autoconf
m4_include([gatbps.ac])

GATBPS_CHECK(
  <message>,
  <name>,
  [code],
  <precondition>?,
  <skip_value=no>?)

The GATBPS_CHECK macro extends the AC_CACHE_CHECK macro as follows:

  • The cache variable is named gatbps_cv_<name>.

  • <name> is set to $gatbps_cv_<name> after AC_CACHE_CHECK completes.

  • <name>_was_cached is set to 1 or 0 to indicate whether <name> was cached.

  • <name>_was_cached_sh is set to : or false corresponding to <name>_was_cached.

  • AC_SUBST is called for <name>.

  • The end of <name> may include zero or more specifiers, each of which consists of a : character followed by an identifier. These specifiers are removed from <name> when forming variable names.

  • If :notmake is specified at the end of <name>, then AM_SUBST_NOTMAKE is called for <name>.

  • If :notbool is specified at the end of <name>, then boolean detection is disabled. Otherwise, boolean detection is enabled, in which case all of the following occur:

    • If gatbps_cv_<name> is set to yes, no, yes (guess), or no (guess), then all of the following occur:

      • <name> is adjusted to 1 if it is yes or yes (guess), or to 0 if it is no or no (guess).

      • <name>_sh is set to : or false to indicate whether $<name> is 1 or 0.

      • <name>_is_guess is set to 1 or 0 to indicate whether $<name> originally ended in (guess).

      • <name>_is_guess_sh is set to : or false to indicate whether $<name>_is_guess is 1 or 0.

      • AC_DEFINE is called for <name>.

    • If gatbps_cv_<name> is not set to yes, no, yes (guess), or no (guess), then <name>_sh is set to false.

    • AM_CONDITIONAL is called for <name> using $<name>_sh.

  • If :bool is specified at the end of <name>, then the :notbool specifier is ignored and boolean behavior is enforced: an error will occur if gatbps_cv_<name> is not set to yes or no.

  • If <precondition> is given, it will be interpreted as a boolean expression. If the result of the expression is false, gatbps_cv_<name> will be set to <skip_value> instead of executing [code] to set it. The expression may use variable names, literal 1's, 0’s, yes’s, and no’s, the `!, &&, and || operators, parentheses for precedence, and space, tab, and newline characters for separation. Each variable should be set to 1, 0, yes, or no.

2.12. The GATBPS_CHECK_COMPILE macro

Autoconf
m4_include([gatbps.ac])

GATBPS_CHECK_COMPILE(
  <message>,
  <name>,
  <prologue>,
  <body>,
  <precondition>?)

2.13. The GATBPS_CHECK_EXPR macro

Autoconf
m4_include([gatbps.ac])

GATBPS_CHECK_EXPR(<message>, <name>, <expression>)
Autoconf
m4_include([gatbps.ac])

GATBPS_CHECK_LINK(
  <message>,
  <name>,
  <prologue>,
  <body>,
  <precondition>?)

2.15. The GATBPS_CHECK_RUN macro

Autoconf
m4_include([gatbps.ac])

GATBPS_CHECK_RUN(
  <message>,
  <name>,
  <prologue>,
  <body>,
  <guess>?,
  <precondition>?)
  • <name>_is_guess is set to 1 or 0 to indicate whether <name> was set from <guess>.

  • <name>_is_guess_sh is set to : or false corresponding to <name>_is_guess.

2.16. The GATBPS_BARF macro

Autoconf
m4_include([gatbps.ac])

GATBPS_BARF(<message>)

The GATBPS_BARF macro generates portable shell code that, when run at configure time, writes <message> to standard error and terminates the configure script with exit status 1.

Regarding shell quoting, <message> will be adjusted by converting each " to \", converting each ` to \`, and enclosing the entire message in " characters. You should ensure that <message> does not contain any occurrences of \" or \` that are not immediately preceded by another \.

2.17. The GATBPS_LANG_PROGRAM macro

Autoconf
m4_include([gatbps.ac])

GATBPS_LANG_PROGRAM([[prologue], [[body]]])

2.18. The GATBPS_PROG macro

Autoconf
m4_include([gatbps.ac])

GATBPS_PROG(
  <name>,
  <primary>,
  <secondaries>?,
  <extra_code>?)

2.19. The GATBPS_PROTECT macro

Autoconf
m4_include([gatbps.ac])

GATBPS_PROTECT([<arg>…​])

The GATBPS_PROTECT macro protects every identifier x appearing anywhere in the arguments from expansion by calling m4_pushdef([x], ). The identifiers can later be unprotected by calling GATBPS_UNPROTECT with the same arguments.

2.20. The GATBPS_SOFT_VAR macro

Autoconf
m4_include([gatbps.ac])

GATBPS_SOFT_VAR(
  <name>,
  <default_value>?)

The GATBPS_SOFT_VAR macro expands to [<name>] if DEFINE_<name> is defined as a macro, or to [<default_value>] if not. If <default_value> is omitted, it is taken to be [1].

2.21. The GATBPS_SQUISH macro

Autoconf
m4_include([gatbps.ac])

GATBPS_SQUISH(
  <text>)

The GATBPS_SQUISH macro expands to [<text>] with the following adjustments performed, in order:

  1. Each maximal sequence of characters in <text> that contains only newline, tab, or space characters is replaced with a single space character.

  2. If the result of the previous step begins with a space character, that character is deleted.

  3. If the result of the previous step ends with a space character, that character is deleted.

2.22. The GATBPS_UNPROTECT macro

Autoconf
m4_include([gatbps.ac])

GATBPS_UNPROTECT([<arg>…​])

The GATBPS_UNPROTECT macro unprotects every identifier x appearing anywhere in the arguments from expansion by calling m4_popdef([x]). Each call should have a corresponding previous call to GATBPS_PROTECT with the same arguments in the same order. The identifiers are unprotected in the reverse order that they were protected.

2.23. The GATBPS_REQUIRE macro

Autoconf
m4_include([gatbps.ac])

GATBPS_REQUIRE(<name>, [<options>])

The GATBPS_REQUIRE macro is equivalent to the AC_REQUIRE macro except it can also be called from the top level.

If <options> is the literal word soft, then the call will have no effect if <name> is undefined instead of causing an error.

Unresolved directive in autoconf_library.adoc - include::acl_attributes.adoc[]

3. Automake library

3.1. The GATBPS_at macro

Automake
include $(srcdir)/build-aux/gatbps.am

GATBPS_at = @

GATBPS uses $(GATBPS_at) instead of plain @ for all recipe lines whose echoing should normally be unconditionally suppressed. This way, you can run make V=1 GATBPS_at= to produce maximally verbose output for debugging purposes.

3.2. Recipe tracing

The GATBPS_RECIPE_MARKER_TOP and GATBPS_RECIPE_MARKER_BOT variables can be used to mark the start and finish of a recipe, which can be useful when analyzing the output of make. Each variable expands to a no-op command that includes $@, resulting in the command itself acting as a marker message when it is written to standard output by make.

Example 1.
Automake code
foo:
	$(AM_V_at)$(GATBPS_RECIPE_MARKER_TOP)
	echo bar >$@
	$(AM_V_at)$(GATBPS_RECIPE_MARKER_BOT)
Output of make V=1 foo
: recipe starting: foo
echo bar >foo
: recipe finished: foo
Output of make V=0 foo
echo bar >foo

3.3. Temporary files

Every recipe generated by GATBPS uses $@$(TMPEXT).tmp* as the naming pattern for any temporary files and directories that may be created during the process of building $@. GATBPS also defines TSUF = $(TMPEXT).tmp to simplify the use of the naming pattern. For example, a recipe that needs to create two temporary files could name them $@$(TSUF)1 and $@$(TSUF)2.

GATBPS itself does not define TMPEXT, but the user may do so to add extra suffixes for other purposes. For example, the user could define TMPEXT = .gitignorable and add .gitignorable. to their .gitignore file to ensure that all temporary files and directories are ignored by Git. Note that TSUF will be .tmp if the user leaves TMPEXT undefined, which is a reasonable default.

foo:
	echo bar >$@$(TSUF)1
	echo baz >$@$(TSUF)2
	cat $@$(TSUF)1 $@$(TSUF)2 >$@$(TSUF)3
	mv -f $@$(TSUF)3 $@

foo/clean: FORCE
	-rm -f -r ./$(@D) ./$(@D)$(TSUF)*

mostlyclean-local: foo/clean

Index