2013-02-18 15:32:11 +00:00
|
|
|
"""Just a template for subclassing"""
|
|
|
|
import uuid, shutil, os, logging, fnmatch
|
2013-11-15 18:59:19 +00:00
|
|
|
from os import walk, remove
|
2013-02-18 15:32:11 +00:00
|
|
|
from os.path import join, dirname, isdir, split
|
2013-11-15 18:59:19 +00:00
|
|
|
from copy import copy
|
2014-06-21 14:35:32 +00:00
|
|
|
from jinja2 import Template, FileSystemLoader
|
|
|
|
from jinja2.environment import Environment
|
2013-02-18 15:32:11 +00:00
|
|
|
from contextlib import closing
|
|
|
|
from zipfile import ZipFile, ZIP_DEFLATED
|
|
|
|
|
2013-11-14 16:24:51 +00:00
|
|
|
from workspace_tools.utils import mkdir
|
2013-02-18 15:32:11 +00:00
|
|
|
from workspace_tools.toolchains import TOOLCHAIN_CLASSES
|
2013-04-19 13:59:13 +00:00
|
|
|
from workspace_tools.targets import TARGET_MAP
|
2013-02-18 15:32:11 +00:00
|
|
|
|
2015-11-30 19:48:24 +00:00
|
|
|
from project_generator.generate import Generator
|
|
|
|
from project_generator.project import Project
|
|
|
|
from project_generator.settings import ProjectSettings
|
|
|
|
|
2013-02-18 15:32:11 +00:00
|
|
|
class OldLibrariesException(Exception): pass
|
|
|
|
|
2015-11-30 19:48:24 +00:00
|
|
|
class Exporter(object):
|
2013-02-18 15:32:11 +00:00
|
|
|
TEMPLATE_DIR = dirname(__file__)
|
|
|
|
DOT_IN_RELATIVE_PATH = False
|
2014-05-29 13:42:03 +00:00
|
|
|
|
2015-12-09 19:16:52 +00:00
|
|
|
# mapping mbed to progen targets
|
2015-11-30 19:48:24 +00:00
|
|
|
PROGEN_TARGETS = {
|
2015-12-29 16:35:06 +00:00
|
|
|
'LPC1768': 'mbed-lpc1768',
|
2015-12-29 13:42:44 +00:00
|
|
|
'LPC11U24': 'lpc11u24_201',
|
2015-12-09 19:16:52 +00:00
|
|
|
'LPC1347':'lpc1347',
|
|
|
|
'LPC1114':'lpc1114_102',
|
|
|
|
'LPC11C24':'lpc11c24_301',
|
|
|
|
'LPC4088':'lpc4088',
|
|
|
|
'LPC4088_DM':'lpc4088',
|
|
|
|
'LPC4330_M4':'lpc4330',
|
|
|
|
'LPC4337':'lpc4337',
|
|
|
|
'LPC812':'lpc812m101',
|
2015-12-29 14:56:07 +00:00
|
|
|
'LPC824': 'lpc824m201',
|
2015-12-09 19:16:52 +00:00
|
|
|
'LPC1549':'lpc1549',
|
|
|
|
'LPC11U68':'lpc11u68',
|
|
|
|
'LPC11U35_501':'lpc11u35_501',
|
2015-12-29 14:56:07 +00:00
|
|
|
'LPC11U35_401': 'lpc11u35_401',
|
2015-12-09 19:16:52 +00:00
|
|
|
'LPC11U37H_401':'lpc11u37_401',
|
|
|
|
|
2015-12-29 16:35:06 +00:00
|
|
|
'KL05Z':'frdm-kl05z',
|
|
|
|
'KL25Z':'frdm-kl25z',
|
|
|
|
'KL43Z':'frdm-kl43z',
|
|
|
|
'KL46Z':'frdm-kl46z',
|
|
|
|
'K64F': 'frdm-k64f',
|
|
|
|
'K22F': 'frdm-k22f',
|
2015-11-30 19:48:24 +00:00
|
|
|
'K20D50M': 'frdm-k20d50m',
|
2015-12-29 16:35:06 +00:00
|
|
|
'TEENSY3_1':'teensy-31',
|
2015-12-09 19:16:52 +00:00
|
|
|
|
2015-11-30 19:48:24 +00:00
|
|
|
'NUCLEO_F030R8':'nucleo-f030r8',
|
|
|
|
'NUCLEO_F031K6':'nucleo-f031k6',
|
|
|
|
'NUCLEO_F042K6':'nucleo-f042k6',
|
|
|
|
'NUCLEO_F070RB':'nucleo-f070rb',
|
|
|
|
'NUCLEO_F072RB':'nucleo-f072rb',
|
|
|
|
'NUCLEO_F091RC':'nucleo-f091rc',
|
|
|
|
'NUCLEO_F103RB':'nucleo-f103rb',
|
|
|
|
'NUCLEO_F302R8':'nucleo-f302r8',
|
|
|
|
'NUCLEO_F303K8':'nucleo-f303k8',
|
|
|
|
'NUCLEO_F303RE':'nucleo-f303re',
|
|
|
|
'NUCLEO_F334R8':'nucleo-f334r8',
|
|
|
|
'NUCLEO_F401RE':'nucleo-f401re',
|
|
|
|
'NUCLEO_F410RB':'nucleo-f410rb',
|
|
|
|
'NUCLEO_F411RE':'nucleo-f411re',
|
|
|
|
'NUCLEO_F446RE':'nucleo-f446re',
|
|
|
|
'NUCLEO_L053R8':'nucleo-l053r8',
|
|
|
|
'NUCLEO_L073RZ':'nucleo-l073rz',
|
|
|
|
'NUCLEO_L152RE':'nucleo-l152re',
|
|
|
|
'NUCLEO_L476RG':'nucleo-l476rg',
|
2015-12-09 19:16:52 +00:00
|
|
|
|
2015-12-29 16:35:06 +00:00
|
|
|
'DISCO_F407VG':'disco-f407vg',
|
2015-11-30 19:48:24 +00:00
|
|
|
'DISCO_F429ZI':'disco-f429zi',
|
|
|
|
'DISCO_L053C8':'disco-l053c8',
|
|
|
|
'DISCO_F334C8':'disco-f334c8',
|
|
|
|
'DISCO_F469NI':'disco-f469ni',
|
|
|
|
'DISCO_F746NG':'disco-f746ng',
|
|
|
|
'DISCO_L476VG':'disco-l476vg',
|
2015-12-09 19:16:52 +00:00
|
|
|
|
|
|
|
'UBLOX_C027':'ublox-c027',
|
|
|
|
'NRF51822':'mkit',
|
|
|
|
'HRM1017':'hrm1017',
|
2015-12-29 16:35:06 +00:00
|
|
|
'RBLAB_NRF51822':'rblab-nrf51822',
|
2015-12-29 13:42:44 +00:00
|
|
|
'ARCH_PRO':'arch-pro',
|
2015-12-09 19:16:52 +00:00
|
|
|
'ARCH_BLE':'arch-ble',
|
2015-12-29 13:42:44 +00:00
|
|
|
'MTS_GAMBIT':'mts-gambit',
|
2015-12-09 19:16:52 +00:00
|
|
|
'ARCH_MAX':'lpc1768',
|
2015-12-29 16:35:06 +00:00
|
|
|
'MTS_MDOT_F405RG':'mts-mdot-f405rg',
|
|
|
|
'MTS_MDOT_F411RE': 'mts-mdot-f411re',
|
|
|
|
'MTS_DRAGONFLY_F411RE': 'mts-dragonfly-f411re',
|
|
|
|
'NRF51_DK':'nrf51-dk',
|
|
|
|
'NRF51_DONGLE':'nrf51-dongle',
|
|
|
|
'SEEED_TINY_BLE':'seed-tinyble',
|
2015-12-09 19:16:52 +00:00
|
|
|
|
|
|
|
'DELTA_DFCM_NNN40':'dfcm-nnn40',
|
2015-11-30 19:48:24 +00:00
|
|
|
'MAXWSNENV':'maxwsnenv',
|
|
|
|
'MAX32600MBED':'max32600mbed',
|
2015-12-09 19:16:52 +00:00
|
|
|
'MOTE_L152RC':'stm32l151rc',
|
|
|
|
'NZ32SC151':'stm32l151rc',
|
|
|
|
|
|
|
|
'SAMR21G18A':'samr21g18a',
|
|
|
|
'SAMD21J18A':'samd21j18a',
|
|
|
|
'SAMD21G18A':'samd21g18a',
|
|
|
|
'SAML21J18A':'samr21j18a',
|
2015-11-30 19:48:24 +00:00
|
|
|
}
|
|
|
|
|
2014-11-11 14:56:26 +00:00
|
|
|
def __init__(self, target, inputDir, program_name, build_url_resolver, extra_symbols=None):
|
2013-02-18 15:32:11 +00:00
|
|
|
self.inputDir = inputDir
|
|
|
|
self.target = target
|
|
|
|
self.program_name = program_name
|
2013-09-17 14:56:35 +00:00
|
|
|
self.toolchain = TOOLCHAIN_CLASSES[self.get_toolchain()](TARGET_MAP[target])
|
2013-02-18 15:32:11 +00:00
|
|
|
self.build_url_resolver = build_url_resolver
|
2014-06-21 14:35:32 +00:00
|
|
|
jinja_loader = FileSystemLoader(os.path.dirname(os.path.abspath(__file__)))
|
|
|
|
self.jinja_environment = Environment(loader=jinja_loader)
|
2014-11-11 14:56:26 +00:00
|
|
|
self.extra_symbols = extra_symbols
|
2014-05-29 13:42:03 +00:00
|
|
|
|
2013-09-17 14:56:35 +00:00
|
|
|
def get_toolchain(self):
|
|
|
|
return self.TOOLCHAIN
|
2014-05-29 13:42:03 +00:00
|
|
|
|
2013-02-18 15:32:11 +00:00
|
|
|
def __scan_and_copy(self, src_path, trg_path):
|
|
|
|
resources = self.toolchain.scan_resources(src_path)
|
2014-05-29 13:42:03 +00:00
|
|
|
|
2013-11-14 16:24:51 +00:00
|
|
|
for r_type in ['headers', 's_sources', 'c_sources', 'cpp_sources',
|
|
|
|
'objects', 'libraries', 'linker_script',
|
2015-02-04 10:29:31 +00:00
|
|
|
'lib_builds', 'lib_refs', 'repo_files', 'hex_files', 'bin_files']:
|
2013-02-18 15:32:11 +00:00
|
|
|
r = getattr(resources, r_type)
|
|
|
|
if r:
|
2013-06-14 16:32:15 +00:00
|
|
|
self.toolchain.copy_files(r, trg_path, rel_path=src_path)
|
2013-11-14 16:24:51 +00:00
|
|
|
return resources
|
2013-11-15 18:59:19 +00:00
|
|
|
|
2015-11-30 19:48:24 +00:00
|
|
|
def get_project_data(self):
|
|
|
|
""" Get ProGen project data """
|
|
|
|
# provide default data, some tools don't require any additional
|
|
|
|
# tool specific settings
|
|
|
|
sources = []
|
|
|
|
for r_type in ['c_sources', 'cpp_sources', 's_sources']:
|
|
|
|
for file in getattr(self.resources, r_type):
|
|
|
|
sources.append(file)
|
|
|
|
|
|
|
|
# TODO: sources in groups
|
|
|
|
project_data = {
|
|
|
|
'common': {
|
|
|
|
'sources': sources + self.resources.hex_files +
|
|
|
|
self.resources.objects + self.resources.libraries,
|
|
|
|
# 'includes': self.resources.inc_dirs,
|
|
|
|
'target': [self.PROGEN_TARGETS[self.target]],
|
|
|
|
'debugger': ['cmsis-dap'], #TODO: per target to set this
|
|
|
|
'macros': self.get_symbols(),
|
|
|
|
'export_dir': [self.inputDir],
|
|
|
|
'linker_file': [self.resources.linker_script],
|
|
|
|
'template': [''],
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return project_data
|
|
|
|
|
2013-11-15 18:59:19 +00:00
|
|
|
def __scan_all(self, path):
|
|
|
|
resources = []
|
2014-05-29 13:42:03 +00:00
|
|
|
|
2013-11-15 18:59:19 +00:00
|
|
|
for root, dirs, files in walk(path):
|
|
|
|
for d in copy(dirs):
|
|
|
|
if d == '.' or d == '..':
|
|
|
|
dirs.remove(d)
|
|
|
|
|
|
|
|
for file in files:
|
|
|
|
file_path = join(root, file)
|
|
|
|
resources.append(file_path)
|
2014-05-29 13:42:03 +00:00
|
|
|
|
2013-11-15 18:59:19 +00:00
|
|
|
return resources
|
2014-05-29 13:42:03 +00:00
|
|
|
|
2013-02-18 15:32:11 +00:00
|
|
|
def scan_and_copy_resources(self, prj_path, trg_path):
|
|
|
|
# Copy only the file for the required target and toolchain
|
|
|
|
lib_builds = []
|
|
|
|
for src in ['lib', 'src']:
|
2013-11-14 16:24:51 +00:00
|
|
|
resources = self.__scan_and_copy(join(prj_path, src), trg_path)
|
|
|
|
lib_builds.extend(resources.lib_builds)
|
2013-11-15 18:59:19 +00:00
|
|
|
|
|
|
|
# The repository files
|
|
|
|
for repo_dir in resources.repo_dirs:
|
|
|
|
repo_files = self.__scan_all(repo_dir)
|
|
|
|
self.toolchain.copy_files(repo_files, trg_path, rel_path=join(prj_path, src))
|
2014-05-29 13:42:03 +00:00
|
|
|
|
2013-02-18 15:32:11 +00:00
|
|
|
# The libraries builds
|
|
|
|
for bld in lib_builds:
|
|
|
|
build_url = open(bld).read().strip()
|
|
|
|
lib_data = self.build_url_resolver(build_url)
|
|
|
|
lib_path = lib_data['path'].rstrip('\\/')
|
|
|
|
self.__scan_and_copy(lib_path, join(trg_path, lib_data['name']))
|
2013-11-15 18:59:19 +00:00
|
|
|
|
|
|
|
# Create .hg dir in mbed build dir so it's ignored when versioning
|
2013-11-14 16:24:51 +00:00
|
|
|
hgdir = join(trg_path, lib_data['name'], '.hg')
|
|
|
|
mkdir(hgdir)
|
|
|
|
fhandle = file(join(hgdir, 'keep.me'), 'a')
|
|
|
|
fhandle.close()
|
|
|
|
|
2013-02-18 15:32:11 +00:00
|
|
|
# Final scan of the actual exported resources
|
|
|
|
self.resources = self.toolchain.scan_resources(trg_path)
|
|
|
|
self.resources.relative_to(trg_path, self.DOT_IN_RELATIVE_PATH)
|
|
|
|
# Check the existence of a binary build of the mbed library for the desired target
|
|
|
|
# This prevents exporting the mbed libraries from source
|
|
|
|
# if not self.toolchain.mbed_libs:
|
|
|
|
# raise OldLibrariesException()
|
2013-11-15 18:59:19 +00:00
|
|
|
|
2015-11-30 19:48:24 +00:00
|
|
|
def gen_file_progen(self, tool_name, project_data):
|
|
|
|
"""" Generate project using ProGen Project API """
|
|
|
|
settings = ProjectSettings()
|
|
|
|
project = Project(self.program_name, [project_data], settings)
|
|
|
|
# TODO: fix
|
|
|
|
# this hack is for these scripts which know too much
|
|
|
|
project.project['common']['include_paths'] = self.resources.inc_dirs
|
|
|
|
project.generate(tool_name, copied=True)
|
|
|
|
|
2013-02-18 15:32:11 +00:00
|
|
|
def gen_file(self, template_file, data, target_file):
|
|
|
|
template_path = join(Exporter.TEMPLATE_DIR, template_file)
|
2014-06-21 14:35:32 +00:00
|
|
|
template = self.jinja_environment.get_template(template_file)
|
2013-02-18 15:32:11 +00:00
|
|
|
target_text = template.render(data)
|
2014-05-29 13:42:03 +00:00
|
|
|
|
2013-02-18 15:32:11 +00:00
|
|
|
target_path = join(self.inputDir, target_file)
|
|
|
|
logging.debug("Generating: %s" % target_path)
|
|
|
|
open(target_path, "w").write(target_text)
|
|
|
|
|
2014-11-11 14:56:26 +00:00
|
|
|
def get_symbols(self, add_extra_symbols=True):
|
|
|
|
""" This function returns symbols which must be exported.
|
|
|
|
Please add / overwrite symbols in each exporter separately
|
|
|
|
"""
|
|
|
|
symbols = self.toolchain.get_symbols()
|
|
|
|
# We have extra symbols from e.g. libraries, we want to have them also added to export
|
|
|
|
if add_extra_symbols:
|
|
|
|
if self.extra_symbols is not None:
|
|
|
|
symbols.extend(self.extra_symbols)
|
|
|
|
return symbols
|
2013-02-18 15:32:11 +00:00
|
|
|
|
|
|
|
def zip_working_directory_and_clean_up(tempdirectory=None, destination=None, program_name=None, clean=True):
|
|
|
|
uid = str(uuid.uuid4())
|
|
|
|
zipfilename = '%s.zip'%uid
|
2014-05-29 13:42:03 +00:00
|
|
|
|
2013-02-18 15:32:11 +00:00
|
|
|
logging.debug("Zipping up %s to %s" % (tempdirectory, join(destination, zipfilename)))
|
|
|
|
# make zip
|
|
|
|
def zipdir(basedir, archivename):
|
|
|
|
assert isdir(basedir)
|
|
|
|
fakeroot = program_name + '/'
|
|
|
|
with closing(ZipFile(archivename, "w", ZIP_DEFLATED)) as z:
|
|
|
|
for root, _, files in os.walk(basedir):
|
|
|
|
# NOTE: ignore empty directories
|
|
|
|
for fn in files:
|
|
|
|
absfn = join(root, fn)
|
|
|
|
zfn = fakeroot + '/' + absfn[len(basedir)+len(os.sep):]
|
|
|
|
z.write(absfn, zfn)
|
2014-05-29 13:42:03 +00:00
|
|
|
|
2013-02-18 15:32:11 +00:00
|
|
|
zipdir(tempdirectory, join(destination, zipfilename))
|
2014-05-29 13:42:03 +00:00
|
|
|
|
2013-02-18 15:32:11 +00:00
|
|
|
if clean:
|
|
|
|
shutil.rmtree(tempdirectory)
|
2014-05-29 13:42:03 +00:00
|
|
|
|
2013-02-18 15:32:11 +00:00
|
|
|
return join(destination, zipfilename)
|