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