crosstool.py revision f81680c018729fd4499e1e200d04b48c4b90127c
1#!/usr/bin/python2.6 2# 3# Copyright 2011 Google Inc. All Rights Reserved. 4 5__author__ = 'kbaclawski@google.com (Krystian Baclawski)' 6 7import os.path 8import time 9 10from automation.clients.helper import jobs 11from automation.clients.helper import perforce 12from automation.common import command as cmd 13from automation.common import job 14 15 16class JobsFactory(object): 17 def __init__(self): 18 self.commands = CommandsFactory() 19 20 def CheckoutCrosstool(self, target): 21 command = self.commands.CheckoutCrosstool() 22 new_job = jobs.CreateLinuxJob('CheckoutCrosstool(%s)' % target, command) 23 checkout_dir_dep = job.FolderDependency( 24 new_job, CommandsFactory.CHECKOUT_DIR) 25 manifests_dir_dep = job.FolderDependency( 26 new_job, os.path.join(self.commands.buildit_path, target), 'manifests') 27 return new_job, checkout_dir_dep, manifests_dir_dep 28 29 def BuildRelease(self, checkout_dir, target): 30 command = self.commands.BuildRelease(target) 31 new_job = jobs.CreateLinuxJob('BuildRelease(%s)' % target, command) 32 new_job.DependsOnFolder(checkout_dir) 33 build_tree_dep = job.FolderDependency( 34 new_job, self.commands.buildit_work_dir_path) 35 return new_job, build_tree_dep 36 37 def RunTests(self, checkout_dir, build_tree_dir, target, board, component): 38 command = self.commands.RunTests(target, board, component) 39 new_job = jobs.CreateLinuxJob( 40 'RunTests(%s, %s, %s)' % (target, component, board), command) 41 new_job.DependsOnFolder(checkout_dir) 42 new_job.DependsOnFolder(build_tree_dir) 43 testrun_dir_dep = job.FolderDependency( 44 new_job, self.commands.dejagnu_output_path, board) 45 return new_job, testrun_dir_dep 46 47 def GenerateReport(self, testrun_dirs, manifests_dir, target, boards): 48 command = self.commands.GenerateReport(boards) 49 new_job = jobs.CreateLinuxJob('GenerateReport(%s)' % target, command) 50 new_job.DependsOnFolder(manifests_dir) 51 for testrun_dir in testrun_dirs: 52 new_job.DependsOnFolder(testrun_dir) 53 return new_job 54 55 56class CommandsFactory(object): 57 CHECKOUT_DIR = 'crosstool-checkout-dir' 58 59 def __init__(self): 60 self.buildit_path = os.path.join( 61 self.CHECKOUT_DIR, 'gcctools', 'crosstool', 'v15') 62 63 self.buildit_work_dir = 'buildit-tmp' 64 self.buildit_work_dir_path = os.path.join('$JOB_TMP', self.buildit_work_dir) 65 self.dejagnu_output_path = os.path.join( 66 self.buildit_work_dir_path, 'dejagnu-output') 67 68 paths = { 69 'gcctools': [ 70 'crosstool/v15/...', 71 'scripts/...'], 72 'gcctools/google_vendor_src_branch': [ 73 'binutils/binutils-2.21/...', 74 'gdb/gdb-7.2.x/...', 75 'zlib/zlib-1.2.3/...'], 76 'gcctools/vendor_src': [ 77 'gcc/google/gcc-4_6/...']} 78 79 p4view = perforce.View('depot2', 80 perforce.PathMapping.ListFromPathDict(paths)) 81 82 self.p4client = perforce.CommandsFactory(self.CHECKOUT_DIR, p4view) 83 84 def CheckoutCrosstool(self): 85 p4client = self.p4client 86 87 return p4client.SetupAndDo(p4client.Sync(), 88 p4client.SaveCurrentCLNumber('CLNUM'), 89 p4client.Remove()) 90 91 def BuildRelease(self, target): 92 clnum_path = os.path.join('$JOB_TMP', self.CHECKOUT_DIR, 'CLNUM') 93 94 toolchain_root = os.path.join( 95 '/google/data/rw/projects/toolchains', target, 'unstable') 96 toolchain_path = os.path.join(toolchain_root, '${CLNUM}') 97 98 build_toolchain = cmd.Wrapper( 99 cmd.Chain( 100 cmd.MakeDir(toolchain_path), 101 cmd.Shell( 102 'buildit', 103 '--keep-work-dir', 104 '--build-type=release', 105 '--work-dir=%s' % self.buildit_work_dir_path, 106 '--results-dir=%s' % toolchain_path, 107 '--force-release=%s' % '${CLNUM}', 108 target, 109 path='.')), 110 cwd=self.buildit_path, 111 umask='0022', 112 env={'CLNUM': '$(< %s)' % clnum_path}) 113 114 # remove all but 10 most recent directories 115 remove_old_toolchains_from_x20 = cmd.Wrapper( 116 cmd.Pipe( 117 cmd.Shell('ls', '-1', '-r'), 118 cmd.Shell('sed', '-e', '1,10d'), 119 cmd.Shell('xargs', 'rm', '-r', '-f')), 120 cwd=toolchain_root) 121 122 return cmd.Chain(build_toolchain, remove_old_toolchains_from_x20) 123 124 def RunTests(self, target, board, component='gcc'): 125 dejagnu_flags = ['--outdir=%s' % self.dejagnu_output_path, 126 '--target_board=%s' % board] 127 128 # Look for {pandaboard,qemu}.exp files in 129 # //depot/google3/experimental/users/kbaclawski/dejagnu/boards 130 131 site_exp_file = os.path.join('/google/src/head/depot/google3', 132 'experimental/users/kbaclawski', 133 'dejagnu/site.exp') 134 135 build_dir_path = os.path.join( 136 target, 'rpmbuild/BUILD/crosstool*-0.0', 'build-%s' % component) 137 138 run_dejagnu = cmd.Wrapper( 139 cmd.Chain( 140 cmd.MakeDir(self.dejagnu_output_path), 141 cmd.Shell('make', 'check', '-k', 142 '-j $(grep -c processor /proc/cpuinfo)', 143 'RUNTESTFLAGS="%s"' % ' '.join(dejagnu_flags), 144 'DEJAGNU="%s"' % site_exp_file, 145 ignore_error=True)), 146 cwd=os.path.join(self.buildit_work_dir_path, build_dir_path), 147 env={'REMOTE_TMPDIR': 'job-$JOB_ID'}) 148 149 save_results = cmd.Copy( 150 self.dejagnu_output_path, to_dir='$JOB_TMP/results', recursive=True) 151 152 return cmd.Chain(run_dejagnu, save_results) 153 154 def GenerateReport(self, boards): 155 sumfiles = [os.path.join('$JOB_TMP', board, '*.sum') for board in boards] 156 157 return cmd.Wrapper( 158 cmd.Shell('dejagnu.sh', 'report', 159 '-m', '$JOB_TMP/manifests/*.xfail', 160 '-o', '$JOB_TMP/results/report.html', 161 *sumfiles, 162 path='.'), 163 cwd='$HOME/automation/clients/report') 164