NAME
antimake - Minimal Automake syntax on plain GNU Make
DESCRIPTION
Antimake makes possible to use GNU Automake conventions to describe builds in ordinary Makefiles for GNU Make.
It’s main abstractions are target lists and target variables. Target list describes target type and where to install. Target variables give source files and additional flags for build.
EXAMPLE
# target list bin_PROGRAMS = prog # target variables for 'prog' prog_SOURCES = prog.c prog.h prog_LDADD = libutil.a # target list noinst_LIBRARIES = libutil.a # target variables for 'libutil.a' libutil_a_SOURCES = util.c util.h # load Antimake include antimake.mk
Terminology
- Primary
-
target type, describes how to build and install particular type of targets.
- Target
-
a file that needs to be built and/or installed.
- Distribute
-
Include file in source .tar.gz. Non-distributed files are skipped when building .tar.gz and are cleaned during make distclean.
- Source
-
Source files are files that appear in ..._SOURCES per-target variable. They are distributed by default. They may or may not result in object files. It’s fine to put both .h and .c files into _SOURCES.
TARGET LISTS
Target lists are variables that contain file names that need to be built and installed. They are specially named so that the name also describes how they are built, how and where they will be installed.
The target list name contains 3 parts, separated with underscore, in following order:
-
Optional flags. Flags are: nodist, dist, nobase, base. (Default: base, nodist)
-
Destination directory name. Destination directory called bin actual location is stored in Make variable $(bindir). Some common values: bin, lib, include. There are more and the list can be extended. Special name noinst means the target file should not be installed.
-
Target type, also called "primary". This will describe how the target needs to be built. Common values: PROGRAMS, LIBRARIES, DATA
For details, what the various values mean, see next sections.
bin_PROGRAMS = prog1 prog2 # flags: base, nodist # dest: $(bindir) # type: PROGRAMS noinst_LIBRARIES = lib1.a lib2.a # flags: base, nodist # dest: noinst # type: LIBRARIES nobase_dist_doc_DATA = docs/README # flags: dist, nobase # dest: $(docdir)/docs # type: DATA
Primaries
- PROGRAMS
-
executable programs, linked together from objects built from source files
- LIBARIES
-
static libraries, linked together from objects built from source files
- LTLIBRARIES
-
dynamic or static libraries, linked together from objects built from source files
- HEADERS
-
header files, no default build method, the target files have dist flag by default.
- MANS
-
man pages, no default build method, installed into manX subdir.
- SCRIPTS
-
scripts, executable file, no default build method
- DATA
-
data, non-executable file, no default build method
Target list flags
- dist
-
The target should be distributed with other sources. Default for HEADERS type, others have nodist by default.
- nodist
-
Target is not distributed and should be cleaned with distclean. Default for all primaries, except HEADERS.
- base
-
On install relative path is ignored, all files end up in destination directory. Always default.
- nobase
-
On install relative path is kept. Eg: if includedir=/usr/include then nobase_include_HEADERS=mylib/common.h is installed to /usr/include/mylib/common.h.
- noinst
-
Target is built as part of build process, but is not installed.
- EXTRA
-
Targets in such list are not built, nor installed. Useful to make sure that sources for dynamically configured targets will end up in source tarball. Unlike other target list ariables, EXTRA_<primary> may contain targets already defined in other target lists, they will be filtered out from this list then.
Target variables
Only big targets take additional variables: PROGRAMS/LIBRARIES/LTLIBRARIES.
- <tgt>_SOURCES
-
All source files, *.c *.h *.cpp *.hpp.
- nodist_<tgt>_SOURCES
-
Source files that should not be distributed.
- EXTRA_<tgt>_SOURCES
-
In case tgt_SOURCES is dynamic, here is non-dynamic list of sources for distribution. Only dynamic sources need to be listed here.
- <tgt>_DEPENDENCIES
-
Add dependencies that need to be build before target build will start.
- <tgt>_CFLAGS, <tgt>_CPPFLAGS, <tgt>_LDFLAGS, <tgt>_LIBTOOLFLAGS
-
Override corresponging AM_xx variable
- <tgt>_LDADD
-
Add dependencies that are used during linking. For PROGRAMS only. They will be added to linker command line.
- <tgt>_LIBADD
-
Add dependencies that are used during linking. For LIBRARIES/LTLIBRARIES only. They will be added to linker command line.
- <tgt>_AR
-
Overrides $(AR) $(ARFLAGS). For LIBRARIES only.
bin_PROGRAMS = prog prog_SOURCE = main.c util.c util.h prog_CFLAGS = $(GTK_CFLAGS) prog_LDADD = $(GTK_LIBS)
Global variables
They can be set before antimake.mk inclusion to change build behaviour.
- EXTRA_DIST
-
Additional files to include in source archive.
- CLEANFILES
-
Additional files to make clean.
- DISTCLEANFILES
-
Additional files to make distclean.
- MAINTAINERCLEANFILES
-
Additional files to make maintainer-clean.
- SUBDIRS
-
Subdirectories of current directory where Make needs to be recursively launched. If subdirectory Makefile is Antimake-base, it should set SUBLOC.
- SUBLOC
-
Current diretory location in overall source tree. This can stay unset in top directory. Needed for subdirectiories entered with SUBDIRS to find its position in source tree.
- DIST_SUBDIRS
-
Subdirs that only make dist, make distclean and make maintainer-clean will enter.
- EMBED_SUBDIRS
-
Subdirectories that are built non-recursively: they need to contain Makefile.am that contains makefile-fragment with Antimake syntax that describes local targets using relative filenames. The fragment is included in main makefile and file and variable names are converted and merged with top-level targets.
- AM_FEATURES
-
List of extensions to load. Extensions are Makefile fragments that are loaded before actual rules are generated, so they can change or add targets.
More details on EMBED_SUBDIRS
It acts like include $(dir)/Makefile.am for each directory, except it converts file and variable names. Example:
Makefile: EMBED_SUBDIRS = src src/Makefile.am: bin_PROGRAMS = hello hello_SOURCES = main.c hello_CPPFLAGS = -I./include
Conversion results as if top-level Makefile had contained following rows:
bin_PROGRAMS += src/hello src_hello_SOURCES = src/main.c src_hello_CPPFLAGS = -I./src/include
Variables, where file names are converted:
-
SUBDIRS, DIST_SUBDIRS, EMBED_SUBDIRS
-
DISTFILES, CLEANFILES, DISTCLEANFILES, MAINTAINERCLEANFILES
-
target lists
-
<tgt>_SOURCES, <tgt>_LDADD, <tgt>_LIBADD
Variables, where -L and -I flags are converted:
-
<tgt>_CFLAGS
-
<tgt>_CPPFLAGS
-
<tgt>_LDFLAGS
Makefile should be written in a way that those conversions would be enough.
Global variables for current location
-
srcdir, builddir - relative path to source dir and build dir.
-
top_srcdir, top_builddir - relative path to top-level source and build dir.
-
abs_srcdir, abs_builddir - absolute path to source and build dir
-
abs_top_srcdir, abs_top_builddir - absolute path to top-level source and build dir
-
nosub_top_srcdir, nosub_top_builddir - relative path from top of builddir to srcdir and builddir.
Global variables that target can override
-
AM_CPPFLAGS
-
AM_CFLAGS
-
AM_LDFLAGS
-
AM_LIBTOOLFLAGS
-
AM_DEFS
-
AM_MAKEFLAGS
Global variables from autoconf
These variables come usually from autoconf, but also have reasonable defaults:
CC, DEFS, CPPFLAGS, CFLAGS, LDFLAGS, LIBS, LIBTOOL, LIBTOOLFLAGS, AR, ARFLAGS, RANLIB, CXX, CXXFLAGS, INSTALL, MKDIR_P, LN_S
Global variables for extending Antimake
- AM_DIST_DEFAULT
-
Default format(s) for make dist target. One or more of: gzip, bzip2, xz, zip. Default: gzip.
- AM_DESTINATIONS
-
Additional directory names to consider as valid destinations. Expects corresponding dir-variable to be set.
- AM_SMALL_PRIMARIES
-
Additional single-file primaries. (Builtin: HEADERS, SCRIPTS, DATA, MANS)
- AM_BIG_PRIMARIES
-
Additional primaries built from objects. (Builtin: PROGRAMS, LIBRARIES, LTLIBRARIES)
- AM_LANGUAGES
-
Additional language names. Antimake expects variables AM_LANG_$(name)_SRCEXTS, AM_LANG_$(name)_COMPILE and AM_LANG_$(name)_LINK to be set.
Variables for command-line usage
- DESTDIR
-
Relocate installation root.
- AM_TRACE
-
Turns on function-call debug info. Can be set from command-line.
Hacking variables
- GNUMAKE380, GNUMAKE381, GNUMAKE382
-
If we have at least that version of GNU Make. GNUMAKE380 is always set, others may not be. If Makefile uses features from newer GNU Make it would be good idea to use those flags and error out with clear error message, instead having mysterious failures.
Libtool flags
Useful Libtool flags that can be put int tgt_LDFLAGS for a LTLIBRARY:
-
-export-dynamic
-
-export-symbols symfile
-
-export-symbols-regex regex
-
-module
See libtool "Versioning" chapter about those:
-
-avoid-version
-
-version-info current[:revision[:age]]
-
-version-number major[:minor[:revision]]
-
-release major[:minor[:revision]]
Top-level pseudo-targets
all
The default target when no other target is given on command-line. Builds all target files.
Simple targets
These are simple - either the file already exists, or the user needs to give build command.
Object-based targets
The targets in primaries PROGRAMS, LIBRARIES and LTLIBRARIES consist of multiple source files that need to be compiled into objects. Then the objects need to be linked into final target. The process is roughly following:
-
Dependencies are built (_LDADD, _LIBADD, _DEPENDENCIES).
-
Source list is filtered for extensions that can be compiled into object files, object file list is created based on them. The rest of files are used and dependencies for target, but otherwise ignored.
-
Object files are built.
-
Linker is picked based on source files - as there can be files in multiple languages, the most advanced language wins (the one that appears later in AM_LANGUAGES)
-
Final executable is linked.
install
Install all targets to their destination directories, which is mentioned in their target list variable name. Eg. bin_PROGRAMS will be installed to $(bindir). If destination is named noinst, it will not be installed.
If the flag nobase is given, the relative filename is kept, otherwise basename is taken and it will appear directly under destination directory.
include_HEADERS = func1.h lib/func2.h # Files will end up in: # $(includedir)/func1.h # $(includedir)/func2.h nobase_include_HEADERS = func1.h lib/func2.h # Files will end up in: # $(includedir)/func1.h # $(includedir)/lib/func2.h
clean
-
Remove files in $(CLEANFILES)
-
Remove built objects.
-
Remove target files, unless they are marked as dist. (Note: HEADERS primary is dist by default, all other are nodist)
distclean
-
Remove files in $(DISTCLEANFILES)
-
Remove sources tagged with nodist. All sources as dist by default.
maintainer-clean
-
Remove files in $(MAINTAINERCLEANFILES)
help
Describe top-level targets.
am-test
Regression test for low-level Antimake functions.
am-debug
Show Antimake internal state.
FEATURES
Done:
-
Big primaries: PROGRAMS, LIBRARIES, LTLIBRARIES
-
Small primaries: DATA, SCRIPTS, MANS, HEADERS
-
Flags: base nobase dist nodist noinst EXTRA
-
Target vars: SOURCES, CPPFLAGS, CFLAGS, LDFLAGS, LDADD/LIBADD
-
Separate build dir
-
Per-target objects
-
Languages: C, CXX
-
SUBDIRS, DIST_SUBDIRS
-
EMBED_SUBDIRS
Todo:
-
Improve docs
-
Standardize and document how to extend
-
Deps with non-gcc?
-
Long if-s to support O= seems to break GNU Make 3.80. Drop O= or drop 3.80?
Probably out of scope:
-
make uninstall
-
make distcheck
-
make dist from separate build dir
-
install-(exec|data)-hook - based on dir not primary
-
Default file list for EXTRA_DIST. (Problem: distclean / maintainer-clean)
Definitely out of scope:
-
automake conditionals
-
automake extras (autoconf macros, ltdl)
-
automake nanny mode (gnu/gnits)
SEE ALSO
GNU Make Reference: http://www.gnu.org/software/make/manual/make.html#Quick-Reference
Recursive Make Considered Harmful: http://miller.emu.id.au/pmiller/books/rmch/
Paul’s Rules of Makefiles: http://make.mad-scientist.us/rules.html
Small BSD-ish build system: https://webkeks.org/hg/buildsys/
GNU Make Standard Library: http://sourceforge.net/projects/gmsl/