Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • Jenkinsfile

    r14ce3392 rf51ef6f  
    22
    33//===========================================================================================================
     4// Main compilation routines
     5//===========================================================================================================
     6//Compilation script is done here but environnement set-up and error handling is done in main loop
     7def cfa_build(boolean full_build, String flags) {
     8        build_stage 'Checkout'
     9                def install_dir = pwd tmp: true
     10                //checkout the source code and clean the repo
     11                checkout scm
     12
     13                //Clean all temporary files to make sure no artifacts of the previous build remain
     14                sh 'git clean -fdqx'
     15
     16                //Reset the git repo so no local changes persist
     17                sh 'git reset --hard'
     18
     19        build_stage 'Build'
     20
     21                //Configure the conpilation (Output is not relevant)
     22                //Use the current directory as the installation target so nothing
     23                //escapes the sandbox
     24                //Also specify the compiler by hand
     25                sh "./configure CXX=${currentCC.cpp_cc} ${flags} --with-backend-compiler=${currentCC.cfa_backend_cc} --prefix=${install_dir} --enable-silent-rules --quiet"
     26
     27                //Compile the project
     28                sh 'make -j 8 --no-print-directory V=0 install'
     29
     30        build_stage 'Test'
     31
     32                //Run the tests from the tests directory
     33                if (full_build) {
     34                        sh 'make -C src/tests all-tests debug=yes'
     35                        sh 'make -C src/tests all-tests debug=no'
     36                }
     37                else {
     38                        sh 'make -C src/tests'
     39                }
     40
     41        build_stage 'Cleanup'
     42
     43                //do a maintainer-clean to make sure we need to remake from scratch
     44                sh 'make maintainer-clean > /dev/null'
     45}
     46
     47def make_doc() {
     48        def err = null
     49
     50        try {
     51                sh 'make clean > /dev/null'
     52                sh 'make > /dev/null 2>&1'
     53        }
     54
     55        catch (Exception caughtError) {
     56                //rethrow error later
     57                err = caughtError
     58
     59                sh 'cat *.log'
     60        }
     61
     62        finally {
     63                /* Must re-throw exception to propagate error */
     64                if (err) {
     65                        throw err
     66                }
     67        }
     68}
     69
     70def doc_build() {
     71        stage 'Documentation'
     72
     73                status_prefix = 'Documentation'
     74
     75                dir ('doc/user') {
     76                        make_doc()
     77                }
     78
     79                dir ('doc/refrat') {
     80                        make_doc()
     81                }
     82}
     83
     84def benchmark() {
     85        stage 'Benchmark'
     86
     87                status_prefix = 'Documentation'
     88
     89                // //We can't just write to a file outside our repo
     90                // //Copy the file locally using ssh
     91                // sh 'scp plg2.cs.uwaterloo.ca:/u/cforall/public_html/perf-history/concurrency.csv bench.csv'
     92
     93                // //Then append to the local file
     94                // sh 'make -C src/benchmark csv-data >> bench.csv'
     95
     96                // //Then publish the file again
     97                // sh 'scp bench.csv plg2.cs.uwaterloo.ca:/u/cforall/public_html/perf-history/concurrency.csv'         
     98}
     99
     100//===========================================================================================================
     101// Helper classes/variables/routines to make the status and stage name easier to use
     102//===========================================================================================================
     103//Description of a compiler (Must be serializable since pipelines are persistent)
     104class CC_Desc implements Serializable {
     105        public String cc_name
     106        public String cpp_cc
     107        public String cfa_backend_cc
     108
     109        CC_Desc(String cc_name, String cpp_cc, String cfa_backend_cc) {
     110                this.cc_name = cc_name
     111                this.cpp_cc = cpp_cc
     112                this.cfa_backend_cc = cfa_backend_cc
     113        }
     114}
     115
     116//Global Variables defining the compiler and at which point in the build we are
     117// These variables are used but can't be declared before hand because of wierd scripting rules
     118// @Field String currentCC
     119// @Field String status_prefix
     120
     121//Wrapper to sync stage name and status name
     122def build_stage(String name) {
     123        def stage_name = "${currentCC.cc_name} ${name}".trim()
     124        stage stage_name
     125
     126                status_prefix = stage_name
     127}
     128
     129//Helper routine to collect information about the git history
     130def collect_git_info() {
     131
     132        //create the temporary output directory in case it doesn't already exist
     133        def out_dir = pwd tmp: true
     134        sh "mkdir -p ${out_dir}"
     135
     136        //parse git logs to find what changed
     137        gitRefName = env.BRANCH_NAME
     138        dir("../${gitRefName}@script") {
     139                sh "git reflog > ${out_dir}/GIT_COMMIT"
     140        }
     141        git_reflog = readFile("${out_dir}/GIT_COMMIT")
     142        gitRefOldValue = (git_reflog =~ /moving from (.+) to (.+)/)[0][1]
     143        gitRefNewValue = (git_reflog =~ /moving from (.+) to (.+)/)[0][2]
     144}
     145
     146//===========================================================================================================
    4147// Main loop of the compilation
    5148//===========================================================================================================
    6149node ('master'){
    7150
    8         boolean bIsSandbox = env.BRANCH_NAME == "jenkins-sandbox"
     151        boolean bIsFullBuild
    9152        def err = null
    10153        def log_needed = false
    11 
    12         stage_name              = ''
    13 
    14         compiler                = null
    15         architecture    = ''
    16        
    17         do_alltests             = false
    18         do_benchmark    = false
    19         do_doc          = false
    20         do_publish              = false
    21         do_sendemail    = true
    22 
    23154        currentBuild.result = "SUCCESS"
     155        status_prefix = ''
    24156
    25157        try {
    26                 //Wrap build to add timestamp to command line
    27                 wrap([$class: 'TimestamperBuildWrapper']) {
    28 
    29                         //Prevent the build from exceeding 60 minutes
    30                         timeout(60) {
    31 
    32                                 notify_server()
    33 
    34                                 prepare_build()
    35 
    36                                 checkout()
    37 
    38                                 build()
    39 
    40                                 test()
    41 
     158                //Prevent the build from exceeding 30 minutes
     159                timeout(60) {
     160
     161                        //Wrap build to add timestamp to command line
     162                        wrap([$class: 'TimestamperBuildWrapper']) {
     163
     164                                collect_git_info()
     165
     166                                properties ([                                                                   \
     167                                        [$class: 'ParametersDefinitionProperty',                                \
     168                                                parameterDefinitions: [                                         \
     169                                                [$class: 'BooleanParameterDefinition',                          \
     170                                                  defaultValue: false,                                          \
     171                                                  description: 'If true, the build will be promoted to the do-lang git repository (on successful builds only)', \
     172                                                  name: 'isFullBuild'                                   \
     173                                                ],                                                              \
     174                                                [$class: 'ChoiceParameterDefinition',                           \
     175                                                  choices: '64-bit\n32-bit',                                    \
     176                                                  defaultValue: '64-bit',                                       \
     177                                                  description: 'The architecture to use for compilation',       \
     178                                                  name: 'buildArchitecture'                                     \
     179                                                ]]                                                              \
     180                                        ]])
     181
     182                                bIsSandbox = env.BRANCH_NAME == "jenkins-sandbox"
     183                                bIsFullBuild = isFullBuild == 'true'
     184                                architectureFlag = ''
     185                                if (buildArchitecture == '64-bit') {
     186                                        architectureFlag = '--host=x86_64 CXXFLAGS="-m64" CFAFLAGS="-m64"'
     187                                } else if (buildArchitecture == '32-bit'){
     188                                        architectureFlag = '--host=i386 CXXFLAGS="-m32" CFAFLAGS="-m32"'
     189                                } else {
     190                                        architectureFlag = 'ERROR'
     191                                }
     192
     193                                echo "FULL BUILD = ${isFullBuild}\nArchitecture = ${buildArchitecture} (flag ${architectureFlag})"
     194
     195                                //Compile using gcc-4.9
     196                                currentCC = new CC_Desc('gcc-4.9', 'g++-4.9', 'gcc-4.9')
     197                                cfa_build(bIsFullBuild, architectureFlag)
     198
     199                                //Compile latex documentation
     200                                doc_build()
     201
     202                                //Run benchmark and save result
    42203                                benchmark()
    43204
    44                                 clean()
    45 
    46                                 build_doc()
    47 
    48                                 publish()
    49 
    50                                 notify_server()
     205                                if( bIsFullBuild ) {
     206                                        //Compile using gcc-5
     207                                        currentCC = new CC_Desc('gcc-5', 'g++-5', 'gcc-5')
     208                                        cfa_build(true, architectureFlag)
     209
     210                                        //Compile using gcc-4.9
     211                                        currentCC = new CC_Desc('gcc-6', 'g++-6', 'gcc-6')
     212                                        cfa_build(true, architectureFlag)
     213                                }
    51214                        }
    52215                }
     
    63226
    64227                //Store the result of the build log
    65                 currentBuild.result = "${stage_name} FAILURE".trim()
     228                currentBuild.result = "${status_prefix} FAILURE".trim()
    66229        }
    67230
    68231        finally {
     232                echo 'Build Completed'
     233
    69234                //Send email with final results if this is not a full build
    70                 if( do_sendemail && !bIsSandbox ) {
     235                if( !bIsFullBuild && !bIsSandbox ) {
    71236                        echo 'Notifying users of result'
    72237                        email(currentBuild.result, log_needed)
    73238                }
    74 
    75                 echo 'Build Completed'
    76239
    77240                /* Must re-throw exception to propagate error */
     
    80243                }
    81244        }
    82 }
    83 
    84 //===========================================================================================================
    85 // Helper classes/variables/routines
    86 //===========================================================================================================
    87 //Helper routine to collect information about the git history
    88 def collect_git_info() {
    89 
    90         //create the temporary output directory in case it doesn't already exist
    91         def out_dir = pwd tmp: true
    92         sh "mkdir -p ${out_dir}"
    93 
    94         //parse git logs to find what changed
    95         gitRefName = env.BRANCH_NAME
    96         dir("../${gitRefName}@script") {
    97                 sh "git reflog > ${out_dir}/GIT_COMMIT"
    98         }
    99         git_reflog = readFile("${out_dir}/GIT_COMMIT")
    100         gitRefOldValue = (git_reflog =~ /moving from (.+) to (.+)/)[0][1]
    101         gitRefNewValue = (git_reflog =~ /moving from (.+) to (.+)/)[0][2]
    102 }
    103 
    104 def prepare_build() {
    105         properties ([                                                                                                   \
    106                 [$class: 'ParametersDefinitionProperty',                                                                \
    107                         parameterDefinitions: [                                                                         \
    108                                 [$class: 'ChoiceParameterDefinition',                                           \
    109                                         description: 'Which compiler to use',                                   \
    110                                         name: 'pCompiler',                                                              \
    111                                         choices: 'gcc-6\ngcc-5\ngcc-4.9\nclang',                                        \
    112                                         defaultValue: 'gcc-6',                                                          \
    113                                 ],                                                                                              \
    114                                 [$class: 'ChoiceParameterDefinition',                                           \
    115                                         description: 'The target architecture',                                 \
    116                                         name: 'pArchitecture',                                                          \
    117                                         choices: 'x64\nx86',                                                            \
    118                                         defaultValue: 'x64',                                                            \
    119                                 ],                                                                                              \
    120                                 [$class: 'BooleanParameterDefinition',                                                  \
    121                                         description: 'If false, only the quick test suite is ran',              \
    122                                         name: 'pRunAllTests',                                                           \
    123                                         defaultValue: false,                                                            \
    124                                 ],                                                                                              \
    125                                 [$class: 'BooleanParameterDefinition',                                                  \
    126                                         description: 'If true, jenkins also runs benchmarks',           \
    127                                         name: 'pRunBenchmark',                                                          \
    128                                         defaultValue: true,                                                             \
    129                                 ],                                                                                              \
    130                                 [$class: 'BooleanParameterDefinition',                                                  \
    131                                         description: 'If true, jenkins also builds documentation',              \
    132                                         name: 'pBuildDocumentation',                                                            \
    133                                         defaultValue: true,                                                             \
    134                                 ],                                                                                              \
    135                                 [$class: 'BooleanParameterDefinition',                                                  \
    136                                         description: 'If true, jenkins also publishes results',                 \
    137                                         name: 'pPublish',                                                               \
    138                                         defaultValue: true,                                                             \
    139                                 ],                                                                                              \
    140                                 [$class: 'BooleanParameterDefinition',                                                  \
    141                                         description: 'If true, jenkins will not send emails',           \
    142                                         name: 'pSilent',                                                \
    143                                         defaultValue: false,                                                            \
    144                                 ],                                                                                              \
    145                         ],
    146                 ]])
    147 
    148         compiler                = compiler_from_params( pCompiler )
    149         architecture    = architecture_from_params( pArchitecture )
    150 
    151         do_alltests             = (pRunAllTests == 'true')
    152         do_benchmark    = (pRunBenchmark == 'true')
    153         do_doc          = (pBuildDocumentation == 'true')
    154         do_publish              = (pPublish == 'true')
    155         do_sendemail    = ! (pSilent == 'true')
    156 
    157         echo """Compiler                : ${compiler.cc_name} (${compiler.cpp_cc}/${compiler.cfa_cc})
    158 Architecture            : ${architecture}
    159 Run All Tests           : ${ pRunAllTests.toString() }
    160 Run Benchmark           : ${ pRunBenchmark.toString() }
    161 Build Documentation     : ${ pBuildDocumentation.toString() }
    162 Publish         : ${ pPublish.toString() }
    163 Silent                  : ${ pSilent.toString() }
    164 """
    165 
    166         collect_git_info()
    167 }
    168 
    169 def build_stage(String name) {
    170         stage_name = name
    171         stage name
    172 }
    173 
    174 def notify_server() {
    175         sh 'curl --silent -X POST http://plg2:8082/jenkins/notify > /dev/null'
    176         return
    177 }
    178 
    179 def make_doc() {
    180         def err = null
    181         try {
    182                 sh 'make clean > /dev/null'
    183                 sh 'make > /dev/null 2>&1'
    184         }
    185         catch (Exception caughtError) {
    186                 err = caughtError //rethrow error later
    187                 sh 'cat *.log'
    188         }
    189         finally {
    190                 if (err) throw err // Must re-throw exception to propagate error
    191         }
    192 }
    193 
    194 //Description of a compiler (Must be serializable since pipelines are persistent)
    195 class CC_Desc implements Serializable {
    196         public String cc_name
    197         public String cpp_cc
    198         public String cfa_cc
    199 
    200         CC_Desc(String cc_name, String cpp_cc, String cfa_cc) {
    201                 this.cc_name = cc_name
    202                 this.cpp_cc = cpp_cc
    203                 this.cfa_cc = cfa_cc
    204         }
    205 }
    206 
    207 def compiler_from_params(cc) {
    208         switch( cc ) {
    209                 case 'gcc-6':
    210                         return new CC_Desc('gcc-6', 'g++-6', 'gcc-6')
    211                 break
    212                 case 'gcc-5':
    213                         return new CC_Desc('gcc-5', 'g++-5', 'gcc-5')
    214                 break
    215                 case 'gcc-4.9':
    216                         return new CC_Desc('gcc-4.9', 'g++-4.9', 'gcc-4.9')
    217                 break
    218                 case 'clang':
    219                         return new CC_Desc('clang', 'clang++', 'gcc-6')
    220                 break
    221                 default :
    222                         error "Unhandled compiler : ${cc}"
    223         }
    224 }
    225 
    226 def architecture_from_params( arch ) {
    227         switch( arch ) {
    228                 case 'x64':
    229                         return '--host=x86_64 CXXFLAGS="-m64" CFAFLAGS="-m64"'
    230                 break
    231                 case 'x86':
    232                         return '--host=i386   CXXFLAGS="-m32" CFAFLAGS="-m32"'
    233                 break
    234                 default :
    235                         error "Unhandled architecture : ${arch}"
    236         }
    237 }
    238 
    239 //===========================================================================================================
    240 // Main compilation routines
    241 //===========================================================================================================
    242 //Compilation script is done here but environnement set-up and error handling is done in main loop
    243 def checkout() {
    244         build_stage'Checkout'
    245                 //checkout the source code and clean the repo
    246                 checkout scm
    247 
    248                 //Clean all temporary files to make sure no artifacts of the previous build remain
    249                 sh 'git clean -fdqx'
    250 
    251                 //Reset the git repo so no local changes persist
    252                 sh 'git reset --hard'
    253 }
    254 
    255 def build() {
    256         build_stage'Build'
    257        
    258                 def install_dir = pwd tmp: true
    259                
    260                 //Configure the conpilation (Output is not relevant)
    261                 //Use the current directory as the installation target so nothing
    262                 //escapes the sandbox
    263                 //Also specify the compiler by hand
    264                 sh "./configure CXX=${compiler.cpp_cc} ${architecture} --with-backend-compiler=${compiler.cfa_cc} --prefix=${install_dir} --enable-silent-rules --quiet"
    265 
    266                 //Compile the project
    267                 sh 'make -j 8 --no-print-directory V=0 install'
    268 }
    269 
    270 def test() {
    271         build_stage'Test'
    272 
    273                 //Run the tests from the tests directory
    274                 if ( do_alltests ) {
    275                         sh 'make -C src/tests all-tests debug=yes'
    276                         sh 'make -C src/tests all-tests debug=no'
    277                 }
    278                 else {
    279                         sh 'make -C src/tests'
    280                 }
    281 }
    282 
    283 def benchmark() {
    284         build_stage'Benchmark'
    285 
    286                 if( !do_benchmark ) return
    287 
    288                 //Write the commit id to Benchmark
    289                 writeFile  file: 'bench.csv', text:'data=' + gitRefNewValue + ','
    290  
    291                 //Append bench results
    292                 sh 'make -C src/benchmark --no-print-directory csv-data >> bench.csv'
    293 }
    294 
    295 def clean() {
    296         build_stage'Cleanup'
    297 
    298                 //do a maintainer-clean to make sure we need to remake from scratch
    299                 sh 'make maintainer-clean > /dev/null'
    300 }
    301 
    302 def build_doc() {
    303         build_stage'Documentation'
    304 
    305                 if( !do_doc ) return
    306 
    307                 dir ('doc/user') {
    308                         make_doc()
    309                 }
    310 
    311                 dir ('doc/refrat') {
    312                         make_doc()
    313                 }
    314 }
    315 
    316 def publish() {
    317         build_stage'Publish'
    318 
    319                 if( !do_publish ) return
    320 
    321                 //Then publish the results
    322                 sh 'curl --silent --data @bench.csv http://plg2:8082/jenkins/publish > /dev/null'
    323245}
    324246
Note: See TracChangeset for help on using the changeset viewer.