source: Jenkinsfile @ d971c8d

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

Forgot to stage som stuff

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