source: Jenkinsfile @ b399ca2

ADTarm-ehast-experimentalenumforall-pointer-decayjacob/cs343-translationnew-ast-unique-exprpthread-emulationqualifiedEnum
Last change on this file since b399ca2 was b399ca2, checked in by Thierry Delisle <tdelisle@…>, 3 years ago

Testing some scripting options

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