]> git.karo-electronics.de Git - karo-tx-uboot.git/blobdiff - tools/buildman/builderthread.py
mmc: Probe DM based mmc devices in u-boot
[karo-tx-uboot.git] / tools / buildman / builderthread.py
index 8214662e368890d05bc1017c15adc9acb430031f..cf25bb8f1a7e325192b8410d3081cea27c864bf0 100644 (file)
@@ -12,14 +12,19 @@ import threading
 import command
 import gitutil
 
-def Mkdir(dirname):
+RETURN_CODE_RETRY = -1
+
+def Mkdir(dirname, parents = False):
     """Make a directory if it doesn't already exist.
 
     Args:
         dirname: Directory to create
     """
     try:
-        os.mkdir(dirname)
+        if parents:
+            os.makedirs(dirname)
+        else:
+            os.mkdir(dirname)
     except OSError as err:
         if err.errno == errno.EEXIST:
             pass
@@ -138,16 +143,21 @@ class BuilderThread(threading.Thread):
         result.already_done = os.path.exists(done_file)
         will_build = (force_build or force_build_failures or
             not result.already_done)
-        if result.already_done and will_build:
+        if result.already_done:
             # Get the return code from that build and use it
             with open(done_file, 'r') as fd:
                 result.return_code = int(fd.readline())
-            err_file = self.builder.GetErrFile(commit_upto, brd.target)
-            if os.path.exists(err_file) and os.stat(err_file).st_size:
-                result.stderr = 'bad'
-            elif not force_build:
-                # The build passed, so no need to build it again
-                will_build = False
+
+            # Check the signal that the build needs to be retried
+            if result.return_code == RETURN_CODE_RETRY:
+                will_build = True
+            elif will_build:
+                err_file = self.builder.GetErrFile(commit_upto, brd.target)
+                if os.path.exists(err_file) and os.stat(err_file).st_size:
+                    result.stderr = 'bad'
+                elif not force_build:
+                    # The build passed, so no need to build it again
+                    will_build = False
 
         if will_build:
             # We are going to have to build it. First, get a toolchain
@@ -173,10 +183,11 @@ class BuilderThread(threading.Thread):
                     commit = 'current'
 
                 # Set up the environment and command line
-                env = self.toolchain.MakeEnvironment()
+                env = self.toolchain.MakeEnvironment(self.builder.full_path)
                 Mkdir(out_dir)
                 args = []
                 cwd = work_dir
+                src_dir = os.path.realpath(work_dir)
                 if not self.builder.in_tree:
                     if commit_upto is None:
                         # In this case we are building in the original source
@@ -189,9 +200,13 @@ class BuilderThread(threading.Thread):
                         work_dir = os.path.realpath(work_dir)
                         args.append('O=%s/build' % work_dir)
                         cwd = None
+                        src_dir = os.getcwd()
                     else:
                         args.append('O=build')
-                args.append('-s')
+                if self.builder.verbose_build:
+                    args.append('V=1')
+                else:
+                    args.append('-s')
                 if self.builder.num_jobs is not None:
                     args.extend(['-j', str(self.builder.num_jobs)])
                 config_args = ['%s_defconfig' % brd.target]
@@ -202,13 +217,16 @@ class BuilderThread(threading.Thread):
                 if do_config:
                     result = self.Make(commit, brd, 'mrproper', cwd,
                             'mrproper', *args, env=env)
+                    config_out = result.combined
                     result = self.Make(commit, brd, 'config', cwd,
                             *(args + config_args), env=env)
-                    config_out = result.combined
+                    config_out += result.combined
                     do_config = False   # No need to configure next time
                 if result.return_code == 0:
                     result = self.Make(commit, brd, 'build', cwd, *args,
                             env=env)
+                result.stderr = result.stderr.replace(src_dir + '/', '')
+                if self.builder.verbose_build:
                     result.stdout = config_out + result.stdout
             else:
                 result.return_code = 1
@@ -233,9 +251,10 @@ class BuilderThread(threading.Thread):
         if result.return_code < 0:
             return
 
-        # Aborted?
-        if result.stderr and 'No child processes' in result.stderr:
-            return
+        # If we think this might have been aborted with Ctrl-C, record the
+        # failure but not that we are 'done' with this board. A retry may fix
+        # it.
+        maybe_aborted =  result.stderr and 'No child processes' in result.stderr
 
         if result.already_done:
             return
@@ -265,7 +284,11 @@ class BuilderThread(threading.Thread):
             done_file = self.builder.GetDoneFile(result.commit_upto,
                     result.brd.target)
             with open(done_file, 'w') as fd:
-                fd.write('%s' % result.return_code)
+                if maybe_aborted:
+                    # Special code to indicate we need to retry
+                    fd.write('%s' % RETURN_CODE_RETRY)
+                else:
+                    fd.write('%s' % result.return_code)
             with open(os.path.join(build_dir, 'toolchain'), 'w') as fd:
                 print >>fd, 'gcc', result.toolchain.gcc
                 print >>fd, 'path', result.toolchain.path
@@ -278,7 +301,7 @@ class BuilderThread(threading.Thread):
                 print >>fd, 'path', result.toolchain.path
 
             # Write out the image and function size information and an objdump
-            env = result.toolchain.MakeEnvironment()
+            env = result.toolchain.MakeEnvironment(self.builder.full_path)
             lines = []
             for fname in ['u-boot', 'spl/u-boot-spl']:
                 cmd = ['%snm' % self.toolchain.cross, '--size-sort', fname]
@@ -324,16 +347,37 @@ class BuilderThread(threading.Thread):
                 with open(sizes, 'w') as fd:
                     print >>fd, '\n'.join(lines)
 
+        # Write out the configuration files, with a special case for SPL
+        for dirname in ['', 'spl', 'tpl']:
+            self.CopyFiles(result.out_dir, build_dir, dirname, ['u-boot.cfg',
+                'spl/u-boot-spl.cfg', 'tpl/u-boot-tpl.cfg', '.config',
+                'include/autoconf.mk', 'include/generated/autoconf.h'])
+
         # Now write the actual build output
         if keep_outputs:
-            patterns = ['u-boot', '*.bin', 'u-boot.dtb', '*.map',
-                        'include/autoconf.mk', 'spl/u-boot-spl',
-                        'spl/u-boot-spl.bin']
-            for pattern in patterns:
-                file_list = glob.glob(os.path.join(result.out_dir, pattern))
-                for fname in file_list:
-                    shutil.copy(fname, build_dir)
+            self.CopyFiles(result.out_dir, build_dir, '', ['u-boot*', '*.bin',
+                '*.map', '*.img', 'MLO', 'SPL', 'include/autoconf.mk',
+                'spl/u-boot-spl*'])
 
+    def CopyFiles(self, out_dir, build_dir, dirname, patterns):
+        """Copy files from the build directory to the output.
+
+        Args:
+            out_dir: Path to output directory containing the files
+            build_dir: Place to copy the files
+            dirname: Source directory, '' for normal U-Boot, 'spl' for SPL
+            patterns: A list of filenames (strings) to copy, each relative
+               to the build directory
+        """
+        for pattern in patterns:
+            file_list = glob.glob(os.path.join(out_dir, dirname, pattern))
+            for fname in file_list:
+                target = os.path.basename(fname)
+                if dirname:
+                    base, ext = os.path.splitext(target)
+                    if ext:
+                        target = '%s-%s%s' % (base, dirname, ext)
+                shutil.copy(fname, os.path.join(build_dir, target))
 
     def RunJob(self, job):
         """Run a single job