Add _assemble() and _compile() methods to generate one or more commands per source file

Support multiple commands per compile
Reuse _assemble() and _compile() for sequential and parallel compiles
Preserve compile(), compile_c(), compile_cpp() and assemble() methods functionality
pull/395/head
Mihail Stoyanov 2014-08-05 18:22:50 +03:00
parent 647c96172c
commit d5835221ec
4 changed files with 94 additions and 59 deletions

View File

@ -68,14 +68,20 @@ def print_notify_verbose(event):
print_notify(event) # standard handle print_notify(event) # standard handle
def compile_worker(job): def compile_worker(job):
_, stderr, rc = run_cmd(job['command'], job['work_dir']) results = []
for command in job['commands']:
_, stderr, rc = run_cmd(command, job['work_dir'])
results.append({
'code': rc,
'output': stderr,
'command': command
})
return { return {
'code': rc,
'output': stderr,
'command': job['command'],
'source': job['source'], 'source': job['source'],
'object': job['object'] 'object': job['object'],
'commands': job['commands'],
'results': results
} }
class Resources: class Resources:
@ -481,12 +487,12 @@ class mbedToolchain:
mkdir(work_dir) mkdir(work_dir)
# Queue mode (multiprocessing) # Queue mode (multiprocessing)
command = self._compile_command(source, object, inc_paths) commands = self._compile_command(source, object, inc_paths)
if command is not None: if commands is not None:
queue.append({ queue.append({
'source': source, 'source': source,
'object': object, 'object': object,
'command': command, 'commands': commands,
'work_dir': work_dir, 'work_dir': work_dir,
'chroot': self.CHROOT 'chroot': self.CHROOT
}) })
@ -498,10 +504,23 @@ class mbedToolchain:
if jobs > CPU_COUNT_MIN and len(queue) > jobs: if jobs > CPU_COUNT_MIN and len(queue) > jobs:
return self.compile_queue(queue, objects) return self.compile_queue(queue, objects)
else: else:
for item in queue: return self.compile_seq(queue, objects)
self.compile(item['source'], item['object'], inc_paths)
objects.append(item['object']) def compile_seq(self, queue, objects):
return objects for item in queue:
result = compile_worker(item)
self.compiled += 1
self.progress("compile", item['source'], build_update=True)
for res in result['results']:
self.debug("Command: %s" % ' '.join(res['command']))
self._compile_output([
res['code'],
res['output'],
res['command']
])
objects.append(result['object'])
return objects
def compile_queue(self, queue, objects): def compile_queue(self, queue, objects):
jobs_count = int(self.jobs if self.jobs else cpu_count()) jobs_count = int(self.jobs if self.jobs else cpu_count())
@ -528,12 +547,13 @@ class mbedToolchain:
self.compiled += 1 self.compiled += 1
self.progress("compile", result['source'], build_update=True) self.progress("compile", result['source'], build_update=True)
self.debug("Command: %s" % ' '.join(result['command'])) for res in result['results']:
self._compile_output([ self.debug("Command: %s" % ' '.join(res['command']))
result['code'], self._compile_output([
result['output'], res['code'],
result['command'] res['output'],
]) res['command']
])
objects.append(result['object']) objects.append(result['object'])
except ToolException, err: except ToolException, err:
p.terminate() p.terminate()
@ -560,37 +580,20 @@ class mbedToolchain:
# Check dependencies # Check dependencies
_, ext = splitext(source) _, ext = splitext(source)
ext = ext.lower() ext = ext.lower()
base, _ = splitext(object)
dep_path = base + '.d'
asm_mode = False
if ext == '.c': if ext == '.c' or ext == '.cpp':
cc = self.cc base, _ = splitext(object)
elif ext == '.cpp': dep_path = base + '.d'
cc = self.cppc deps = self.parse_dependencies(dep_path) if (exists(dep_path)) else []
if len(deps) == 0 or self.need_update(object, deps):
return self._compile(source, object, includes)
elif ext == '.s': elif ext == '.s':
cc = self.asm deps = [source]
asm_mode = True if self.need_update(object, deps):
return self._assemble(source, object, includes)
else: else:
return False return False
deps = []
if asm_mode:
deps = [source]
elif exists(dep_path):
deps = self.parse_dependencies(dep_path)
if len(deps) == 0 or self.need_update(object, deps):
command = cc + ['-D%s' % s for s in self.get_symbols()] + ["-I%s" % i for i in includes] + ["-o", object, source]
if asm_mode is False and hasattr(self, "get_dep_opt"):
command.extend(self.get_dep_opt(dep_path))
if hasattr(self, "cc_extra"):
command.extend(self.cc_extra(base))
return command
return None return None
def _compile_output(self, output=[]): def _compile_output(self, output=[]):
@ -607,16 +610,31 @@ class mbedToolchain:
if rc != 0: if rc != 0:
raise ToolException(stderr) raise ToolException(stderr)
def _compile(self, source, object, includes):
_, ext = splitext(source)
ext = ext.lower()
cc = self.cppc if ext == ".cpp" else self.cc
command = cc + ['-D%s' % s for s in self.get_symbols()] + ["-I%s" % i for i in includes] + ["-o", object, source]
if hasattr(self, "get_dep_opt"):
base, _ = splitext(object)
dep_path = base + '.d'
command.extend(self.get_dep_opt(dep_path))
if hasattr(self, "cc_extra"):
command.extend(self.cc_extra(base))
return [command]
def compile(self, source, object, includes): def compile(self, source, object, includes):
self.compiled += 1
self.progress("compile", source, build_update=True) self.progress("compile", source, build_update=True)
command = self._compile_command(source, object, includes) commands = self._compile(source, object, includes)
if command is None: return True for command in commands:
self.debug("Command: %s" % ' '.join(command))
self.debug("Command: %s" % ' '.join(command)) _, stderr, rc = run_cmd(command, dirname(object))
_, stderr, rc = run_cmd(command, dirname(object)) self._compile_output([rc, stderr, command])
self._compile_output([rc, stderr, command])
def compile_c(self, source, object, includes): def compile_c(self, source, object, includes):
self.compile(source, object, includes) self.compile(source, object, includes)

View File

@ -80,11 +80,18 @@ class ARM(mbedToolchain):
if option in tool: if option in tool:
tool.remove(option) tool.remove(option)
def assemble(self, source, object, includes): def _assemble(self, source, object, includes):
# Preprocess first, then assemble # Preprocess first, then assemble
tempfile = object + '.E.s' tempfile = object + '.E.s'
self.default_cmd(self.asm + ['-D%s' % s for s in self.get_symbols() + self.macros] + ["-I%s" % i for i in includes] + ["-E", "-o", tempfile, source]) return [
self.default_cmd(self.hook.get_cmdline_assembler(self.asm + ["-o", object, tempfile])) self.asm + ['-D%s' % s for s in self.get_symbols() + self.macros] + ["-I%s" % i for i in includes] + ["-E", "-o", tempfile, source],
self.hook.get_cmdline_assembler(self.asm + ["-o", object, tempfile])
]
def assemble(self, source, object, includes):
commands = self._assemble(source, object, includes);
for command in commands:
self.default_cmd(command)
def parse_dependencies(self, dep_path): def parse_dependencies(self, dep_path):
dependencies = [] dependencies = []

View File

@ -81,8 +81,13 @@ class GCC(mbedToolchain):
self.ar = join(tool_path, "arm-none-eabi-ar") self.ar = join(tool_path, "arm-none-eabi-ar")
self.elf2bin = join(tool_path, "arm-none-eabi-objcopy") self.elf2bin = join(tool_path, "arm-none-eabi-objcopy")
def _assemble(self, source, object, includes):
return [self.hook.get_cmdline_assembler(self.asm + ['-D%s' % s for s in self.get_symbols() + self.macros] + ["-I%s" % i for i in includes] + ["-o", object, source])]
def assemble(self, source, object, includes): def assemble(self, source, object, includes):
self.default_cmd(self.hook.get_cmdline_assembler(self.asm + ['-D%s' % s for s in self.get_symbols() + self.macros] + ["-I%s" % i for i in includes] + ["-o", object, source])) commands = self._assemble(source, object, includes);
for command in commands:
self.default_cmd(command)
def parse_dependencies(self, dep_path): def parse_dependencies(self, dep_path):
dependencies = [] dependencies = []

View File

@ -94,8 +94,13 @@ class IAR(mbedToolchain):
return [path.strip() for path in open(dep_path).readlines() return [path.strip() for path in open(dep_path).readlines()
if (path and not path.isspace())] if (path and not path.isspace())]
def _assemble(self, source, object, includes):
return [self.hook.get_cmdline_assembler(self.asm + ['-D%s' % s for s in self.get_symbols() + self.macros] + ["-I%s" % i for i in includes] + ["-o", object, source])]
def assemble(self, source, object, includes): def assemble(self, source, object, includes):
self.default_cmd(self.hook.get_cmdline_assembler(self.asm + ['-D%s' % s for s in self.get_symbols() + self.macros] + ["-I%s" % i for i in includes] + ["-o", object, source])) commands = self._assemble(source, object, includes);
for command in commands:
self.default_cmd(command)
def archive(self, objects, lib_path): def archive(self, objects, lib_path):
if exists(lib_path): if exists(lib_path):