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