Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of mbed-tools by
exporters.py
00001 """Just a template for subclassing""" 00002 import uuid, shutil, os, logging, fnmatch 00003 from os import walk, remove 00004 from os.path import join, dirname, isdir, split 00005 from copy import copy 00006 from jinja2 import Template, FileSystemLoader 00007 from jinja2.environment import Environment 00008 from contextlib import closing 00009 from zipfile import ZipFile, ZIP_DEFLATED 00010 00011 from tools.utils import mkdir 00012 from tools.toolchains import TOOLCHAIN_CLASSES 00013 from tools.targets import TARGET_MAP 00014 00015 from project_generator.generate import Generator 00016 from project_generator.project import Project 00017 from project_generator.settings import ProjectSettings 00018 00019 class OldLibrariesException(Exception): pass 00020 00021 class Exporter(object): 00022 TEMPLATE_DIR = dirname(__file__) 00023 DOT_IN_RELATIVE_PATH = False 00024 00025 def __init__(self, target, inputDir, program_name, build_url_resolver, extra_symbols=None): 00026 self.inputDir = inputDir 00027 self.target = target 00028 self.program_name = program_name 00029 self.toolchain = TOOLCHAIN_CLASSES[self.get_toolchain()](TARGET_MAP[target]) 00030 self.build_url_resolver = build_url_resolver 00031 jinja_loader = FileSystemLoader(os.path.dirname(os.path.abspath(__file__))) 00032 self.jinja_environment = Environment(loader=jinja_loader) 00033 self.extra_symbols = extra_symbols 00034 00035 def get_toolchain(self): 00036 return self.TOOLCHAIN 00037 00038 def __scan_and_copy(self, src_path, trg_path): 00039 resources = self.toolchain.scan_resources(src_path) 00040 00041 for r_type in ['headers', 's_sources', 'c_sources', 'cpp_sources', 00042 'objects', 'libraries', 'linker_script', 00043 'lib_builds', 'lib_refs', 'repo_files', 'hex_files', 'bin_files']: 00044 r = getattr(resources, r_type) 00045 if r: 00046 self.toolchain.copy_files(r, trg_path, rel_path=src_path) 00047 return resources 00048 00049 def progen_get_project_data(self): 00050 """ Get ProGen project data """ 00051 # provide default data, some tools don't require any additional 00052 # tool specific settings 00053 sources = [] 00054 for r_type in ['c_sources', 'cpp_sources', 's_sources']: 00055 for file in getattr(self.resources, r_type): 00056 sources.append(file) 00057 00058 project_data = { 00059 'common': { 00060 'sources': { 00061 'Source Files': sources + self.resources.hex_files + 00062 self.resources.objects + self.resources.libraries, 00063 }, 00064 'includes': { 00065 'Include Files': self.resources.headers, 00066 }, 00067 'target': [TARGET_MAP[self.target].progen['target']], 00068 'macros': self.get_symbols(), 00069 'export_dir': [self.inputDir], 00070 'linker_file': [self.resources.linker_script], 00071 } 00072 } 00073 return project_data 00074 00075 def progen_gen_file(self, tool_name, project_data): 00076 """" Generate project using ProGen Project API """ 00077 settings = ProjectSettings() 00078 project = Project(self.program_name, [project_data], settings) 00079 # TODO: Fix this, the inc_dirs are not valid (our scripts copy files), therefore progen 00080 # thinks it is not dict but a file, and adds them to workspace. 00081 project.project['common']['include_paths'] = self.resources.inc_dirs 00082 project.generate(tool_name, copied=True) 00083 00084 def __scan_all(self, path): 00085 resources = [] 00086 00087 for root, dirs, files in walk(path): 00088 for d in copy(dirs): 00089 if d == '.' or d == '..': 00090 dirs.remove(d) 00091 00092 for file in files: 00093 file_path = join(root, file) 00094 resources.append(file_path) 00095 00096 return resources 00097 00098 def scan_and_copy_resources(self, prj_path, trg_path): 00099 # Copy only the file for the required target and toolchain 00100 lib_builds = [] 00101 for src in ['lib', 'src']: 00102 resources = self.__scan_and_copy(join(prj_path, src), trg_path) 00103 lib_builds.extend(resources.lib_builds) 00104 00105 # The repository files 00106 for repo_dir in resources.repo_dirs: 00107 repo_files = self.__scan_all(repo_dir) 00108 self.toolchain.copy_files(repo_files, trg_path, rel_path=join(prj_path, src)) 00109 00110 # The libraries builds 00111 for bld in lib_builds: 00112 build_url = open(bld).read().strip() 00113 lib_data = self.build_url_resolver(build_url) 00114 lib_path = lib_data['path'].rstrip('\\/') 00115 self.__scan_and_copy(lib_path, join(trg_path, lib_data['name'])) 00116 00117 # Create .hg dir in mbed build dir so it's ignored when versioning 00118 hgdir = join(trg_path, lib_data['name'], '.hg') 00119 mkdir(hgdir) 00120 fhandle = file(join(hgdir, 'keep.me'), 'a') 00121 fhandle.close() 00122 00123 # Final scan of the actual exported resources 00124 self.resources = self.toolchain.scan_resources(trg_path) 00125 self.resources.relative_to(trg_path, self.DOT_IN_RELATIVE_PATH) 00126 # Check the existence of a binary build of the mbed library for the desired target 00127 # This prevents exporting the mbed libraries from source 00128 # if not self.toolchain.mbed_libs: 00129 # raise OldLibrariesException() 00130 00131 def gen_file(self, template_file, data, target_file): 00132 template_path = join(Exporter.TEMPLATE_DIR, template_file) 00133 template = self.jinja_environment.get_template(template_file) 00134 target_text = template.render(data) 00135 00136 target_path = join(self.inputDir, target_file) 00137 logging.debug("Generating: %s" % target_path) 00138 open(target_path, "w").write(target_text) 00139 00140 def get_symbols(self, add_extra_symbols=True): 00141 """ This function returns symbols which must be exported. 00142 Please add / overwrite symbols in each exporter separately 00143 """ 00144 symbols = self.toolchain.get_symbols() 00145 # We have extra symbols from e.g. libraries, we want to have them also added to export 00146 if add_extra_symbols: 00147 if self.extra_symbols is not None: 00148 symbols.extend(self.extra_symbols) 00149 return symbols 00150 00151 def zip_working_directory_and_clean_up(tempdirectory=None, destination=None, program_name=None, clean=True): 00152 uid = str(uuid.uuid4()) 00153 zipfilename = '%s.zip'%uid 00154 00155 logging.debug("Zipping up %s to %s" % (tempdirectory, join(destination, zipfilename))) 00156 # make zip 00157 def zipdir(basedir, archivename): 00158 assert isdir(basedir) 00159 fakeroot = program_name + '/' 00160 with closing(ZipFile(archivename, "w", ZIP_DEFLATED)) as z: 00161 for root, _, files in os.walk(basedir): 00162 # NOTE: ignore empty directories 00163 for fn in files: 00164 absfn = join(root, fn) 00165 zfn = fakeroot + '/' + absfn[len(basedir)+len(os.sep):] 00166 z.write(absfn, zfn) 00167 00168 zipdir(tempdirectory, join(destination, zipfilename)) 00169 00170 if clean: 00171 shutil.rmtree(tempdirectory) 00172 00173 return join(destination, zipfilename)
Generated on Thu Jun 15 2023 14:54:59 by
