1 -------------------------------------------------------------------------
2 -- Copyright (c) 2007-2011, ETH Zurich.
3 -- All rights reserved.
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, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group.
9 -- Basic Hake rule definitions and combinators
11 --------------------------------------------------------------------------
15 import List (intersect)
17 import qualified X86_64
18 import qualified X86_32
21 import qualified ARM11MP
22 import qualified Beehive
23 import qualified XScale
26 import qualified Config
30 -- should we move this to Config.hs? -AB
34 -- Is a token to be displayed in a rule?
36 inRule :: RuleToken -> Bool
37 inRule (Dep _ _ _) = False
38 inRule (PreDep _ _ _) = False
39 inRule (Target _ _) = False
43 -- Look for a set of files: this is called using the "find" combinator
45 withSuffix :: [String] -> String -> String -> [String]
46 withSuffix af tf arg =
47 [ basename f | f <- af, f `isInSameDirAs` tf, isSuffixOf arg f ]
48 withSuffices :: [String] -> String -> [String] -> [String]
49 withSuffices af tf args =
50 concat [ withSuffix af tf arg | arg <- args ]
53 -- Find files with a given suffix in a given dir
55 inDir :: [String] -> String -> String -> String -> [String]
56 inDir af tf dir suffix =
57 -- Dummy is here so that we can find files in the same dir :-/
58 let subdir = (if head dir == '/' then absdir else reldir) ./. "dummy"
59 absdir = if head tf == '/' then dir else '.':dir
60 reldir = (dirname tf) ./. dir
61 files = withSuffix af subdir suffix
63 [ dir ./. f | f <- files ]
65 cInDir :: [String] -> String -> String -> [String]
66 cInDir af tf dir = inDir af tf dir ".c"
67 cxxInDir :: [String] -> String -> String -> [String]
68 cxxInDir af tf dir = inDir af tf dir ".cpp"
69 sInDir :: [String] -> String -> String -> [String]
70 sInDir af tf dir = inDir af tf dir ".S"
72 -------------------------------------------------------------------------
74 -- Architecture specific definitions
76 -------------------------------------------------------------------------
78 options :: String -> Options
79 options "x86_64" = X86_64.options
80 options "x86_32" = X86_32.options
81 options "scc" = SCC.options
82 options "arm" = ARM.options
83 options "arm11mp" = ARM11MP.options
84 options "beehive" = Beehive.options
85 options "xscale" = XScale.options
87 kernelCFlags "x86_64" = X86_64.kernelCFlags
88 kernelCFlags "x86_32" = X86_32.kernelCFlags
89 kernelCFlags "scc" = SCC.kernelCFlags
90 kernelCFlags "arm" = ARM.kernelCFlags
91 kernelCFlags "arm11mp" = ARM11MP.kernelCFlags
92 kernelCFlags "beehive" = Beehive.kernelCFlags
93 kernelCFlags "xscale" = XScale.kernelCFlags
95 kernelLdFlags "x86_64" = X86_64.kernelLdFlags
96 kernelLdFlags "x86_32" = X86_32.kernelLdFlags
97 kernelLdFlags "scc" = SCC.kernelLdFlags
98 kernelLdFlags "arm" = ARM.kernelLdFlags
99 kernelLdFlags "arm11mp" = ARM11MP.kernelLdFlags
100 kernelLdFlags "beehive" = Beehive.kernelLdFlags
101 kernelLdFlags "xscale" = XScale.kernelLdFlags
103 archFamily :: String -> String
104 archFamily arch = optArchFamily (options arch)
106 -------------------------------------------------------------------------
108 -- Options for compiling the kernel, which is special
110 -------------------------------------------------------------------------
112 kernelIncludes arch = [ NoDep BuildTree arch f | f <- [
116 [ NoDep SrcTree "src" f | f <- [
117 "/kernel/include/arch" ./. arch,
118 "/kernel/include/arch" ./. archFamily arch,
121 "/include/arch" ./. archFamily arch,
122 "/include/target" ./. archFamily arch]]
124 kernelOptions arch = Options {
126 optArchFamily = archFamily arch,
127 optFlags = kernelCFlags arch,
129 optDefines = (optDefines (options arch)) ++ [ Str "-DIN_KERNEL",
130 Str ("-DCONFIG_SCHEDULER_" ++ (show Config.scheduler)),
131 Str ("-DCONFIG_TIMESLICE=" ++ (show Config.timeslice)) ],
132 optIncludes = kernelIncludes arch,
134 [ Dep InstallTree arch "/include/errors/errno.h",
135 Dep InstallTree arch "/include/barrelfish_kpi/capbits.h",
136 Dep InstallTree arch "/include/asmoffsets.h" ],
137 optLdFlags = kernelLdFlags arch,
142 optInterconnectDrivers = [],
143 optFlounderBackends = [],
147 extraDependencies = [],
152 -------------------------------------------------------------------------
154 -- IMPORTANT: This section contains extraction of functions from the
155 -- relevant architecture module. The names and types should be
156 -- exactly the same as in the architecture.hs file. This section
157 -- should not contain any logic; ony architecture extraction.
159 --------------------------------------------------------------------------
162 -- First, the default C compiler for an architecture
164 cCompiler :: Options -> String -> String -> String -> [ RuleToken ]
165 cCompiler opts phase src obj
166 | optArch opts == "x86_64" = X86_64.cCompiler opts phase src obj
167 | optArch opts == "x86_32" = X86_32.cCompiler opts phase src obj
168 | optArch opts == "scc" = SCC.cCompiler opts phase src obj
169 | optArch opts == "arm" = ARM.cCompiler opts phase src obj
170 | optArch opts == "arm11mp" = ARM11MP.cCompiler opts phase src obj
171 | optArch opts == "beehive" = Beehive.cCompiler opts phase src obj
172 | optArch opts == "xscale" = XScale.cCompiler opts phase src obj
173 | otherwise = [ ErrorMsg ("no C compiler for " ++ (optArch opts)) ]
175 cPreprocessor :: Options -> String -> String -> String -> [ RuleToken ]
176 cPreprocessor opts phase src obj
177 | optArch opts == "beehive" = Beehive.cPreprocessor opts phase src obj
178 | otherwise = [ ErrorMsg ("no C preprocessor for " ++ (optArch opts)) ]
181 -- C++ compiler, where supported
183 cxxCompiler :: Options -> String -> String -> String -> [ RuleToken ]
184 cxxCompiler opts phase src obj
185 | optArch opts == "x86_64" = X86_64.cxxCompiler opts phase src obj
186 | optArch opts == "beehive" = Beehive.cxxCompiler opts phase src obj
187 | otherwise = [ ErrorMsg ("no C++ compiler for " ++ (optArch opts)) ]
191 -- makeDepend step; note that obj can be whatever the intended output is
193 makeDepend :: Options -> String -> String -> String -> String -> [ RuleToken ]
194 makeDepend opts phase src obj depfile
195 | optArch opts == "x86_64" =
196 X86_64.makeDepend opts phase src obj depfile
197 | optArch opts == "x86_32" =
198 X86_32.makeDepend opts phase src obj depfile
199 | optArch opts == "scc" =
200 SCC.makeDepend opts phase src obj depfile
201 | optArch opts == "arm" =
202 ARM.makeDepend opts phase src obj depfile
203 | optArch opts == "arm11mp" =
204 ARM11MP.makeDepend opts phase src obj depfile
205 | optArch opts == "beehive" =
206 Beehive.makeDepend opts phase src obj depfile
207 | optArch opts == "xscale" =
208 XScale.makeDepend opts phase src obj depfile
209 | otherwise = [ ErrorMsg ("no dependency generator for " ++ (optArch opts)) ]
211 makeCxxDepend :: Options -> String -> String -> String -> String -> [ RuleToken ]
212 makeCxxDepend opts phase src obj depfile
213 | optArch opts == "x86_64" =
214 X86_64.makeCxxDepend opts phase src obj depfile
215 | optArch opts == "beehive" =
216 Beehive.makeCxxDepend opts phase src obj depfile
217 | otherwise = [ ErrorMsg ("no C++ dependency generator for " ++ (optArch opts)) ]
219 cToAssembler :: Options -> String -> String -> String -> String -> [ RuleToken ]
220 cToAssembler opts phase src afile objdepfile
221 | optArch opts == "x86_64" = X86_64.cToAssembler opts phase src afile objdepfile
222 | optArch opts == "x86_32" = X86_32.cToAssembler opts phase src afile objdepfile
223 | optArch opts == "scc" = SCC.cToAssembler opts phase src afile objdepfile
224 | optArch opts == "arm" = ARM.cToAssembler opts phase src afile objdepfile
225 | optArch opts == "arm11mp" = ARM11MP.cToAssembler opts phase src afile objdepfile
226 | optArch opts == "beehive" = Beehive.cToAssembler opts phase src afile objdepfile
227 | optArch opts == "xscale" = XScale.cToAssembler opts phase src afile objdepfile
228 | otherwise = [ ErrorMsg ("no C compiler for " ++ (optArch opts)) ]
231 -- Assemble an assembly language file
233 assembler :: Options -> String -> String -> [ RuleToken ]
234 assembler opts src obj
235 | optArch opts == "x86_64" = X86_64.assembler opts src obj
236 | optArch opts == "x86_32" = X86_32.assembler opts src obj
237 | optArch opts == "scc" = SCC.assembler opts src obj
238 | optArch opts == "arm" = ARM.assembler opts src obj
239 | optArch opts == "arm11mp" = ARM11MP.assembler opts src obj
240 | optArch opts == "beehive" = Beehive.assembler opts src obj
241 | optArch opts == "xscale" = XScale.assembler opts src obj
242 | otherwise = [ ErrorMsg ("no assembler for " ++ (optArch opts)) ]
244 archive :: Options -> [String] -> String -> [ RuleToken ]
245 archive opts objs libname
246 | optArch opts == "x86_64" = X86_64.archive opts objs libname
247 | optArch opts == "x86_32" = X86_32.archive opts objs libname
248 | optArch opts == "scc" = SCC.archive opts objs libname
249 | optArch opts == "arm" = ARM.archive opts objs libname
250 | optArch opts == "arm11mp" = ARM11MP.archive opts objs libname
251 | optArch opts == "beehive" = Beehive.archive opts objs libname
252 | optArch opts == "xscale" = XScale.archive opts objs libname
253 | otherwise = [ ErrorMsg ("Can't build a library for " ++ (optArch opts)) ]
255 linker :: Options -> [String] -> [String] -> String -> [RuleToken]
256 linker opts objs libs bin
257 | optArch opts == "x86_64" = X86_64.linker opts objs libs bin
258 | optArch opts == "x86_32" = X86_32.linker opts objs libs bin
259 | optArch opts == "scc" = SCC.linker opts objs libs bin
260 | optArch opts == "arm" = ARM.linker opts objs libs bin
261 | optArch opts == "arm11mp" = ARM11MP.linker opts objs libs bin
262 | optArch opts == "beehive" = Beehive.linker opts objs libs bin
263 | optArch opts == "xscale" = XScale.linker opts objs libs bin
264 | otherwise = [ ErrorMsg ("Can't link executables for " ++ (optArch opts)) ]
266 cxxlinker :: Options -> [String] -> [String] -> String -> [RuleToken]
267 cxxlinker opts objs libs bin
268 | optArch opts == "x86_64" = X86_64.cxxlinker opts objs libs bin
269 | otherwise = [ ErrorMsg ("Can't link C++ executables for " ++ (optArch opts)) ]
272 -- The C compiler for compiling things on the host
274 nativeCCompiler :: String
275 nativeCCompiler = "$(CC)"
277 -------------------------------------------------------------------------
279 -- Functions to create useful filenames
282 dependFilePath :: String -> String
283 dependFilePath obj = obj ++ ".depend"
285 objectFilePath :: Options -> String -> String
286 objectFilePath opts src = (optSuffix opts) ./. ((removeSuffix src) ++ ".o")
288 generatedObjectFilePath :: Options -> String -> String
289 generatedObjectFilePath opts src = (removeSuffix src) ++ ".o"
291 preprocessedFilePath :: Options -> String -> String
292 preprocessedFilePath opts src = (optSuffix opts) ./. ((removeSuffix src) ++ ".i")
294 -- Standard convention is that human generated assembler is .S, machine generated is .s
295 assemblerFilePath :: Options -> String -> String
296 assemblerFilePath opts src = (optSuffix opts) ./. ((removeSuffix src) ++ ".s")
299 -------------------------------------------------------------------------
301 -- Functions with logic to start doing things
305 -- Create C file dependencies
308 -- Since this is where we know what the depfile is called it is here that we also
309 -- decide to include it. This stops many different places below trying to
310 -- guess what the depfile is called
312 makeDependArchSub :: Options -> String -> String -> String -> String -> [ RuleToken ]
313 makeDependArchSub opts phase src objfile depfile =
314 [ Str ("@echo Generating $@"), NL ] ++
315 makeDepend opts phase src objfile depfile
317 makeDependArch :: Options -> String -> String -> String -> String -> HRule
318 makeDependArch opts phase src objfile depfile =
319 Rules [ Rule (makeDependArchSub opts phase src objfile depfile),
320 Include (Out (optArch opts) depfile)
323 -- Make depend for a standard object file
324 makeDependObj :: Options -> String -> String -> HRule
325 makeDependObj opts phase src =
326 let objfile = (objectFilePath opts src)
328 makeDependArch opts phase src objfile (dependFilePath objfile)
330 -- Make depend for a C++ object file
331 makeDependCxxArchSub :: Options -> String -> String -> String -> String -> [ RuleToken ]
332 makeDependCxxArchSub opts phase src objfile depfile =
333 [ Str ("@echo Generating $@"), NL ] ++
334 makeCxxDepend opts phase src objfile depfile
336 makeDependCxxArch :: Options -> String -> String -> String -> String -> HRule
337 makeDependCxxArch opts phase src objfile depfile =
338 Rules [ Rule (makeDependCxxArchSub opts phase src objfile depfile),
339 Include (Out (optArch opts) depfile)
342 makeDependCxxObj :: Options -> String -> String -> HRule
343 makeDependCxxObj opts phase src =
344 let objfile = (objectFilePath opts src)
346 makeDependCxxArch opts phase src objfile (dependFilePath objfile)
348 -- Make depend for an assembler output
349 makeDependAssembler :: Options -> String -> String -> HRule
350 makeDependAssembler opts phase src =
351 let objfile = (assemblerFilePath opts src)
353 makeDependArch opts phase src objfile (dependFilePath objfile)
356 -- Compile a C program to assembler
358 makecToAssembler :: Options -> String -> String -> String -> [ RuleToken ]
359 makecToAssembler opts phase src obj =
360 cToAssembler opts phase src (assemblerFilePath opts src) (dependFilePath obj)
363 -- Assemble an assembly language file
365 assemble :: Options -> String -> [ RuleToken ]
367 assembler opts src (objectFilePath opts src)
370 -- Create a library from a set of object files
372 archiveLibrary :: Options -> String -> [String] -> [ RuleToken ]
373 archiveLibrary opts name objs =
374 archive opts objs (libraryPath name)
377 -- Link an executable
379 linkExecutable :: Options -> [String] -> [String] -> String -> [RuleToken]
380 linkExecutable opts objs libs bin =
381 linker opts objs libs (applicationPath bin)
384 -- Link a C++ executable
386 linkCxxExecutable :: Options -> [String] -> [String] -> String -> [RuleToken]
387 linkCxxExecutable opts objs libs bin =
388 cxxlinker opts objs libs (applicationPath bin)
390 -------------------------------------------------------------------------
396 -------------------------------------------------------------------------
398 -- Hake macros (hacros?): each of these evaluates to HRule, i.e. a
399 -- list of templates for Makefile rules
401 -------------------------------------------------------------------------
404 -- Compile a C file for a particular architecture
405 -- We include cToAssembler to permit humans to type "make foo/bar.s"
407 compileCFile :: Options -> String -> HRule
408 compileCFile opts src =
409 Rules [ Rule (cCompiler opts "src" src (objectFilePath opts src)),
410 Rule (makecToAssembler opts "src" src (objectFilePath opts src)),
411 makeDependObj opts "src" src
415 -- Compile a C++ file for a particular architecture
417 compileCxxFile :: Options -> String -> HRule
418 compileCxxFile opts src =
419 Rules [ Rule (cxxCompiler opts "src" src (objectFilePath opts src)),
420 makeDependCxxObj opts "src" src
424 -- Compile a C file for a particular architecture
426 compileGeneratedCFile :: Options -> String -> HRule
427 compileGeneratedCFile opts src =
428 let o2 = opts { optSuffix = "" }
431 Rules [ Rule (cCompiler o2 arch src (objectFilePath o2 src) ),
432 Rule (makecToAssembler o2 arch src (objectFilePath o2 src)),
433 makeDependObj o2 arch src
436 compileCFiles :: Options -> [String] -> HRule
437 compileCFiles opts srcs = Rules [ compileCFile opts s | s <- srcs ]
438 compileCxxFiles :: Options -> [String] -> HRule
439 compileCxxFiles opts srcs = Rules [ compileCxxFile opts s | s <- srcs ]
440 compileGeneratedCFiles :: Options -> [String] -> HRule
441 compileGeneratedCFiles opts srcs =
442 Rules [ compileGeneratedCFile opts s | s <- srcs ]
445 -- Add a set of C (or whatever) dependences on a *generated* file.
446 -- Somewhere else this file has to be defined as a target, of
449 extraCDependencyForObj :: Options -> String -> String -> String -> [RuleToken]
450 extraCDependencyForObj opts file s obj =
451 let arch = optArch opts
453 [ Target arch (dependFilePath obj),
455 Dep BuildTree arch file
458 extraCDependency :: Options -> String -> String -> HRule
459 extraCDependency opts file s = Rule (extraCDependencyForObj opts file s obj)
460 where obj = objectFilePath opts s
463 extraCDependencies :: Options -> String -> [String] -> HRule
464 extraCDependencies opts file srcs =
465 Rules [ extraCDependency opts file s | s <- srcs ]
467 extraGeneratedCDependency :: Options -> String -> String -> HRule
468 extraGeneratedCDependency opts file s =
469 extraCDependency (opts { optSuffix = "" }) file s
472 -- Copy include files to the appropriate directory
474 includeFile :: Options -> String -> HRule
475 includeFile opts hdr =
476 Rules [ (Rule [ Str "cp", In SrcTree "src" hdr, Out (optArch opts) hdr ]),
477 (Rule [ PreDep BuildTree (optArch opts) hdr,
478 Target (optArch opts) "/include/errors/errno.h" ]
483 -- Build a Mackerel header file from a definition.
485 mackerelProgLoc = In InstallTree "tools" "/bin/mackerel"
486 mackerelDevFileLoc d = In SrcTree "src" ("/devices" ./. (d ++ ".dev"))
487 mackerelDevHdrPath d = "/include/dev/" ./. (d ++ "_dev.h")
489 mackerel2 :: Options -> String -> HRule
490 mackerel2 opts dev = mackerel_generic opts dev "shift-driver"
492 mackerel :: Options -> String -> HRule
493 mackerel opts dev = mackerel_generic opts dev "bitfield-driver"
495 mackerel_generic :: Options -> String -> String -> HRule
496 mackerel_generic opts dev flag =
500 Rule [ mackerelProgLoc,
502 Str "-c", mackerelDevFileLoc dev,
503 Str "-o", Out arch (mackerelDevHdrPath dev)
506 mackerelDependencies :: Options -> String -> [String] -> HRule
507 mackerelDependencies opts d srcs =
508 extraCDependencies opts (mackerelDevHdrPath d) srcs
511 -- Basic Flounder definitions: where things are
514 flounderProgLoc = In InstallTree "tools" "/bin/flounder"
515 flounderIfFileLoc ifn = In SrcTree "src" ("/if" ./. (ifn ++ ".if"))
517 -- new-style stubs: path for generic header
518 flounderIfDefsPath ifn = "/include/if" ./. (ifn ++ "_defs.h")
519 -- new-style stubs: path for specific backend header
520 flounderIfDrvDefsPath ifn drv = "/include/if" ./. (ifn ++ "_" ++ drv ++ "_defs.h")
522 -- new-style stubs: generated C code (for all default enabled backends)
523 flounderBindingPath opts ifn =
524 (optSuffix opts) ./. (ifn ++ "_flounder_bindings.c")
525 -- new-style stubs: generated C code (for extra backends enabled by the user)
526 flounderExtraBindingPath opts ifn =
527 (optSuffix opts) ./. (ifn ++ "_flounder_extra_bindings.c")
529 flounderTHCHdrPath ifn = "/include/if" ./. (ifn ++ "_thc.h")
530 flounderTHCStubPath opts ifn =
531 (optSuffix opts) ./. (ifn ++ "_thc.c")
533 applicationPath name = "/sbin" ./. name
534 libraryPath libname = "/lib" ./. ("lib" ++ libname ++ ".a")
535 kernelPath = "/sbin/cpu"
537 -- construct include arguments to flounder for common types
539 -- 1. platform-specific types (if/platform/foo.if)
540 -- 2. architecture-specific types (if/arch/foo.if)
541 -- 3. generic types (if/types.if)
542 flounderIncludes :: Options -> [RuleToken]
543 flounderIncludes opts
544 = concat [ [Str "-i", flounderIfFileLoc ifn]
545 | ifn <- [ "platform" ./. (optArch opts), -- XXX: optPlatform
546 "arch" ./. (optArch opts),
549 flounderRule :: Options -> [RuleToken] -> HRule
550 flounderRule opts args
551 = Rule $ [ flounderProgLoc ] ++ (flounderIncludes opts) ++ args
554 -- Build new-style Flounder header files from a definition
555 -- (generic header, plus one per backend)
557 flounderGenDefs :: Options -> String -> HRule
558 flounderGenDefs opts ifn =
559 Rules $ flounderRule opts [
560 Str "--generic-header", flounderIfFileLoc ifn,
561 Out (optArch opts) (flounderIfDefsPath ifn)
562 ] : [ flounderRule opts [
563 Str $ "--" ++ drv ++ "-header", flounderIfFileLoc ifn,
564 Out (optArch opts) (flounderIfDrvDefsPath ifn drv)]
565 | drv <- Args.allFlounderBackends ]
568 -- Build a new Flounder binding file from a definition.
569 -- This builds the binding for all enabled backends
571 flounderBinding :: Options -> String -> [String] -> HRule
572 flounderBinding opts ifn =
573 flounderBindingHelper opts ifn backends (flounderBindingPath opts ifn)
575 backends = "generic" : (optFlounderBackends opts)
577 -- as above, but for a specific set of user-specified backends
578 flounderExtraBinding :: Options -> String -> [String] -> [String] -> HRule
579 flounderExtraBinding opts ifn backends =
580 flounderBindingHelper opts ifn backends (flounderExtraBindingPath opts ifn)
582 flounderBindingHelper :: Options -> String -> [String] -> String -> [String] -> HRule
583 flounderBindingHelper opts ifn backends cfile srcs = Rules $
584 [ flounderRule opts $ args ++ [flounderIfFileLoc ifn, Out arch cfile ],
585 compileGeneratedCFile opts cfile,
586 flounderDefsDepend opts ifn allbackends srcs]
587 ++ [extraGeneratedCDependency opts (flounderIfDrvDefsPath ifn d) cfile
591 archfam = optArchFamily opts
592 args = [Str "-a", Str archfam] ++ [Str $ "--" ++ d ++ "-stub" | d <- backends]
593 allbackends = backends `union` optFlounderBackends opts \\ ["generic"]
596 -- Build a Flounder THC header file from a definition.
598 flounderTHCFile :: Options -> String -> HRule
599 flounderTHCFile opts ifn =
601 Str "--thc-header", flounderIfFileLoc ifn,
602 Out (optArch opts) (flounderTHCHdrPath ifn)
606 -- Build a Flounder THC stubs file from a definition.
608 flounderTHCStub :: Options -> String -> [String] -> HRule
609 flounderTHCStub opts ifn srcs =
610 let cfile = flounderTHCStubPath opts ifn
611 hfile = flounderTHCHdrPath ifn
614 Rules [ flounderRule opts [
615 Str "--thc-stubs", flounderIfFileLoc ifn,
618 compileGeneratedCFile opts cfile,
619 extraCDependencies opts hfile srcs,
620 extraGeneratedCDependency opts hfile cfile
624 -- Create a dependency on a Flounder header file for a set of files,
625 -- but don't actually build either stub (useful for libraries)
627 flounderDefsDepend :: Options -> String -> [String] -> [String] -> HRule
628 flounderDefsDepend opts ifn backends srcs = Rules $
629 (extraCDependencies opts (flounderIfDefsPath ifn) srcs) :
630 [extraCDependencies opts (flounderIfDrvDefsPath ifn drv) srcs
631 | drv <- backends, drv /= "generic" ]
634 -- Emit all the Flounder-related rules/dependencies for a given target
637 flounderRules :: Options -> Args.Args -> [String] -> [HRule]
638 flounderRules opts args csrcs =
639 ([ flounderBinding opts f csrcs | f <- Args.flounderBindings args ]
641 [ flounderExtraBinding opts f backends csrcs
642 | (f, backends) <- Args.flounderExtraBindings args ]
644 [ flounderTHCStub opts f csrcs | f <- Args.flounderTHCStubs args ]
646 -- Flounder extra defs (header files) also depend on the base
647 -- Flounder headers for the same interface
648 [ flounderDefsDepend opts f baseBackends csrcs | f <- allIf ]
650 -- Extra defs only for non-base backends (those were already emitted above)
651 [ flounderDefsDepend opts f (backends \\ baseBackends) csrcs
652 | (f, backends) <- Args.flounderExtraDefs args ]
655 -- base backends enabled by default
656 baseBackends = optFlounderBackends opts
658 -- all interfaces mentioned in flounderDefs or ExtraDefs
659 allIf = nub $ Args.flounderDefs args ++ [f | (f,_) <- Args.flounderExtraDefs args]
663 -- Build a Fugu library
665 fuguFile :: Options -> String -> HRule
667 let arch = optArch opts
669 hfile = "/include/errors/" ++ file ++ ".h"
671 Rules [ Rule [In InstallTree "tools" "/bin/fugu",
672 In SrcTree "src" (file++".fugu"),
675 compileGeneratedCFile opts cfile
679 -- Build a Hamlet file
681 hamletFile :: Options -> String -> HRule
682 hamletFile opts file =
683 let arch = optArch opts
684 hfile = "/include/barrelfish_kpi/capbits.h"
685 cfile = "cap_predicates.c"
686 usercfile = "user_cap_predicates.c"
687 ofile = "user_cap_predicates.o"
688 afile = "/lib/libcap_predicates.a"
690 Rules [ Rule [In InstallTree "tools" "/bin/hamlet",
691 In SrcTree "src" (file++".hl"),
694 Out arch usercfile ],
695 compileGeneratedCFile opts usercfile,
696 Rule (archive opts [ ofile ] afile)
700 -- Link a set of object files and libraries together
702 link :: Options -> [String] -> [ String ] -> String -> HRule
703 link opts objs libs bin =
704 Rule (linkExecutable opts objs libs bin)
707 -- Link a set of C++ object files and libraries together
709 linkCxx :: Options -> [String] -> [ String ] -> String -> HRule
710 linkCxx opts objs libs bin =
711 Rule (linkCxxExecutable opts objs libs bin)
714 -- Link a CPU driver. This is where it gets distinctly architecture-specific.
716 linkKernel :: Options -> String -> [String] -> [String] -> HRule
717 linkKernel opts name objs libs
718 | optArch opts == "x86_64" = X86_64.linkKernel opts objs [libraryPath l | l <- libs ] kernelPath
719 | optArch opts == "x86_32" = X86_32.linkKernel opts objs [libraryPath l | l <- libs ] kernelPath
720 | optArch opts == "scc" = SCC.linkKernel opts objs [libraryPath l | l <- libs ] kernelPath
721 | optArch opts == "arm" = ARM.linkKernel opts objs [libraryPath l | l <- libs ] kernelPath
722 | optArch opts == "arm11mp" = ARM11MP.linkKernel opts objs [libraryPath l | l <- libs ] kernelPath
723 | optArch opts == "beehive" = Beehive.linkKernel opts objs [libraryPath l | l <- libs ] kernelPath
724 | optArch opts == "xscale" = XScale.linkKernel opts objs [libraryPath l | l <- libs ] kernelPath
726 Rule [ Str ("Error: Can't link kernel for '" ++ (optArch opts) ++ "'") ]
729 -- Copy a file from one place to another
731 copy :: Options -> String -> String -> HRule
733 Rule [ Str "cp", In BuildTree (optArch opts) src, Out (optArch opts) dest ]
736 -- Assemble a list of S files for a particular architecture
738 assembleSFile :: Options -> String -> HRule
739 assembleSFile opts src =
740 Rules [ Rule (assemble opts src),
741 makeDependObj opts "src" src
744 assembleSFiles :: Options -> [String] -> HRule
745 assembleSFiles opts srcs = Rules [ assembleSFile opts s | s <- srcs ]
748 -- Archive a bunch of objects into a library
750 staticLibrary :: Options -> String -> [String] -> HRule
751 staticLibrary opts libpath objs =
752 Rule (archiveLibrary opts libpath objs)
755 -- Compile a Haskell binary (for the host architecture)
757 compileHaskell prog main deps = compileHaskellWithLibs prog main deps []
758 compileHaskellWithLibs prog main deps dirs =
759 Rule ([ NStr "ghc -i",
760 NoDep SrcTree "src" ".",
761 Str "-odir ", NoDep BuildTree "tools" ".",
762 Str "-hidir ", NoDep BuildTree "tools" ".",
764 In SrcTree "src" main,
766 Out "tools" ("/bin" ./. prog),
768 ++ concat [[ NStr "-i", NoDep SrcTree "src" d] | d <- dirs]
769 ++ [ (Dep SrcTree "src" dep) | dep <- deps ])
772 -- Compile (and link) a C binary (for the host architecture)
774 compileNativeC :: String -> [String] -> [String] -> [String] -> HRule
775 compileNativeC prog cfiles cflags ldflags =
776 Rule ([ Str nativeCCompiler,
778 Out "tools" ("/bin" ./. prog),
781 ++ [ (Str flag) | flag <- cflags ]
782 ++ [ (Str flag) | flag <- ldflags ]
783 ++ [ (In SrcTree "src" dep) | dep <- cfiles ])
786 -- Build a Technical Note
788 buildTechNote :: String -> String -> Bool -> Bool -> [String] -> HRule
789 buildTechNote input output bib glo figs =
790 buildTechNoteWithDeps input output bib glo figs []
791 buildTechNoteWithDeps :: String -> String -> Bool -> Bool -> [String] -> [RuleToken] -> HRule
792 buildTechNoteWithDeps input output bib glo figs deps =
794 working_dir = NoDep BuildTree "tools" "/tmp/"
795 style_files = [ "bfish-logo.pdf", "bftn.sty", "defs.bib", "barrelfish.bib" ]
797 Rule ( [ Dep SrcTree "src" (f ++ ".pdf") | f <- figs]
799 [ Dep SrcTree "src" ("/doc/style" ./. f) | f <- style_files ]
801 [ Str "mkdir", Str "-p", working_dir, NL ]
805 [ In SrcTree "src" "/tools/run-pdflatex.sh",
806 Str "--input-tex", In SrcTree "src" input,
807 Str "--working-dir", working_dir,
808 Str "--output-pdf", Out "docs" ("/" ++ output),
809 Str "--texinput", NoDep SrcTree "src" "/doc/style",
810 Str "--bibinput", NoDep SrcTree "src" "/doc/style"
812 ++ (if bib then [ Str "--has-bib" ] else [])
813 ++ (if glo then [ Str "--has-glo" ] else [])
816 ---------------------------------------------------------------------
818 -- Transformations on file names
820 ----------------------------------------------------------------------
822 allObjectPaths :: Options -> Args.Args -> [String]
823 allObjectPaths opts args =
824 [objectFilePath opts g
825 | g <- (Args.cFiles args)++(Args.cxxFiles args)++(Args.assemblyFiles args)]
827 [generatedObjectFilePath opts g
828 | g <- [ flounderBindingPath opts f
829 | f <- (Args.flounderBindings args)]
831 [ flounderExtraBindingPath opts f
832 | (f, _) <- (Args.flounderExtraBindings args)]
834 [ flounderTHCStubPath opts f
835 | f <- (Args.flounderTHCStubs args)]
838 allLibraryPaths :: Args.Args -> [String]
839 allLibraryPaths args =
840 [ libraryPath l | l <- Args.addLibraries args ]
843 ---------------------------------------------------------------------
845 -- Very large-scale macros
847 ----------------------------------------------------------------------
850 -- Build an application binary
853 application :: Args.Args
854 application = Args.defaultArgs { Args.buildFunction = applicationBuildFn }
856 applicationBuildFn :: [String] -> String -> Args.Args -> HRule
857 applicationBuildFn af tf args
858 | debugFlag && trace (Args.showArgs (tf ++ " Application ") args) False
860 applicationBuildFn af tf args =
861 Rules [ appBuildArch af tf args arch | arch <- Args.architectures args ]
863 appGetOptionsForArch arch args =
864 (options arch) { extraIncludes =
865 [ NoDep SrcTree "src" a | a <- Args.addIncludes args],
866 optIncludes = (optIncludes $ options arch) \\
867 [ NoDep SrcTree "src" i | i <- Args.omitIncludes args ],
868 optFlags = (optFlags $ options arch) \\
869 [ Str f | f <- Args.omitCFlags args ],
870 optCxxFlags = (optCxxFlags $ options arch) \\
871 [ Str f | f <- Args.omitCxxFlags args ],
872 optSuffix = "_for_app_" ++ Args.target args,
873 extraFlags = Args.addCFlags args ++ Args.addCxxFlags args,
874 extraLdFlags = [ Str f | f <- Args.addLinkFlags args ],
876 [Dep BuildTree arch s | s <- Args.addGeneratedDependencies args]
879 appBuildArch af tf args arch =
880 let -- Fiddle the options
881 opts = appGetOptionsForArch arch args
882 csrcs = Args.cFiles args
883 cxxsrcs = Args.cxxFiles args
884 appname = Args.target args
885 -- XXX: Not sure if this is correct. Currently assuming that if the app
886 -- contains C++ files, we have to use the C++ linker.
887 mylink = if cxxsrcs == [] then link else linkCxx
889 Rules ( flounderRules opts args csrcs
891 [ mackerelDependencies opts m csrcs | m <- Args.mackerelDevices args ]
893 [ compileCFiles opts csrcs,
894 compileCxxFiles opts cxxsrcs,
895 assembleSFiles opts (Args.assemblyFiles args),
896 mylink opts (allObjectPaths opts args) (allLibraryPaths args) appname
901 -- Build a static library
905 library = Args.defaultArgs { Args.buildFunction = libraryBuildFn }
907 libraryBuildFn :: [String] -> String -> Args.Args -> HRule
908 libraryBuildFn af tf args | debugFlag && trace (Args.showArgs (tf ++ " Library ") args) False = undefined
909 libraryBuildFn af tf args =
910 Rules [ libBuildArch af tf args arch | arch <- Args.architectures args ]
912 libGetOptionsForArch arch args =
913 (options arch) { extraIncludes =
914 [ NoDep SrcTree "src" a | a <- Args.addIncludes args],
915 optIncludes = (optIncludes $ options arch) \\
916 [ NoDep SrcTree "src" i | i <- Args.omitIncludes args ],
917 optFlags = (optFlags $ options arch) \\
918 [ Str f | f <- Args.omitCFlags args ],
919 optCxxFlags = (optCxxFlags $ options arch) \\
920 [ Str f | f <- Args.omitCxxFlags args ],
921 optSuffix = "_for_lib_" ++ Args.target args,
922 extraFlags = Args.addCFlags args ++ Args.addCxxFlags args,
924 [Dep BuildTree arch s | s <- Args.addGeneratedDependencies args]
927 libBuildArch af tf args arch =
928 let -- Fiddle the options
929 opts = libGetOptionsForArch arch args
930 csrcs = Args.cFiles args
931 cxxsrcs = Args.cxxFiles args
933 Rules ( flounderRules opts args csrcs
935 [ mackerelDependencies opts m csrcs | m <- Args.mackerelDevices args ]
937 [ compileCFiles opts csrcs,
938 compileCxxFiles opts cxxsrcs,
939 assembleSFiles opts (Args.assemblyFiles args),
940 staticLibrary opts (Args.target args) (allObjectPaths opts args)