1 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2 % Copyright (c) 2011, ETH Zurich.
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 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
10 \documentclass[a4paper,twoside]{report} % for a report (default)
12 \usepackage{bftn} % You need this
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
19 % \date{Month Year} % Not needed - will be taken from version history
25 % Include version history first
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}
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
39 \chapter{Introduction}
41 Hake is how we build Barrelfish.
43 Hake isn't designed to operate outside Barrelfish, so this document
44 will assume you're trying to build Barrelfish.
48 Suppose you have a fresh Barrelfish source tree in:
50 \texttt{/home/barrelfish/src}
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:
56 $ cd /home/barrelfish/src
59 $ ../src/hake/hake.sh -s ../src -a x86_64
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
68 You can supply multiple \texttt{-a} options to build for multiple
69 architectures at the same time.
71 Edit the file \texttt{symbolic\_targets.mk} in your build directory to
72 add extra make targets.
74 Edit the file \texttt{hake/Config.hs} in your build directory and
75 rebuild Hake to reconfigure your build tree.
79 \section{How to think about hake}
81 Hake builds a single, very large \texttt{Makefile} which
82 \texttt{make} can then use to build any part of Barrelfish.
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.
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.
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
99 \section{When hake runs}
101 When you run Hake in a Barrelfish source tree, it does the following things:
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
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
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.
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.
131 The Makefile also includes comments to help you locate the make rules
132 generated from any particular Hakefile.
134 \section{Motivation and Design Principles}
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
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.
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.
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).
163 \chapter{Simple Hakefiles}
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
173 [ build application {
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" ]
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).
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
204 The complete list of possible arguments for applications (or
205 libraries) can be found by looking at \texttt{Args.hs}. The ones used
208 \item[target]: the name of the binary to build.
209 \item[cFiles]: list of names of C source files. You need to include
211 \item[flounderBindings]: Flounder interfaces for which to compile
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.
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).
223 Libraries are similar. Here's the Hakefile for the X86 emulator
228 cFiles = [ "debug.c", "decode.c", "fpu.c", "ops2.c",
229 "ops.c", "prim_ops.c", "sys.c"],
230 addCFlags = ["-Wno-shadow" ]
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:
241 [ platform "ARMv5" [ "armv5" ]
242 ([ ("armv5", "/sbin/" ++ f) | f <- [ "cpu", "cpu.bin" ]])
243 "Very basic ARMv5 configuration for testing",
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
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}.
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
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.
265 \chapter{Hake from the bottom up}
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.
271 \section{The Hake name space for files}
273 Unlike most build systems, Hake uses a 3-dimensional name space for
276 The first component is called the ``tree''. Whenever Hake runs, it
277 deals with three ``trees'':
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.
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.
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.
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.
304 Some ``architectures'' are special when building the core Barrelfish OS:
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
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.
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
325 Here are some examples of hake file locations:
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
330 \texttt{InstallTree} & \texttt{tools} & \texttt{/tools/flounder/flounder} & The (built) binary for the
332 \texttt{InstallTree} & \texttt{x86\_64} & \texttt{/lib/libbarrelfish.a} & The Barrelfish
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
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 \\
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}.
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}.
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.
364 \section{Representing rules}\label{sec:reprules}
366 Each Hakefile is an expression that must evaluate to a list of
367 \texttt{HRule}s. The declaration of \texttt{HRule} is:
369 data HRule = Rule [ RuleToken ]
372 | Phony String Bool [ RuleToken ]
374 deriving (Show,Typeable)
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.
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
388 The \texttt{Error} constructor is used to signal errors, but in
389 practice is rarely used.
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''
396 An actual basic Makefile rule is constructed by \texttt{Rule} as a
397 list of \texttt{RuleToken}s. The declaration of \texttt{RuleToken}
401 data TreeRef = SrcTree | BuildTree | InstallTree
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)
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
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
428 archive :: Options -> [String] -> String -> [ RuleToken ]
429 archive opts objs libpath =
430 [ Str "ar cr ", Out arch libpath ]
432 [ In BuildTree arch o | o <- objs ]
434 [ NL, Str "ranlib ", Out arch libpath ]
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
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.
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
455 archiveLibrary "x86_64" "e1000drv" [ "e1000.o", "e1000srv.o"]
457 -- the resulting Makefile would contain:
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
468 The precise definitions of each token are as follows:
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
474 head. \textbf{In} file references can be in any architecture.
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
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.
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.
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.
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
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.
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.
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})}.
517 \item[NL] tokens are simply newlines in the rule.
521 In practice, a Hakefile rarely has to resort to explicit
522 \texttt{RuleToken}s, but instead calls functions inside Hake to return
526 \section{Higher rule abstractions}
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}.
535 \section{Target architectures}
537 Most of the flexibility required of Hake in building for multiple
538 architectures is simply coded into the Haskell source of the program.
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.
548 \section{Host architectures}
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).
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.
559 \section{Configuration}
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.
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.
570 \chapter{Bootstrapping and Configuring Hake}
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.
577 \texttt{hake.sh} takes the following command-line options:
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
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
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.
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
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.
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}).
613 \chapter{Debugging Hakefiles}
615 At least three things can go wrong when you modify or write a
618 \section{The Hakefile has a compile error}
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.:
623 ../barrelfish.oothake/usr/pci/Hakefile:13:0:
624 Couldn't match expected type `t -> [HRule]'
625 against inferred type `[a]'
629 {target = "pci", flounderBindings = ["pci"],
630 flounderDefs = ["monitor"],
631 mackerelDevices = ["pci_hdr0", "pci_hdr1", ....],
634 <command line>: module is not loaded: `Hakefiles' (Hakefiles.hs)
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}).
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.
648 \section{The Makefile has an error}
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
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.
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
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).
671 \section{The Makefile works, but the build fails}
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.
677 \chapter{Command-line arguments}
679 The Hake binary built in a Barrelfish tree can be found in
680 \texttt{/hake/hake}, and takes the following command-line arguments:
682 \item[--source-dir:] this option is mandatory and specifies the root
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}.
700 \subsection{Building an external application or library}
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.
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:
718 $ /projects/barrelfish/install/hake/hake \
719 --source-dir ~/quake \
720 --install-dir /projects/barrelfish/install \
721 --architecture x86_32
727 Hake is missing many desirable features. Hopefully, this list will
728 reduce in size over time. Here are a few:
731 \item Support for multiple host build environments (such as Cygwin).
732 \item The bootstrapping process for Hake, while short, is a little