blob: e0ff2d350a1317d65de89ad5a6673fb75d6fb9b6 [file] [log] [blame]
Galina Kistanova1e2edfc2016-08-08 22:08:21 +00001from buildbot.steps.shell import ShellCommand
Galina Kistanova1e2edfc2016-08-08 22:08:21 +00002from buildbot.steps.slave import RemoveDirectory
Galina Kistanovab3ff2752016-08-15 19:35:56 +00003from buildbot.process.properties import WithProperties
Galina Kistanova1e2edfc2016-08-08 22:08:21 +00004
5from zorg.buildbot.commands.CmakeCommand import CmakeCommand
6from zorg.buildbot.commands.NinjaCommand import NinjaCommand
7from zorg.buildbot.conditions.FileConditions import FileDoesNotExist
8from zorg.buildbot.process.factory import LLVMBuildFactory
9
10def _addSteps4SystemCompiler(
11 f,
12 stage_idx = 0,
13 clean = True,
14 jobs = None,
15 extra_configure_args = None,
16 env = None):
17
18 # Index is zero-based, so we want to use a human friendly number instead.
19 stage_num = stage_idx + 1
20
21 # Directories to use on this stage.
22 obj_dir = f.stage_objdirs[stage_idx]
23 src_dir = LLVMBuildFactory.pathRelativeToBuild(f.llvm_srcdir, obj_dir)
24 install_dir = LLVMBuildFactory.pathRelativeToBuild(f.stage_installdirs[stage_idx], obj_dir)
25
26 # This stage could use incremental build.
27 # Clean stage1, only if requested.
28 f.addStep(RemoveDirectory(name='clean-%s-dir' % obj_dir,
29 dir=obj_dir,
30 haltOnFailure=False,
31 flunkOnFailure=False,
32 doStepIf=clean
33 ))
34 f.addStep(RemoveDirectory(name='clean-%s-dir' % f.stage_installdirs[stage_idx],
35 dir=f.stage_installdirs[stage_idx],
36 haltOnFailure=False,
37 flunkOnFailure=False,
38 doStepIf=clean
39 ))
40
41 # Reconcile the cmake options for this stage.
42
43 # Make a local copy of the configure args, as we are going to modify that.
44 if extra_configure_args:
45 cmake_args = extra_configure_args[:]
46 else:
47 cmake_args = list()
48
49 # Set proper defaults.
50 CmakeCommand.applyDefaultOptions(cmake_args, [
51 ('-DCMAKE_BUILD_TYPE=', 'Release'),
52 ('-DCLANG_BUILD_EXAMPLES=', 'OFF'),
53 ('-DLLVM_BUILD_TESTS=', 'ON'),
54 ('-DLLVM_ENABLE_ASSERTIONS=', 'OFF'),
55 ('-DLLVM_OPTIMIZED_TABLEGEN=', 'ON'),
56 # Do not expect warning free build by the system toolchain.
57 ('-DLLVM_ENABLE_WERROR=', 'OFF'),
58 ('-DCMAKE_COLOR_MAKEFILE=', 'OFF'),
59 ])
60
61 # Some options are required for this stage no matter what.
62 CmakeCommand.applyRequiredOptions(cmake_args, [
63 ('-G', 'Unix Makefiles'),
64 ('-DCMAKE_INSTALL_PREFIX=', install_dir),
65 ])
66
67 # Note: On this stage we do not care of warnings, as we build with
68 # a system toolchain and cannot control the environment.
69 # Warnings are likely, and we ignore them.
70
71 # Create configuration files with cmake
72 f.addStep(CmakeCommand(name="cmake-configure-stage%s" % stage_num,
73 description=["stage%s cmake configure" % stage_num],
74 haltOnFailure=True,
75 flunkOnWarnings=False,
76 options=cmake_args,
77 path=src_dir,
78 env=env,
79 workdir=obj_dir,
80 doStepIf=FileDoesNotExist("CMakeCache.txt")))
81
82 # Build clang by the system compiler
83 f.addStep(ShellCommand(name="build-stage%s-compiler"% stage_num,
84 command=['make', WithProperties("-j%s" % jobs), "-k"],
85 haltOnFailure=True,
86 flunkOnWarnings=False,
87 description=["build stage%s compiler" % stage_num],
88 env=env,
89 workdir=obj_dir))
90
91 # Test stage1 compiler
92 f.addStep(ShellCommand(name="test-stage%s-compiler"% stage_num,
93 command=["make", WithProperties("-j%s" % jobs), "check-all"], # or "check-llvm", "check-clang"
94 haltOnFailure=True,
95 flunkOnWarnings=False,
96 description=["test stage%s compiler" % stage_num],
97 env=env,
98 workdir=obj_dir))
99
100 # Install stage1 compiler
101 f.addStep(ShellCommand(name="install-stage%s-compiler"% stage_num,
102 command=["make", WithProperties("-j%s" % jobs), "install"],
103 haltOnFailure=True,
104 flunkOnWarnings=False,
105 description=["install stage%s compiler" % stage_num],
106 env=env,
107 workdir=obj_dir))
108
109
110def _addSteps4StagedCompiler(
111 f,
112 stage_idx = 1,
113 use_stage_idx = -1,
114 withLTOSupport = False,
115 jobs = None,
116 extra_configure_args = None,
117 env = None):
118
119 if use_stage_idx < 0:
120 use_stage_idx = stage_idx - 1
121
122 # Index is zero-based, so we want to use a human friendly number instead.
123 stage_num = stage_idx + 1
124
125 # Directories to use on this stage.
126 obj_dir = f.stage_objdirs[stage_idx]
127 src_dir = LLVMBuildFactory.pathRelativeToBuild(f.llvm_srcdir, obj_dir)
128 install_dir = LLVMBuildFactory.pathRelativeToBuild(f.stage_installdirs[stage_idx], obj_dir)
Galina Kistanovab3ff2752016-08-15 19:35:56 +0000129 staged_install = f.stage_installdirs[use_stage_idx]
Galina Kistanova1e2edfc2016-08-08 22:08:21 +0000130
131 # Always do a clean build for the staged compiler.
132 f.addStep(RemoveDirectory(name='clean-%s-dir' % obj_dir,
133 dir=obj_dir,
134 haltOnFailure=False,
135 flunkOnFailure=False,
136 ))
137
138 f.addStep(RemoveDirectory(name='clean-%s-dir' % f.stage_installdirs[stage_idx],
139 dir=f.stage_installdirs[stage_idx],
140 haltOnFailure=False,
141 flunkOnFailure=False,
142 ))
143
144 # Reconcile the cmake options for this stage.
145
146 # Make a local copy of the configure args, as we are going to modify that.
147 if extra_configure_args:
148 cmake_args = extra_configure_args[:]
149 else:
150 cmake_args = list()
151
152 # Set proper defaults.
153 CmakeCommand.applyDefaultOptions(cmake_args, [
154 ('-DCMAKE_BUILD_TYPE=', 'Release'),
155 ('-DCLANG_BUILD_EXAMPLES=', 'OFF'),
156 ('-DLLVM_BUILD_TESTS=', 'ON'),
157 ('-DLLVM_ENABLE_ASSERTIONS=', 'ON'),
158 ('-DLLVM_OPTIMIZED_TABLEGEN=', 'ON'),
Galina Kistanova1e2edfc2016-08-08 22:08:21 +0000159 ])
Galina Kistanovab3ff2752016-08-15 19:35:56 +0000160 if withLTOSupport:
161 CmakeCommand.applyDefaultOptions(cmake_args, [
162 # LTO Plugin dependency:
163 ('-DLLVM_BINUTILS_INCDIR=', '/opt/binutils/include'),
164 ])
Galina Kistanova1e2edfc2016-08-08 22:08:21 +0000165
166 # Some options are required for this stage no matter what.
167 CmakeCommand.applyRequiredOptions(cmake_args, [
168 ('-G', 'Ninja'),
169 ('-DCMAKE_INSTALL_PREFIX=', install_dir),
Galina Kistanova1e2edfc2016-08-08 22:08:21 +0000170 ])
171
Galina Kistanovab3ff2752016-08-15 19:35:56 +0000172 cmake_args.append(
173 WithProperties(
174 "-DCMAKE_CXX_COMPILER=%(workdir)s/" + staged_install + "/bin/clang++"
175 ))
176 cmake_args.append(
177 WithProperties(
178 "-DCMAKE_C_COMPILER=%(workdir)s/" + staged_install + "/bin/clang"
179 ))
180
Galina Kistanova1e2edfc2016-08-08 22:08:21 +0000181 # Create configuration files with cmake
182 f.addStep(CmakeCommand(name="cmake-configure-stage%s" % stage_num,
183 description=["stage%s cmake configure" % stage_num],
184 haltOnFailure=True,
185 options=cmake_args,
186 path=src_dir,
187 env=env,
188 workdir=obj_dir,
189 doStepIf=FileDoesNotExist("CMakeCache.txt")
190 ))
191 if withLTOSupport:
192 # Build LTO plugin if requested.
193 f.addStep(NinjaCommand(name="build-stage%s-LLVMgold.so" % stage_num,
194 targets=['lib/LLVMgold.so'],
195 haltOnFailure=True,
196 description=["stage%s build LLVMgold.so" % stage_num],
197 env=env,
198 workdir=obj_dir,
199 ))
200
201 # Build clang by the staged compiler
202 f.addStep(NinjaCommand(name="build-stage%s-compiler" % stage_num,
203 haltOnFailure=True,
204 description=["build stage%s compiler" % stage_num],
Galina Kistanovab3ff2752016-08-15 19:35:56 +0000205 timeout=10800, # LTO could take time.
Galina Kistanova1e2edfc2016-08-08 22:08:21 +0000206 env=env,
207 workdir=obj_dir,
208 ))
209
210 # Test just built compiler
211 f.addStep(NinjaCommand(name="test-stage%s-compiler"% stage_num,
212 targets=["check-all"],
213 haltOnFailure=True,
214 description=["test stage%s compiler" % stage_num],
Galina Kistanovab3ff2752016-08-15 19:35:56 +0000215 timeout=10800, # LTO could take time.
Galina Kistanova1e2edfc2016-08-08 22:08:21 +0000216 env=env,
217 workdir=obj_dir,
218 ))
219
220 # Install just built compiler
221 f.addStep(NinjaCommand(name="install-stage%s-compiler"% stage_num,
222 targets=["install"],
223 haltOnFailure=True,
224 description=["install stage%s compiler" % stage_num],
Galina Kistanovab3ff2752016-08-15 19:35:56 +0000225 timeout=10800, # LTO could take time.
Galina Kistanova1e2edfc2016-08-08 22:08:21 +0000226 env=env,
227 workdir=obj_dir,
228 ))
229
230
231def getClangWithLTOBuildFactory(
Galina Kistanova9a7a1b62016-10-16 05:02:20 +0000232 depends_on_projects = None,
Galina Kistanova1e2edfc2016-08-08 22:08:21 +0000233 clean = False,
234 jobs = None,
235 extra_configure_args = None,
236 compare_last_2_stages = True,
Galina Kistanova83d12a92016-10-13 19:32:23 +0000237 lto = None, # The string gets passed to -flto flag as is. Like -flto=thin.
Galina Kistanova1e2edfc2016-08-08 22:08:21 +0000238 env = None):
239
240 # Set defaults
Galina Kistanova9a7a1b62016-10-16 05:02:20 +0000241 if depends_on_projects:
242 depends_on_projects = list(depends_on_projects)
243 else:
244 # By default we link with LLD.
245 depends_on_projects = ['llvm', 'clang', 'lld']
246
Galina Kistanova1e2edfc2016-08-08 22:08:21 +0000247 if jobs is None:
248 jobs = "%(jobs)s"
249
250 if extra_configure_args is None:
251 extra_configure_args = []
Galina Kistanova17d62422016-10-20 18:41:02 +0000252 else:
253 extra_configure_args = list(extra_configure_args)
Galina Kistanova1e2edfc2016-08-08 22:08:21 +0000254
255 # Make sure CMAKE_INSTALL_PREFIX and -G are not specified
256 # in the extra_configure_args. We set them internally as needed.
257 # TODO: assert extra_configure_args.
258 install_prefix_specified = any(a.startswith('-DCMAKE_INSTALL_PREFIX=') for a in extra_configure_args)
259 assert True, "Please do not explicitly specify the install prefix for multi-stage build."
260
261 # Prepare environmental variables. Set here all env we want everywhere.
262 merged_env = {
263 'TERM' : 'dumb' # Be cautious and disable color output from all tools.
264 }
265 if env is not None:
266 # Overwrite pre-set items with the given ones, so user can set anything.
267 merged_env.update(env)
268
269 f = LLVMBuildFactory(
Galina Kistanova9a7a1b62016-10-16 05:02:20 +0000270 depends_on_projects=depends_on_projects,
Galina Kistanova1e2edfc2016-08-08 22:08:21 +0000271 llvm_srcdir="llvm.src",
272 stage_objdirs=[
273 "build/stage1",
274 "build/stage2",
275 "build/stage3",
276 "build/stage4",
277 ],
278 stage_installdirs=[
279 "install/stage1",
280 "install/stage2",
281 "install/stage3",
282 "install/stage4",
283 ],
284 staged_compiler_idx = 1)
285
286 cleanBuildRequested = lambda step: step.build.getProperty("clean") or clean
287
288 # Do a clean checkout if requested.
289 f.addStep(RemoveDirectory(name='clean-src-dir',
290 dir=f.llvm_srcdir,
291 haltOnFailure=False,
292 flunkOnFailure=False,
293 doStepIf=cleanBuildRequested,
294 ))
295
296 # Get the source code.
297 f.addSVNSteps()
298
299 # Build with the system compiler first
300 _addSteps4SystemCompiler(f,
301 stage_idx=0,
302 clean=cleanBuildRequested,
303 jobs=jobs,
304 extra_configure_args=extra_configure_args,
305 env=merged_env)
306
307 # Then build the compiler we would use for the bootstrap.
308 _addSteps4StagedCompiler(f,
309 stage_idx=1,
310 withLTOSupport=True,
311 jobs=jobs,
312 extra_configure_args=extra_configure_args,
313 env=merged_env)
314
315 # Build all the remaining stages with exactly the same configuration.
316
Galina Kistanova17d62422016-10-20 18:41:02 +0000317 CmakeCommand.applyRequiredOptions(extra_configure_args, [
318 ('-DLLVM_ENABLE_LTO=', lto.upper() or 'ON'),
Galina Kistanova1e2edfc2016-08-08 22:08:21 +0000319 ])
320
Galina Kistanova17d62422016-10-20 18:41:02 +0000321 # If we build LLD, we would link with LLD.
322 # Otherwise we link with the system linker.
323 if 'lld' in depends_on_projects:
324 CmakeCommand.applyRequiredOptions(extra_configure_args, [
325 ('-DLLVM_ENABLE_LLD=', 'ON'),
326 ])
327
Galina Kistanova1e2edfc2016-08-08 22:08:21 +0000328 # The rest are test stages, which depend on the staged compiler we are ultimately after.
329 s = f.staged_compiler_idx + 1
Galina Kistanovab3ff2752016-08-15 19:35:56 +0000330 staged_install = f.stage_installdirs[f.staged_compiler_idx]
Galina Kistanova1e2edfc2016-08-08 22:08:21 +0000331 for i in range(s, len(f.stage_objdirs[s:]) + s):
332 configure_args = extra_configure_args[:]
333
Galina Kistanovab3ff2752016-08-15 19:35:56 +0000334 configure_args.append(
335 WithProperties(
336 "-DCMAKE_AR=%(workdir)s/" + staged_install + "/bin/llvm-ar"
337 ))
338 configure_args.append(
339 WithProperties(
340 "-DCMAKE_RANLIB=%(workdir)s/" + staged_install + "/bin/llvm-ranlib"
341 ))
Galina Kistanova1e2edfc2016-08-08 22:08:21 +0000342
343 _addSteps4StagedCompiler(f,
344 stage_idx=i,
345 use_stage_idx=f.staged_compiler_idx,
346 jobs=jobs,
347 extra_configure_args=configure_args,
348 env=merged_env)
349
350 if compare_last_2_stages:
351 # Compare the compilers built on the last 2 stages if requested.
352 diff_command = [
353 "diff",
354 "-q",
Galina Kistanovab3ff2752016-08-15 19:35:56 +0000355 f.stage_installdirs[-2] + "/bin/clang",
356 f.stage_installdirs[-1] + "/bin/clang",
Galina Kistanova1e2edfc2016-08-08 22:08:21 +0000357 ]
358 f.addStep(
359 ShellCommand(
360 name="compare-compilers",
361 description=[
362 "compare",
363 "stage%d" % (len(f.stage_installdirs)-1),
364 "and",
365 "stage%d" % len(f.stage_installdirs),
366 "compilers",
367 ],
368 haltOnFailure=True,
369 command=WithProperties(" ".join(diff_command)),
370 workdir=".",
371 env=merged_env
372 )
373 )
374
375 return f