Use wildcards to automatically match source files when using GNU Automake
This Makefile module provides the following features:
- Automatically match names of files to populate lists of sources in Automake
- Automaitcally update Automake output when matched files are added, removed or renamed
The GNU Automake documentation provides some rationalisations explaining why wildcards are not a good idea. In the end, apart from differences in personal taste, practical considerations boil down to one issue: portability.
The constructs used in this Makefile module to provide this functionality are specific to GNU Make. Their Use constrains the module to environments that support GNU Make. This does not seem to be such an impediment given that environments that host GNU Automake are also more than likely to also host GNU Make.
The other minor point raised in the Automake documentation is that "developers would need to remember to run automake each time they add, delete, or rename files". Automake itself already implements capabilities to address this very issue. Automake arranges for Makefile to depend on Makefile.am so that when Makefile.am is changed, the dependent Makefile is automatically regenerated.
- GNU Make
- GNU Automake
- Install
wildcard.mk
in the root of source tree. - Add
AM_INIT_AUTOMAKE([-Wno-portability])
toconfigure.ac
if applicable, to silence warnings about portability. - Add
$(eval include $(top_srcdir)/wildcard.mk)
to each applicable Makefile.am. - For each Automake list of sources decide three things:
- The name of the Automake variable to hold the names (eg
SOURCES
,target_SOURCES
) - The shell glob that will match the file names (eg
[a-z]*.[ch]
) - The prefix to be used to name the ancillary files generated by this module (eg
sources
,target
).
- The name of the Automake variable to hold the names (eg
- For each of the Automake list of sources, insert a pair of lines:
- An Automake include directive to read the generate Automake list of source files
- A Makefile directive to generate and update a Makefile fragment that is used to generate and update the Automake list of source files
- For each of the Automake list of sources, initialise the Automake list of source files to be empty.
The following is an example that shows a Makefile.am fragment demonstrating
the above steps. First the Makefile.am is printed using cat
. The line
specifying $(eval include $(top_srcdir)/wildcard.mk)
is presented first.
A pair of lines is present to populate the _test_SOURCES
Automake source list. The line containing include _test_c.am
is the
first line of the pair and is the Automake include directive to read
the generated Automake list of source files. The line containing
$(call WILDCARD,...)
is the second line of the pair, and is used to
generate and update a corresponding Makefile fragment.
Finally the example shows how the Automake list of source files can be
initialised, or re-initialised should it become corrupt. After
initialisation, the next invocation of make
will write the appropriate
content into the file.
% cat Makefile.am
$(eval include $(top_srcdir)/wildcard.mk)
TESTS = $(check_PROGRAMS)
check_PROGRAMS = _test
include _test_c.am
$(call WILDCARD, _test_c, _test_SOURCES, [a-z]*.c)
% cat /dev/null > _test_c.am
A unit test is provided that is used to verify the operation, and is also useful to illustrate usage. The following shows how to run the unit test:
% ls
Makefile README.md test/ wildcard.mk
% make
cd test/ && ./autogen.sh
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for a thread-safe mkdir -p... /bin/mkdir -p
checking for gawk... gawk
...
cd test/ && make
make all-recursive
Making all in src
make[3]: Nothing to be done for `all'.
cd test/ && make check
Making check in src
make _test
make[3]: `_test' is up to date.
make check-TESTS
PASS: _test
=============
1 test passed
=============