1 ##########################################################################
2 # Copyright (c) 2009, 2010, 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, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group.
8 ##########################################################################
14 MPSS_LINUX_PATH=':/opt/mpss/3.7.1/sysroots/x86_64-mpsssdk-linux/usr/bin:/opt/mpss/3.7.1/sysroots/x86_64-mpsssdk-linux/usr/bin/k1om-mpss-linux'
18 name = None # should be overriden by a subclass
20 def __init__(self, options):
22 self.options = options
24 def _make_build_dir(self, build_dir=None):
26 build_dir = os.path.join(self.options.buildbase, self.name.lower())
27 self.build_dir = build_dir
28 debug.verbose('creating build directory %s' % build_dir)
30 os.makedirs(build_dir)
32 if e.errno == errno.EEXIST:
33 debug.log("reusing existing build in directory %s" % build_dir)
37 def configure(self, checkout):
38 raise NotImplementedError
40 def build(self, targets):
41 raise NotImplementedError
43 def install(self, targets, path):
44 """install to the given path"""
45 raise NotImplementedError
48 class HakeBuildBase(Build):
49 def _run_hake(self, srcdir, archs):
50 # if srcdir is relative, adjust to be wrt build_dir
52 if not os.path.isabs(srcdir):
53 srcdir = os.path.relpath(srcdir, self.build_dir)
54 debug.checkcmd([os.path.join(srcdir, "hake", "hake.sh"), "--source-dir", srcdir],
57 def _get_hake_conf(self, srcdir, archs):
59 "source_dir": "\"%s\"" % srcdir,
60 "architectures": "[" + ", ".join("\"%s\"" % a for a in archs) + "]",
61 "install_dir": "\".\"",
62 "toolroot": "Nothing",
63 "arm_toolspec": "Nothing",
64 "aarch64_toolspec": "Nothing",
65 "thumb_toolspec": "Nothing",
66 "armeb_toolspec": "Nothing",
67 "x86_toolspec": "Nothing",
68 "k1om_toolspec": "Nothing",
69 "cache_dir": "\"%s\"" % os.path.expanduser("~/.cache/barrelfish/"),
70 "hagfish_location" : "\"%s\"" % siteconfig.get('HAGFISH_LOCATION')
74 def _write_hake_conf(self, srcdir, archs):
76 hakedir = os.path.join(self.build_dir, 'hake')
77 if not os.path.isdir(hakedir):
80 # read default config template
81 with open(os.path.join(srcdir, 'hake', 'Config.hs.template')) as fh:
82 conf_template = fh.readlines()
84 # if srcdir is relative, adjust to be wrt build_dir
85 if os.path.isabs(srcdir):
88 rel_srcdir = os.path.relpath(srcdir, self.build_dir)
90 # get custom configuration options as a dictionary
91 conf = self._get_hake_conf(rel_srcdir, archs)
93 # create a new config file: template and then local options
95 for line in conf_template:
96 # XXX: exclude options from the defaults that are set locally
97 # where is the haskell parsing library for python? :)
98 if any([line.startswith(k) and re.match(' +=', line[len(k):])
99 for k in conf.keys()]):
102 newconf.extend(['\n', '\n', '-- Added by test harness:\n'])
103 for item in conf.items():
104 newconf.append("%s = %s\n" % item)
106 # write it, only if it's different or the old one doesn't exist
108 with open(os.path.join(hakedir, 'Config.hs'), 'r') as fh:
109 if fh.readlines() == newconf:
110 return # identical files
114 with open(os.path.join(hakedir, 'Config.hs'), 'w') as fh:
115 fh.writelines(newconf)
117 def configure(self, checkout, archs):
118 srcdir = checkout.get_base_dir()
119 environ = dict(os.environ)
121 environ['PATH'] = environ['PATH'] + MPSS_LINUX_PATH
122 self._make_build_dir()
123 self._write_hake_conf(srcdir, archs)
124 self._run_hake(srcdir, archs)
126 # this should be a nop -- building it here causes us to stop early
127 # with any tool or dependency-generation errors before doing test setup
128 self.build(["Makefile"], env=environ)
132 def split_reduce_env(state, c):
133 if not state[0] and c == '\\':
134 return True, state[1]
135 elif not state[0] and c.isspace():
139 s = ec.decode('string_escape')
141 # decode had no effect, just drop backslash
146 return False, state[1]
149 e = reduce(split_reduce_env, e, (False, ['']))[1]
153 def build(self, targets, **kwargs):
154 makeopts = self.split_env(os.environ.get('MAKEOPTS', ''))
155 debug.checkcmd(["make"] + makeopts + targets, cwd=self.build_dir, **kwargs)
157 def install(self, targets, path):
158 debug.checkcmd(["make", "install",
159 "INSTALL_PREFIX=%s" % path,
160 "MODULES=%s" % (" ".join(targets))],
164 class HakeReleaseBuild(HakeBuildBase):
165 """Release build (optimisations, no debug information)"""
168 def _get_hake_conf(self, *args):
169 conf = super(HakeReleaseBuild, self)._get_hake_conf(*args)
170 conf["cOptFlags"] = "[\"-O2\", \"-DNDEBUG\", \"-Wno-unused-variable\"]"
173 class HakeTestBuild(HakeBuildBase):
174 """Test build (optimisations, no debug symbols, but assertions enabled)"""
177 def _get_hake_conf(self, *args):
178 conf = super(HakeTestBuild, self)._get_hake_conf(*args)
179 conf["cOptFlags"] = "[\"-O2\"]"
182 class HakeReleaseTraceBuild(HakeBuildBase):
183 """optimisations, no debug information, and tracing """
184 name = 'release_trace'
186 def _get_hake_conf(self, *args):
187 conf = super(HakeReleaseBuild, self)._get_hake_conf(*args)
188 conf["cOptFlags"] = "[\"-O2\", \"-DNDEBUG\"]"
189 conf["trace"] = "True"
192 class HakeTestMdbInvariantsBuild(HakeTestBuild):
193 """optimisations, no debug symbols, assertions and MDB invariant checking enabled"""
194 name = 'test_mdbinvariants'
196 def _get_hake_conf(self, *args):
197 conf = super(HakeTestMdbInvariantsBuild, self)._get_hake_conf(*args)
198 conf["mdb_check_invariants"] = "True"
201 class HakeDebugBuild(HakeBuildBase):
202 """Default Hake build: debug symbols, optimisations, assertions"""
205 def _get_hake_conf(self, *args):
206 conf = super(HakeDebugBuild, self)._get_hake_conf(*args)
207 conf["cOptFlags"] = "[\"-O2\", \"-g\"]"
210 class HakeDebugTraceBuild(HakeBuildBase):
211 """debug symbols, optimisations, assertions, and tracing"""
214 def _get_hake_conf(self, *args):
215 conf = super(HakeDebugTraceBuild, self)._get_hake_conf(*args)
216 conf["cOptFlags"] = "[\"-O2\"]"
217 conf["trace"] = "True"
221 all_builds = [HakeReleaseBuild, HakeTestBuild, HakeDebugBuild, HakeReleaseTraceBuild,
222 HakeTestMdbInvariantsBuild, HakeDebugTraceBuild]
225 class ExistingBuild(HakeBuildBase):
226 '''Dummy build class for an existing Hake build dir.'''
229 def __init__(self, options, build_dir):
230 super(ExistingBuild, self).__init__(options)
231 debug.verbose('using existing build directory %s' % build_dir)
232 self.build_dir = build_dir
234 def configure(self, *args):
238 def existingbuild(*args):
239 """construct the build class for an existing build"""
240 return ExistingBuild(*args)