source: Jenkinsfile@ a951171

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 a951171 was c09ae73, checked in by Thierry Delisle <tdelisle@…>, 5 years ago

Removed hack in Jenkins file that is no longer needed after .autogen change

  • Property mode set to 100644
File size: 16.7 KB
RevLine 
[a63ad80]1#!groovy
2
[7a230fd]3import groovy.transform.Field
4
[8ecb590]5// For skipping stages
6import org.jenkinsci.plugins.pipeline.modeldefinition.Utils
7
[29f4fe62]8//===========================================================================================================
[9beae23]9// Main loop of the compilation
[29f4fe62]10//===========================================================================================================
[56a9ce6]11
[85142648]12node('master') {
13 // Globals
14 BuildDir = pwd tmp: true
15 SrcDir = pwd tmp: false
16 Settings = null
17 StageName = ''
[4f9e706]18
[85142648]19 // Local variables
20 def err = null
21 def log_needed = false
[5b8413b4]22
[85142648]23 currentBuild.result = "SUCCESS"
[4f9e706]24
[85142648]25 try {
26 //Wrap build to add timestamp to command line
27 wrap([$class: 'TimestamperBuildWrapper']) {
[0ef06b6]28
[85142648]29 Settings = prepare_build()
[952ee7a]30
[85142648]31 node(Settings.Architecture.node) {
32 BuildDir = pwd tmp: true
33 SrcDir = pwd tmp: false
[23a14d86]34
[85142648]35 clean()
[7aebc62]36
[85142648]37 checkout()
[fde808df]38
[85142648]39 build()
[95fdb0a]40
[85142648]41 test()
[95fdb0a]42
[85142648]43 benchmark()
[95fdb0a]44
[85142648]45 build_doc()
[7359098]46
[85142648]47 publish()
48 }
[9beae23]49
[85142648]50 // Update the build directories when exiting the node
51 BuildDir = pwd tmp: true
52 SrcDir = pwd tmp: false
[9beae23]53 }
[738cf8f]54 }
55
[85142648]56 //If an exception is caught we need to change the status and remember to
57 //attach the build log to the email
58 catch (Exception caughtError) {
59 //rethrow error later
60 err = caughtError
[738cf8f]61
[85142648]62 echo err.toString()
[e966ec0]63
[85142648]64 //An error has occured, the build log is relevent
65 log_needed = true
[9beae23]66
[85142648]67 //Store the result of the build log
68 currentBuild.result = "${StageName} FAILURE".trim()
69 }
[738cf8f]70
[85142648]71 finally {
72 //Send email with final results if this is not a full build
73 email(log_needed)
[9beae23]74
[85142648]75 echo 'Build Completed'
[734891d]76
[85142648]77 /* Must re-throw exception to propagate error */
78 if (err) {
79 throw err
80 }
[738cf8f]81 }
82}
[29f4fe62]83//===========================================================================================================
[9beae23]84// Main compilation routines
[29f4fe62]85//===========================================================================================================
[0dc3ac3]86def clean() {
[6c55a3d]87 build_stage('Cleanup', true) {
[0dc3ac3]88 // clean the build by wipping the build directory
[5b8413b4]89 dir(BuildDir) {
[d4cd491]90 deleteDir()
[ece8a80]91 }
[620dd2b]92 }
[95fdb0a]93}
[29f4fe62]94
[0dc3ac3]95//Compilation script is done here but environnement set-up and error handling is done in main loop
96def checkout() {
[6c55a3d]97 build_stage('Checkout', true) {
[0dc3ac3]98 //checkout the source code and clean the repo
[a336d46]99 final scmVars = checkout scm
100 Settings.GitNewRef = scmVars.GIT_COMMIT
101 Settings.GitOldRef = scmVars.GIT_PREVIOUS_COMMIT
[d3a4564a]102
[a336d46]103 echo GitLogMessage()
[0dc3ac3]104 }
105}
106
[95fdb0a]107def build() {
[e507c11]108 debug = true
109 release = Settings.RunAllTests || Settings.RunBenchmark
110 build_stage('Build : configure', true) {
[dcf1979]111 // Configure must be run inside the tree
112 dir (SrcDir) {
113 // Generate the necessary build files
114 sh './autogen.sh'
115 }
116
[50f2cfc]117 // Build outside of the src tree to ease cleaning
[5b8413b4]118 dir (BuildDir) {
[50f2cfc]119 //Configure the conpilation (Output is not relevant)
120 //Use the current directory as the installation target so nothing escapes the sandbox
121 //Also specify the compiler by hand
[3fc5f010]122 targets=""
[d4510ea]123 if( Settings.RunAllTests || Settings.RunBenchmark ) {
[6bde81d]124 targets="--with-target-hosts='host:debug,host:nodebug'"
[3fc5f010]125 } else {
[6bde81d]126 targets="--with-target-hosts='host:debug'"
[3fc5f010]127 }
128
[aa96fba]129 sh "${SrcDir}/configure CXX=${Settings.Compiler.CXX} CC=${Settings.Compiler.CC} ${Settings.Architecture.flags} AR=gcc-ar RANLIB=gcc-ranlib ${targets} --quiet --prefix=${BuildDir}"
[f253e4a]130
131 // Configure libcfa
[e70e54e]132 sh 'make -j 8 --no-print-directory configure-libcfa'
[e507c11]133 }
134 }
135
136 build_stage('Build : cfa-cpp', true) {
137 // Build outside of the src tree to ease cleaning
138 dir (BuildDir) {
139 // Build driver
140 sh 'make -j 8 --no-print-directory -C driver'
141
142 // Build translator
143 sh 'make -j 8 --no-print-directory -C src'
144 }
145 }
[1752d0e]146
[e507c11]147 build_stage('Build : libcfa(debug)', debug) {
148 // Build outside of the src tree to ease cleaning
149 dir (BuildDir) {
150 sh "make -j 8 --no-print-directory -C libcfa/${Settings.Architecture.name}-debug"
151 }
152 }
153
154 build_stage('Build : libcfa(nodebug)', release) {
155 // Build outside of the src tree to ease cleaning
156 dir (BuildDir) {
157 sh "make -j 8 --no-print-directory -C libcfa/${Settings.Architecture.name}-nodebug"
[50f2cfc]158 }
[620dd2b]159 }
[aa96fba]160
161 build_stage('Build : install', true) {
162 // Build outside of the src tree to ease cleaning
163 dir (BuildDir) {
164 sh "make -j 8 --no-print-directory install"
165 }
166 }
[95fdb0a]167}
[24eecab]168
[95fdb0a]169def test() {
[4c1b9ea8]170 try {
171 build_stage('Test: short', !Settings.RunAllTests) {
172 dir (BuildDir) {
[3e93c00]173 //Run the tests from the tests directory
[4c51aca]174 sh "make --no-print-directory -C tests archiveerrors=${BuildDir}/tests/crashes/short"
[3e93c00]175 }
[4c1b9ea8]176 }
177
178 build_stage('Test: full', Settings.RunAllTests) {
179 dir (BuildDir) {
180 //Run the tests from the tests directory
[4c51aca]181 sh """make --no-print-directory -C tests timeouts="--timeout=600 --global-timeout=14400" all-tests debug=yes archiveerrors=${BuildDir}/tests/crashes/full-debug"""
182 sh """make --no-print-directory -C tests timeouts="--timeout=600 --global-timeout=14400" all-tests debug=no archiveerrors=${BuildDir}/tests/crashes/full-nodebug"""
[143e6f3]183 }
[9beae23]184 }
[620dd2b]185 }
[4c1b9ea8]186 catch (Exception err) {
187 echo "Archiving core dumps"
[c95fdc9]188 dir (BuildDir) {
[62f96ae]189 archiveArtifacts artifacts: "tests/crashes/**/*,lib/**/lib*.so*", fingerprint: true
[c95fdc9]190 }
[4c1b9ea8]191 throw err
192 }
[95fdb0a]193}
194
195def benchmark() {
[6c55a3d]196 build_stage('Benchmark', Settings.RunBenchmark) {
[5b8413b4]197 dir (BuildDir) {
[0dc3ac3]198 //Append bench results
[c6f1f3e]199 sh "make --no-print-directory -C benchmark jenkins arch=${Settings.Architecture.name}"
[0dc3ac3]200 }
[620dd2b]201 }
[9beae23]202}
[efd60d67]203
[95fdb0a]204def build_doc() {
[6c55a3d]205 build_stage('Documentation', Settings.BuildDocumentation) {
[9beae23]206 dir ('doc/user') {
207 make_doc()
208 }
209
210 dir ('doc/refrat') {
211 make_doc()
212 }
[620dd2b]213 }
[9beae23]214}
215
[95fdb0a]216def publish() {
[6c55a3d]217 build_stage('Publish', true) {
[95fdb0a]218
[1b3eef8]219 if( Settings.Publish && !Settings.RunBenchmark ) { echo 'No results to publish!!!' }
[95fdb0a]220
[3221a2b]221 def groupCompile = new PlotGroup('Compilation', 'duration (s) - lower is better', true)
222 def groupConcurrency = new PlotGroup('Concurrency', 'duration (n) - lower is better', false)
[a2a0065]223
[3898392]224 //Then publish the results
[13d2dac]225 do_plot(Settings.RunBenchmark && Settings.Publish, 'compile' , groupCompile , false, 'Compilation')
226 do_plot(Settings.RunBenchmark && Settings.Publish, 'compile.diff' , groupCompile , true , 'Compilation (relative)')
227 do_plot(Settings.RunBenchmark && Settings.Publish, 'ctxswitch' , groupConcurrency, false, 'Context Switching')
228 do_plot(Settings.RunBenchmark && Settings.Publish, 'ctxswitch.diff' , groupConcurrency, true , 'Context Switching (relative)')
229 do_plot(Settings.RunBenchmark && Settings.Publish, 'mutex' , groupConcurrency, false, 'Mutual Exclusion')
230 do_plot(Settings.RunBenchmark && Settings.Publish, 'mutex.diff' , groupConcurrency, true , 'Mutual Exclusion (relative)')
231 do_plot(Settings.RunBenchmark && Settings.Publish, 'scheduling' , groupConcurrency, false, 'Internal and External Scheduling')
232 do_plot(Settings.RunBenchmark && Settings.Publish, 'scheduling.diff', groupConcurrency, true , 'Internal and External Scheduling (relative)')
[620dd2b]233 }
[95fdb0a]234}
235
[29f4fe62]236//===========================================================================================================
237//Routine responsible of sending the email notification once the build is completed
238//===========================================================================================================
[6b6c26e]239@NonCPS
240def SplitLines(String text) {
241 def list = []
242
243 text.eachLine {
244 list += it
245 }
246
247 return list
248}
249
[a336d46]250def GitLogMessage() {
251 if (!Settings || !Settings.GitOldRef || !Settings.GitNewRef) return "\nERROR retrieveing git information!\n"
[e8a22a7]252
[fce01e7]253 def oldRef = Settings.GitOldRef
254 def newRef = Settings.GitNewRef
[6badd87]255
[fdb6ac6]256 def revText = sh(returnStdout: true, script: "git rev-list ${oldRef}..${newRef}").trim()
[6b6c26e]257 def revList = SplitLines( revText )
[6e31c43]258
[fdb6ac6]259 def gitUpdate = ""
260 revList.each { rev ->
[249091f]261 def type = sh(returnStdout: true, script: "git cat-file -t ${rev}").trim()
[fce01e7]262 gitUpdate = gitUpdate + " via ${rev} (${type})"
263 }
264
265 def rev = oldRef
[249091f]266 def type = sh(returnStdout: true, script: "git cat-file -t ${rev}").trim()
267 gitUpdate = gitUpdate + " from ${rev} (${type})"
[fce01e7]268
[249091f]269 def gitLog = sh(returnStdout: true, script: "git rev-list --format=short ${oldRef}...${newRef}").trim()
[fce01e7]270
[249091f]271 def gitDiff = sh(returnStdout: true, script: "git diff --stat --color ${newRef} ${oldRef}").trim()
[fce01e7]272 gitDiff = gitDiff.replace('[32m', '<span style="color: #00AA00;">')
273 gitDiff = gitDiff.replace('[31m', '<span style="color: #AA0000;">')
274 gitDiff = gitDiff.replace('[m', '</span>')
[7a927ed0]275
[a336d46]276 return """
[13c98a4]277<pre>
[848fb00]278The branch ${env.BRANCH_NAME} has been updated.
[7a927ed0]279${gitUpdate}
[13c98a4]280</pre>
281
282<p>Check console output at ${env.BUILD_URL} to view the results.</p>
[7b1a604]283
[13c98a4]284<p>- Status --------------------------------------------------------------</p>
[7b1a604]285
[13c98a4]286<p>BUILD# ${env.BUILD_NUMBER} - ${currentBuild.result}</p>
[7b1a604]287
[13c98a4]288<p>- Log -----------------------------------------------------------------</p>
[e8a22a7]289
[13c98a4]290<pre>
[7a927ed0]291${gitLog}
[13c98a4]292</pre>
293
294<p>-----------------------------------------------------------------------</p>
295<pre>
[7b1a604]296Summary of changes:
[7a927ed0]297${gitDiff}
[13c98a4]298</pre>
[7b1a604]299"""
[a336d46]300}
301
302//Standard build email notification
[13c98a4]303def email(boolean log) {
[a336d46]304 //Since tokenizer doesn't work, figure stuff out from the environnement variables and command line
305 //Configurations for email format
306 echo 'Notifying users of result'
307
308 def project_name = (env.JOB_NAME =~ /(.+)\/.+/)[0][1].toLowerCase()
309 def email_subject = "[${project_name} git][BUILD# ${env.BUILD_NUMBER} - ${currentBuild.result}] - branch ${env.BRANCH_NAME}"
[13c98a4]310 def email_body = """<p>This is an automated email from the Jenkins build machine. It was
[a336d46]311generated because of a git hooks/post-receive script following
[986e260]312a ref change which was pushed to the C\u2200 repository.</p>
[a336d46]313""" + GitLogMessage()
[e8a22a7]314
[13c98a4]315 def email_to = !Settings.IsSandbox ? "cforall@lists.uwaterloo.ca" : "tdelisle@uwaterloo.ca"
[e8a22a7]316
[13c98a4]317 if( Settings && !Settings.Silent ) {
[094a42c]318 //send email notification
319 emailext body: email_body, subject: email_subject, to: email_to, attachLog: log
320 } else {
321 echo "Would send email to: ${email_to}"
322 echo "With title: ${email_subject}"
323 echo "Content: \n${email_body}"
324 }
[e8a22a7]325}
[5b8413b4]326
327//===========================================================================================================
328// Helper classes/variables/routines
329//===========================================================================================================
330//Description of a compiler (Must be serializable since pipelines are persistent)
331class CC_Desc implements Serializable {
[93fe3154]332 public String name
333 public String CXX
[6ebc13f]334 public String CC
[bf22bc6]335 public String lto
[93fe3154]336
[bf22bc6]337 CC_Desc(String name, String CXX, String CC, String lto) {
[93fe3154]338 this.name = name
339 this.CXX = CXX
[bf22bc6]340 this.CC = CC
341 this.lto = lto
[5b8413b4]342 }
343}
344
345//Description of an architecture (Must be serializable since pipelines are persistent)
346class Arch_Desc implements Serializable {
347 public String name
348 public String flags
[5307c33]349 public String node
[5b8413b4]350
[5307c33]351 Arch_Desc(String name, String flags, String node) {
[5b8413b4]352 this.name = name
353 this.flags = flags
[5307c33]354 this.node = node
[5b8413b4]355 }
356}
357
358class BuildSettings implements Serializable {
359 public final CC_Desc Compiler
360 public final Arch_Desc Architecture
361 public final Boolean RunAllTests
362 public final Boolean RunBenchmark
363 public final Boolean BuildDocumentation
364 public final Boolean Publish
365 public final Boolean Silent
366 public final Boolean IsSandbox
367 public final String DescLong
368 public final String DescShort
369
[a336d46]370 public String GitNewRef
371 public String GitOldRef
372
[490cb3c]373 BuildSettings(java.util.Collections$UnmodifiableMap param, String branch) {
[5b8413b4]374 switch( param.Compiler ) {
[099f5bd]375 case 'gcc-9':
[bf22bc6]376 this.Compiler = new CC_Desc('gcc-9', 'g++-9', 'gcc-9', '-flto=auto')
[099f5bd]377 break
378 case 'gcc-8':
[bf22bc6]379 this.Compiler = new CC_Desc('gcc-8', 'g++-8', 'gcc-8', '-flto=auto')
[099f5bd]380 break
381 case 'gcc-7':
[bf22bc6]382 this.Compiler = new CC_Desc('gcc-7', 'g++-7', 'gcc-7', '-flto=auto')
[099f5bd]383 break
[5b8413b4]384 case 'gcc-6':
[bf22bc6]385 this.Compiler = new CC_Desc('gcc-6', 'g++-6', 'gcc-6', '-flto=auto')
[5b8413b4]386 break
387 case 'gcc-5':
[bf22bc6]388 this.Compiler = new CC_Desc('gcc-5', 'g++-5', 'gcc-5', '-flto=auto')
[5b8413b4]389 break
390 case 'gcc-4.9':
[bf22bc6]391 this.Compiler = new CC_Desc('gcc-4.9', 'g++-4.9', 'gcc-4.9', '-flto=auto')
[5b8413b4]392 break
393 case 'clang':
[bf22bc6]394 this.Compiler = new CC_Desc('clang', 'clang++-6.0', 'gcc-6', '-flto=thin -flto-jobs=0')
[5b8413b4]395 break
396 default :
397 error "Unhandled compiler : ${cc}"
398 }
399
400 switch( param.Architecture ) {
401 case 'x64':
[a3e8281]402 this.Architecture = new Arch_Desc('x64', '--host=x86_64', 'x64')
[5b8413b4]403 break
404 case 'x86':
[a3e8281]405 this.Architecture = new Arch_Desc('x86', '--host=i386', 'x86')
[5b8413b4]406 break
407 default :
408 error "Unhandled architecture : ${arch}"
409 }
410
[f95e8f0]411 this.IsSandbox = (branch == "jenkins-sandbox")
[5b8413b4]412 this.RunAllTests = param.RunAllTests
[7a230fd]413 this.RunBenchmark = param.RunBenchmark
[5b8413b4]414 this.BuildDocumentation = param.BuildDocumentation
[7a230fd]415 this.Publish = param.Publish
[5b8413b4]416 this.Silent = param.Silent
417
418 def full = param.RunAllTests ? " (Full)" : ""
[490cb3c]419 this.DescShort = "${ this.Compiler.name }:${ this.Architecture.name }${full}"
[5b8413b4]420
[93fe3154]421 this.DescLong = """Compiler : ${ this.Compiler.name } (${ this.Compiler.CXX }/${ this.Compiler.CC })
[5b8413b4]422Architecture : ${ this.Architecture.name }
423Arc Flags : ${ this.Architecture.flags }
424Run All Tests : ${ this.RunAllTests.toString() }
425Run Benchmark : ${ this.RunBenchmark.toString() }
426Build Documentation : ${ this.BuildDocumentation.toString() }
427Publish : ${ this.Publish.toString() }
428Silent : ${ this.Silent.toString() }
429"""
[a336d46]430
431 this.GitNewRef = ''
432 this.GitOldRef = ''
[5b8413b4]433 }
434}
435
[490cb3c]436class PlotGroup implements Serializable {
437 public String name
438 public String unit
439 public boolean log
440
441 PlotGroup(String name, String unit, boolean log) {
442 this.name = name
443 this.unit = unit
444 this.log = log
445 }
446}
447
[5b8413b4]448def prepare_build() {
449 // prepare the properties
450 properties ([ \
[62f96ae]451 buildDiscarder(logRotator( \
452 artifactDaysToKeepStr: '', \
453 artifactNumToKeepStr: '', \
454 daysToKeepStr: '730', \
455 numToKeepStr: '1000' \
456 )), \
[5b8413b4]457 [$class: 'ParametersDefinitionProperty', \
458 parameterDefinitions: [ \
459 [$class: 'ChoiceParameterDefinition', \
460 description: 'Which compiler to use', \
461 name: 'Compiler', \
[c09ae73]462 choices: 'gcc-9\ngcc-8\ngcc-7\ngcc-6\ngcc-5\ngcc-4.9\nclang', \
[fe27d99]463 defaultValue: 'gcc-8', \
[5b8413b4]464 ], \
465 [$class: 'ChoiceParameterDefinition', \
466 description: 'The target architecture', \
467 name: 'Architecture', \
468 choices: 'x64\nx86', \
469 defaultValue: 'x64', \
470 ], \
471 [$class: 'BooleanParameterDefinition', \
472 description: 'If false, only the quick test suite is ran', \
473 name: 'RunAllTests', \
474 defaultValue: false, \
475 ], \
476 [$class: 'BooleanParameterDefinition', \
477 description: 'If true, jenkins also runs benchmarks', \
478 name: 'RunBenchmark', \
479 defaultValue: false, \
480 ], \
481 [$class: 'BooleanParameterDefinition', \
482 description: 'If true, jenkins also builds documentation', \
483 name: 'BuildDocumentation', \
484 defaultValue: true, \
485 ], \
486 [$class: 'BooleanParameterDefinition', \
487 description: 'If true, jenkins also publishes results', \
488 name: 'Publish', \
489 defaultValue: false, \
490 ], \
491 [$class: 'BooleanParameterDefinition', \
492 description: 'If true, jenkins will not send emails', \
493 name: 'Silent', \
494 defaultValue: false, \
495 ], \
496 ],
497 ]])
498
[4c55047]499 // It's unfortunate but it looks like we need to checkout the entire repo just to get the pretty git printer
500 checkout scm
[2407853]501
[490cb3c]502 final settings = new BuildSettings(params, env.BRANCH_NAME)
[5b8413b4]503
504 currentBuild.description = settings.DescShort
505 echo settings.DescLong
506
507 return settings
508}
509
[6c55a3d]510def build_stage(String name, boolean run, Closure block ) {
[5b8413b4]511 StageName = name
512 echo " -------- ${StageName} -------- "
[8ecb590]513 if(run) {
514 stage(name, block)
515 } else {
516 stage(name) { Utils.markStageSkippedForConditional(STAGE_NAME) }
517 }
[5b8413b4]518}
519
520def make_doc() {
521 def err = null
522 try {
523 sh 'make clean > /dev/null'
524 sh 'make > /dev/null 2>&1'
525 }
526 catch (Exception caughtError) {
527 err = caughtError //rethrow error later
[65f4a51]528 sh 'cat build/*.log'
[5b8413b4]529 }
530 finally {
531 if (err) throw err // Must re-throw exception to propagate error
532 }
[a2a0065]533}
534
[3221a2b]535def do_plot(boolean new_data, String file, PlotGroup group, boolean relative, String title) {
[8d63649]536
[1b3eef8]537 if(new_data) {
538 echo "Publishing new data"
539 }
540
[cdcd53dc]541 def series = new_data ? [[
[df57a84]542 file: "${file}.csv",
[3c40dc2a]543 exclusionValues: '',
544 displayTableFlag: false,
545 inclusionFlag: 'OFF',
546 url: ''
[cdcd53dc]547 ]] : [];
[8d63649]548
549 echo "file is ${BuildDir}/benchmark/${file}.csv, group ${group}, title ${title}"
550 dir("${BuildDir}/benchmark/") {
551 plot csvFileName: "cforall-${env.BRANCH_NAME}-${file}.csv",
552 csvSeries: series,
[490cb3c]553 group: "${group.name}",
[3c40dc2a]554 title: "${title}",
555 style: 'lineSimple',
556 exclZero: false,
557 keepRecords: false,
[3221a2b]558 logarithmic: !relative && group.log,
[3c40dc2a]559 numBuilds: '120',
560 useDescr: true,
[490cb3c]561 yaxis: group.unit,
[3c40dc2a]562 yaxisMaximum: '',
563 yaxisMinimum: ''
[df57a84]564 }
565}
Note: See TracBrowser for help on using the repository browser.