blob: 80e2e869c60eb08208237681f797d88aacc3fbdf [file] [log] [blame]
Galina Kistanova0035b5d2016-10-07 20:47:51 +00001from buildbot.steps.slave import RemoveDirectory
Galina Kistanova8358cdd2017-03-10 01:06:35 +00002from buildbot.process.properties import WithProperties, Property
3from buildbot.steps.shell import SetProperty
Galina Kistanova0035b5d2016-10-07 20:47:51 +00004
5from zorg.buildbot.commands.CmakeCommand import CmakeCommand
6from zorg.buildbot.commands.NinjaCommand import NinjaCommand
Galina Kistanova0035b5d2016-10-07 20:47:51 +00007
8from zorg.buildbot.conditions.FileConditions import FileDoesNotExist
9from zorg.buildbot.process.factory import LLVMBuildFactory
10
Galina Kistanova8358cdd2017-03-10 01:06:35 +000011import zorg.buildbot.builders.Util as builders_util
12
Galina Kistanova9124b832016-12-22 00:46:41 +000013def getLLVMBuildFactoryAndSVNSteps(
Galina Kistanova0035b5d2016-10-07 20:47:51 +000014 depends_on_projects = None,
15 llvm_srcdir = None,
16 obj_dir = None,
17 install_dir = None,
Galina Kistanova9124b832016-12-22 00:46:41 +000018 cleanBuildRequested = None,
Galina Kistanova0035b5d2016-10-07 20:47:51 +000019 env = None,
20 **kwargs):
21
Galina Kistanova53f05f32017-05-03 20:22:21 +000022 def cleanBuildRequestedByProperty(step):
23 return step.build.getProperty("clean")
24
Galina Kistanova0035b5d2016-10-07 20:47:51 +000025 # Set defaults
26 if not depends_on_projects:
27 depends_on_projects=['llvm', 'clang']
28
Galina Kistanova9124b832016-12-22 00:46:41 +000029 if cleanBuildRequested is None:
Galina Kistanova53f05f32017-05-03 20:22:21 +000030 cleanBuildRequested = cleanBuildRequestedByProperty
Galina Kistanova0035b5d2016-10-07 20:47:51 +000031
32 f = LLVMBuildFactory(
33 depends_on_projects=depends_on_projects,
Galina Kistanova9124b832016-12-22 00:46:41 +000034 llvm_srcdir=llvm_srcdir or "llvm",
35 obj_dir=obj_dir or "build",
Galina Kistanova0035b5d2016-10-07 20:47:51 +000036 install_dir=install_dir,
37 cleanBuildRequested=cleanBuildRequested,
Galina Kistanova9124b832016-12-22 00:46:41 +000038 **kwargs) # Pass through all the extra arguments.
Galina Kistanova0035b5d2016-10-07 20:47:51 +000039
Galina Kistanova53f05f32017-05-03 20:22:21 +000040 # Do a clean checkout if requested by a build property.
Galina Kistanova9124b832016-12-22 00:46:41 +000041 # TODO: Some Windows slaves do not handle RemoveDirectory command well.
42 # So, consider running "rmdir /S /Q <dir>" if the build runs on Windows.
Galina Kistanova0035b5d2016-10-07 20:47:51 +000043 f.addStep(RemoveDirectory(name='clean-src-dir',
44 dir=f.llvm_srcdir,
45 haltOnFailure=False,
46 flunkOnFailure=False,
Galina Kistanova53f05f32017-05-03 20:22:21 +000047 doStepIf=cleanBuildRequestedByProperty,
Galina Kistanova0035b5d2016-10-07 20:47:51 +000048 ))
49
50 # Get the source code.
51 f.addSVNSteps()
52
Galina Kistanova9124b832016-12-22 00:46:41 +000053 return f
Galina Kistanova0035b5d2016-10-07 20:47:51 +000054
Galina Kistanova9124b832016-12-22 00:46:41 +000055def addCmakeSteps(
56 f,
57 cleanBuildRequested,
58 obj_dir,
59 install_dir = None,
60 extra_configure_args = None,
61 env = None,
62 stage_name = None,
63 **kwargs):
Galina Kistanova0035b5d2016-10-07 20:47:51 +000064
65 # Make a local copy of the configure args, as we are going to modify that.
66 if extra_configure_args:
67 cmake_args = extra_configure_args[:]
68 else:
69 cmake_args = list()
70
Galina Kistanova9124b832016-12-22 00:46:41 +000071 # This is an incremental build, unless otherwise has been requested.
72 # Remove obj and install dirs for a clean build.
73 # TODO: Some Windows slaves do not handle RemoveDirectory command well.
74 # So, consider running "rmdir /S /Q <dir>" if the build runs on Windows.
75 f.addStep(RemoveDirectory(name='clean-%s-dir' % obj_dir,
76 dir=obj_dir,
77 haltOnFailure=False,
78 flunkOnFailure=False,
79 doStepIf=cleanBuildRequested,
80 ))
81
82 if install_dir:
83 install_dir_rel = LLVMBuildFactory.pathRelativeToBuild(
84 install_dir,
85 obj_dir)
86 CmakeCommand.applyRequiredOptions(cmake_args, [
87 ('-DCMAKE_INSTALL_PREFIX=', install_dir_rel),
88 ])
89
90 f.addStep(RemoveDirectory(name='clean-%s-dir' % install_dir,
91 dir=install_dir,
92 haltOnFailure=False,
93 flunkOnFailure=False,
94 doStepIf=cleanBuildRequested,
95 ))
96
97 # Reconcile the cmake options for this build.
98
Galina Kistanova0035b5d2016-10-07 20:47:51 +000099 # Set proper defaults.
100 CmakeCommand.applyDefaultOptions(cmake_args, [
101 ('-DCMAKE_BUILD_TYPE=', 'Release'),
102 ('-DCLANG_BUILD_EXAMPLES=', 'OFF'),
103 ('-DLLVM_BUILD_TESTS=', 'ON'),
104 ('-DLLVM_ENABLE_ASSERTIONS=', 'ON'),
105 ('-DLLVM_OPTIMIZED_TABLEGEN=', 'ON'),
Galina Kistanova958820f2017-04-29 02:38:35 +0000106 ('-DLLVM_LIT_ARGS=', '"-v"'),
Galina Kistanova0035b5d2016-10-07 20:47:51 +0000107 ])
108
109 # Create configuration files with cmake, unless this has been already done
110 # for an incremental build.
Galina Kistanova9124b832016-12-22 00:46:41 +0000111 if stage_name:
112 step_name = "cmake-configure-%s" % stage_name
113 else:
Galina Kistanova40b9ed52017-03-10 07:56:38 +0000114 stage_name = ""
Galina Kistanova9124b832016-12-22 00:46:41 +0000115 step_name = "cmake-configure"
116
117 src_dir = LLVMBuildFactory.pathRelativeToBuild(f.llvm_srcdir, obj_dir)
118
119 f.addStep(CmakeCommand(name=step_name,
120 description=["Cmake", "configure", stage_name],
Galina Kistanova9975c382017-01-03 04:10:02 +0000121 haltOnFailure=True,
Galina Kistanova0035b5d2016-10-07 20:47:51 +0000122 options=cmake_args,
123 path=src_dir,
124 env=env,
125 workdir=obj_dir,
126 doStepIf=FileDoesNotExist("CMakeCache.txt"),
127 **kwargs # Pass through all the extra arguments.
128 ))
129
Galina Kistanova9124b832016-12-22 00:46:41 +0000130def addNinjaSteps(
131 f,
Galina Kistanova0035b5d2016-10-07 20:47:51 +0000132 obj_dir = None,
Galina Kistanova9124b832016-12-22 00:46:41 +0000133 env = None,
134 stage_name = None,
135 **kwargs):
136
137 # Build the unified tree.
138 if stage_name:
139 step_name = "%s-" % stage_name
140 else:
Galina Kistanova40b9ed52017-03-10 07:56:38 +0000141 stage_name = ""
Galina Kistanova9124b832016-12-22 00:46:41 +0000142 step_name = ""
143
144 if obj_dir is None:
145 obj_dir = f.obj_dir
146
147 f.addStep(NinjaCommand(name="build-%sunified-tree" % step_name,
Galina Kistanova9975c382017-01-03 04:10:02 +0000148 haltOnFailure=True,
Galina Kistanova9124b832016-12-22 00:46:41 +0000149 description=["Build", stage_name, "unified", "tree"],
150 env=env,
151 workdir=obj_dir,
152 **kwargs # Pass through all the extra arguments.
153 ))
154
155 # Test just built components
156 f.addStep(NinjaCommand(name="test-%scheck-all" % step_name,
157 targets=["check-all"],
Galina Kistanova9975c382017-01-03 04:10:02 +0000158 haltOnFailure=True,
Galina Kistanova9124b832016-12-22 00:46:41 +0000159 description=["Test", "just", "built", "components"],
160 env=env,
161 workdir=obj_dir,
162 **kwargs # Pass through all the extra arguments.
163 ))
164
165 # Install just built components
166 f.addStep(NinjaCommand(name="install-%sall" % step_name,
167 targets=["install"],
Galina Kistanova9975c382017-01-03 04:10:02 +0000168 haltOnFailure=True,
Galina Kistanova9124b832016-12-22 00:46:41 +0000169 description=["Install", "just", "built", "components"],
170 env=env,
171 workdir=obj_dir,
172 **kwargs # Pass through all the extra arguments.
173 ))
174
175def getCmakeBuildFactory(
176 depends_on_projects = None,
177 llvm_srcdir = None,
178 obj_dir = None,
179 install_dir = None,
Galina Kistanova0035b5d2016-10-07 20:47:51 +0000180 clean = False,
181 extra_configure_args = None,
182 env = None,
183 **kwargs):
184
Galina Kistanova9124b832016-12-22 00:46:41 +0000185 # Prepare environmental variables. Set here all env we want everywhere.
186 merged_env = {
187 'TERM' : 'dumb' # Be cautious and disable color output from all tools.
188 }
189 if env is not None:
190 # Overwrite pre-set items with the given ones, so user can set anything.
191 merged_env.update(env)
192
Galina Kistanova958820f2017-04-29 02:38:35 +0000193 cleanBuildRequested = lambda step: clean or step.build.getProperty("clean")
Galina Kistanova9124b832016-12-22 00:46:41 +0000194
195 f = getLLVMBuildFactoryAndSVNSteps(
196 depends_on_projects=depends_on_projects,
197 llvm_srcdir=llvm_srcdir,
198 obj_dir=obj_dir,
199 install_dir=install_dir,
Galina Kistanova958820f2017-04-29 02:38:35 +0000200 # We want a clean checkout only if requested by the property.
Galina Kistanova53f05f32017-05-03 20:22:21 +0000201 cleanBuildRequested=cleanBuildRequested,
Galina Kistanova9124b832016-12-22 00:46:41 +0000202 **kwargs) # Pass through all the extra arguments.
203
204 addCmakeSteps(
205 f,
206 cleanBuildRequested=cleanBuildRequested,
207 obj_dir=f.obj_dir,
208 install_dir=f.install_dir,
209 extra_configure_args=extra_configure_args,
210 env=env,
211 **kwargs)
212
213 return f
214
Galina Kistanova8358cdd2017-03-10 01:06:35 +0000215
Galina Kistanova9124b832016-12-22 00:46:41 +0000216def getCmakeWithNinjaBuildFactory(
217 depends_on_projects = None,
218 llvm_srcdir = None,
219 obj_dir = None,
220 install_dir = None,
221 clean = False,
222 extra_configure_args = None,
223 env = None,
224 **kwargs):
Galina Kistanova0035b5d2016-10-07 20:47:51 +0000225
226 # Make a local copy of the configure args, as we are going to modify that.
227 if extra_configure_args:
228 cmake_args = extra_configure_args[:]
229 else:
230 cmake_args = list()
231
Galina Kistanova0035b5d2016-10-07 20:47:51 +0000232 # Some options are required for this build no matter what.
233 CmakeCommand.applyRequiredOptions(cmake_args, [
234 ('-G', 'Ninja'),
235 ])
236
237 f = getCmakeBuildFactory(
238 depends_on_projects=depends_on_projects,
239 llvm_srcdir=llvm_srcdir,
240 obj_dir=obj_dir,
Galina Kistanova9124b832016-12-22 00:46:41 +0000241 install_dir=install_dir,
242 clean=clean,
Galina Kistanova0035b5d2016-10-07 20:47:51 +0000243 extra_configure_args=cmake_args,
244 env=env,
Galina Kistanova9124b832016-12-22 00:46:41 +0000245 **kwargs) # Pass through all the extra arguments.
Galina Kistanova0035b5d2016-10-07 20:47:51 +0000246
Galina Kistanova9124b832016-12-22 00:46:41 +0000247 addNinjaSteps(
248 f,
249 obj_dir=obj_dir,
250 env=env,
251 **kwargs)
Galina Kistanova0035b5d2016-10-07 20:47:51 +0000252
253 return f
254
Galina Kistanova8358cdd2017-03-10 01:06:35 +0000255def getCmakeWithNinjaWithMSVCBuildFactory(
256 depends_on_projects = None,
257 llvm_srcdir = None,
258 obj_dir = None,
259 install_dir = None,
260 clean = False,
261 extra_configure_args = None,
262 # VS tools environment variable if using MSVC. For example,
263 # %VS140COMNTOOLS% selects the 2015 toolchain.
264 vs=None,
265 target_arch=None,
266 env = None,
267 **kwargs):
268
269 assert not env, "Can't have custom builder env vars with MSVC build"
270
271 # Make a local copy of the configure args, as we are going to modify that.
272 if extra_configure_args:
273 cmake_args = extra_configure_args[:]
274 else:
275 cmake_args = list()
276
277 # Set up VS environment, if appropriate.
278 if not vs:
279 # We build by Visual Studio 2015, unless otherwise is requested.
280 vs=r"""%VS140COMNTOOLS%"""
281
282 cleanBuildRequested = lambda step: step.build.getProperty("clean") or clean
283
284 f = getLLVMBuildFactoryAndSVNSteps(
285 depends_on_projects=depends_on_projects,
286 llvm_srcdir=llvm_srcdir,
287 obj_dir=obj_dir,
288 install_dir=install_dir,
289 cleanBuildRequested=cleanBuildRequested,
290 **kwargs) # Pass through all the extra arguments.
291
292 f.addStep(SetProperty(
293 command=builders_util.getVisualStudioEnvironment(vs, target_arch),
294 extract_fn=builders_util.extractSlaveEnvironment))
295 env = Property('slave_env')
296
297 # Some options are required for this build no matter what.
298 CmakeCommand.applyRequiredOptions(cmake_args, [
299 ('-G', 'Ninja'),
300 ])
301
302 addCmakeSteps(
303 f,
304 f.cleanBuildRequested,
305 obj_dir=f.obj_dir,
306 install_dir=f.install_dir,
307 extra_configure_args=cmake_args,
308 env=env,
309 **kwargs)
310
311 addNinjaSteps(
312 f,
313 obj_dir=obj_dir,
314 env=env,
315 **kwargs)
316
317 return f
318
Galina Kistanova9124b832016-12-22 00:46:41 +0000319def getCmakeWithNinjaMultistageBuildFactory(
320 depends_on_projects = None,
321 llvm_srcdir = None,
Galina Kistanova0035b5d2016-10-07 20:47:51 +0000322 obj_dir = None,
Galina Kistanova9124b832016-12-22 00:46:41 +0000323 install_dir = None,
Galina Kistanova0035b5d2016-10-07 20:47:51 +0000324 clean = False,
Galina Kistanova0035b5d2016-10-07 20:47:51 +0000325 extra_configure_args = None,
326 env = None,
Galina Kistanova9124b832016-12-22 00:46:41 +0000327 stages=2,
328 stage_names=None,
Galina Kistanova0035b5d2016-10-07 20:47:51 +0000329 **kwargs):
330
Galina Kistanova9124b832016-12-22 00:46:41 +0000331 # Prepare environmental variables. Set here all env we want everywhere.
332 merged_env = {
333 'TERM' : 'dumb' # Be cautious and disable color output from all tools.
334 }
335 if env is not None:
336 # Overwrite pre-set items with the given ones, so user can set anything.
337 merged_env.update(env)
Galina Kistanova0035b5d2016-10-07 20:47:51 +0000338
339 # Make a local copy of the configure args, as we are going to modify that.
340 if extra_configure_args:
341 cmake_args = extra_configure_args[:]
342 else:
343 cmake_args = list()
344
Galina Kistanova9124b832016-12-22 00:46:41 +0000345 assert stages > 1, "It should be at least 2 stages in a multistage build."
346 if stage_names is None:
347 stage_names = list()
348 for i in range(1, stages + 1):
349 stage_names.append("stage%s" % i)
350 else:
351 assert len(stage_names) == stages, "Please specify names for none or all of the requested stages."
352
353 if obj_dir is None:
354 obj_dir = "build"
355 if install_dir is None:
356 install_dir = "install"
357
358 stage_objdirs = list()
359 stage_installdirs = list()
360 for s in stage_names:
361 stage_objdirs.append("%s/%s" % (obj_dir, s))
362 stage_installdirs.append("%s/%s" % (install_dir, s))
363
364 cleanBuildRequested = lambda step: step.build.getProperty("clean") or clean
365
366 f = getLLVMBuildFactoryAndSVNSteps(
367 depends_on_projects=depends_on_projects,
368 llvm_srcdir=llvm_srcdir,
369 obj_dir=obj_dir,
370 install_dir=install_dir,
371 cleanBuildRequested=cleanBuildRequested,
372 env=env,
373 stage_objdirs=stage_objdirs,
374 stage_installdirs=stage_installdirs,
375 stage_names=stage_names,
376 **kwargs) # Pass through all the extra arguments.
377
Galina Kistanova0035b5d2016-10-07 20:47:51 +0000378 # Set proper defaults.
379 CmakeCommand.applyDefaultOptions(cmake_args, [
Galina Kistanova9124b832016-12-22 00:46:41 +0000380 ('-DCMAKE_BUILD_TYPE=', 'Release'),
381 ('-DCLANG_BUILD_EXAMPLES=', 'OFF'),
382 ('-DLLVM_BUILD_TESTS=', 'ON'),
383 ('-DLLVM_ENABLE_ASSERTIONS=', 'OFF'),
384 ('-DLLVM_OPTIMIZED_TABLEGEN=', 'ON'),
Galina Kistanova0035b5d2016-10-07 20:47:51 +0000385 ])
386
387 # Some options are required for this build no matter what.
388 CmakeCommand.applyRequiredOptions(cmake_args, [
Galina Kistanova9124b832016-12-22 00:46:41 +0000389 ('-G', 'Ninja'),
Galina Kistanova0035b5d2016-10-07 20:47:51 +0000390 ])
391
Galina Kistanova9124b832016-12-22 00:46:41 +0000392 # The stage 1 is special, though. We use the system compiler and
Galina Kistanova9975c382017-01-03 04:10:02 +0000393 # do incremental build, unless a clean one has been requested.
Galina Kistanova9124b832016-12-22 00:46:41 +0000394 cmake_args_stage1 = cmake_args[:]
395 CmakeCommand.applyDefaultOptions(cmake_args_stage1, [
396 # Do not expect warning free build by the system toolchain.
397 ('-DLLVM_ENABLE_WERROR=', 'OFF'),
398 ])
Galina Kistanova0035b5d2016-10-07 20:47:51 +0000399
Galina Kistanova9124b832016-12-22 00:46:41 +0000400 addCmakeSteps(
401 f,
402 f.cleanBuildRequested,
403 obj_dir=stage_objdirs[0],
404 install_dir=stage_installdirs[0],
405 extra_configure_args=cmake_args_stage1,
406 env=env,
407 stage_name=stage_names[0],
408 **kwargs)
Galina Kistanova0035b5d2016-10-07 20:47:51 +0000409
Galina Kistanova9124b832016-12-22 00:46:41 +0000410 addNinjaSteps(
411 f,
412 obj_dir=stage_objdirs[0],
413 env=env,
414 stage_name=stage_names[0],
415 **kwargs)
Galina Kistanova0035b5d2016-10-07 20:47:51 +0000416
Galina Kistanova9124b832016-12-22 00:46:41 +0000417 # Build the rest stage by stage, using just built compiler to compile
418 # the next stage.
419 CmakeCommand.applyDefaultOptions(cmake_args, [
Galina Kistanova9975c382017-01-03 04:10:02 +0000420 # We should be warnings free when use just built compiler.
Galina Kistanova9124b832016-12-22 00:46:41 +0000421 ('-DLLVM_ENABLE_WERROR=', 'ON'),
422 ])
423 # If we build LLD, we would link with LLD.
424 # Otherwise we link with a system linker.
425 if 'lld' in f.depends_on_projects:
426 CmakeCommand.applyDefaultOptions(cmake_args, [
427 ('-DLLVM_ENABLE_LLD=', 'ON'),
428 ])
429
430 for stage_idx in range(1, stages):
431
Galina Kistanova9975c382017-01-03 04:10:02 +0000432 # Directories to use in this stage.
Galina Kistanova9124b832016-12-22 00:46:41 +0000433 obj_dir = f.stage_objdirs[stage_idx]
434 src_dir = LLVMBuildFactory.pathRelativeToBuild(f.llvm_srcdir, obj_dir)
435 install_dir = LLVMBuildFactory.pathRelativeToBuild(f.stage_installdirs[stage_idx], obj_dir)
436 staged_install = f.stage_installdirs[stage_idx - 1]
437
Galina Kistanova9975c382017-01-03 04:10:02 +0000438 # Configure the compiler to use in this stage.
Galina Kistanova9124b832016-12-22 00:46:41 +0000439 cmake_args_stageN = cmake_args[:]
440 CmakeCommand.applyRequiredOptions(cmake_args_stageN, [
441 ('-DCMAKE_INSTALL_PREFIX=', install_dir),
442 ])
443 cmake_args_stageN.append(
444 WithProperties(
445 "-DCMAKE_CXX_COMPILER=%(workdir)s/" + staged_install + "/bin/clang++"
446 ))
447 cmake_args_stageN.append(
448 WithProperties(
449 "-DCMAKE_C_COMPILER=%(workdir)s/" + staged_install + "/bin/clang"
450 ))
451
452 addCmakeSteps(
453 f,
454 True, # We always do a clean build for the staged builds.
455 obj_dir=stage_objdirs[stage_idx],
456 install_dir=stage_installdirs[stage_idx],
457 extra_configure_args=cmake_args_stageN,
458 env=env,
459 stage_name=stage_names[stage_idx],
460 **kwargs)
461
462 addNinjaSteps(
463 f,
464 obj_dir=stage_objdirs[stage_idx],
465 env=env,
466 stage_name=stage_names[stage_idx],
467 **kwargs)
Galina Kistanova0035b5d2016-10-07 20:47:51 +0000468
469 return f