source: Jenkinsfile @ b59d6d1

ADTast-experimentalpthread-emulation
Last change on this file since b59d6d1 was 6b00c53, checked in by Thierry Delisle <tdelisle@…>, 2 years ago

Jenkins no longer offers the option to build the old ast

  • Property mode set to 100644
File size: 13.1 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                        sh "${SrcDir}/configure CXX=${Settings.Compiler.CXX} CC=${Settings.Compiler.CC} ${Settings.Architecture.flags} AR=gcc-ar RANLIB=gcc-ranlib ${targets} --quiet --prefix=${BuildDir}"
106
107                        // Configure libcfa
108                        sh 'make -j $(nproc) --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 $(nproc) --no-print-directory -C driver'
117
118                        // Build translator
119                        sh 'make -j $(nproc) --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 \$(nproc) --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 \$(nproc) --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 $(nproc) --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                                        jopt = '-j $(nproc)'
162                                        if( Settings.Architecture.node == 'x86' ) {
163                                                jopt = '-j2'
164                                        }
165                                        //Run the tests from the tests directory
166                                        sh """make ${jopt} --no-print-directory -C tests timeouts="--timeout=600 --global-timeout=14400" all-tests debug=yes archiveerrors=${BuildDir}/tests/crashes/full-debug"""
167                                        sh """make ${jopt} --no-print-directory -C tests timeouts="--timeout=600 --global-timeout=14400" all-tests debug=no  archiveerrors=${BuildDir}/tests/crashes/full-nodebug"""
168                        }
169                }
170        }
171        catch (Exception err) {
172                echo "Archiving core dumps"
173                dir (BuildDir) {
174                        def exists = fileExists 'tests/crashes'
175                        if( exists ) {
176                                sh """${SrcDir}/tools/jenkins/archive-gen.sh"""
177                                archiveArtifacts artifacts: "tests/crashes/**/*,lib/**/lib*.so*,setup.sh", fingerprint: true
178                        }
179                }
180                throw err
181        }
182}
183
184def benchmark() {
185        Tools.BuildStage('Benchmark', Settings.RunBenchmark) {
186                dir (BuildDir) {
187                        //Append bench results
188                        sh "make --no-print-directory -C benchmark jenkins arch=${Settings.Architecture.name}"
189                }
190        }
191}
192
193def build_doc() {
194        Tools.BuildStage('Documentation', Settings.BuildDocumentation) {
195                dir ('doc/user') {
196                        make_doc()
197                }
198
199                dir ('doc/refrat') {
200                        make_doc()
201                }
202        }
203}
204
205def publish() {
206        Tools.BuildStage('Publish', true) {
207
208                if( Settings.Publish && !Settings.RunBenchmark ) { echo 'No results to publish!!!' }
209        }
210}
211
212//===========================================================================================================
213//Routine responsible of sending the email notification once the build is completed
214//===========================================================================================================
215//Standard build email notification
216def email(boolean log) {
217        node {
218                //Since tokenizer doesn't work, figure stuff out from the environnement variables and command line
219                //Configurations for email format
220                echo 'Notifying users of result'
221
222                def project_name = (env.JOB_NAME =~ /(.+)\/.+/)[0][1].toLowerCase()
223                def email_subject = "[${project_name} git][BUILD# ${env.BUILD_NUMBER} - ${currentBuild.result}] - branch ${env.BRANCH_NAME}"
224                def email_body = """<p>This is an automated email from the Jenkins build machine. It was
225generated because of a git hooks/post-receive script following
226a ref change which was pushed to the C\u2200 repository.</p>
227
228<p>- Status --------------------------------------------------------------</p>
229
230<p>BUILD# ${env.BUILD_NUMBER} - ${currentBuild.result}</p>
231<p>Check console output at ${env.BUILD_URL} to view the results.</p>
232""" + Tools.GitLogMessage()
233
234                def email_to = !Settings.IsSandbox ? "cforall@lists.uwaterloo.ca" : "tdelisle@uwaterloo.ca"
235
236                if( Settings && !Settings.Silent ) {
237                        //send email notification
238                        emailext body: email_body, subject: email_subject, to: email_to, attachLog: log
239                } else {
240                        echo "Would send email to: ${email_to}"
241                        echo "With title: ${email_subject}"
242                        echo "Content: \n${email_body}"
243                }
244        }
245}
246
247//===========================================================================================================
248// Helper classes/variables/routines
249//===========================================================================================================
250//Description of a compiler (Must be serializable since pipelines are persistent)
251class CC_Desc implements Serializable {
252        public String name
253        public String CXX
254        public String CC
255        public String lto
256
257        CC_Desc(String name, String CXX, String CC, String lto) {
258                this.name = name
259                this.CXX = CXX
260                this.CC  = CC
261                this.lto = lto
262        }
263}
264
265//Description of an architecture (Must be serializable since pipelines are persistent)
266class Arch_Desc implements Serializable {
267        public String name
268        public String flags
269        public String node
270
271        Arch_Desc(String name, String flags, String node) {
272                this.name  = name
273                this.flags = flags
274                this.node  = node
275        }
276}
277
278class BuildSettings implements Serializable {
279        public final CC_Desc Compiler
280        public final Arch_Desc Architecture
281        public final Boolean RunAllTests
282        public final Boolean RunBenchmark
283        public final Boolean BuildDocumentation
284        public final Boolean Publish
285        public final Boolean Silent
286        public final Boolean IsSandbox
287        public final String DescLong
288        public final String DescShort
289
290        public String GitNewRef
291        public String GitOldRef
292
293        BuildSettings(java.util.Collections$UnmodifiableMap param, String branch) {
294                switch( param.Compiler ) {
295                        case 'gcc-11':
296                                this.Compiler = new CC_Desc('gcc-11', 'g++-11', 'gcc-11', '-flto=auto')
297                        break
298                        case 'gcc-10':
299                                this.Compiler = new CC_Desc('gcc-10', 'g++-10', 'gcc-10', '-flto=auto')
300                        break
301                        case 'gcc-9':
302                                this.Compiler = new CC_Desc('gcc-9', 'g++-9', 'gcc-9', '-flto=auto')
303                        break
304                        case 'gcc-8':
305                                this.Compiler = new CC_Desc('gcc-8', 'g++-8', 'gcc-8', '-flto=auto')
306                        break
307                        case 'gcc-7':
308                                this.Compiler = new CC_Desc('gcc-7', 'g++-7', 'gcc-7', '-flto=auto')
309                        break
310                        case 'gcc-6':
311                                this.Compiler = new CC_Desc('gcc-6', 'g++-6', 'gcc-6', '-flto=auto')
312                        break
313                        case 'gcc-5':
314                                this.Compiler = new CC_Desc('gcc-5', 'g++-5', 'gcc-5', '-flto=auto')
315                        break
316                        case 'gcc-4.9':
317                                this.Compiler = new CC_Desc('gcc-4.9', 'g++-4.9', 'gcc-4.9', '-flto=auto')
318                        break
319                        case 'clang':
320                                this.Compiler = new CC_Desc('clang', 'clang++-10', 'gcc-10', '-flto=thin -flto-jobs=0')
321                        break
322                        default :
323                                error "Unhandled compiler : ${cc}"
324                }
325
326                switch( param.Architecture ) {
327                        case 'x64':
328                                this.Architecture = new Arch_Desc('x64', '--host=x86_64', 'x64')
329                        break
330                        case 'x86':
331                                this.Architecture = new Arch_Desc('x86', '--host=i386', 'x86')
332                        break
333                        default :
334                                error "Unhandled architecture : ${arch}"
335                }
336
337                this.IsSandbox          = (branch == "jenkins-sandbox")
338                this.RunAllTests        = param.RunAllTests
339                this.RunBenchmark       = param.RunBenchmark
340                this.BuildDocumentation = param.BuildDocumentation
341                this.Publish            = param.Publish
342                this.Silent             = param.Silent
343
344                def full = param.RunAllTests ? " (Full)" : ""
345                this.DescShort = "${ this.Compiler.name }:${ this.Architecture.name }${full}"
346
347                this.DescLong = """Compiler              : ${ this.Compiler.name } (${ this.Compiler.CXX }/${ this.Compiler.CC })
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
362def prepare_build() {
363        // prepare the properties
364        properties ([                                                                                                   \
365                buildDiscarder(logRotator(                                                                              \
366                        artifactDaysToKeepStr: '',                                                                      \
367                        artifactNumToKeepStr: '',                                                                       \
368                        daysToKeepStr: '730',                                                                           \
369                        numToKeepStr: '1000'                                                                            \
370                )),                                                                                                             \
371                [$class: 'ParametersDefinitionProperty',                                                                \
372                        parameterDefinitions: [                                                                         \
373                                [$class: 'ChoiceParameterDefinition',                                           \
374                                        description: 'Which compiler to use',                                   \
375                                        name: 'Compiler',                                                                       \
376                                        choices: 'gcc-11\ngcc-10\ngcc-9\ngcc-8\ngcc-7\ngcc-6\ngcc-5\ngcc-4.9\nclang',   \
377                                        defaultValue: 'gcc-8',                                                          \
378                                ],                                                                                              \
379                                [$class: 'ChoiceParameterDefinition',                                           \
380                                        description: 'The target architecture',                                 \
381                                        name: 'Architecture',                                                           \
382                                        choices: 'x64\nx86',                                                            \
383                                        defaultValue: 'x64',                                                            \
384                                ],                                                                                              \
385                                [$class: 'BooleanParameterDefinition',                                                  \
386                                        description: 'If false, only the quick test suite is ran',              \
387                                        name: 'RunAllTests',                                                            \
388                                        defaultValue: false,                                                            \
389                                ],                                                                                              \
390                                [$class: 'BooleanParameterDefinition',                                                  \
391                                        description: 'If true, jenkins also runs benchmarks',           \
392                                        name: 'RunBenchmark',                                                           \
393                                        defaultValue: false,                                                            \
394                                ],                                                                                              \
395                                [$class: 'BooleanParameterDefinition',                                                  \
396                                        description: 'If true, jenkins also builds documentation',              \
397                                        name: 'BuildDocumentation',                                                     \
398                                        defaultValue: true,                                                             \
399                                ],                                                                                              \
400                                [$class: 'BooleanParameterDefinition',                                                  \
401                                        description: 'If true, jenkins also publishes results',                 \
402                                        name: 'Publish',                                                                        \
403                                        defaultValue: false,                                                            \
404                                ],                                                                                              \
405                                [$class: 'BooleanParameterDefinition',                                                  \
406                                        description: 'If true, jenkins will not send emails',           \
407                                        name: 'Silent',                                                                         \
408                                        defaultValue: false,                                                            \
409                                ],                                                                                              \
410                        ],
411                ]])
412
413        // It's unfortunate but it looks like we need to checkout the entire repo just to get
414        // - the pretty git printer
415        // - Jenkins.tools
416        checkout scm
417
418        Tools = load "Jenkins/tools.groovy"
419
420        final settings = new BuildSettings(params, env.BRANCH_NAME)
421
422        currentBuild.description = settings.DescShort
423        echo                       settings.DescLong
424
425        return settings
426}
427
428def make_doc() {
429        def err = null
430        try {
431                sh 'make clean > /dev/null'
432                sh 'make > /dev/null 2>&1'
433        }
434        catch (Exception caughtError) {
435                err = caughtError //rethrow error later
436                sh 'cat build/*.log'
437        }
438        finally {
439                if (err) throw err // Must re-throw exception to propagate error
440        }
441}
Note: See TracBrowser for help on using the repository browser.