1
\documentclass[a4paper]{article}
3
% Comment the following line out if you don't have the geometry
4
% package on your system.
6
\usepackage[includemp=no]{geometry}
11
\title{GNUstep Makefile Package Internals}
12
\author{Nicola Pero n.pero@mi.flashnet.it}
13
\date{last days of June 2001 - revised end of July 2001}
17
\section{Introduction}
18
This short document attempts to explain simply how the gnustep
19
makefile package works internally. When I first wrote this document,
20
the mechanism used to be extremely complex, involving many recursive
21
make invocations; I have now simplified it so that it involves only a
22
single recursive make invocation per target/type/operation. As a
23
result, I hope that the mechanism is now so simple that you can figure
24
out how it works without reading this document, by just reading the
25
gnustep-make source code. Anyway, the thing might still not be still
26
totally trivial at a first approach, so this document might help you
27
to get familiar with the gnustep-make source code in a shorter time
30
\section{From `make' to the internal-all rule}
31
Imagine for example that in your \texttt{ GNUmakefile} you include both
32
\texttt{tool.make} and \texttt{library.make}, as in the following example:
34
include $(GNUSTEP_MAKEFILES)/common.make
37
decrypt_OBJC_FILES = decrypt.m
40
libDvd_OBJC_FILES = decss.m
42
include $(GNUSTEP_MAKEFILES)/tool.make
43
include $(GNUSTEP_MAKEFILES)/library.make
44
\end{verbatim} % $ fool emacs's buggy tex mode
45
Then you type `make' on the command line. We want to understand what
48
Make will process your \texttt{GNUmakefile}, which includes
49
\texttt{tool.make}, and that will include \texttt{rules.make}. In
50
\texttt{rules.make} make finds the first rule (the one which is
53
all:: before-all internal-all after-all
55
This means that make will build by default that target \texttt{ all},
56
and that building that target requires building the
57
\texttt{before-all}, \texttt{internal-all} and \texttt{after-all}
58
targets. We ignore the \texttt{before-all} and \texttt{after-all}
59
targets for now, and only concentrate on the core target, which is
60
\texttt{internal-all}.
62
\section{From the internal-all rule to the \%.variables rule}
63
Make needs to build this target \texttt{internal-all}. In
64
\texttt{rules.make} this target appears as
68
because of the double colons (that is, because it is
69
\texttt{internal-all::} rather than \texttt{internal-all:}) this
70
target can have multiple totally separated rules. Each rule must be a
71
double colon rule, and is processed separately from the other rules
72
(even if they refer to the same target).
74
The real rules for \texttt{internal-all} are included by the specific
75
makefiles; in our example, \texttt{tool.make} includes
77
internal-all:: $(TOOL_NAME:=.all.tool.variables)
79
now - in our case - because \texttt{TOOL\_NAME} is \texttt{decrypt}, then
80
this rule actually means
82
internal-all:: decrypt.all.tool.variables
84
This means that to build \texttt{internal-all}, make has to build (at
85
least) the \texttt{decrypt.all.tool.variables} target.
86
\texttt{library.make} includes the completely analogous rule
88
internal-all:: $(LIBRARY_NAME:=.all.library.variables)
90
which in our case means
92
internal-all:: libDvd.all.library.variables
94
This rule is completely separated from the other one; to build
95
\texttt{internal-all}, make has to build the two different targets:
97
decrypt.all.tool.variables
98
libDvd.all.library.variables
101
\section{The \%.variables rule - dependencies}
102
The rule for building these targets is in the \texttt{rules.make} file,
103
it is the \texttt{\%.variables} rule:
105
%.variables: %.tools %.subprojects
107
target=$(basename $(basename $*)); \
108
operation=$(subst .,,$(suffix $(basename $*))); \
109
type=$(subst -,_,$(subst .,,$(suffix $*))); \
110
echo Making $$operation for $$type $$target...; \
111
$(MAKE) -f $(MAKEFILE_NAME) --no-print-directory --no-keep-going \
112
internal-$${type}-$$operation \
113
INTERNAL_$${type}_NAME=$$target \
115
_SUBPROJECTS="$($(basename $(basename $*))_SUBPROJECTS)" \
118
This rule matches all targets ending in \texttt{.variables}. First of
119
all, the rule depends on the corresponding \texttt{\%.tools} and
120
\texttt{\%.subprojects} rules. This is because before processing the
121
target itself, gnustep-make needs to process the related subprojects
122
and (only for frameworks) the framework tools. We ignore this
123
complication of subprojects and framework tools for now; if you look
124
at the \texttt{\%.subprojects} and \texttt{\%.tools} rules you see
125
that they do nothing if you are not actually using subprojects or
126
framework tools in your makefile.
128
\section{The \%.variables rule - second make invocation}
129
The rule body parses the \texttt{\%.variables} string - for example when
130
the rule is applied to
132
decrypt.all.tool.variables
134
then (remember that \texttt{\$*} is the stem of the rule,
135
\texttt{decrypt.all.tool} in this case) it extracts
141
and then it runs a make subprocess, specific to that target, type and
142
operation. In our case, the \texttt{\%.variables} rules is executed
145
decrypt.all.tool.variables
149
libDvd.all.tool.variables
151
so the result is to run two separate make processes:
153
make internal-tool-all INTERNAL_tool_NAME=decrypt TARGET=decrypt \
154
_SUBPROJECTS="$(decrypt_SUBPROJECTS)" \
155
OBJC_FILES="$(decrypt_OBJC_FILES)" \
157
make internal-library-all INTERNAL_library_NAME=libDvd TARGET=libDvd \
158
_SUBPROJECTS="$(libDvd_SUBPROJECTS)" \
159
OBJC_FILES="$(libDvs_OBJC_FILES)" \
162
where \texttt{...} stands for a lot of other variables, including all
163
variables needed to perform the final stage: \texttt{OBJC\_FILES},
164
\texttt{C\_FILES}, \texttt{JAVA\_FILES},
165
\texttt{ADDITIONAL\_INCLUDE\_DIRS} etc. Note that each make
166
subprocess will get passed different, specific, variables. If
167
gnustep-make wants to modify these variables in some way, it does it
168
at this stage, before passing them to the submake process. For
169
example, some library flags are filtered through the
170
\texttt{WHICH\_LIB\_SCRIPT}.
172
What this means is that for each target/type/operation, a separate
173
make process is run. For example, if you have two tools,
174
\texttt{decrypt} and \texttt{crypt}, and you want to both compile and install
175
them, it will run four make subprocesses:
177
make internal-tool-all INTERNAL_tool_NAME=decrypt ...
178
make internal-tool-all INTERNAL_tool_NAME=crypt ...
179
make internal-tool-install INTERNAL_tool_NAME=decrypt ...
180
make internal-tool-install INTERNAL_tool_NAME=crypt ...
182
This is the `second make invocation'. The make package knows that it
183
is being invoked for the second time, because of the
184
\texttt{INTERNAL\_tool\_NAME} being non-empty.
186
\section{Second make invocation}
187
Because of the \texttt{INTERNAL\_tool\_NAME} variable being a
188
non-empty string (while it was empty in the previous top-level
189
invocation), \texttt{tool.make} will include the actual rules to build
190
the tool; in particular, the \texttt{internal-tool-all} rule, which is
191
then executed and builds the tool. All variables such as
192
\texttt{OBJC\_FILES} or the library flags are now available directly
193
in the makefiles, they have already been prepared and preprocessed, so
194
that the rules in \texttt{tool.make} can just plainly use these
195
variables naively to perform their job (compiling, installing, or