summaryrefslogtreecommitdiff
path: root/tools/buildman
diff options
context:
space:
mode:
Diffstat (limited to 'tools/buildman')
-rw-r--r--tools/buildman/README9
-rw-r--r--tools/buildman/builder.py33
-rw-r--r--tools/buildman/builderthread.py16
-rwxr-xr-xtools/buildman/buildman.py2
-rw-r--r--tools/buildman/test.py4
-rw-r--r--tools/buildman/toolchain.py18
6 files changed, 52 insertions, 30 deletions
diff --git a/tools/buildman/README b/tools/buildman/README
index 8c5f8610d02..514bebc9f81 100644
--- a/tools/buildman/README
+++ b/tools/buildman/README
@@ -211,6 +211,15 @@ arm: arm-none-eabi-
and buildman will find arm-none-eabi-gcc in /usr/bin if you have it installed.
+[toolchain-wrapper]
+wrapper: ccache
+
+This tells buildman to use a compiler wrapper in front of CROSS_COMPILE. In
+this example, ccache. It doesn't affect the toolchain scan. The wrapper is
+added when CROSS_COMPILE environtal variable is set. The name in this
+section is ignored. If more than one line is provided, only the last one
+is taken.
+
3. Make sure you have the require Python pre-requisites
Buildman uses multiprocessing, Queue, shutil, StringIO, ConfigParser and
diff --git a/tools/buildman/builder.py b/tools/buildman/builder.py
index 8ec35517290..e27a28577c2 100644
--- a/tools/buildman/builder.py
+++ b/tools/buildman/builder.py
@@ -12,8 +12,10 @@ import os
import re
import Queue
import shutil
+import signal
import string
import sys
+import threading
import time
import builderthread
@@ -126,7 +128,6 @@ class Builder:
"""Class for building U-Boot for a particular commit.
Public members: (many should ->private)
- active: True if the builder is active and has not been stopped
already_done: Number of builds already completed
base_dir: Base directory to use for builder
checkout: True to check out source, False to skip that step.
@@ -234,7 +235,6 @@ class Builder:
self.base_dir = base_dir
self._working_dir = os.path.join(base_dir, '.bm-work')
self.threads = []
- self.active = True
self.do_make = self.Make
self.gnu_make = gnu_make
self.checkout = checkout
@@ -283,11 +283,17 @@ class Builder:
ignore_lines = ['(make.*Waiting for unfinished)', '(Segmentation fault)']
self.re_make_err = re.compile('|'.join(ignore_lines))
+ # Handle existing graceful with SIGINT / Ctrl-C
+ signal.signal(signal.SIGINT, self.signal_handler)
+
def __del__(self):
"""Get rid of all threads created by the builder"""
for t in self.threads:
del t
+ def signal_handler(self, signal, frame):
+ sys.exit(1)
+
def SetDisplayOptions(self, show_errors=False, show_sizes=False,
show_detail=False, show_bloat=False,
list_error_boards=False, show_config=False):
@@ -389,11 +395,6 @@ class Builder:
if result:
target = result.brd.target
- if result.return_code < 0:
- self.active = False
- command.StopAll()
- return
-
self.upto += 1
if result.return_code != 0:
self.fail += 1
@@ -1366,8 +1367,10 @@ class Builder:
if os.path.exists(git_dir):
gitutil.Fetch(git_dir, thread_dir)
else:
- Print('Cloning repo for thread %d' % thread_num)
+ Print('\rCloning repo for thread %d' % thread_num,
+ newline=False)
gitutil.Clone(src_dir, thread_dir)
+ Print('\r%s\r' % (' ' * 30), newline=False)
def _PrepareWorkingSpace(self, max_threads, setup_git):
"""Prepare the working directory for use.
@@ -1395,8 +1398,14 @@ class Builder:
for commit_upto in range(self.commit_count):
dir_list.append(self._GetOutputDir(commit_upto))
+ to_remove = []
for dirname in glob.glob(os.path.join(self.base_dir, '*')):
if dirname not in dir_list:
+ to_remove.append(dirname)
+ if to_remove:
+ Print('Removing %d old build directories' % len(to_remove),
+ newline=False)
+ for dirname in to_remove:
shutil.rmtree(dirname)
def BuildBoards(self, commits, board_selected, keep_outputs, verbose):
@@ -1422,6 +1431,7 @@ class Builder:
self._PrepareWorkingSpace(min(self.num_threads, len(board_selected)),
commits is not None)
self._PrepareOutputSpace()
+ Print('\rStarting build...', newline=False)
self.SetupBuild(board_selected, commits)
self.ProcessResult(None)
@@ -1434,8 +1444,11 @@ class Builder:
job.step = self._step
self.queue.put(job)
- # Wait until all jobs are started
- self.queue.join()
+ term = threading.Thread(target=self.queue.join)
+ term.setDaemon(True)
+ term.start()
+ while term.isAlive():
+ term.join(100)
# Wait until we have processed all output
self.out_queue.join()
diff --git a/tools/buildman/builderthread.py b/tools/buildman/builderthread.py
index c512d3b521f..8974351225c 100644
--- a/tools/buildman/builderthread.py
+++ b/tools/buildman/builderthread.py
@@ -304,10 +304,6 @@ class BuilderThread(threading.Thread):
print >>fd, 'arch', result.toolchain.arch
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
-
# Write out the image and function size information and an objdump
env = result.toolchain.MakeEnvironment(self.builder.full_path)
lines = []
@@ -470,17 +466,7 @@ class BuilderThread(threading.Thread):
This thread picks a job from the queue, runs it, and then goes to the
next job.
"""
- alive = True
while True:
job = self.builder.queue.get()
- if self.builder.active and alive:
- self.RunJob(job)
- '''
- try:
- if self.builder.active and alive:
- self.RunJob(job)
- except Exception as err:
- alive = False
- print err
- '''
+ self.RunJob(job)
self.builder.queue.task_done()
diff --git a/tools/buildman/buildman.py b/tools/buildman/buildman.py
index d0afeda6c07..607429df7bc 100755
--- a/tools/buildman/buildman.py
+++ b/tools/buildman/buildman.py
@@ -15,7 +15,7 @@ import unittest
# Bring in the patman libraries
our_path = os.path.dirname(os.path.realpath(__file__))
-sys.path.append(os.path.join(our_path, '../patman'))
+sys.path.insert(1, os.path.join(our_path, '../patman'))
# Our modules
import board
diff --git a/tools/buildman/test.py b/tools/buildman/test.py
index d8f3c81fadf..ed2a3a8929b 100644
--- a/tools/buildman/test.py
+++ b/tools/buildman/test.py
@@ -198,9 +198,9 @@ class TestBuild(unittest.TestCase):
if line.text.strip():
count += 1
- # We should get one starting message, then an update for every commit
+ # We should get two starting messages, then an update for every commit
# built.
- self.assertEqual(count, len(commits) * len(boards) + 1)
+ self.assertEqual(count, len(commits) * len(boards) + 2)
build.SetDisplayOptions(show_errors=True);
build.ShowSummary(self.commits, board_selected)
#terminal.EchoPrintTestLines()
diff --git a/tools/buildman/toolchain.py b/tools/buildman/toolchain.py
index 41e4e4c5350..47788762016 100644
--- a/tools/buildman/toolchain.py
+++ b/tools/buildman/toolchain.py
@@ -127,6 +127,18 @@ class Toolchain:
return PRIORITY_CALC + prio
return PRIORITY_CALC + prio
+ def GetWrapper(self, show_warning=True):
+ """Get toolchain wrapper from the setting file.
+ """
+ value = ''
+ for name, value in bsettings.GetItems('toolchain-wrapper'):
+ if not value:
+ print "Warning: Wrapper not found"
+ if value:
+ value = value + ' '
+
+ return value
+
def MakeEnvironment(self, full_path):
"""Returns an environment for using the toolchain.
@@ -138,10 +150,12 @@ class Toolchain:
PATH
"""
env = dict(os.environ)
+ wrapper = self.GetWrapper()
+
if full_path:
- env['CROSS_COMPILE'] = os.path.join(self.path, self.cross)
+ env['CROSS_COMPILE'] = wrapper + os.path.join(self.path, self.cross)
else:
- env['CROSS_COMPILE'] = self.cross
+ env['CROSS_COMPILE'] = wrapper + self.cross
env['PATH'] = self.path + ':' + env['PATH']
return env