Tidying up techical notes
[barrelfish] / doc / 003-hake / Hake.tex
1 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2 % Copyright (c) 2011, ETH Zurich.
3 % All rights reserved.
4 %
5 % This file is distributed under the terms in the attached LICENSE file.
6 % If you do not find this file, copies can be found by writing to:
7 % ETH Zurich D-INFK, Universitaetstr. 6, CH-8092 Zurich. Attn: Systems Group.
8 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9
10 \documentclass[a4paper,twoside]{report} % for a report (default)
11
12 \usepackage{bftn} % You need this
13
14 \title{Hake}   % title of report
15 \author{Timothy Roscoe} % author
16 \tnnumber{003}  % give the number of the tech report
17 \tnkey{Hake: the Barrelfish build system} % Short title, will appear in footer
18
19 % \date{Month Year} % Not needed - will be taken from version history
20
21 \begin{document}
22 \maketitle
23
24 %
25 % Include version history first
26 %
27 \begin{versionhistory}
28 \vhEntry{1.0}{3.06.2010}{TR}{Initial version}
29 \vhEntry{1.1}{11.04.2010}{TR}{Support for out-of-tree builds}
30 \end{versionhistory}
31
32 % \intro{Abstract}              % Insert abstract here
33 % \intro{Acknowledgements}      % Uncomment (if needed) for acknowledgements
34 \tableofcontents                % Uncomment (if needed) for final draft
35 % \listoffigures                % Uncomment (if needed) for final draft
36 % \listoftables                 % Uncomment (if needed) for final draft
37
38 \chapter{Introduction}
39
40 Hake is how we build Barrelfish. 
41
42 Hake isn't designed to operate outside Barrelfish, so this document
43 will assume you're trying to build Barrelfish. 
44
45 \section{Quick start}
46
47 Suppose you have a fresh Barrelfish source tree in:
48
49 \texttt{/home/barrelfish/src}
50
51 To build a tree, create a directory for it, \texttt{cd} to that
52 directory, and run the Hake bootstrap script, and then Make:
53
54 \begin{verbatim}
55 $ cd /home/barrelfish/src
56 $ mkdir ../build
57 $ cd ../build
58 $ ../src/hake/hake.sh -s ../src
59 ...
60 $ make -j 32
61 ...
62 \end{verbatim}
63
64 Edit the file \texttt{symbolic\_targets.mk} in your build directory to
65 add extra make targets. 
66
67 Edit the file \texttt{hake/Config.hs} in your build directory and
68 rebuild Hake to reconfigure your build tree. 
69
70 That's about it. 
71
72 \section{How to think about hake}
73
74 Hake is essentially a Haskell embedded domain-specific language,
75 except that it is also evaluated dyanically (using the
76 \texttt{System.Eval.Haskell} package) and written by scattering code
77 around the source tree. 
78
79 Hake consists of the main hake program (which itself contains
80 considerable information on how to build code), together with a set of
81 Hakefiles spread throughout the source tree.  
82
83 Each Hakefile should be thought of as containing a Haskell expression
84 which evaluates to a set of rules for Make.  The expression will be 
85 evaluated in an environment which includes the path to the directory
86 where the Hakefile is located, plus a complete list of all files in
87 the source tree. 
88
89 \section{When hake runs}
90
91 When you run Hake in a Barrelfish source tree, it does the following things:
92 \begin{enumerate}
93 \item Hake builds a list of (almost) every file and directory in the
94   source tree.  The list of files Hake ignores is currently hardcoded
95   into Hake, but basically it skips editor temporary files, version
96   control directories, and products of a previous build process. 
97 \item From this, Hake extracts a list of all Hakefiles in the tree. 
98 \item Hake reads every Hakefile.  Each Hakefile contains a single
99   Haskell expression which itself evaluates to a set of Make rules. 
100 \item Hake constructs a single very large Haskell expression out of
101   all these Hakefiles.  Each Hakefile is evaluated in an environment
102   which includes the pathname of the Hakefile itself (to resolve
103   relative names), and the entire list is evaluated in an environment
104   which includes the list of files in the whole tree (to allow
105   wildcards). 
106 \item This large expression is then evaluated.  The result is a single
107   tree of Hake rule representations (see
108   Chapter~\ref{sec:reprules}). 
109 \item The rule tree is traversed to derive a list of every directory
110   in the build tree.  
111 \item Finally, a single Makefile is generated which contains rules to
112   build every target in the build tree, for every architecture
113   (including the host-based build tools themsevles), and also create
114   every directory in the build tree. 
115 \end{enumerate}
116
117 This single Makefile is large, but is also quite simple: it contains
118 no use of Make variables or generic Make rules, instead it simply
119 includes explicit rules to build every file required for Barrelfish. 
120
121 \section{Motivation and Design Principles}
122
123 \paragraph{Hake should be a full programming language.}  The lesson
124 from countless built systems is that if one starts without a full
125 programming language built in, one ends up implementing a bad one
126 (CMake being only one example).  It's much easier to bite the bullet
127 and admit that we need a complete language, and plenty are available
128 for this. 
129
130 \paragraph{Hake should be a functional language.}  \texttt{make} is a
131 canonical example of a successful declarative language: Hake should
132 not try and replicate what make does well.  
133
134 \paragraph{Hake should generate one Makefile.} One Makefile is easier
135 to debug: all the information is available in the same file.  There is
136 no need to hunt through 5 levels of include files.  The only thing
137 Hake-generated Makefiles include are generated C dependency lists, and
138 a single, top-level file giving symbolic targets.  The Makefile
139 generated by Hake also makes minimal, and highly stylized, use of make
140 variables: wherever possible, any variable substitution is done in Haskell
141 before the Makefile is generated. 
142
143 \paragraph{Hake is for building Barrelfish.}  We make no claims as to
144 Hake's suitability for any project other than Barrelfish, and indeed
145 the current implementation is pretty tied to the Barrelfish tree.
146 This has helped to keep the system focussed and tractable.  One
147 non-goal of Hake, for example, is to support portability across host
148 machines (as CMake tries to do). 
149
150 \chapter{Simple Hakefiles}
151
152 Hake can in principle build anything, but there are two simple use
153 cases for Hake: building Barrelfish applications (user-space
154 binaries), and building Barrelfish libraries.  Here's how, at time of
155 writing, the Barrelfish PCI driver is specified.  This is the entire
156 Hakefile: 
157
158 \begin{verbatim}
159
160 [ build application { 
161        target = "pci",
162        cFiles = [ "pcimain.c", "pci.c", "pci_service.c", 
163                   "ioapic.c", "acpi.c", "ht_config.c",
164                   "acpica_osglue.c", "interrupts.c", 
165                   "pci_confspace.c", "pcie_confspace.c",
166                   "video.c", "buttons.c", "acpi_ec.c" ],
167         flounderBindings = [ "pci" ],
168         flounderDefs = [ "monitor" ],
169         mackerelDevices = [ "pci_hdr0", "pci_hdr1",
170                             "lpc_ioapic", "ht_config",
171                             "lpc_bridge", "acpi_ec" ],
172         addIncludes = [ "acpica/include" ],
173         addCFlags = [ "-Wno-redundant-decls" ],
174         addLibraries = [ "mm", "acpi", "skb", "pci" ],
175         architectures = [ "x86_64", "x86_32" ]
176        }
177 ]
178 \end{verbatim}
179
180 The outermost square brackets are a Haskell list expression - each
181 Hakefile should be such a list (the exact type will be explained
182 later).   This list has a single element, the instruction to built an
183 application (you can have more of these, separated by commas). 
184
185 The \texttt{build application} specifies a number of arguments, all of
186 which are optional.  These are actually Haskell record field
187 specifiers, and \texttt{application} returns a complete default set.
188 \texttt{build} then generates the Make rules to build the
189 application. 
190
191 The complete list of possible arguments for applications (or
192 libraries) can be found by looking at \texttt{Args.hs}.  The ones used
193 here are:
194 \begin{description}
195 \item[target]: the name of the binary to build.  
196 \item[cFiles]: list of names of C source files. You need to include
197   ``\texttt{.c}''. 
198 \item[flounderBindings]: Flounder interfaces for which to compile 
199   the stub files.  
200 \item[flounderDefs]: Flounder interfaces to use from a library
201 \item[mackerelDevices]: list of Mackerel device specs this application uses or depends on. 
202 \item[addIncludes]: additional include paths for header files. 
203 \item[addLibraries]: additional libraries to link against.
204 \end{description}
205
206 Note that filenames are relative to the current source
207 directory. Those with a leading '/' are interpreted relative to the
208 root of the tree (not the root file system).   
209
210 Libraries are similar.  Here's the Hakefile for the X86 emulator
211 library:
212 \begin{verbatim}
213 [ build library { 
214          target = "x86emu",
215          cFiles = [ "debug.c", "decode.c", "fpu.c", "ops2.c",
216                     "ops.c", "prim_ops.c", "sys.c"],
217          addCFlags = ["-Wno-shadow" ]
218      }
219 ]
220 \end{verbatim}
221 This should be all you need to know to write simple Hakefile{s} for
222 the Barrelfish, and indeed to understand most of the Hakefile{s} in
223 the Barrelfish tree.
224
225 Doing (or understanding) more fancy things in the Hakefile requires
226 more knowledge of how Hake internally generates and represents Make
227 rules, described later. 
228
229 \chapter{Hake from the bottom up}
230
231 The core of Hake consists of the code to walk the source tree, a
232 minimal set of data types used to represent Make rules, and codes to
233 render these data types into a Makefile.  
234
235 \section{The Hake name space for files}
236
237 Unlike most build systems, Hake uses a 3-dimensional name space for
238 files.  
239
240 The first component is called the ``tree''.  Whenever Hake runs, it
241 deals with three ``trees'':
242 \begin{enumerate}
243
244 \item The ``source tree'' (written as \texttt{SrcTree}) is the fle
245   system directory tree containing the source code for the programs
246   and libraries currently being built.  When building the core OS,
247   this is the main OS source tree. When building an external
248   application or library, this is the directory tree containing the
249   application or library's source code. 
250
251 \item The ``build tree'' (written as \texttt{BuildTree}) is where the
252   intermediate and final results of the compilation end up.  This is
253   typically the current working directory when Hake was run. 
254
255 \item The ``install tree'' (written as \texttt{InstallTree}) is the
256   directory tree containing a core Barrelfish OS build tree.  When
257   building the OS, the install tree and the build tree are the same,
258   but when building an external application or library, the install
259   tree is a pre-built Barrelfish tree and the build tree is where the
260   new application or library is built. 
261 \end{enumerate}
262
263 The second component is called the ``architecture'' (for want
264 of a better name), and corresponds to building the same code for
265 different target architectures (\texttt{x86\_64}, \texttt{arm}, etc.)
266 Architectures themselves form a flat namespace. 
267
268 Some ``architectures'' are special when building the core Barrelfish OS:
269 \begin{description}
270 \item[src] refers to files which are always present in the source
271 tree.  Hake should not be used to build anything in the \texttt{src}
272 architecture, and anything in any other architecture must be generated
273 at build time. 
274 \item[hake] is used by Hake as part of the bootstrapping process.
275 \item[root] refers to files relative to the top of the build
276 tree, and should be used with caution. 
277 \item[tools] is used to build other build process tools (Mackerel,
278   Fugu, Flounder, etc.)
279 \item[docs] is used to build documentation (Technical Notes),
280   including this document.
281 \end{description}
282
283 The final component is called the ``path'', and corresponds roughly
284 to the pathname of the file from the root of the designated tree. 
285 In the source for hake itself,``path'' usually refers to this path,
286 and file ``location'' or just ``loc'' refers to the 3-dimensional file
287 reference. 
288
289 Here are some examples of hake file locations:
290
291 \begin{tabular}{crll} Tree & Architecture & Path & Description \\ \hline
292 \texttt{SrcTree} & \texttt{src} & \texttt{/tools/hake/Main.hs} & Part of the source code for Hake
293 itself \\
294 \texttt{InstallTree} & \texttt{tools} & \texttt{/tools/flounder/flounder} & The (built) binary for the
295 flounder compiler \\
296 \texttt{InstallTree} & \texttt{x86\_64} & \texttt{/lib/libbarrelfish.a} & The Barrelfish
297 library \\
298 \texttt{InstallTree} & \texttt{src} & \texttt{/include/stdio.h} & C header file \\
299 \texttt{BuildTree} & \texttt{x86\_64} & \texttt{/include/asmoffsets.h} & Generated C header
300 file \\
301 \texttt{SrcTree} & \texttt{src} & \texttt{/devices/xapic.dev} & Mackerel source file \\
302 \texttt{BuildTree} & \texttt{x86\_64} &
303 \texttt{/include/dev/xapic\_dev.h} & Generated header file from Mackerel \\
304 \end{tabular}
305
306 When referring to files in Hake, files whose paths are ``relative''
307 (i.e.\ do not start with a leading ``/'') are considered relative to
308 the path of their Hakefile, and are converted into
309 ``absolute'' paths from the top of their tree when they appear.
310 This is more intuitive than it sounds.  For example, a file referred
311 to as \texttt{(SrcTree,"src","e1000.c")} in
312 \texttt{drivers/e1000/Hakefile} will appear in the resulting Makefile
313 as {drivers/e1000/e1000.c}.  
314
315 The Hake namespace is mapped onto the file system as follows: all
316 files with architecture \texttt{src} are relative to the top of the
317 source tree, whereas a file in a different architecture \texttt{foo}
318 is relative to directory \texttt{foo/} in the build or install tree.
319 Thus, \texttt{(BuildTree,"x86\_64","e1000.o")} in
320 \texttt{drivers/e1000/Hakefile} will  appear in the resulting Makefile
321 as {./x86\_64/drivers/e1000/e1000.o}. 
322
323 Hake will generate all Makefile rules necessary to create any
324 directories in the build tree that it needs - it's perfectly possible
325 (and sometimes useful) with Hake to type ``\texttt{rm -rf ./*;
326   make}'' and have everything work.  
327
328 \section{Representing rules}\label{sec:reprules}
329
330 Each Hakefile is an expression that must evaluate to a list of
331 \texttt{HRule}s.  The declaration of \texttt{HRule} is:
332 \begin{verbatim}
333 data HRule = Rule [ RuleToken ]
334            | Include RuleToken
335            | Error String
336            | Rules [ HRule ]
337              deriving (Show,Typeable)
338 \end{verbatim}
339
340 The \texttt{Include} constructor creates an ``include'' directive in a
341 Makefile.  In theory, there should be no need for developers to use
342 this; it is only used currently to include automatically-generated
343 dependency files for C and assembly source. 
344
345 The \texttt{Rules} constructor allows a tree of rules to be
346 constructed.  This is purely a convenience: any time that one can
347 return a single rule, one can also return a list of rules.  This makes
348 it easier to write functions which return rules, which is the basis of
349 Hake.
350
351 The \texttt{Error} constructor is used to signal errors, but in
352 practice is rarely used. 
353
354 An actual basic Makefile rule is constructed by \texttt{Rule} as a
355 list of \texttt{RuleToken}s.  The declaration of \texttt{RuleToken}
356 is:
357 \begin{verbatim}
358
359 data TreeRef = SrcTree | BuildTree | InstallTree
360              deriving (Show,Eq)
361
362 data RuleToken = In     TreeRef String String -- Input to the computation
363                | Dep    TreeRef String String -- Extra (implicit) dependency
364                | NoDep  TreeRef String String -- File that's not a dependency
365                | PreDep TreeRef String String -- One-time dependency
366                | Out    String String         -- Output of the computation
367                | Target String String   -- Target that's not involved
368                | Str String             -- String with trailing " "
369                | NStr String            -- Just a string
370                | ErrorMsg String        -- Error message: $(error x)
371                | NL                     -- New line
372                  deriving (Show,Eq)
373 \end{verbatim}
374 Each rule token can either be a string of some form, or a reference to
375 a file.   Note that for some file references, the tree is implicit:
376 \texttt{Out} and \texttt{Target} files are always in the
377 \texttt{BuildTree}.
378
379 Rules in Hake differ from plain Makefile rules in that
380 they only consist of rule bodies (i.e., exactly what needs to be
381 done), and the targets and dependencies are inferred (so they only
382 need to be written once).  An example may make this clear.  Here is a
383 function which returns list of \texttt{RuleToken}s for maintaining a
384 Unix library:
385 \begin{verbatim}
386 archive :: Options -> [String] -> String -> [ RuleToken ]
387 archive opts objs libpath =
388     [ Str "ar cr ", Out arch libpath ] 
389     ++ 
390     [ In BuildTree arch o | o <- objs ]
391     ++ 
392     [ NL, Str "ranlib ", Out arch libpath ]
393 \end{verbatim}
394 The arguments to this function include a set of ``options'', which are
395 used extensively inside Hake to pass around values like C flags,
396 include paths, link options, etc., together with a set of object file
397 paths and the path of a library file to build.  The architecture
398 ``\texttt{arch}'' is defined elsewhere (this example is from the file
399 with rules specific to \texttt{x86\_64}, so within the scope it is
400 defined globally)
401
402 The library is referred to as an \texttt{Out} token, since it is a target
403 of the rule, whereas the object files are referred to by \texttt{In}
404 tokens, since they are prerequisites.   Both are in the \texttt{arch}
405 architecture, since they have presumably been built by other rules. 
406
407 This function is called from another, \texttt{arch}-independent
408 function called ``\texttt{archiveLibrary}, which dispatches based on
409 the architectures that need to be built for a given library. 
410 Hence, if a Hakefile at ``\texttt{drivers/e1000/Hakefile}'' contained
411 the expression:
412 \begin{verbatim}
413 archiveLibrary "x86_64" "e1000drv" [ "e1000.o", "e1000srv.o"]
414 \end{verbatim}
415 -- the resulting Makefile would contain:
416 \begin{verbatim}
417 ./x86_64/drivers/e1000/libe1000drv.a: \
418                        ./x86_64/drivers/e1000/e1000.o \
419                        ./x86_64/drivers/e1000/e1000srv.o 
420         ar cr ./x86_64/drivers/e1000/libe1000drv.a \
421                        ./x86_64/drivers/e1000/e1000.o \
422                        ./x86_64/drivers/e1000/e1000srv.o 
423         ranlib ./x86_64/drivers/e1000/libe1000drv.a
424 \end{verbatim}
425
426 The precise definitions of each token are as follows:
427 \begin{description}
428 \item[In] tokens are file references which are dependent inputs for a
429   Make rule.   In other words, they refer to files which will appear
430   both in the rule body and the list of dependencies (the right hand
431   side) in the rule
432   head.  \textbf{In} file references can be in any architecture. 
433
434 \item[Dep] tokens are file references to implicit dependencies.  In
435   Make terms, these are file names which appear in the list of
436   dependencies in rule head, but don't explicitly appear in the rule
437   body. 
438
439 \item[PreDep] tokens are like \textbf{Dep} tokens, but appear in the
440   rule head following a \textbf{$|$} character.  GNU Make will require
441   these dependencies to be built only if they do not already exist -
442   it does not check for modification times.  In Barrelfish, such
443   dependencies are used for files such as \texttt{errno.h} which must
444   be generated first in order to calculate C dependencies, but which
445   ultimately not all C files depend upon.  Any true dependency of a C
446   file on \texttt{errno.h} will be specified by the generated depend
447   files, and thus override the \textbf{PreDep} declaration. 
448
449 \item[NoDep] tokens are file references that are not dependencies at
450   all.  The file name only appears in the rule body, never in the
451   head.   For example, \textbf{NoDep} references are used for
452   directories for include files. 
453
454 \item[Out] tokens are file references to output files from a rule,
455   which are mentioned in the rule body. This is the common case for
456   most files generated by Make rules. 
457
458 \item[Target] tokens are file references that are implicit outputs of
459   the rule, but do not appear in the rule body.  In Make terms they
460   appear only in the left-hand side of the rule head, and not in the
461   body.  
462
463 \item[Str] tokens are simply strings.  They will be followed in the
464   Makefile by a space character, which is usually what you want.  
465
466 \item[NStr] tokens are like \textbf{Str}, but not followed by a
467   space.  This is useful for situations like the \texttt{-I} flag to
468   the C compiler, which takes a directory name (specified by a
469   \textbf{NoDep} token) without any intervening whitespace.
470
471 \item[ErrorMsg] tokens are a way to incorporate error conditions into
472   the Makefile - they are translated into the GNU make construct
473   \texttt{\$(error \textit{x})}. 
474
475 \item[NL] tokens are simply newlines in the rule. 
476
477 \end{description}
478
479 In practice, a Hakefile rarely has to resort to explicit
480 \texttt{RuleToken}s, but instead calls functions inside Hake to return
481 \texttt{HRule}s.  
482
483
484 \section{Higher rule abstractions}
485
486 The guts of Hake is mostly contained in the file \texttt{RuleDefs.hs},
487 which provides a big lattice of functions to automate generating
488 rules for commonly used patterns.  If you want to do more complex
489 things than simply ``\texttt{build application}'' or ``\texttt{build
490   library}'', it's a good idea to understand how these features use
491 the definitions in \texttt{RuleDefs.hs}. 
492
493 \section{Target architectures}
494
495 Most of the flexibility required of Hake in building for multiple
496 architectures is simply coded into the Haskell source of the program.  
497
498 For every target architecture (at time of writing, only
499 \texttt{x86\_64}), there is a file (\texttt{X64\_64.hs}) which
500 contains the definitions required to build the system for that
501 target.   Adding a new target architecture for Barrelfish involves
502 writing a new one of these files (e.g. \texttt{ARM.hs}, or
503 \texttt{X86\_32.hs}, etc.) and modifying the code in
504 \texttt{RuleDefs.hs} to dispatch to the correct module. 
505
506 \section{Host architectures}
507
508 Hake at present supports only a single host architecture: the
509 toolchain to build Barrelfish is specified once in the target
510 architecture files (see above).  
511
512 To add support for multiple host build environments, one way to slice the
513 problem is for the target architecture modules to import different
514 host architecture modules and decide which one to call to get tool and
515 path defnitions at runtime. 
516
517 \section{Configuration}
518
519 The file \texttt{hake/Config.hs} in the build directory contains all
520 the configuration variables (at time of writing) used for Barrelfish.
521 Unlike in Make or CMake, these are Haskell values of arbitrary type,
522 since they are evaluated entirely within Hake. 
523
524 To reconfigure a build tree, therefore, one modifies this file,
525 and rebuilds Hake and the top-level Makefile.
526 The \texttt{rehake} target performs this task.
527
528 \chapter{Bootstrapping and Configuring Hake}
529
530 Hake is bootstrapped using a shell script found in the Barrelfish
531 source tree in \texttt{hake/hake.sh}.  This script is the place to
532 start configuring a new core Barrelfish OS build tree, and must be
533 run in the root of the new build directory. 
534
535 \texttt{hake.sh} takes the following command-line options:
536 \begin{description}
537 \item[-s,--source-dir:] This option is mandatory and specifies the
538   path to the Barrelfish source directory tree.
539 \item[-i,--install-dir:] This option specifies a path to an
540   alternative install directory, and defaults to \texttt{`pwd`}.
541 \item[-a,--architecture:] This option can be given multiple times and
542   specifies the list of architectures to build Barrelfish for.  Run
543   the script with the \texttt{-h} option to get the default list of
544   architectures. 
545 \item[-h,--help:] Prints a usage message.
546 \item[-n,--no-hake:] This option simply rebuilds Hake, but does not
547   run it to generate a Makefile. It can be handy for debugging Hake
548   itself. 
549 \end{description}
550
551 After parsing and checking arguments, \texttt{hake.sh} next creates a new
552 configuration file \texttt{hake/Config.hs} in the build tree.   The
553 configuration options in this file are defaults: it is a copy of the
554 template \texttt{hake/Config.hs.template} in the source tree. 
555
556 If this file already exists in the build tree, however, it is left
557 unchanged, which means that any user modifications to this file
558 persist across multiple bootstrapping runs of \texttt{hake.sh}.
559 If you really want to reconfigure a build tree from scratch, you
560 should therefore remove everything in the build tree, including this
561 file. 
562
563 \texttt{hake.sh} next similarly creates a file called
564 \texttt{symbolic\_targets.mk} in the root of the build tree, if it
565 does not already exist. 
566
567 After this, Hake itself is recompiled in the build tree (including the
568 new \texttt{Config.hs} file), and then run with default options (most
569 of which will be picked up from \texttt{Config.hs}). 
570
571 \chapter{Debugging Hakefiles}
572
573 At least three things can go wrong when you modify or write a
574 Hakefile.  
575
576 \section{The Hakefile has a compile error}
577
578 If you make a mistake in a Hakefile, the most likely output you will
579 see is a funny-looking Haskell compile error, e.g.:
580 \begin{verbatim}
581 ../barrelfish.oothake/usr/pci/Hakefile:13:0:
582     Couldn't match expected type `t -> [HRule]'
583            against inferred type `[a]'
584     In the expression:
585         [build
586            (application
587               {target = "pci", flounderBindings = ["pci"],
588                flounderDefs = ["monitor"],
589                mackerelDevices = ["pci_hdr0", "pci_hdr1", ....],
590  \ldots
591  \ldots
592 <command line>: module is not loaded: `Hakefiles' (Hakefiles.hs)
593 \end{verbatim}
594
595 Ignoring the last line for the moment, if you know enough Haskell this
596 should tell you exactly what is wrong with some Hakefile.   However,
597 even if you don't know enough Haskell, it does say which Hakefile is
598 at fault and whereabouts in the offending Hakefile the problem is (in
599 this case line 13 of \texttt{usr/pci/Hakefile}). 
600
601 Also, the file that Hake tried to compile will be left for you in
602 \texttt{Hakefiles.hs}.  If you look at this, you'll see it's
603 constructed out of individual Hakefile{s} together with a preamble
604 giving details of the files in the tree.  
605
606 \section{The Makefile has an error}
607
608 Hake generates a single large Makefile at the top of the tree.
609 While it's huge (often several 100,000 lines), it's actually very easy to
610 understand 
611 since (a) it only refers to files, (b) it contains comments saying
612 where each bit comes from, and (c) it barely uses any
613 Make variables at all.  
614
615 It is hard to persuade Hake to generate an invalid Makefile,
616 but it's possible.  If so, it may still be due to an error in some
617 Hakefile, in which case look at the file comments preceding the line
618 where Make thinks the error is to find out which Hakefile to look
619 at. 
620
621 The most common problem is actually due to out of date dependencies.
622 Hake does its best to calculate dependencies properly, but sometimes
623 (such as when Hakefiles themselves change) they get confused.  In this
624 case, the first thing to try to is completely remove the build tree
625 and try again.  As you get more of a feel for the system it's possible
626 to more surgically remove bits of the tree (the Makefile knows how to
627 recreate any part of the build tree). 
628
629 \section{The Makefile works, but the build fails}
630
631 In this case, you've written valid Hake rules, but they don't do what
632 you want them to.  In this case as well, looking at the generated Makefile
633 can often help work out what went wrong. 
634
635 \chapter{Command-line arguments}
636
637 The Hake binary built in a Barrelfish tree can be found in
638 \texttt{/hake/hake}, and takes the following command-line arguments:
639 \begin{description}
640 \item[--source-dir:] this option is mandatory and specifies the root
641   of the source tree. 
642 \item[--output-filename:] this option specifies the name of the output
643   Makefile, and defaults to \texttt{Makefile}
644 \item[--quiet:] this option turns off some information and warning
645   messages as Hake runs.
646 \item[--verbose:] this option increases the verbosity level of Hake's
647   information messages.
648 \item[--install-dir:] this option specifies the install tree.  It
649   defaults to the build tree (the current working directory where Hake runs).
650 \item[--architecture:] this option can be specified multiple times and
651   gives an architecture for Hake to build.  It overrides the default
652   list of architectures to build that was set when Hake was
653   configured.  At time of writing, supported architectures include
654   \texttt{x86\_64}, \texttt{x86\_32}, \texttt{arm}, \texttt{arm11mp},
655   \texttt{beehive}, and \texttt{scc}. 
656 \end{description}
657
658 \subsection{Building an external application or library}
659
660 Building an application or library \emph{outside} the main Barrelfish
661 tree involves invoking Hake directly (rather than bootstrapping with
662 \texttt{hake.sh}), and requires to you have a pre-built Barrelfish
663 tree with at least as many architectures built as you would like to
664 build the application or library for.
665
666 For example, suppose \texttt{/projects/barrelfish/install} contains a
667 core Barrelfish tree built for all supported architectures, and the
668 user's home directory contains a small source tree
669 \verb!~/quake3! containing an application to be built for
670 \texttt{x86\_32} only.  As long as this source tree has a correct
671 Hakefile (or Hakefiles), the following should build the application:
672
673 \begin{verbatim}
674 $ mkdir quake_build
675 $ cd quake_build
676 $ /projects/barrelfish/install/hake/hake \
677         --source-dir ~/quake \
678         --install-dir /projects/barrelfish/install \
679         --architecture x86_32
680 $ make -j 16
681 \end{verbatim}
682
683 \chapter{Wishlist}
684
685 Hake is missing many desirable features.  Hopefully, this list will
686 reduce in size over time.  Here are a few:
687
688 \begin{itemize}
689 \item Support for multiple host build environments (such as Cygwin). 
690 \item The bootstrapping process for Hake, while short, is a little
691   unsatisfactory. 
692 \end{itemize}
693 \end{document}