source: Jenkinsfile@ a8d8547

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

Fix error in previous commit

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