source: Jenkinsfile @ 847bb6f

ADTast-experimentalpthread-emulationqualifiedEnum
Last change on this file since 847bb6f was 4f3807d, checked in by Thierry Delisle <tdelisle@…>, 2 years ago

Removed jenkins performance plots since they were not very useful

  • Property mode set to 100644
File size: 13.5 KB
Line 
1#!groovy
2
3import groovy.transform.Field
4
5//===========================================================================================================
6// Main loop of the compilation
7//===========================================================================================================
8
9// Globals
10BuildDir  = null
11SrcDir    = null
12Settings  = null
13Tools     = null
14
15// Local variables
16def err = null
17def log_needed = false
18
19currentBuild.result = "SUCCESS"
20
21try {
22        node {
23                //Wrap build to add timestamp to command line
24                wrap([$class: 'TimestamperBuildWrapper']) {
25                        Settings = prepare_build()
26                }
27        }
28
29        node(Settings.Architecture.node) {
30                //Wrap build to add timestamp to command line
31                wrap([$class: 'TimestamperBuildWrapper']) {
32                        BuildDir  = pwd tmp: true
33                        SrcDir    = pwd tmp: false
34                        currentBuild.description = "${currentBuild.description} on ${env.NODE_NAME}"
35
36                        Tools.Clean()
37
38                        Tools.Checkout()
39
40                        build()
41
42                        test()
43
44                        benchmark()
45
46                        build_doc()
47
48                        publish()
49                }
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
55catch (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
69finally {
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// Main compilation routines
82//===========================================================================================================
83def build() {
84        debug = true
85        release = Settings.RunAllTests || Settings.RunBenchmark
86        Tools.BuildStage('Build : configure', true) {
87                // Configure must be run inside the tree
88                dir (SrcDir) {
89                        // Generate the necessary build files
90                        sh './autogen.sh'
91                }
92
93                // Build outside of the src tree to ease cleaning
94                dir (BuildDir) {
95                        //Configure the compilation (Output is not relevant)
96                        //Use the current directory as the installation target so nothing escapes the sandbox
97                        //Also specify the compiler by hand
98                        targets=""
99                        if( Settings.RunAllTests || Settings.RunBenchmark ) {
100                                targets="--with-target-hosts='host:debug,host:nodebug'"
101                        } else {
102                                targets="--with-target-hosts='host:debug'"
103                        }
104
105                        ast = Settings.NewAST ? "--enable-new-ast" : "--disable-new-ast"
106
107                        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}"
108
109                        // Configure libcfa
110                        sh 'make -j $(nproc) --no-print-directory configure-libcfa'
111                }
112        }
113
114        Tools.BuildStage('Build : cfa-cpp', true) {
115                // Build outside of the src tree to ease cleaning
116                dir (BuildDir) {
117                        // Build driver
118                        sh 'make -j $(nproc) --no-print-directory -C driver'
119
120                        // Build translator
121                        sh 'make -j $(nproc) --no-print-directory -C src'
122                }
123        }
124
125        Tools.BuildStage('Build : libcfa(debug)', debug) {
126                // Build outside of the src tree to ease cleaning
127                dir (BuildDir) {
128                        sh "make -j \$(nproc) --no-print-directory -C libcfa/${Settings.Architecture.name}-debug"
129                }
130        }
131
132        Tools.BuildStage('Build : libcfa(nodebug)', release) {
133                // Build outside of the src tree to ease cleaning
134                dir (BuildDir) {
135                        sh "make -j \$(nproc) --no-print-directory -C libcfa/${Settings.Architecture.name}-nodebug"
136                }
137        }
138
139        Tools.BuildStage('Build : install', true) {
140                // Build outside of the src tree to ease cleaning
141                dir (BuildDir) {
142                        sh 'make -j $(nproc) --no-print-directory install'
143                }
144        }
145}
146
147def test() {
148        try {
149                // Print potential limits before testing
150                // in case jenkins messes with them
151                sh 'free -h'
152                sh 'ulimit -a'
153
154                Tools.BuildStage('Test: short', !Settings.RunAllTests) {
155                        dir (BuildDir) {
156                                //Run the tests from the tests directory
157                                sh "make --no-print-directory -C tests archiveerrors=${BuildDir}/tests/crashes/short"
158                        }
159                }
160
161                Tools.BuildStage('Test: full', Settings.RunAllTests) {
162                        dir (BuildDir) {
163                                        jopt = '-j $(nproc)'
164                                        if( Settings.Architecture.node == 'x86' ) {
165                                                jopt = '-j2'
166                                        }
167                                        //Run the tests from the tests directory
168                                        sh """make ${jopt} --no-print-directory -C tests timeouts="--timeout=600 --global-timeout=14400" all-tests debug=yes archiveerrors=${BuildDir}/tests/crashes/full-debug"""
169                                        sh """make ${jopt} --no-print-directory -C tests timeouts="--timeout=600 --global-timeout=14400" all-tests debug=no  archiveerrors=${BuildDir}/tests/crashes/full-nodebug"""
170                        }
171                }
172        }
173        catch (Exception err) {
174                echo "Archiving core dumps"
175                dir (BuildDir) {
176                        def exists = fileExists 'tests/crashes'
177                        if( exists ) {
178                                sh """${SrcDir}/tools/jenkins/archive-gen.sh"""
179                                archiveArtifacts artifacts: "tests/crashes/**/*,lib/**/lib*.so*,setup.sh", fingerprint: true
180                        }
181                }
182                throw err
183        }
184}
185
186def benchmark() {
187        Tools.BuildStage('Benchmark', Settings.RunBenchmark) {
188                dir (BuildDir) {
189                        //Append bench results
190                        sh "make --no-print-directory -C benchmark jenkins arch=${Settings.Architecture.name}"
191                }
192        }
193}
194
195def build_doc() {
196        Tools.BuildStage('Documentation', Settings.BuildDocumentation) {
197                dir ('doc/user') {
198                        make_doc()
199                }
200
201                dir ('doc/refrat') {
202                        make_doc()
203                }
204        }
205}
206
207def publish() {
208        Tools.BuildStage('Publish', true) {
209
210                if( Settings.Publish && !Settings.RunBenchmark ) { echo 'No results to publish!!!' }
211        }
212}
213
214//===========================================================================================================
215//Routine responsible of sending the email notification once the build is completed
216//===========================================================================================================
217//Standard build email notification
218def email(boolean log) {
219        node {
220                //Since tokenizer doesn't work, figure stuff out from the environnement variables and command line
221                //Configurations for email format
222                echo 'Notifying users of result'
223
224                def project_name = (env.JOB_NAME =~ /(.+)\/.+/)[0][1].toLowerCase()
225                def email_subject = "[${project_name} git][BUILD# ${env.BUILD_NUMBER} - ${currentBuild.result}] - branch ${env.BRANCH_NAME}"
226                def email_body = """<p>This is an automated email from the Jenkins build machine. It was
227generated because of a git hooks/post-receive script following
228a ref change which was pushed to the C\u2200 repository.</p>
229
230<p>- Status --------------------------------------------------------------</p>
231
232<p>BUILD# ${env.BUILD_NUMBER} - ${currentBuild.result}</p>
233<p>Check console output at ${env.BUILD_URL} to view the results.</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//===========================================================================================================
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-11':
299                                this.Compiler = new CC_Desc('gcc-11', 'g++-11', 'gcc-11', '-flto=auto')
300                        break
301                        case 'gcc-10':
302                                this.Compiler = new CC_Desc('gcc-10', 'g++-10', 'gcc-10', '-flto=auto')
303                        break
304                        case 'gcc-9':
305                                this.Compiler = new CC_Desc('gcc-9', 'g++-9', 'gcc-9', '-flto=auto')
306                        break
307                        case 'gcc-8':
308                                this.Compiler = new CC_Desc('gcc-8', 'g++-8', 'gcc-8', '-flto=auto')
309                        break
310                        case 'gcc-7':
311                                this.Compiler = new CC_Desc('gcc-7', 'g++-7', 'gcc-7', '-flto=auto')
312                        break
313                        case 'gcc-6':
314                                this.Compiler = new CC_Desc('gcc-6', 'g++-6', 'gcc-6', '-flto=auto')
315                        break
316                        case 'gcc-5':
317                                this.Compiler = new CC_Desc('gcc-5', 'g++-5', 'gcc-5', '-flto=auto')
318                        break
319                        case 'gcc-4.9':
320                                this.Compiler = new CC_Desc('gcc-4.9', 'g++-4.9', 'gcc-4.9', '-flto=auto')
321                        break
322                        case 'clang':
323                                this.Compiler = new CC_Desc('clang', 'clang++-10', 'gcc-10', '-flto=thin -flto-jobs=0')
324                        break
325                        default :
326                                error "Unhandled compiler : ${cc}"
327                }
328
329                switch( param.Architecture ) {
330                        case 'x64':
331                                this.Architecture = new Arch_Desc('x64', '--host=x86_64', 'x64')
332                        break
333                        case 'x86':
334                                this.Architecture = new Arch_Desc('x86', '--host=i386', 'x86')
335                        break
336                        default :
337                                error "Unhandled architecture : ${arch}"
338                }
339
340                this.IsSandbox          = (branch == "jenkins-sandbox")
341                this.NewAST             = param.NewAST
342                this.RunAllTests        = param.RunAllTests
343                this.RunBenchmark       = param.RunBenchmark
344                this.BuildDocumentation = param.BuildDocumentation
345                this.Publish            = param.Publish
346                this.Silent             = param.Silent
347
348                def full = param.RunAllTests ? " (Full)" : ""
349                this.DescShort = "${ this.Compiler.name }:${ this.Architecture.name }${full}"
350
351                final ast = this.NewAST ? "New AST" : "Old AST"
352                this.DescLong = """Compiler              : ${ this.Compiler.name } (${ this.Compiler.CXX }/${ this.Compiler.CC })
353AST Version             : ${ ast.toString() }
354Architecture            : ${ this.Architecture.name }
355Arc Flags               : ${ this.Architecture.flags }
356Run All Tests           : ${ this.RunAllTests.toString() }
357Run Benchmark           : ${ this.RunBenchmark.toString() }
358Build Documentation     : ${ this.BuildDocumentation.toString() }
359Publish                 : ${ this.Publish.toString() }
360Silent                  : ${ this.Silent.toString() }
361"""
362
363                this.GitNewRef = ''
364                this.GitOldRef = ''
365        }
366}
367
368def prepare_build() {
369        // prepare the properties
370        properties ([                                                                                                   \
371                buildDiscarder(logRotator(                                                                              \
372                        artifactDaysToKeepStr: '',                                                                      \
373                        artifactNumToKeepStr: '',                                                                       \
374                        daysToKeepStr: '730',                                                                           \
375                        numToKeepStr: '1000'                                                                            \
376                )),                                                                                                             \
377                [$class: 'ParametersDefinitionProperty',                                                                \
378                        parameterDefinitions: [                                                                         \
379                                [$class: 'ChoiceParameterDefinition',                                           \
380                                        description: 'Which compiler to use',                                   \
381                                        name: 'Compiler',                                                                       \
382                                        choices: 'gcc-11\ngcc-10\ngcc-9\ngcc-8\ngcc-7\ngcc-6\ngcc-5\ngcc-4.9\nclang',   \
383                                        defaultValue: 'gcc-8',                                                          \
384                                ],                                                                                              \
385                                [$class: 'ChoiceParameterDefinition',                                           \
386                                        description: 'The target architecture',                                 \
387                                        name: 'Architecture',                                                           \
388                                        choices: 'x64\nx86',                                                            \
389                                        defaultValue: 'x64',                                                            \
390                                ],                                                                                              \
391                                [$class: 'BooleanParameterDefinition',                                                  \
392                                        description: 'If true, build compiler using new AST',           \
393                                        name: 'NewAST',                                                                         \
394                                        defaultValue: true,                                                             \
395                                ],                                                                                              \
396                                [$class: 'BooleanParameterDefinition',                                                  \
397                                        description: 'If false, only the quick test suite is ran',              \
398                                        name: 'RunAllTests',                                                            \
399                                        defaultValue: false,                                                            \
400                                ],                                                                                              \
401                                [$class: 'BooleanParameterDefinition',                                                  \
402                                        description: 'If true, jenkins also runs benchmarks',           \
403                                        name: 'RunBenchmark',                                                           \
404                                        defaultValue: false,                                                            \
405                                ],                                                                                              \
406                                [$class: 'BooleanParameterDefinition',                                                  \
407                                        description: 'If true, jenkins also builds documentation',              \
408                                        name: 'BuildDocumentation',                                                     \
409                                        defaultValue: true,                                                             \
410                                ],                                                                                              \
411                                [$class: 'BooleanParameterDefinition',                                                  \
412                                        description: 'If true, jenkins also publishes results',                 \
413                                        name: 'Publish',                                                                        \
414                                        defaultValue: false,                                                            \
415                                ],                                                                                              \
416                                [$class: 'BooleanParameterDefinition',                                                  \
417                                        description: 'If true, jenkins will not send emails',           \
418                                        name: 'Silent',                                                                         \
419                                        defaultValue: false,                                                            \
420                                ],                                                                                              \
421                        ],
422                ]])
423
424        // It's unfortunate but it looks like we need to checkout the entire repo just to get
425        // - the pretty git printer
426        // - Jenkins.tools
427        checkout scm
428
429        Tools = load "Jenkins/tools.groovy"
430
431        final settings = new BuildSettings(params, env.BRANCH_NAME)
432
433        currentBuild.description = settings.DescShort
434        echo                       settings.DescLong
435
436        return settings
437}
438
439def make_doc() {
440        def err = null
441        try {
442                sh 'make clean > /dev/null'
443                sh 'make > /dev/null 2>&1'
444        }
445        catch (Exception caughtError) {
446                err = caughtError //rethrow error later
447                sh 'cat build/*.log'
448        }
449        finally {
450                if (err) throw err // Must re-throw exception to propagate error
451        }
452}
Note: See TracBrowser for help on using the repository browser.