source: Jenkinsfile@ 5e64df8e

ADT ast-experimental enum forall-pointer-decay jacob/cs343-translation new-ast-unique-expr pthread-emulation qualifiedEnum
Last change on this file since 5e64df8e was 4969efd, checked in by Thierry Delisle <tdelisle@…>, 4 years ago

Testing out Jenkins not using master anymore

  • Property mode set to 100644
File size: 15.1 KB
Line 
1#!groovy
2
3import groovy.transform.Field
4
5//===========================================================================================================
6// Main loop of the compilation
7//===========================================================================================================
8
9node {
10 // Globals
11 BuildDir = pwd tmp: true
12 SrcDir = pwd tmp: false
13 Settings = null
14 Tools = null
15
16 // Local variables
17 def err = null
18 def log_needed = false
19
20 currentBuild.result = "SUCCESS"
21
22 try {
23 //Wrap build to add timestamp to command line
24 wrap([$class: 'TimestamperBuildWrapper']) {
25
26 Settings = prepare_build()
27
28 node(Settings.Architecture.node) {
29 BuildDir = pwd tmp: true
30 SrcDir = pwd tmp: false
31 currentBuild.description = "${currentBuild.description} on ${env.NODE_NAME}"
32
33 Tools.Clean()
34
35 Tools.Checkout()
36
37 build()
38
39 test()
40
41 benchmark()
42
43 build_doc()
44
45 publish()
46 }
47
48 // Update the build directories when exiting the node
49 BuildDir = pwd tmp: true
50 SrcDir = pwd tmp: false
51 }
52 }
53
54 //If an exception is caught we need to change the status and remember to
55 //attach the build log to the email
56 catch (Exception caughtError) {
57 // Store the result of the build log
58 currentBuild.result = "FAILURE"
59
60 // An error has occured, the build log is relevent
61 log_needed = true
62
63 // rethrow error later
64 err = caughtError
65
66 // print the error so it shows in the log
67 echo err.toString()
68 }
69
70 finally {
71 //Send email with final results if this is not a full build
72 email(log_needed)
73
74 echo 'Build Completed'
75
76 /* Must re-throw exception to propagate error */
77 if (err) {
78 throw err
79 }
80 }
81}
82//===========================================================================================================
83// Main compilation routines
84//===========================================================================================================
85def build() {
86 debug = true
87 release = Settings.RunAllTests || Settings.RunBenchmark
88 Tools.BuildStage('Build : configure', true) {
89 // Configure must be run inside the tree
90 dir (SrcDir) {
91 // Generate the necessary build files
92 sh './autogen.sh'
93 }
94
95 // Build outside of the src tree to ease cleaning
96 dir (BuildDir) {
97 //Configure the compilation (Output is not relevant)
98 //Use the current directory as the installation target so nothing escapes the sandbox
99 //Also specify the compiler by hand
100 targets=""
101 if( Settings.RunAllTests || Settings.RunBenchmark ) {
102 targets="--with-target-hosts='host:debug,host:nodebug'"
103 } else {
104 targets="--with-target-hosts='host:debug'"
105 }
106
107 ast = Settings.NewAST ? "--enable-new-ast" : "--disable-new-ast"
108
109 sh "${SrcDir}/configure CXX=${Settings.Compiler.CXX} CC=${Settings.Compiler.CC} ${Settings.Architecture.flags} AR=gcc-ar RANLIB=gcc-ranlib ${targets} ${ast} --quiet --prefix=${BuildDir}"
110
111 // Configure libcfa
112 sh 'make -j 8 --no-print-directory configure-libcfa'
113 }
114 }
115
116 Tools.BuildStage('Build : cfa-cpp', true) {
117 // Build outside of the src tree to ease cleaning
118 dir (BuildDir) {
119 // Build driver
120 sh 'make -j 8 --no-print-directory -C driver'
121
122 // Build translator
123 sh 'make -j 8 --no-print-directory -C src'
124 }
125 }
126
127 Tools.BuildStage('Build : libcfa(debug)', debug) {
128 // Build outside of the src tree to ease cleaning
129 dir (BuildDir) {
130 sh "make -j 8 --no-print-directory -C libcfa/${Settings.Architecture.name}-debug"
131 }
132 }
133
134 Tools.BuildStage('Build : libcfa(nodebug)', release) {
135 // Build outside of the src tree to ease cleaning
136 dir (BuildDir) {
137 sh "make -j 8 --no-print-directory -C libcfa/${Settings.Architecture.name}-nodebug"
138 }
139 }
140
141 Tools.BuildStage('Build : install', true) {
142 // Build outside of the src tree to ease cleaning
143 dir (BuildDir) {
144 sh "make -j 8 --no-print-directory install"
145 }
146 }
147}
148
149def test() {
150 try {
151 // Print potential limits before testing
152 // in case jenkins messes with them
153 sh 'free -h'
154 sh 'ulimit -a'
155
156 Tools.BuildStage('Test: short', !Settings.RunAllTests) {
157 dir (BuildDir) {
158 //Run the tests from the tests directory
159 sh "make --no-print-directory -C tests archiveerrors=${BuildDir}/tests/crashes/short"
160 }
161 }
162
163 Tools.BuildStage('Test: full', Settings.RunAllTests) {
164 dir (BuildDir) {
165 //Run the tests from the tests directory
166 sh """make --no-print-directory -C tests timeouts="--timeout=600 --global-timeout=14400" all-tests debug=yes archiveerrors=${BuildDir}/tests/crashes/full-debug"""
167 sh """make --no-print-directory -C tests timeouts="--timeout=600 --global-timeout=14400" all-tests debug=no archiveerrors=${BuildDir}/tests/crashes/full-nodebug"""
168 }
169 }
170 }
171 catch (Exception err) {
172 echo "Archiving core dumps"
173 dir (BuildDir) {
174 def exists = fileExists 'tests/crashes'
175 if( exists ) {
176 sh """${SrcDir}/tools/jenkins/archive-gen.sh"""
177 archiveArtifacts artifacts: "tests/crashes/**/*,lib/**/lib*.so*,setup.sh", fingerprint: true
178 }
179 }
180 throw err
181 }
182}
183
184def benchmark() {
185 Tools.BuildStage('Benchmark', Settings.RunBenchmark) {
186 dir (BuildDir) {
187 //Append bench results
188 sh "make --no-print-directory -C benchmark jenkins arch=${Settings.Architecture.name}"
189 }
190 }
191}
192
193def build_doc() {
194 Tools.BuildStage('Documentation', Settings.BuildDocumentation) {
195 dir ('doc/user') {
196 make_doc()
197 }
198
199 dir ('doc/refrat') {
200 make_doc()
201 }
202 }
203}
204
205def publish() {
206 Tools.BuildStage('Publish', true) {
207
208 if( Settings.Publish && !Settings.RunBenchmark ) { echo 'No results to publish!!!' }
209
210 def groupCompile = new PlotGroup('Compilation', 'duration (s) - lower is better', true)
211 def groupConcurrency = new PlotGroup('Concurrency', 'duration (n) - lower is better', false)
212
213 //Then publish the results
214 do_plot(Settings.RunBenchmark && Settings.Publish, 'compile' , groupCompile , false, 'Compilation')
215 do_plot(Settings.RunBenchmark && Settings.Publish, 'compile.diff' , groupCompile , true , 'Compilation (relative)')
216 do_plot(Settings.RunBenchmark && Settings.Publish, 'ctxswitch' , groupConcurrency, false, 'Context Switching')
217 do_plot(Settings.RunBenchmark && Settings.Publish, 'ctxswitch.diff' , groupConcurrency, true , 'Context Switching (relative)')
218 do_plot(Settings.RunBenchmark && Settings.Publish, 'mutex' , groupConcurrency, false, 'Mutual Exclusion')
219 do_plot(Settings.RunBenchmark && Settings.Publish, 'mutex.diff' , groupConcurrency, true , 'Mutual Exclusion (relative)')
220 do_plot(Settings.RunBenchmark && Settings.Publish, 'scheduling' , groupConcurrency, false, 'Internal and External Scheduling')
221 do_plot(Settings.RunBenchmark && Settings.Publish, 'scheduling.diff', groupConcurrency, true , 'Internal and External Scheduling (relative)')
222 }
223}
224
225//===========================================================================================================
226//Routine responsible of sending the email notification once the build is completed
227//===========================================================================================================
228//Standard build email notification
229def email(boolean log) {
230 //Since tokenizer doesn't work, figure stuff out from the environnement variables and command line
231 //Configurations for email format
232 echo 'Notifying users of result'
233
234 def project_name = (env.JOB_NAME =~ /(.+)\/.+/)[0][1].toLowerCase()
235 def email_subject = "[${project_name} git][BUILD# ${env.BUILD_NUMBER} - ${currentBuild.result}] - branch ${env.BRANCH_NAME}"
236 def email_body = """<p>This is an automated email from the Jenkins build machine. It was
237generated because of a git hooks/post-receive script following
238a ref change which was pushed to the C\u2200 repository.</p>
239""" + Tools.GitLogMessage()
240
241 def email_to = !Settings.IsSandbox ? "cforall@lists.uwaterloo.ca" : "tdelisle@uwaterloo.ca"
242
243 if( Settings && !Settings.Silent ) {
244 //send email notification
245 emailext body: email_body, subject: email_subject, to: email_to, attachLog: log
246 } else {
247 echo "Would send email to: ${email_to}"
248 echo "With title: ${email_subject}"
249 echo "Content: \n${email_body}"
250 }
251}
252
253//===========================================================================================================
254// Helper classes/variables/routines
255//===========================================================================================================
256//Description of a compiler (Must be serializable since pipelines are persistent)
257class CC_Desc implements Serializable {
258 public String name
259 public String CXX
260 public String CC
261 public String lto
262
263 CC_Desc(String name, String CXX, String CC, String lto) {
264 this.name = name
265 this.CXX = CXX
266 this.CC = CC
267 this.lto = lto
268 }
269}
270
271//Description of an architecture (Must be serializable since pipelines are persistent)
272class Arch_Desc implements Serializable {
273 public String name
274 public String flags
275 public String node
276
277 Arch_Desc(String name, String flags, String node) {
278 this.name = name
279 this.flags = flags
280 this.node = node
281 }
282}
283
284class BuildSettings implements Serializable {
285 public final CC_Desc Compiler
286 public final Arch_Desc Architecture
287 public final Boolean NewAST
288 public final Boolean RunAllTests
289 public final Boolean RunBenchmark
290 public final Boolean BuildDocumentation
291 public final Boolean Publish
292 public final Boolean Silent
293 public final Boolean IsSandbox
294 public final String DescLong
295 public final String DescShort
296
297 public String GitNewRef
298 public String GitOldRef
299
300 BuildSettings(java.util.Collections$UnmodifiableMap param, String branch) {
301 switch( param.Compiler ) {
302 case 'gcc-9':
303 this.Compiler = new CC_Desc('gcc-9', 'g++-9', 'gcc-9', '-flto=auto')
304 break
305 case 'gcc-8':
306 this.Compiler = new CC_Desc('gcc-8', 'g++-8', 'gcc-8', '-flto=auto')
307 break
308 case 'gcc-7':
309 this.Compiler = new CC_Desc('gcc-7', 'g++-7', 'gcc-7', '-flto=auto')
310 break
311 case 'gcc-6':
312 this.Compiler = new CC_Desc('gcc-6', 'g++-6', 'gcc-6', '-flto=auto')
313 break
314 case 'gcc-5':
315 this.Compiler = new CC_Desc('gcc-5', 'g++-5', 'gcc-5', '-flto=auto')
316 break
317 case 'gcc-4.9':
318 this.Compiler = new CC_Desc('gcc-4.9', 'g++-4.9', 'gcc-4.9', '-flto=auto')
319 break
320 case 'clang':
321 this.Compiler = new CC_Desc('clang', 'clang++-10', 'gcc-9', '-flto=thin -flto-jobs=0')
322 break
323 default :
324 error "Unhandled compiler : ${cc}"
325 }
326
327 switch( param.Architecture ) {
328 case 'x64':
329 this.Architecture = new Arch_Desc('x64', '--host=x86_64', 'x64')
330 break
331 case 'x86':
332 this.Architecture = new Arch_Desc('x86', '--host=i386', 'x86')
333 break
334 default :
335 error "Unhandled architecture : ${arch}"
336 }
337
338 this.IsSandbox = (branch == "jenkins-sandbox")
339 this.NewAST = param.NewAST
340 this.RunAllTests = param.RunAllTests
341 this.RunBenchmark = param.RunBenchmark
342 this.BuildDocumentation = param.BuildDocumentation
343 this.Publish = param.Publish
344 this.Silent = param.Silent
345
346 def full = param.RunAllTests ? " (Full)" : ""
347 this.DescShort = "${ this.Compiler.name }:${ this.Architecture.name }${full}"
348
349 final ast = this.NewAST ? "New AST" : "Old AST"
350 this.DescLong = """Compiler : ${ this.Compiler.name } (${ this.Compiler.CXX }/${ this.Compiler.CC })
351AST Version : ${ ast.toString() }
352Architecture : ${ this.Architecture.name }
353Arc Flags : ${ this.Architecture.flags }
354Run All Tests : ${ this.RunAllTests.toString() }
355Run Benchmark : ${ this.RunBenchmark.toString() }
356Build Documentation : ${ this.BuildDocumentation.toString() }
357Publish : ${ this.Publish.toString() }
358Silent : ${ this.Silent.toString() }
359"""
360
361 this.GitNewRef = ''
362 this.GitOldRef = ''
363 }
364}
365
366class PlotGroup implements Serializable {
367 public String name
368 public String unit
369 public boolean log
370
371 PlotGroup(String name, String unit, boolean log) {
372 this.name = name
373 this.unit = unit
374 this.log = log
375 }
376}
377
378def prepare_build() {
379 // prepare the properties
380 properties ([ \
381 buildDiscarder(logRotator( \
382 artifactDaysToKeepStr: '', \
383 artifactNumToKeepStr: '', \
384 daysToKeepStr: '730', \
385 numToKeepStr: '1000' \
386 )), \
387 [$class: 'ParametersDefinitionProperty', \
388 parameterDefinitions: [ \
389 [$class: 'ChoiceParameterDefinition', \
390 description: 'Which compiler to use', \
391 name: 'Compiler', \
392 choices: 'gcc-9\ngcc-8\ngcc-7\ngcc-6\ngcc-5\ngcc-4.9\nclang', \
393 defaultValue: 'gcc-8', \
394 ], \
395 [$class: 'ChoiceParameterDefinition', \
396 description: 'The target architecture', \
397 name: 'Architecture', \
398 choices: 'x64\nx86', \
399 defaultValue: 'x64', \
400 ], \
401 [$class: 'BooleanParameterDefinition', \
402 description: 'If true, build compiler using new AST', \
403 name: 'NewAST', \
404 defaultValue: true, \
405 ], \
406 [$class: 'BooleanParameterDefinition', \
407 description: 'If false, only the quick test suite is ran', \
408 name: 'RunAllTests', \
409 defaultValue: false, \
410 ], \
411 [$class: 'BooleanParameterDefinition', \
412 description: 'If true, jenkins also runs benchmarks', \
413 name: 'RunBenchmark', \
414 defaultValue: false, \
415 ], \
416 [$class: 'BooleanParameterDefinition', \
417 description: 'If true, jenkins also builds documentation', \
418 name: 'BuildDocumentation', \
419 defaultValue: true, \
420 ], \
421 [$class: 'BooleanParameterDefinition', \
422 description: 'If true, jenkins also publishes results', \
423 name: 'Publish', \
424 defaultValue: false, \
425 ], \
426 [$class: 'BooleanParameterDefinition', \
427 description: 'If true, jenkins will not send emails', \
428 name: 'Silent', \
429 defaultValue: false, \
430 ], \
431 ],
432 ]])
433
434 // It's unfortunate but it looks like we need to checkout the entire repo just to get
435 // - the pretty git printer
436 // - Jenkins.tools
437 checkout scm
438
439 Tools = load "Jenkins/tools.groovy"
440
441 final settings = new BuildSettings(params, env.BRANCH_NAME)
442
443 currentBuild.description = settings.DescShort
444 echo settings.DescLong
445
446 return settings
447}
448
449def make_doc() {
450 def err = null
451 try {
452 sh 'make clean > /dev/null'
453 sh 'make > /dev/null 2>&1'
454 }
455 catch (Exception caughtError) {
456 err = caughtError //rethrow error later
457 sh 'cat build/*.log'
458 }
459 finally {
460 if (err) throw err // Must re-throw exception to propagate error
461 }
462}
463
464def do_plot(boolean new_data, String file, PlotGroup group, boolean relative, String title) {
465
466 if(new_data) {
467 echo "Publishing new data"
468 }
469
470 def series = new_data ? [[
471 file: "${file}.csv",
472 exclusionValues: '',
473 displayTableFlag: false,
474 inclusionFlag: 'OFF',
475 url: ''
476 ]] : [];
477
478 echo "file is ${BuildDir}/benchmark/${file}.csv, group ${group}, title ${title}"
479 dir("${BuildDir}/benchmark/") {
480 plot csvFileName: "cforall-${env.BRANCH_NAME}-${file}.csv",
481 csvSeries: series,
482 group: "${group.name}",
483 title: "${title}",
484 style: 'lineSimple',
485 exclZero: false,
486 keepRecords: false,
487 logarithmic: !relative && group.log,
488 numBuilds: '120',
489 useDescr: true,
490 yaxis: group.unit,
491 yaxisMaximum: '',
492 yaxisMinimum: ''
493 }
494}
Note: See TracBrowser for help on using the repository browser.