]> git.donarmstrong.com Git - qmk_firmware.git/blob - tool/mbed/mbed-sdk/workspace_tools/export/exporters.py
Squashed 'tmk_core/' changes from 7967731..b9e0ea0
[qmk_firmware.git] / tool / mbed / mbed-sdk / workspace_tools / export / exporters.py
1 """Just a template for subclassing"""
2 import uuid, shutil, os, logging, fnmatch
3 from os import walk, remove
4 from os.path import join, dirname, isdir, split
5 from copy import copy
6 from jinja2 import Template, FileSystemLoader
7 from jinja2.environment import Environment
8 from contextlib import closing
9 from zipfile import ZipFile, ZIP_DEFLATED
10
11 from workspace_tools.utils import mkdir
12 from workspace_tools.toolchains import TOOLCHAIN_CLASSES
13 from workspace_tools.targets import TARGET_MAP
14
15 class OldLibrariesException(Exception): pass
16
17 class Exporter():
18     TEMPLATE_DIR = dirname(__file__)
19     DOT_IN_RELATIVE_PATH = False
20
21     def __init__(self, target, inputDir, program_name, build_url_resolver, extra_symbols=None):
22         self.inputDir = inputDir
23         self.target = target
24         self.program_name = program_name
25         self.toolchain = TOOLCHAIN_CLASSES[self.get_toolchain()](TARGET_MAP[target])
26         self.build_url_resolver = build_url_resolver
27         jinja_loader = FileSystemLoader(os.path.dirname(os.path.abspath(__file__)))
28         self.jinja_environment = Environment(loader=jinja_loader)
29         self.extra_symbols = extra_symbols
30
31     def get_toolchain(self):
32         return self.TOOLCHAIN
33
34     def __scan_and_copy(self, src_path, trg_path):
35         resources = self.toolchain.scan_resources(src_path)
36
37         for r_type in ['headers', 's_sources', 'c_sources', 'cpp_sources',
38             'objects', 'libraries', 'linker_script',
39             'lib_builds', 'lib_refs', 'repo_files', 'hex_files', 'bin_files']:
40             r = getattr(resources, r_type)
41             if r:
42                 self.toolchain.copy_files(r, trg_path, rel_path=src_path)
43         return resources
44
45     def __scan_all(self, path):
46         resources = []
47
48         for root, dirs, files in walk(path):
49             for d in copy(dirs):
50                 if d == '.' or d == '..':
51                     dirs.remove(d)
52
53             for file in files:
54                 file_path = join(root, file)
55                 resources.append(file_path)
56
57         return resources
58
59     def scan_and_copy_resources(self, prj_path, trg_path):
60         # Copy only the file for the required target and toolchain
61         lib_builds = []
62         for src in ['lib', 'src']:
63             resources = self.__scan_and_copy(join(prj_path, src), trg_path)
64             lib_builds.extend(resources.lib_builds)
65
66             # The repository files
67             for repo_dir in resources.repo_dirs:
68                 repo_files = self.__scan_all(repo_dir)
69                 self.toolchain.copy_files(repo_files, trg_path, rel_path=join(prj_path, src))
70
71         # The libraries builds
72         for bld in lib_builds:
73             build_url = open(bld).read().strip()
74             lib_data = self.build_url_resolver(build_url)
75             lib_path = lib_data['path'].rstrip('\\/')
76             self.__scan_and_copy(lib_path, join(trg_path, lib_data['name']))
77
78             # Create .hg dir in mbed build dir so it's ignored when versioning
79             hgdir = join(trg_path, lib_data['name'], '.hg')
80             mkdir(hgdir)
81             fhandle = file(join(hgdir, 'keep.me'), 'a')
82             fhandle.close()
83
84         # Final scan of the actual exported resources
85         self.resources = self.toolchain.scan_resources(trg_path)
86         self.resources.relative_to(trg_path, self.DOT_IN_RELATIVE_PATH)
87         # Check the existence of a binary build of the mbed library for the desired target
88         # This prevents exporting the mbed libraries from source
89         # if not self.toolchain.mbed_libs:
90         #    raise OldLibrariesException()
91
92     def gen_file(self, template_file, data, target_file):
93         template_path = join(Exporter.TEMPLATE_DIR, template_file)
94         template = self.jinja_environment.get_template(template_file)
95         target_text = template.render(data)
96
97         target_path = join(self.inputDir, target_file)
98         logging.debug("Generating: %s" % target_path)
99         open(target_path, "w").write(target_text)
100
101     def get_symbols(self, add_extra_symbols=True):
102         """ This function returns symbols which must be exported.
103             Please add / overwrite symbols in each exporter separately
104         """
105         symbols = self.toolchain.get_symbols()
106         # We have extra symbols from e.g. libraries, we want to have them also added to export
107         if add_extra_symbols:
108             if self.extra_symbols is not None:
109                 symbols.extend(self.extra_symbols)
110         return symbols
111
112 def zip_working_directory_and_clean_up(tempdirectory=None, destination=None, program_name=None, clean=True):
113     uid = str(uuid.uuid4())
114     zipfilename = '%s.zip'%uid
115
116     logging.debug("Zipping up %s to %s" % (tempdirectory,  join(destination, zipfilename)))
117     # make zip
118     def zipdir(basedir, archivename):
119         assert isdir(basedir)
120         fakeroot = program_name + '/'
121         with closing(ZipFile(archivename, "w", ZIP_DEFLATED)) as z:
122             for root, _, files in os.walk(basedir):
123                 # NOTE: ignore empty directories
124                 for fn in files:
125                     absfn = join(root, fn)
126                     zfn = fakeroot + '/' +  absfn[len(basedir)+len(os.sep):]
127                     z.write(absfn, zfn)
128
129     zipdir(tempdirectory, join(destination, zipfilename))
130
131     if clean:
132         shutil.rmtree(tempdirectory)
133
134     return join(destination, zipfilename)