1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
|
# -*- Mode: markdown -*-
Autothing 3: The smart way to write GNU Makefiles
=================================================
Autothing is a thing that does things automatically.
Ok, more helpfully: Autothing is a pair of .mk Makefile fragments that
you can `include` from your Makefiles to make them easier to write;
specifically, it makes it _easy_ to write non-recursive Makefiles--and
ones that are similar to plain recursive Makefiles, at that!
Synopsis
--------
Write your makefiles of the form:
topsrcdir ?= ...
topoutdir ?= ...
at.Makefile ?= Makefile # Optional
include $(topsrcdir)/build-aux/Makefile.head.mk
$(outdir)/%.o: $(srcdir)/%.c:
$(CC) -c -o $@ $<
$(outdir)/hello: $(outdir)/hello.o
at.subdirs = ...
at.targets = ...
include $(topsrcdir)/build-aux/Makefile.tail.mk
This is similar to, but not quite, the comfortable way that you probably
already write your Makefiles.
Details
-------
There are two fundamental things that Autothing provides:
1. Variable namespacing
2. Tools for dealing with paths
The first is important because globals are bad for composability.
The second is important because GNU Make is too dumb to know that
`foo/bar/../baz` == `foo/baz`.
Then, there's something that maybe doesn't belong, but I didn't have the heart
to cut it out:
3. A module (plugin) system.
The module system is "important" because there are very often common bits that
you want to be included in every Makefile, and this gives some structure to
that.
Requirements:
- A version of GNU Make that supports `undefine`. (TODO: check which version
of GNU Make introduced this feature)
Inputs:
- In each `Makefile`:
- Before `Makefile.head.mk`:
- Variable (mandatory) : `topoutdir`
- Variable (mandatory) : `topsrcdir` (must not be a subdirectory of `$(topoutdir)`)
- Variable (optional) : `at.Makefile` (Default: `Makefile`)
- Between `Makefile.head.mk` and `Makefile.tail.mk`:
- Variable: `at.targets` (Default: empty)
- Variable: `at.subdirs` (Default: empty)
- Files:
- `${topsrcdir}/build-aux/Makefile.{each,once}.{head,tail}/*.mk`
Outputs:
- Global:
- Variable (function): `$(call at.is_subdir, parent, child)`
- Variable (function): `$(call at.is_strict_subdir, parent, child)`
- Variable (function): `$(call at.relbase, parent, children...)`
- Variable (function): `$(call at.relto, parent, children...)`
- Variable (function): `$(call at.path, paths...)`
- Variable (function): `$(call at.out2src, paths...)`
- Variable (function): `$(call at.addprefix, prefix, paths...)`
- Per-directory:
- Variable: `$(outdir)`
- Variable: `$(srcdir)`
TODO: actually explain things.
Motivation/Exposition
---------------------
This section needs rewritten. Or really just written.
Other projects like GNU Automake were created to plaster over differences
between make(1) implementations; however, this isn't all that Automake
provides, it also makes it easy to do complex things that users want, or the
GNU Coding Standards require. That's silly.
Autothing does depend on GNU Make; other make(1) implementations will
not work. However, if you are open to adding GNU Make as a
dependency, then Autothing should obviate the need for GNU Automake,
while also making your Makefiles better.
Peter Miller (1997) "Recursive Make Considered Harmful"
<http://aegis.sourceforge.net/auug97.pdf>
----
Copyright (C) 2016 Luke Shumaker
This documentation file is placed into the public domain. If that is
not possible in your legal system, I grant you permission to use it in
absolutely every way that I can legally grant to you.
|