source: Jenkinsfile@ 0fba0d4

ADT ast-experimental enum forall-pointer-decay pthread-emulation qualifiedEnum
Last change on this file since 0fba0d4 was 1781e97, checked in by Thierry Delisle <tdelisle@…>, 4 years ago

Fixed whitespace

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