1\documentclass[a4paper]{article}
2%
3% Comment the following line out if you don't have the geometry
4% package on your system.
5%
6\usepackage[includemp=no]{geometry}
7%
8%
9%
10\begin{document}
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}
14\maketitle
15\tableofcontents
16
17\section{Introduction}
18This short document attempts to explain simply how the gnustep
19makefile package works internally.  When I first wrote this document,
20the mechanism used to be extremely complex, involving many recursive
21make invocations; I have now simplified it so that it involves only a
22single recursive make invocation per target/type/operation.  As a
23result, I hope that the mechanism is now so simple that you can figure
24out how it works without reading this document, by just reading the
25gnustep-make source code.  Anyway, the thing might still not be still
26totally trivial at a first approach, so this document might help you
27to get familiar with the gnustep-make source code in a shorter time
28and with less pain.
29
30\section{From `make' to the internal-all rule}
31Imagine for example that in your \texttt{ GNUmakefile} you include both
32\texttt{tool.make} and \texttt{library.make}, as in the following example:
33\begin{verbatim}
34include $(GNUSTEP_MAKEFILES)/common.make
35
36TOOL_NAME = decrypt
37decrypt_OBJC_FILES = decrypt.m
38
39LIBRARY_NAME = libDvd
40libDvd_OBJC_FILES = decss.m
41
42include $(GNUSTEP_MAKEFILES)/tool.make
43include $(GNUSTEP_MAKEFILES)/library.make
44\end{verbatim} % $ fool emacs's buggy tex mode
45Then you type `make' on the command line.  We want to understand what
46happens.
47
48Make 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
51executed), which is
52\begin{verbatim}
53all:: before-all internal-all after-all
54\end{verbatim}
55This means that make will build by default that target \texttt{ all},
56and that building that target requires building the
57\texttt{before-all}, \texttt{internal-all} and \texttt{after-all}
58targets.  We ignore the \texttt{before-all} and \texttt{after-all}
59targets for now, and only concentrate on the core target, which is
60\texttt{internal-all}.
61
62\section{From the internal-all rule to the \%.variables rule}
63Make needs to build this target \texttt{internal-all}.  In
64\texttt{rules.make} this target appears as
65\begin{verbatim}
66internal-all::
67\end{verbatim}
68because of the double colons (that is, because it is
69\texttt{internal-all::} rather than \texttt{internal-all:}) this
70target can have multiple totally separated rules.  Each rule must be a
71double colon rule, and is processed separately from the other rules
72(even if they refer to the same target).
73
74The real rules for \texttt{internal-all} are included by the specific
75makefiles; in our example, \texttt{tool.make} includes
76\begin{verbatim}
77internal-all:: $(TOOL_NAME:=.all.tool.variables)
78\end{verbatim} %$
79now - in our case - because \texttt{TOOL\_NAME} is \texttt{decrypt}, then
80this rule actually means
81\begin{verbatim}
82internal-all:: decrypt.all.tool.variables
83\end{verbatim}
84This means that to build \texttt{internal-all}, make has to build (at
85least) the \texttt{decrypt.all.tool.variables} target.
86\texttt{library.make} includes the completely analogous rule
87\begin{verbatim}
88internal-all:: $(LIBRARY_NAME:=.all.library.variables)
89\end{verbatim} %$
90which in our case means
91\begin{verbatim}
92internal-all:: libDvd.all.library.variables
93\end{verbatim}
94This rule is completely separated from the other one; to build
95\texttt{internal-all}, make has to build the two different targets:
96\begin{verbatim}
97decrypt.all.tool.variables
98libDvd.all.library.variables
99\end{verbatim}
100
101\section{The \%.variables rule - dependencies}
102The rule for building these targets is in the \texttt{rules.make} file,
103it is the \texttt{\%.variables} rule:
104\begin{verbatim}
105%.variables: %.tools %.subprojects
106@ \
107target=$(basename $(basename $*)); \
108operation=$(subst .,,$(suffix $(basename $*))); \
109type=$(subst -,_,$(subst .,,$(suffix $*))); \
110echo 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 \
114  TARGET=$$target \
115  _SUBPROJECTS="$($(basename $(basename $*))_SUBPROJECTS)" \
116  ...
117\end{verbatim}%$
118This rule matches all targets ending in \texttt{.variables}.  First of
119all, the rule depends on the corresponding \texttt{\%.tools} and
120\texttt{\%.subprojects} rules.  This is because before processing the
121target itself, gnustep-make needs to process the related subprojects
122and (only for frameworks) the framework tools.  We ignore this
123complication of subprojects and framework tools for now; if you look
124at the \texttt{\%.subprojects} and \texttt{\%.tools} rules you see
125that they do nothing if you are not actually using subprojects or
126framework tools in your makefile.
127
128\section{The \%.variables rule - second make invocation}
129The rule body parses the \texttt{\%.variables} string - for example when
130the rule is applied to
131\begin{verbatim}
132decrypt.all.tool.variables
133\end{verbatim}
134then (remember that \texttt{\$*} is the stem of the rule,
135\texttt{decrypt.all.tool} in this case) it extracts
136\begin{verbatim}
137target=decrypt
138operation=all
139type=tool
140\end{verbatim}
141and then it runs a make subprocess, specific to that target, type and
142operation.  In our case, the \texttt{\%.variables} rules is executed
143twice, once to build
144\begin{verbatim}
145decrypt.all.tool.variables
146\end{verbatim}
147and once to build
148\begin{verbatim}
149libDvd.all.tool.variables
150\end{verbatim}
151so the result is to run two separate make processes:
152\begin{verbatim}
153make internal-tool-all INTERNAL_tool_NAME=decrypt TARGET=decrypt \
154  _SUBPROJECTS="$(decrypt_SUBPROJECTS)" \
155  OBJC_FILES="$(decrypt_OBJC_FILES)" \
156  ...
157make internal-library-all INTERNAL_library_NAME=libDvd TARGET=libDvd \
158  _SUBPROJECTS="$(libDvd_SUBPROJECTS)" \
159  OBJC_FILES="$(libDvs_OBJC_FILES)" \
160  ...
161\end{verbatim}
162where \texttt{...} stands for a lot of other variables, including all
163variables 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
166subprocess will get passed different, specific, variables.  If
167gnustep-make wants to modify these variables in some way, it does it
168at this stage, before passing them to the submake process.  For
169example, some library flags are filtered through the
170\texttt{WHICH\_LIB\_SCRIPT}.
171
172What this means is that for each target/type/operation, a separate
173make process is run.  For example, if you have two tools,
174\texttt{decrypt} and \texttt{crypt}, and you want to both compile and install
175them, it will run four make subprocesses:
176\begin{verbatim}
177make internal-tool-all INTERNAL_tool_NAME=decrypt ...
178make internal-tool-all INTERNAL_tool_NAME=crypt ...
179make internal-tool-install INTERNAL_tool_NAME=decrypt ...
180make internal-tool-install INTERNAL_tool_NAME=crypt ...
181\end{verbatim}
182This is the `second make invocation'.  The make package knows that it
183is being invoked for the second time, because of the
184\texttt{INTERNAL\_tool\_NAME} being non-empty.
185
186\section{Second make invocation}
187Because of the \texttt{INTERNAL\_tool\_NAME} variable being a
188non-empty string (while it was empty in the previous top-level
189invocation), \texttt{tool.make} will include the actual rules to build
190the tool; in particular, the \texttt{internal-tool-all} rule, which is
191then executed and builds the tool.  All variables such as
192\texttt{OBJC\_FILES} or the library flags are now available directly
193in the makefiles, they have already been prepared and preprocessed, so
194that the rules in \texttt{tool.make} can just plainly use these
195variables naively to perform their job (compiling, installing, or
196whatever).
197
198\end{document}
199