Because third-party macros defined in *.m4 files are naturally shared between multiple projects, people like to version them. This makes it easier to tell which of two M4 files is newer. Since at least 1996, the convention is to use a ‘#serial’ line for this.
Such a serial number should be a single line of the form
# serial version
where version is a version number containing only digits and dots. Usually people use a single integer, and they increment it each time they change the macro (hence the name of “serial”). Such a line should appear in the M4 file before any macro definition.
The ‘#’ must be the first character on the line, and it is OK to have extra words after the version, as in
#serial version garbage
Normally these serial numbers are completely ignored by
aclocal
and autoconf
, like any genuine comment.
However when using aclocal
’s --install feature, these
serial numbers will modify the way aclocal
selects the
macros to install in the package: if two files with the same basename
exist in your search path, and if at least one of them uses a
‘#serial’ line, aclocal
will ignore the file that has
the older ‘#serial’ line (or the file that has none).
A serial number applies to a whole M4 file, not to any macro it contains. A file can contain multiple macros, but only one serial number.
Here is a use case that illustrates the use of --install and
its interaction with serial numbers. Let’s assume we maintain a
package called MyPackage, the configure.ac of which requires a
third-party macro AX_THIRD_PARTY
defined in
/usr/share/aclocal/thirdparty.m4 as follows:
# serial 1 AC_DEFUN([AX_THIRD_PARTY], [...])
MyPackage uses an m4/ directory to store local macros as explained in Handling Local Macros, and has
AC_CONFIG_MACRO_DIRS([m4])
in its configure.ac.
Initially the m4/ directory is empty. The first time we run
aclocal --install
, it will notice that
AX_THIRD_PARTY
AX_THIRD_PARTY
AX_THIRD_PARTY
with serial number 1.
Because /usr/share/aclocal/thirdparty.m4 is a system-wide macro
and aclocal
was given the --install option, it will
copy this file in m4/thirdparty.m4, and output an
aclocal.m4 that contains ‘m4_include([m4/thirdparty.m4])’.
The next time ‘aclocal --install’ is run, something different
happens. aclocal
notices that
AX_THIRD_PARTY
AX_THIRD_PARTY
with serial number 1.
AX_THIRD_PARTY
with serial number 1.
Because both files have the same serial number, aclocal
uses
the first it found in its search path order (see Macro Search Path). aclocal
therefore ignores
/usr/share/aclocal/thirdparty.m4 and outputs an
aclocal.m4 that contains ‘m4_include([m4/thirdparty.m4])’.
Local directories specified with -I are always searched before system-wide directories, so a local file will always be preferred to the system-wide file in case of equal serial numbers.
Now suppose the system-wide third-party macro is changed. This can happen if the package installing this macro is updated. Let’s suppose the new macro has serial number 2. The next time ‘aclocal --install’ is run the situation is the following:
AX_THIRD_PARTY
AX_THIRD_PARTY
with serial number 1.
AX_THIRD_PARTY
with serial 2.
When aclocal
sees a greater serial number, it immediately
forgets anything it knows from files that have the same basename and a
smaller serial number. So after it has found
/usr/share/aclocal/thirdparty.m4 with serial 2,
aclocal
will proceed as if it had never seen
m4/thirdparty.m4. This brings us back to a situation similar
to that at the beginning of our example, where no local file defined
the macro. aclocal
will install the new version of the
macro in m4/thirdparty.m4, in this case overriding the old
version. MyPackage just had its macro updated as a side effect of
running aclocal
.
If you are leery of letting aclocal
update your local
macro, you can run ‘aclocal --diff’ to review the changes
‘aclocal --install’ would perform on these macros.
Finally, note that the --force option of aclocal
has no effect on the files installed by --install. For
instance, if you have modified your local macros, do not expect
--install --force to replace the local macros by their
system-wide versions. If you want to do so, simply erase the local
macros you want to revert, and run ‘aclocal --install’.