source: Jenkinsfile@ 4858a88

ADT ast-experimental pthread-emulation
Last change on this file since 4858a88 was 6b00c53, checked in by Thierry Delisle <tdelisle@…>, 3 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.