source: Jenkinsfile @ a8d8547

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

Fix error in previous commit

  • Property mode set to 100644
File size: 15.0 KB
Line 
1#!groovy
2
3import groovy.transform.Field
4
5//===========================================================================================================
6// Main loop of the compilation
7//===========================================================================================================
8
9// Globals
10BuildDir  = ""
11SrcDir    = ""
12Settings  = null
13Tools     = null
14
15// Local variables
16def err = null
17def log_needed = false
18
19currentBuild.result = "SUCCESS"
20
21try {
22        //Wrap build to add timestamp to command line
23        wrap([$class: 'TimestamperBuildWrapper']) {
24
25                node {
26                        Settings = prepare_build()
27                }
28
29                node(Settings.Architecture.node) {
30                        BuildDir  = pwd tmp: true
31                        SrcDir    = pwd tmp: false
32                        currentBuild.description = "${currentBuild.description} on ${env.NODE_NAME}"
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}
50
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"
56
57        // An error has occured, the build log is relevent
58        log_needed = true
59
60        // rethrow error later
61        err = caughtError
62
63        // print the error so it shows in the log
64        echo err.toString()
65}
66
67finally {
68        //Send email with final results if this is not a full build
69        email(log_needed)
70
71        echo 'Build Completed'
72
73        /* Must re-throw exception to propagate error */
74        if (err) {
75                throw err
76        }
77}
78//===========================================================================================================
79// Main compilation routines
80//===========================================================================================================
81def build() {
82        debug = true
83        release = Settings.RunAllTests || Settings.RunBenchmark
84        Tools.BuildStage('Build : configure', true) {
85                // Configure must be run inside the tree
86                dir (SrcDir) {
87                        // Generate the necessary build files
88                        sh './autogen.sh'
89                }
90
91                // Build outside of the src tree to ease cleaning
92                dir (BuildDir) {
93                        //Configure the compilation (Output is not relevant)
94                        //Use the current directory as the installation target so nothing escapes the sandbox
95                        //Also specify the compiler by hand
96                        targets=""
97                        if( Settings.RunAllTests || Settings.RunBenchmark ) {
98                                targets="--with-target-hosts='host:debug,host:nodebug'"
99                        } else {
100                                targets="--with-target-hosts='host:debug'"
101                        }
102
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}"
106
107                        // Configure libcfa
108                        sh 'make -j 8 --no-print-directory configure-libcfa'
109                }
110        }
111
112        Tools.BuildStage('Build : cfa-cpp', true) {
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        }
122
123        Tools.BuildStage('Build : libcfa(debug)', debug) {
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
130        Tools.BuildStage('Build : libcfa(nodebug)', release) {
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"
134                }
135        }
136
137        Tools.BuildStage('Build : install', true) {
138                // Build outside of the src tree to ease cleaning
139                dir (BuildDir) {
140                        sh "make -j 8 --no-print-directory install"
141                }
142        }
143}
144
145def test() {
146        try {
147                // Print potential limits before testing
148                // in case jenkins messes with them
149                sh 'free -h'
150                sh 'ulimit -a'
151
152                Tools.BuildStage('Test: short', !Settings.RunAllTests) {
153                        dir (BuildDir) {
154                                //Run the tests from the tests directory
155                                sh "make --no-print-directory -C tests archiveerrors=${BuildDir}/tests/crashes/short"
156                        }
157                }
158
159                Tools.BuildStage('Test: full', Settings.RunAllTests) {
160                        dir (BuildDir) {
161                                        //Run the tests from the tests directory
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"""
164                        }
165                }
166        }
167        catch (Exception err) {
168                echo "Archiving core dumps"
169                dir (BuildDir) {
170                        def exists = fileExists 'tests/crashes'
171                        if( exists ) {
172                                sh """${SrcDir}/tools/jenkins/archive-gen.sh"""
173                                archiveArtifacts artifacts: "tests/crashes/**/*,lib/**/lib*.so*,setup.sh", fingerprint: true
174                        }
175                }
176                throw err
177        }
178}
179
180def benchmark() {
181        Tools.BuildStage('Benchmark', Settings.RunBenchmark) {
182                dir (BuildDir) {
183                        //Append bench results
184                        sh "make --no-print-directory -C benchmark jenkins arch=${Settings.Architecture.name}"
185                }
186        }
187}
188
189def build_doc() {
190        Tools.BuildStage('Documentation', Settings.BuildDocumentation) {
191                dir ('doc/user') {
192                        make_doc()
193                }
194
195                dir ('doc/refrat') {
196                        make_doc()
197                }
198        }
199}
200
201def publish() {
202        Tools.BuildStage('Publish', true) {
203
204                if( Settings.Publish && !Settings.RunBenchmark ) { echo 'No results to publish!!!' }
205
206                def groupCompile = new PlotGroup('Compilation', 'duration (s) - lower is better', true)
207                def groupConcurrency = new PlotGroup('Concurrency', 'duration (n) - lower is better', false)
208
209                //Then publish the results
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)')
218        }
219}
220
221//===========================================================================================================
222//Routine responsible of sending the email notification once the build is completed
223//===========================================================================================================
224//Standard build email notification
225def email(boolean log) {
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}"
232        def email_body = """<p>This is an automated email from the Jenkins build machine. It was
233generated because of a git hooks/post-receive script following
234a ref change which was pushed to the C\u2200 repository.</p>
235""" + Tools.GitLogMessage()
236
237        def email_to = !Settings.IsSandbox ? "cforall@lists.uwaterloo.ca" : "tdelisle@uwaterloo.ca"
238
239        if( Settings && !Settings.Silent ) {
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        }
247}
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 {
254        public String name
255        public String CXX
256        public String CC
257        public String lto
258
259        CC_Desc(String name, String CXX, String CC, String lto) {
260                this.name = name
261                this.CXX = CXX
262                this.CC  = CC
263                this.lto = lto
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
271        public String node
272
273        Arch_Desc(String name, String flags, String node) {
274                this.name  = name
275                this.flags = flags
276                this.node  = node
277        }
278}
279
280class BuildSettings implements Serializable {
281        public final CC_Desc Compiler
282        public final Arch_Desc Architecture
283        public final Boolean NewAST
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
293        public String GitNewRef
294        public String GitOldRef
295
296        BuildSettings(java.util.Collections$UnmodifiableMap param, String branch) {
297                switch( param.Compiler ) {
298                        case 'gcc-9':
299                                this.Compiler = new CC_Desc('gcc-9', 'g++-9', 'gcc-9', '-flto=auto')
300                        break
301                        case 'gcc-8':
302                                this.Compiler = new CC_Desc('gcc-8', 'g++-8', 'gcc-8', '-flto=auto')
303                        break
304                        case 'gcc-7':
305                                this.Compiler = new CC_Desc('gcc-7', 'g++-7', 'gcc-7', '-flto=auto')
306                        break
307                        case 'gcc-6':
308                                this.Compiler = new CC_Desc('gcc-6', 'g++-6', 'gcc-6', '-flto=auto')
309                        break
310                        case 'gcc-5':
311                                this.Compiler = new CC_Desc('gcc-5', 'g++-5', 'gcc-5', '-flto=auto')
312                        break
313                        case 'gcc-4.9':
314                                this.Compiler = new CC_Desc('gcc-4.9', 'g++-4.9', 'gcc-4.9', '-flto=auto')
315                        break
316                        case 'clang':
317                                this.Compiler = new CC_Desc('clang', 'clang++-10', 'gcc-9', '-flto=thin -flto-jobs=0')
318                        break
319                        default :
320                                error "Unhandled compiler : ${cc}"
321                }
322
323                switch( param.Architecture ) {
324                        case 'x64':
325                                this.Architecture = new Arch_Desc('x64', '--host=x86_64', 'x64')
326                        break
327                        case 'x86':
328                                this.Architecture = new Arch_Desc('x86', '--host=i386', 'x86')
329                        break
330                        default :
331                                error "Unhandled architecture : ${arch}"
332                }
333
334                this.IsSandbox          = (branch == "jenkins-sandbox")
335                this.NewAST             = param.NewAST
336                this.RunAllTests        = param.RunAllTests
337                this.RunBenchmark       = param.RunBenchmark
338                this.BuildDocumentation = param.BuildDocumentation
339                this.Publish            = param.Publish
340                this.Silent             = param.Silent
341
342                def full = param.RunAllTests ? " (Full)" : ""
343                this.DescShort = "${ this.Compiler.name }:${ this.Architecture.name }${full}"
344
345                final ast = this.NewAST ? "New AST" : "Old AST"
346                this.DescLong = """Compiler              : ${ this.Compiler.name } (${ this.Compiler.CXX }/${ this.Compiler.CC })
347AST Version             : ${ ast.toString() }
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"""
356
357                this.GitNewRef = ''
358                this.GitOldRef = ''
359        }
360}
361
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
374def prepare_build() {
375        // prepare the properties
376        properties ([                                                                                                   \
377                buildDiscarder(logRotator(                                                                              \
378                        artifactDaysToKeepStr: '',                                                                      \
379                        artifactNumToKeepStr: '',                                                                       \
380                        daysToKeepStr: '730',                                                                           \
381                        numToKeepStr: '1000'                                                                            \
382                )),                                                                                                             \
383                [$class: 'ParametersDefinitionProperty',                                                                \
384                        parameterDefinitions: [                                                                         \
385                                [$class: 'ChoiceParameterDefinition',                                           \
386                                        description: 'Which compiler to use',                                   \
387                                        name: 'Compiler',                                                                       \
388                                        choices: 'gcc-9\ngcc-8\ngcc-7\ngcc-6\ngcc-5\ngcc-4.9\nclang',   \
389                                        defaultValue: 'gcc-8',                                                          \
390                                ],                                                                                              \
391                                [$class: 'ChoiceParameterDefinition',                                           \
392                                        description: 'The target architecture',                                 \
393                                        name: 'Architecture',                                                           \
394                                        choices: 'x64\nx86',                                                            \
395                                        defaultValue: 'x64',                                                            \
396                                ],                                                                                              \
397                                [$class: 'BooleanParameterDefinition',                                                  \
398                                        description: 'If true, build compiler using new AST',           \
399                                        name: 'NewAST',                                                                         \
400                                        defaultValue: true,                                                             \
401                                ],                                                                                              \
402                                [$class: 'BooleanParameterDefinition',                                                  \
403                                        description: 'If false, only the quick test suite is ran',              \
404                                        name: 'RunAllTests',                                                            \
405                                        defaultValue: false,                                                            \
406                                ],                                                                                              \
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
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
433        checkout scm
434
435        Tools = load "Jenkins/tools.groovy"
436
437        final settings = new BuildSettings(params, env.BRANCH_NAME)
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
453                sh 'cat build/*.log'
454        }
455        finally {
456                if (err) throw err // Must re-throw exception to propagate error
457        }
458}
459
460def do_plot(boolean new_data, String file, PlotGroup group, boolean relative, String title) {
461
462        if(new_data) {
463                echo "Publishing new data"
464        }
465
466        def series = new_data ? [[
467                                file: "${file}.csv",
468                                exclusionValues: '',
469                                displayTableFlag: false,
470                                inclusionFlag: 'OFF',
471                                url: ''
472                        ]] : [];
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,
478                        group: "${group.name}",
479                        title: "${title}",
480                        style: 'lineSimple',
481                        exclZero: false,
482                        keepRecords: false,
483                        logarithmic: !relative && group.log,
484                        numBuilds: '120',
485                        useDescr: true,
486                        yaxis: group.unit,
487                        yaxisMaximum: '',
488                        yaxisMinimum: ''
489        }
490}
Note: See TracBrowser for help on using the repository browser.