source: Jenkinsfile@ ef1d025d

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

Don't archive librairies if no test crashed.

  • 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('master') {
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 if( fileExists 'tests/crashes' ) {
175 sh """${SrcDir}/tools/jenkins/archive-gen.sh"""
176 archiveArtifacts artifacts: "tests/crashes/**/*,lib/**/lib*.so*,setup.sh", fingerprint: true
177 }
178 }
179 throw err
180 }
181}
182
183def benchmark() {
184 Tools.BuildStage('Benchmark', Settings.RunBenchmark) {
185 dir (BuildDir) {
186 //Append bench results
187 sh "make --no-print-directory -C benchmark jenkins arch=${Settings.Architecture.name}"
188 }
189 }
190}
191
192def build_doc() {
193 Tools.BuildStage('Documentation', Settings.BuildDocumentation) {
194 dir ('doc/user') {
195 make_doc()
196 }
197
198 dir ('doc/refrat') {
199 make_doc()
200 }
201 }
202}
203
204def publish() {
205 Tools.BuildStage('Publish', true) {
206
207 if( Settings.Publish && !Settings.RunBenchmark ) { echo 'No results to publish!!!' }
208
209 def groupCompile = new PlotGroup('Compilation', 'duration (s) - lower is better', true)
210 def groupConcurrency = new PlotGroup('Concurrency', 'duration (n) - lower is better', false)
211
212 //Then publish the results
213 do_plot(Settings.RunBenchmark && Settings.Publish, 'compile' , groupCompile , false, 'Compilation')
214 do_plot(Settings.RunBenchmark && Settings.Publish, 'compile.diff' , groupCompile , true , 'Compilation (relative)')
215 do_plot(Settings.RunBenchmark && Settings.Publish, 'ctxswitch' , groupConcurrency, false, 'Context Switching')
216 do_plot(Settings.RunBenchmark && Settings.Publish, 'ctxswitch.diff' , groupConcurrency, true , 'Context Switching (relative)')
217 do_plot(Settings.RunBenchmark && Settings.Publish, 'mutex' , groupConcurrency, false, 'Mutual Exclusion')
218 do_plot(Settings.RunBenchmark && Settings.Publish, 'mutex.diff' , groupConcurrency, true , 'Mutual Exclusion (relative)')
219 do_plot(Settings.RunBenchmark && Settings.Publish, 'scheduling' , groupConcurrency, false, 'Internal and External Scheduling')
220 do_plot(Settings.RunBenchmark && Settings.Publish, 'scheduling.diff', groupConcurrency, true , 'Internal and External Scheduling (relative)')
221 }
222}
223
224//===========================================================================================================
225//Routine responsible of sending the email notification once the build is completed
226//===========================================================================================================
227//Standard build email notification
228def email(boolean log) {
229 //Since tokenizer doesn't work, figure stuff out from the environnement variables and command line
230 //Configurations for email format
231 echo 'Notifying users of result'
232
233 def project_name = (env.JOB_NAME =~ /(.+)\/.+/)[0][1].toLowerCase()
234 def email_subject = "[${project_name} git][BUILD# ${env.BUILD_NUMBER} - ${currentBuild.result}] - branch ${env.BRANCH_NAME}"
235 def email_body = """<p>This is an automated email from the Jenkins build machine. It was
236generated because of a git hooks/post-receive script following
237a ref change which was pushed to the C\u2200 repository.</p>
238""" + Tools.GitLogMessage()
239
240 def email_to = !Settings.IsSandbox ? "cforall@lists.uwaterloo.ca" : "tdelisle@uwaterloo.ca"
241
242 if( Settings && !Settings.Silent ) {
243 //send email notification
244 emailext body: email_body, subject: email_subject, to: email_to, attachLog: log
245 } else {
246 echo "Would send email to: ${email_to}"
247 echo "With title: ${email_subject}"
248 echo "Content: \n${email_body}"
249 }
250}
251
252//===========================================================================================================
253// Helper classes/variables/routines
254//===========================================================================================================
255//Description of a compiler (Must be serializable since pipelines are persistent)
256class CC_Desc implements Serializable {
257 public String name
258 public String CXX
259 public String CC
260 public String lto
261
262 CC_Desc(String name, String CXX, String CC, String lto) {
263 this.name = name
264 this.CXX = CXX
265 this.CC = CC
266 this.lto = lto
267 }
268}
269
270//Description of an architecture (Must be serializable since pipelines are persistent)
271class Arch_Desc implements Serializable {
272 public String name
273 public String flags
274 public String node
275
276 Arch_Desc(String name, String flags, String node) {
277 this.name = name
278 this.flags = flags
279 this.node = node
280 }
281}
282
283class BuildSettings implements Serializable {
284 public final CC_Desc Compiler
285 public final Arch_Desc Architecture
286 public final Boolean NewAST
287 public final Boolean RunAllTests
288 public final Boolean RunBenchmark
289 public final Boolean BuildDocumentation
290 public final Boolean Publish
291 public final Boolean Silent
292 public final Boolean IsSandbox
293 public final String DescLong
294 public final String DescShort
295
296 public String GitNewRef
297 public String GitOldRef
298
299 BuildSettings(java.util.Collections$UnmodifiableMap param, String branch) {
300 switch( param.Compiler ) {
301 case 'gcc-9':
302 this.Compiler = new CC_Desc('gcc-9', 'g++-9', 'gcc-9', '-flto=auto')
303 break
304 case 'gcc-8':
305 this.Compiler = new CC_Desc('gcc-8', 'g++-8', 'gcc-8', '-flto=auto')
306 break
307 case 'gcc-7':
308 this.Compiler = new CC_Desc('gcc-7', 'g++-7', 'gcc-7', '-flto=auto')
309 break
310 case 'gcc-6':
311 this.Compiler = new CC_Desc('gcc-6', 'g++-6', 'gcc-6', '-flto=auto')
312 break
313 case 'gcc-5':
314 this.Compiler = new CC_Desc('gcc-5', 'g++-5', 'gcc-5', '-flto=auto')
315 break
316 case 'gcc-4.9':
317 this.Compiler = new CC_Desc('gcc-4.9', 'g++-4.9', 'gcc-4.9', '-flto=auto')
318 break
319 case 'clang':
320 this.Compiler = new CC_Desc('clang', 'clang++-10', 'gcc-9', '-flto=thin -flto-jobs=0')
321 break
322 default :
323 error "Unhandled compiler : ${cc}"
324 }
325
326 switch( param.Architecture ) {
327 case 'x64':
328 this.Architecture = new Arch_Desc('x64', '--host=x86_64', 'x64')
329 break
330 case 'x86':
331 this.Architecture = new Arch_Desc('x86', '--host=i386', 'x86')
332 break
333 default :
334 error "Unhandled architecture : ${arch}"
335 }
336
337 this.IsSandbox = (branch == "jenkins-sandbox")
338 this.NewAST = param.NewAST
339 this.RunAllTests = param.RunAllTests
340 this.RunBenchmark = param.RunBenchmark
341 this.BuildDocumentation = param.BuildDocumentation
342 this.Publish = param.Publish
343 this.Silent = param.Silent
344
345 def full = param.RunAllTests ? " (Full)" : ""
346 this.DescShort = "${ this.Compiler.name }:${ this.Architecture.name }${full}"
347
348 final ast = this.NewAST ? "New AST" : "Old AST"
349 this.DescLong = """Compiler : ${ this.Compiler.name } (${ this.Compiler.CXX }/${ this.Compiler.CC })
350AST Version : ${ ast.toString() }
351Architecture : ${ this.Architecture.name }
352Arc Flags : ${ this.Architecture.flags }
353Run All Tests : ${ this.RunAllTests.toString() }
354Run Benchmark : ${ this.RunBenchmark.toString() }
355Build Documentation : ${ this.BuildDocumentation.toString() }
356Publish : ${ this.Publish.toString() }
357Silent : ${ this.Silent.toString() }
358"""
359
360 this.GitNewRef = ''
361 this.GitOldRef = ''
362 }
363}
364
365class PlotGroup implements Serializable {
366 public String name
367 public String unit
368 public boolean log
369
370 PlotGroup(String name, String unit, boolean log) {
371 this.name = name
372 this.unit = unit
373 this.log = log
374 }
375}
376
377def prepare_build() {
378 // prepare the properties
379 properties ([ \
380 buildDiscarder(logRotator( \
381 artifactDaysToKeepStr: '', \
382 artifactNumToKeepStr: '', \
383 daysToKeepStr: '730', \
384 numToKeepStr: '1000' \
385 )), \
386 [$class: 'ParametersDefinitionProperty', \
387 parameterDefinitions: [ \
388 [$class: 'ChoiceParameterDefinition', \
389 description: 'Which compiler to use', \
390 name: 'Compiler', \
391 choices: 'gcc-9\ngcc-8\ngcc-7\ngcc-6\ngcc-5\ngcc-4.9\nclang', \
392 defaultValue: 'gcc-8', \
393 ], \
394 [$class: 'ChoiceParameterDefinition', \
395 description: 'The target architecture', \
396 name: 'Architecture', \
397 choices: 'x64\nx86', \
398 defaultValue: 'x64', \
399 ], \
400 [$class: 'BooleanParameterDefinition', \
401 description: 'If true, build compiler using new AST', \
402 name: 'NewAST', \
403 defaultValue: true, \
404 ], \
405 [$class: 'BooleanParameterDefinition', \
406 description: 'If false, only the quick test suite is ran', \
407 name: 'RunAllTests', \
408 defaultValue: false, \
409 ], \
410 [$class: 'BooleanParameterDefinition', \
411 description: 'If true, jenkins also runs benchmarks', \
412 name: 'RunBenchmark', \
413 defaultValue: false, \
414 ], \
415 [$class: 'BooleanParameterDefinition', \
416 description: 'If true, jenkins also builds documentation', \
417 name: 'BuildDocumentation', \
418 defaultValue: true, \
419 ], \
420 [$class: 'BooleanParameterDefinition', \
421 description: 'If true, jenkins also publishes results', \
422 name: 'Publish', \
423 defaultValue: false, \
424 ], \
425 [$class: 'BooleanParameterDefinition', \
426 description: 'If true, jenkins will not send emails', \
427 name: 'Silent', \
428 defaultValue: false, \
429 ], \
430 ],
431 ]])
432
433 // It's unfortunate but it looks like we need to checkout the entire repo just to get
434 // - the pretty git printer
435 // - Jenkins.tools
436 checkout scm
437
438 Tools = load "Jenkins/tools.groovy"
439
440 final settings = new BuildSettings(params, env.BRANCH_NAME)
441
442 currentBuild.description = settings.DescShort
443 echo settings.DescLong
444
445 return settings
446}
447
448def make_doc() {
449 def err = null
450 try {
451 sh 'make clean > /dev/null'
452 sh 'make > /dev/null 2>&1'
453 }
454 catch (Exception caughtError) {
455 err = caughtError //rethrow error later
456 sh 'cat build/*.log'
457 }
458 finally {
459 if (err) throw err // Must re-throw exception to propagate error
460 }
461}
462
463def do_plot(boolean new_data, String file, PlotGroup group, boolean relative, String title) {
464
465 if(new_data) {
466 echo "Publishing new data"
467 }
468
469 def series = new_data ? [[
470 file: "${file}.csv",
471 exclusionValues: '',
472 displayTableFlag: false,
473 inclusionFlag: 'OFF',
474 url: ''
475 ]] : [];
476
477 echo "file is ${BuildDir}/benchmark/${file}.csv, group ${group}, title ${title}"
478 dir("${BuildDir}/benchmark/") {
479 plot csvFileName: "cforall-${env.BRANCH_NAME}-${file}.csv",
480 csvSeries: series,
481 group: "${group.name}",
482 title: "${title}",
483 style: 'lineSimple',
484 exclZero: false,
485 keepRecords: false,
486 logarithmic: !relative && group.log,
487 numBuilds: '120',
488 useDescr: true,
489 yaxis: group.unit,
490 yaxisMaximum: '',
491 yaxisMinimum: ''
492 }
493}
Note: See TracBrowser for help on using the repository browser.