[U-Boot] [PATCH] buildman: allow more incremental building
Stephen Warren
swarren at wwwdotorg.org
Tue Mar 29 00:39:35 CEST 2016
From: Stephen Warren <swarren at nvidia.com>
One use-case for buildman is to continually run it interactively after
each small step in a large refactoring operation. This gives more
immediate feedback than making a number of commits and then going back and
testing them. For this to work well, buildman needs to be extremely fast.
At present, a couple issues prevent it being as fast as it could be:
1) Each time buildman runs "make %_defconfig", it runs "make mrproper"
first. This throws away all previous build results, requiring a
from-scratch build. Optionally avoiding this would speed up the build, at
the cost of potentially causing or missing some build issues.
2) A build tree is created per thread rather than per board. When a thread
switches between building different boards, this often causes many files
to be rebuilt due to changing config options. Using a separate build tree
for each board would avoid this. This does put more strain on the system's
disk cache, but it is worth it on my system at least.
This commit adds two command-line options to implement the changes
described above; -I ("--incremental") turns of "make mrproper" and -P
("--per-board-out-dir") creats a build directory per board rather than per
thread.
Tested:
./tools/buildman/buildman.py tegra
./tools/buildman/buildman.py -I -P tegra
./tools/buildman/buildman.py -b tegra_dev tegra
./tools/buildman/buildman.py -b tegra_dev -I -P tegra
... each once after deleting the buildman result/work directory, and once
"incrementally" after a previous identical invocation.
Signed-off-by: Stephen Warren <swarren at nvidia.com>
---
tools/buildman/builder.py | 10 ++++++++--
tools/buildman/builderthread.py | 24 ++++++++++++++++--------
tools/buildman/cmdline.py | 4 ++++
tools/buildman/control.py | 4 +++-
4 files changed, 31 insertions(+), 11 deletions(-)
diff --git a/tools/buildman/builder.py b/tools/buildman/builder.py
index 141bf6469136..8ec355172901 100644
--- a/tools/buildman/builder.py
+++ b/tools/buildman/builder.py
@@ -205,7 +205,8 @@ class Builder:
def __init__(self, toolchains, base_dir, git_dir, num_threads, num_jobs,
gnu_make='make', checkout=True, show_unknown=True, step=1,
- no_subdirs=False, full_path=False, verbose_build=False):
+ no_subdirs=False, full_path=False, verbose_build=False,
+ incremental=False, per_board_out_dir=False):
"""Create a new Builder object
Args:
@@ -224,6 +225,10 @@ class Builder:
full_path: Return the full path in CROSS_COMPILE and don't set
PATH
verbose_build: Run build with V=1 and don't use 'make -s'
+ incremental: Always perform incremental builds; don't run make
+ mrproper when configuring
+ per_board_out_dir: Build in a separate persistent directory per
+ board rather than a thread-specific directory
"""
self.toolchains = toolchains
self.base_dir = base_dir
@@ -263,7 +268,8 @@ class Builder:
self.queue = Queue.Queue()
self.out_queue = Queue.Queue()
for i in range(self.num_threads):
- t = builderthread.BuilderThread(self, i)
+ t = builderthread.BuilderThread(self, i, incremental,
+ per_board_out_dir)
t.setDaemon(True)
t.start()
self.threads.append(t)
diff --git a/tools/buildman/builderthread.py b/tools/buildman/builderthread.py
index cf25bb8f1a7e..c512d3b521f7 100644
--- a/tools/buildman/builderthread.py
+++ b/tools/buildman/builderthread.py
@@ -80,11 +80,13 @@ class BuilderThread(threading.Thread):
thread_num: Our thread number (0-n-1), used to decide on a
temporary directory
"""
- def __init__(self, builder, thread_num):
+ def __init__(self, builder, thread_num, incremental, per_board_out_dir):
"""Set up a new builder thread"""
threading.Thread.__init__(self)
self.builder = builder
self.thread_num = thread_num
+ self.incremental = incremental
+ self.per_board_out_dir = per_board_out_dir
def Make(self, commit, brd, stage, cwd, *args, **kwargs):
"""Run 'make' on a particular commit and board.
@@ -136,7 +138,11 @@ class BuilderThread(threading.Thread):
if self.builder.in_tree:
out_dir = work_dir
else:
- out_dir = os.path.join(work_dir, 'build')
+ if self.per_board_out_dir:
+ out_rel_dir = os.path.join('..', brd.target)
+ else:
+ out_rel_dir = 'build'
+ out_dir = os.path.join(work_dir, out_rel_dir)
# Check if the job was already completed last time
done_file = self.builder.GetDoneFile(commit_upto, brd.target)
@@ -197,12 +203,12 @@ class BuilderThread(threading.Thread):
#
# Symlinks can confuse U-Boot's Makefile since
# we may use '..' in our path, so remove them.
- work_dir = os.path.realpath(work_dir)
- args.append('O=%s/build' % work_dir)
+ out_dir = os.path.realpath(out_dir)
+ args.append('O=%s' % out_dir)
cwd = None
src_dir = os.getcwd()
else:
- args.append('O=build')
+ args.append('O=%s' % out_rel_dir)
if self.builder.verbose_build:
args.append('V=1')
else:
@@ -215,9 +221,11 @@ class BuilderThread(threading.Thread):
# If we need to reconfigure, do that now
if do_config:
- result = self.Make(commit, brd, 'mrproper', cwd,
- 'mrproper', *args, env=env)
- config_out = result.combined
+ config_out = ''
+ if not self.incremental:
+ 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
diff --git a/tools/buildman/cmdline.py b/tools/buildman/cmdline.py
index 8341ab145cfa..3e3bd63e32c7 100644
--- a/tools/buildman/cmdline.py
+++ b/tools/buildman/cmdline.py
@@ -49,6 +49,8 @@ def ParseArgs():
parser.add_option('-i', '--in-tree', dest='in_tree',
action='store_true', default=False,
help='Build in the source tree instead of a separate directory')
+ parser.add_option('-I', '--incremental', action='store_true',
+ default=False, help='Do not run make mrproper (when reconfiguring)')
parser.add_option('-j', '--jobs', dest='jobs', type='int',
default=None, help='Number of jobs to run at once (passed to make)')
parser.add_option('-k', '--keep-outputs', action='store_true',
@@ -70,6 +72,8 @@ def ParseArgs():
default=False, help='Do a rough build, with limited warning resolution')
parser.add_option('-p', '--full-path', action='store_true',
default=False, help="Use full toolchain path in CROSS_COMPILE")
+ parser.add_option('-P', '--per-board-out-dir', action='store_true',
+ default=False, help="Use an O= (output) directory per board rather than per thread")
parser.add_option('-s', '--summary', action='store_true',
default=False, help='Show a build summary')
parser.add_option('-S', '--show-sizes', action='store_true',
diff --git a/tools/buildman/control.py b/tools/buildman/control.py
index c2c54bf0e81b..aeb128a6a3e9 100644
--- a/tools/buildman/control.py
+++ b/tools/buildman/control.py
@@ -250,7 +250,9 @@ def DoBuildman(options, args, toolchains=None, make_func=None, boards=None,
options.threads, options.jobs, gnu_make=gnu_make, checkout=True,
show_unknown=options.show_unknown, step=options.step,
no_subdirs=options.no_subdirs, full_path=options.full_path,
- verbose_build=options.verbose_build)
+ verbose_build=options.verbose_build,
+ incremental=options.incremental,
+ per_board_out_dir=options.per_board_out_dir,)
builder.force_config_on_failure = not options.quick
if make_func:
builder.do_make = make_func
--
2.7.4
More information about the U-Boot
mailing list