source: Jenkinsfile @ 302d84c2

ADTarm-ehast-experimentalenumforall-pointer-decayjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-exprpthread-emulationqualifiedEnum
Last change on this file since 302d84c2 was e70e54e, checked in by Thierry Delisle <tdelisle@…>, 5 years ago

Added configure-libcfa target to help jenkins build in steps

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