source: Jenkinsfile @ 74b0de43

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

Tentative to lint FullBuild? on fast compile

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