source: Jenkinsfile@ c0c8962

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 c0c8962 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
RevLine 
[a63ad80]1#!groovy
2
[7a230fd]3import groovy.transform.Field
4
[29f4fe62]5//===========================================================================================================
[9beae23]6// Main loop of the compilation
[29f4fe62]7//===========================================================================================================
[56a9ce6]8
[85142648]9node('master') {
10 // Globals
11 BuildDir = pwd tmp: true
12 SrcDir = pwd tmp: false
13 Settings = null
[1483a16]14 Tools = null
[4f9e706]15
[85142648]16 // Local variables
17 def err = null
18 def log_needed = false
[5b8413b4]19
[85142648]20 currentBuild.result = "SUCCESS"
[4f9e706]21
[85142648]22 try {
23 //Wrap build to add timestamp to command line
24 wrap([$class: 'TimestamperBuildWrapper']) {
[0ef06b6]25
[85142648]26 Settings = prepare_build()
[952ee7a]27
[85142648]28 node(Settings.Architecture.node) {
[9dd31e7]29 BuildDir = pwd tmp: true
30 SrcDir = pwd tmp: false
[7684557]31 currentBuild.description = "${currentBuild.description} on ${env.NODE_NAME}"
[23a14d86]32
[9dd31e7]33 Tools.Clean()
[7aebc62]34
[9dd31e7]35 Tools.Checkout()
[fde808df]36
[9dd31e7]37 build()
[95fdb0a]38
[9dd31e7]39 test()
[95fdb0a]40
[9dd31e7]41 benchmark()
[95fdb0a]42
[9dd31e7]43 build_doc()
[7359098]44
[9dd31e7]45 publish()
[85142648]46 }
[9beae23]47
[85142648]48 // Update the build directories when exiting the node
49 BuildDir = pwd tmp: true
50 SrcDir = pwd tmp: false
[9beae23]51 }
[738cf8f]52 }
53
[85142648]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) {
[9dd31e7]57 // Store the result of the build log
58 currentBuild.result = "FAILURE"
59
60 // An error has occured, the build log is relevent
[85142648]61 log_needed = true
[9beae23]62
[9dd31e7]63 // rethrow error later
[852ae0ea]64 err = caughtError
65
[9dd31e7]66 // print the error so it shows in the log
[852ae0ea]67 echo err.toString()
[85142648]68 }
[738cf8f]69
[85142648]70 finally {
71 //Send email with final results if this is not a full build
72 email(log_needed)
[9beae23]73
[85142648]74 echo 'Build Completed'
[734891d]75
[85142648]76 /* Must re-throw exception to propagate error */
77 if (err) {
78 throw err
79 }
[738cf8f]80 }
81}
[29f4fe62]82//===========================================================================================================
[9beae23]83// Main compilation routines
[29f4fe62]84//===========================================================================================================
[95fdb0a]85def build() {
[e507c11]86 debug = true
87 release = Settings.RunAllTests || Settings.RunBenchmark
[91aa5ab]88 Tools.BuildStage('Build : configure', true) {
[dcf1979]89 // Configure must be run inside the tree
90 dir (SrcDir) {
91 // Generate the necessary build files
92 sh './autogen.sh'
93 }
94
[50f2cfc]95 // Build outside of the src tree to ease cleaning
[5b8413b4]96 dir (BuildDir) {
[8e58264]97 //Configure the compilation (Output is not relevant)
[50f2cfc]98 //Use the current directory as the installation target so nothing escapes the sandbox
99 //Also specify the compiler by hand
[3fc5f010]100 targets=""
[d4510ea]101 if( Settings.RunAllTests || Settings.RunBenchmark ) {
[6bde81d]102 targets="--with-target-hosts='host:debug,host:nodebug'"
[3fc5f010]103 } else {
[6bde81d]104 targets="--with-target-hosts='host:debug'"
[3fc5f010]105 }
106
[d21dd3cb]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}"
[f253e4a]110
111 // Configure libcfa
[e70e54e]112 sh 'make -j 8 --no-print-directory configure-libcfa'
[e507c11]113 }
114 }
115
[91aa5ab]116 Tools.BuildStage('Build : cfa-cpp', true) {
[e507c11]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 }
[1752d0e]126
[91aa5ab]127 Tools.BuildStage('Build : libcfa(debug)', debug) {
[e507c11]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
[91aa5ab]134 Tools.BuildStage('Build : libcfa(nodebug)', release) {
[e507c11]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"
[50f2cfc]138 }
[620dd2b]139 }
[aa96fba]140
[91aa5ab]141 Tools.BuildStage('Build : install', true) {
[aa96fba]142 // Build outside of the src tree to ease cleaning
143 dir (BuildDir) {
144 sh "make -j 8 --no-print-directory install"
145 }
146 }
[95fdb0a]147}
[24eecab]148
[95fdb0a]149def test() {
[4c1b9ea8]150 try {
[1baf6ed]151 // Print potential limits before testing
152 // in case jenkins messes with them
[a33dcd5]153 sh 'free -h'
[1baf6ed]154 sh 'ulimit -a'
155
[91aa5ab]156 Tools.BuildStage('Test: short', !Settings.RunAllTests) {
[4c1b9ea8]157 dir (BuildDir) {
[3e93c00]158 //Run the tests from the tests directory
[4c51aca]159 sh "make --no-print-directory -C tests archiveerrors=${BuildDir}/tests/crashes/short"
[3e93c00]160 }
[4c1b9ea8]161 }
162
[91aa5ab]163 Tools.BuildStage('Test: full', Settings.RunAllTests) {
[4c1b9ea8]164 dir (BuildDir) {
165 //Run the tests from the tests directory
[4c51aca]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"""
[143e6f3]168 }
[9beae23]169 }
[620dd2b]170 }
[4c1b9ea8]171 catch (Exception err) {
172 echo "Archiving core dumps"
[c95fdc9]173 dir (BuildDir) {
[cece53c]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 }
[c95fdc9]178 }
[4c1b9ea8]179 throw err
180 }
[95fdb0a]181}
182
183def benchmark() {
[91aa5ab]184 Tools.BuildStage('Benchmark', Settings.RunBenchmark) {
[5b8413b4]185 dir (BuildDir) {
[0dc3ac3]186 //Append bench results
[c6f1f3e]187 sh "make --no-print-directory -C benchmark jenkins arch=${Settings.Architecture.name}"
[0dc3ac3]188 }
[620dd2b]189 }
[9beae23]190}
[efd60d67]191
[95fdb0a]192def build_doc() {
[91aa5ab]193 Tools.BuildStage('Documentation', Settings.BuildDocumentation) {
[9beae23]194 dir ('doc/user') {
195 make_doc()
196 }
197
198 dir ('doc/refrat') {
199 make_doc()
200 }
[620dd2b]201 }
[9beae23]202}
203
[95fdb0a]204def publish() {
[91aa5ab]205 Tools.BuildStage('Publish', true) {
[95fdb0a]206
[1b3eef8]207 if( Settings.Publish && !Settings.RunBenchmark ) { echo 'No results to publish!!!' }
[95fdb0a]208
[3221a2b]209 def groupCompile = new PlotGroup('Compilation', 'duration (s) - lower is better', true)
210 def groupConcurrency = new PlotGroup('Concurrency', 'duration (n) - lower is better', false)
[a2a0065]211
[3898392]212 //Then publish the results
[13d2dac]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)')
[620dd2b]221 }
[95fdb0a]222}
223
[29f4fe62]224//===========================================================================================================
225//Routine responsible of sending the email notification once the build is completed
226//===========================================================================================================
[a336d46]227//Standard build email notification
[13c98a4]228def email(boolean log) {
[a336d46]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}"
[13c98a4]235 def email_body = """<p>This is an automated email from the Jenkins build machine. It was
[a336d46]236generated because of a git hooks/post-receive script following
[986e260]237a ref change which was pushed to the C\u2200 repository.</p>
[6a531ab]238""" + Tools.GitLogMessage()
[e8a22a7]239
[13c98a4]240 def email_to = !Settings.IsSandbox ? "cforall@lists.uwaterloo.ca" : "tdelisle@uwaterloo.ca"
[e8a22a7]241
[13c98a4]242 if( Settings && !Settings.Silent ) {
[094a42c]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 }
[e8a22a7]250}
[5b8413b4]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 {
[93fe3154]257 public String name
258 public String CXX
[6ebc13f]259 public String CC
[bf22bc6]260 public String lto
[93fe3154]261
[bf22bc6]262 CC_Desc(String name, String CXX, String CC, String lto) {
[93fe3154]263 this.name = name
264 this.CXX = CXX
[bf22bc6]265 this.CC = CC
266 this.lto = lto
[5b8413b4]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
[5307c33]274 public String node
[5b8413b4]275
[5307c33]276 Arch_Desc(String name, String flags, String node) {
[5b8413b4]277 this.name = name
278 this.flags = flags
[5307c33]279 this.node = node
[5b8413b4]280 }
281}
282
283class BuildSettings implements Serializable {
284 public final CC_Desc Compiler
285 public final Arch_Desc Architecture
[d21dd3cb]286 public final Boolean NewAST
[5b8413b4]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
[a336d46]296 public String GitNewRef
297 public String GitOldRef
298
[490cb3c]299 BuildSettings(java.util.Collections$UnmodifiableMap param, String branch) {
[5b8413b4]300 switch( param.Compiler ) {
[099f5bd]301 case 'gcc-9':
[bf22bc6]302 this.Compiler = new CC_Desc('gcc-9', 'g++-9', 'gcc-9', '-flto=auto')
[099f5bd]303 break
304 case 'gcc-8':
[bf22bc6]305 this.Compiler = new CC_Desc('gcc-8', 'g++-8', 'gcc-8', '-flto=auto')
[099f5bd]306 break
307 case 'gcc-7':
[bf22bc6]308 this.Compiler = new CC_Desc('gcc-7', 'g++-7', 'gcc-7', '-flto=auto')
[099f5bd]309 break
[5b8413b4]310 case 'gcc-6':
[bf22bc6]311 this.Compiler = new CC_Desc('gcc-6', 'g++-6', 'gcc-6', '-flto=auto')
[5b8413b4]312 break
313 case 'gcc-5':
[bf22bc6]314 this.Compiler = new CC_Desc('gcc-5', 'g++-5', 'gcc-5', '-flto=auto')
[5b8413b4]315 break
316 case 'gcc-4.9':
[bf22bc6]317 this.Compiler = new CC_Desc('gcc-4.9', 'g++-4.9', 'gcc-4.9', '-flto=auto')
[5b8413b4]318 break
319 case 'clang':
[391c065]320 this.Compiler = new CC_Desc('clang', 'clang++-10', 'gcc-9', '-flto=thin -flto-jobs=0')
[5b8413b4]321 break
322 default :
323 error "Unhandled compiler : ${cc}"
324 }
325
326 switch( param.Architecture ) {
327 case 'x64':
[a3e8281]328 this.Architecture = new Arch_Desc('x64', '--host=x86_64', 'x64')
[5b8413b4]329 break
330 case 'x86':
[a3e8281]331 this.Architecture = new Arch_Desc('x86', '--host=i386', 'x86')
[5b8413b4]332 break
333 default :
334 error "Unhandled architecture : ${arch}"
335 }
336
[f95e8f0]337 this.IsSandbox = (branch == "jenkins-sandbox")
[d21dd3cb]338 this.NewAST = param.NewAST
[5b8413b4]339 this.RunAllTests = param.RunAllTests
[7a230fd]340 this.RunBenchmark = param.RunBenchmark
[5b8413b4]341 this.BuildDocumentation = param.BuildDocumentation
[7a230fd]342 this.Publish = param.Publish
[5b8413b4]343 this.Silent = param.Silent
344
345 def full = param.RunAllTests ? " (Full)" : ""
[490cb3c]346 this.DescShort = "${ this.Compiler.name }:${ this.Architecture.name }${full}"
[5b8413b4]347
[fe3d9ab]348 final ast = this.NewAST ? "New AST" : "Old AST"
[93fe3154]349 this.DescLong = """Compiler : ${ this.Compiler.name } (${ this.Compiler.CXX }/${ this.Compiler.CC })
[85799aa]350AST Version : ${ ast.toString() }
[5b8413b4]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"""
[a336d46]359
360 this.GitNewRef = ''
361 this.GitOldRef = ''
[5b8413b4]362 }
363}
364
[490cb3c]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
[5b8413b4]377def prepare_build() {
378 // prepare the properties
379 properties ([ \
[62f96ae]380 buildDiscarder(logRotator( \
381 artifactDaysToKeepStr: '', \
382 artifactNumToKeepStr: '', \
383 daysToKeepStr: '730', \
384 numToKeepStr: '1000' \
385 )), \
[5b8413b4]386 [$class: 'ParametersDefinitionProperty', \
387 parameterDefinitions: [ \
388 [$class: 'ChoiceParameterDefinition', \
389 description: 'Which compiler to use', \
390 name: 'Compiler', \
[c09ae73]391 choices: 'gcc-9\ngcc-8\ngcc-7\ngcc-6\ngcc-5\ngcc-4.9\nclang', \
[fe27d99]392 defaultValue: 'gcc-8', \
[5b8413b4]393 ], \
394 [$class: 'ChoiceParameterDefinition', \
395 description: 'The target architecture', \
396 name: 'Architecture', \
397 choices: 'x64\nx86', \
398 defaultValue: 'x64', \
399 ], \
[d21dd3cb]400 [$class: 'BooleanParameterDefinition', \
401 description: 'If true, build compiler using new AST', \
402 name: 'NewAST', \
[6a531ab]403 defaultValue: true, \
[d21dd3cb]404 ], \
[5b8413b4]405 [$class: 'BooleanParameterDefinition', \
406 description: 'If false, only the quick test suite is ran', \
407 name: 'RunAllTests', \
408 defaultValue: false, \
[fe3d9ab]409 ], \
[5b8413b4]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
[bd8dca2]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
[4c55047]436 checkout scm
[2407853]437
[1483a16]438 Tools = load "Jenkins/tools.groovy"
[bd8dca2]439
[490cb3c]440 final settings = new BuildSettings(params, env.BRANCH_NAME)
[5b8413b4]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
[65f4a51]456 sh 'cat build/*.log'
[5b8413b4]457 }
458 finally {
459 if (err) throw err // Must re-throw exception to propagate error
460 }
[a2a0065]461}
462
[3221a2b]463def do_plot(boolean new_data, String file, PlotGroup group, boolean relative, String title) {
[8d63649]464
[1b3eef8]465 if(new_data) {
466 echo "Publishing new data"
467 }
468
[cdcd53dc]469 def series = new_data ? [[
[df57a84]470 file: "${file}.csv",
[3c40dc2a]471 exclusionValues: '',
472 displayTableFlag: false,
473 inclusionFlag: 'OFF',
474 url: ''
[cdcd53dc]475 ]] : [];
[8d63649]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,
[490cb3c]481 group: "${group.name}",
[3c40dc2a]482 title: "${title}",
483 style: 'lineSimple',
484 exclZero: false,
485 keepRecords: false,
[3221a2b]486 logarithmic: !relative && group.log,
[3c40dc2a]487 numBuilds: '120',
488 useDescr: true,
[490cb3c]489 yaxis: group.unit,
[3c40dc2a]490 yaxisMaximum: '',
491 yaxisMinimum: ''
[df57a84]492 }
493}
Note: See TracBrowser for help on using the repository browser.