source: Jenkinsfile@ 8e2cb4a

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

Jenkins file now calls autogen.sh before building

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