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.
Diff: export/__init__.py
- Revision:
- 36:96847d42f010
- Parent:
- 35:da9c89f8be7d
- Child:
- 40:7d3fa6b99b2b
diff -r da9c89f8be7d -r 96847d42f010 export/__init__.py
--- a/export/__init__.py Wed Feb 15 13:53:18 2017 -0600
+++ b/export/__init__.py Thu Jun 22 11:12:28 2017 -0500
@@ -15,15 +15,32 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-from tools.export import codered, ds5_5, iar, makefile
+import sys
+from os.path import join, abspath, dirname, exists
+from os.path import basename, relpath, normpath, splitext
+from os import makedirs, walk
+import copy
+from shutil import rmtree, copyfile
+import zipfile
+ROOT = abspath(join(dirname(__file__), ".."))
+sys.path.insert(0, ROOT)
+
+from tools.build_api import prepare_toolchain
+from tools.build_api import scan_resources
+from tools.toolchains import Resources, mbedToolchain
+from tools.export import lpcxpresso, ds5_5, iar, makefile
from tools.export import embitz, coide, kds, simplicity, atmelstudio
-from tools.export import sw4stm32, e2studio, zip, cmsis, uvision, cdt
-from tools.targets import TARGET_NAMES
+from tools.export import sw4stm32, e2studio, zip, cmsis, uvision, cdt, vscode
+from tools.export import gnuarmeclipse
+from tools.export import qtcreator
+from tools.targets import TARGET_NAMES, set_targets_json_location
+from tools.build_profiles import find_build_profile, find_targets_json
+from tools.build_profiles import get_toolchain_profile
EXPORTERS = {
'uvision5': uvision.Uvision,
'uvision': uvision.Uvision,
- 'lpcxpresso': codered.CodeRed,
+ 'lpcxpresso': lpcxpresso.LPCXpresso,
'gcc_arm': makefile.GccArm,
'make_gcc_arm': makefile.GccArm,
'make_armc5': makefile.Armc5,
@@ -40,8 +57,13 @@
'eclipse_gcc_arm' : cdt.EclipseGcc,
'eclipse_iar' : cdt.EclipseIAR,
'eclipse_armc5' : cdt.EclipseArmc5,
+ 'gnuarmeclipse': gnuarmeclipse.GNUARMEclipse,
+ 'qtcreator': qtcreator.QtCreator,
'zip' : zip.ZIP,
- 'cmsis' : cmsis.CMSIS
+ 'cmsis' : cmsis.CMSIS,
+ 'vscode_gcc_arm' : vscode.VSCodeGcc,
+ 'vscode_iar' : vscode.VSCodeIAR,
+ 'vscode_armc5' : vscode.VSCodeArmc5
}
ERROR_MESSAGE_UNSUPPORTED_TOOLCHAIN = """
@@ -53,6 +75,14 @@
To export this project please <a href='http://mbed.org/compiler/?import=http://mbed.org/users/mbed_official/code/mbed-export/k&mode=lib' target='_blank'>import the export version of the mbed library</a>.
"""
+def mcu_ide_list():
+ """Shows list of exportable ides
+
+ """
+ supported_ides = sorted(EXPORTERS.keys())
+ return "\n".join(supported_ides)
+
+
def mcu_ide_matrix(verbose_html=False):
"""Shows target map using prettytable
@@ -103,3 +133,267 @@
if verbose_html:
result = result.replace("&", "&")
return result
+
+
+def get_exporter_toolchain(ide):
+ """ Return the exporter class and the toolchain string as a tuple
+
+ Positional arguments:
+ ide - the ide name of an exporter
+ """
+ return EXPORTERS[ide], EXPORTERS[ide].TOOLCHAIN
+
+
+def rewrite_basepath(file_name, resources, export_path, loc):
+ """ Replace the basepath of filename with export_path
+
+ Positional arguments:
+ file_name - the absolute path to a file
+ resources - the resources object that the file came from
+ export_path - the final destination of the file after export
+ """
+ new_f = join(loc, relpath(file_name, resources.file_basepath[file_name]))
+ resources.file_basepath[new_f] = export_path
+ return new_f
+
+
+def subtract_basepath(resources, export_path, loc=""):
+ """ Rewrite all of the basepaths with the export_path
+
+ Positional arguments:
+ resources - the resource object to rewrite the basepaths of
+ export_path - the final destination of the resources with respect to the
+ generated project files
+ """
+ keys = ['s_sources', 'c_sources', 'cpp_sources', 'hex_files',
+ 'objects', 'libraries', 'inc_dirs', 'headers', 'linker_script',
+ 'lib_dirs']
+ for key in keys:
+ vals = getattr(resources, key)
+ if isinstance(vals, set):
+ vals = list(vals)
+ if isinstance(vals, list):
+ new_vals = []
+ for val in vals:
+ new_vals.append(rewrite_basepath(val, resources, export_path,
+ loc))
+ if isinstance(getattr(resources, key), set):
+ setattr(resources, key, set(new_vals))
+ else:
+ setattr(resources, key, new_vals)
+ elif vals:
+ setattr(resources, key, rewrite_basepath(vals, resources,
+ export_path, loc))
+
+
+def generate_project_files(resources, export_path, target, name, toolchain, ide,
+ macros=None):
+ """Generate the project files for a project
+
+ Positional arguments:
+ resources - a Resources object containing all of the files needed to build
+ this project
+ export_path - location to place project files
+ name - name of the project
+ toolchain - a toolchain class that corresponds to the toolchain used by the
+ IDE or makefile
+ ide - IDE name to export to
+
+ Optional arguments:
+ macros - additional macros that should be defined within the exported
+ project
+ """
+ exporter_cls, _ = get_exporter_toolchain(ide)
+ exporter = exporter_cls(target, export_path, name, toolchain,
+ extra_symbols=macros, resources=resources)
+ exporter.generate()
+ files = exporter.generated_files
+ return files, exporter
+
+
+def zip_export(file_name, prefix, resources, project_files, inc_repos):
+ """Create a zip file from an exported project.
+
+ Positional Parameters:
+ file_name - the file name of the resulting zip file
+ prefix - a directory name that will prefix the entire zip file's contents
+ resources - a resources object with files that must be included in the zip
+ project_files - a list of extra files to be added to the root of the prefix
+ directory
+ """
+ with zipfile.ZipFile(file_name, "w") as zip_file:
+ for prj_file in project_files:
+ zip_file.write(prj_file, join(prefix, basename(prj_file)))
+ for loc, res in resources.iteritems():
+ to_zip = (
+ res.headers + res.s_sources + res.c_sources +\
+ res.cpp_sources + res.libraries + res.hex_files + \
+ [res.linker_script] + res.bin_files + res.objects + \
+ res.json_files + res.lib_refs + res.lib_builds)
+ if inc_repos:
+ for directory in res.repo_dirs:
+ for root, _, files in walk(directory):
+ for repo_file in files:
+ source = join(root, repo_file)
+ to_zip.append(source)
+ res.file_basepath[source] = res.base_path
+ to_zip += res.repo_files
+ for source in to_zip:
+ if source:
+ zip_file.write(
+ source,
+ join(prefix, loc,
+ relpath(source, res.file_basepath[source])))
+ for source in res.lib_builds:
+ target_dir, _ = splitext(source)
+ dest = join(prefix, loc,
+ relpath(target_dir, res.file_basepath[source]),
+ ".bld", "bldrc")
+ zip_file.write(source, dest)
+
+
+
+def export_project(src_paths, export_path, target, ide, libraries_paths=None,
+ linker_script=None, notify=None, verbose=False, name=None,
+ inc_dirs=None, jobs=1, silent=False, extra_verbose=False,
+ config=None, macros=None, zip_proj=None, inc_repos=False,
+ build_profile=None, app_config=None):
+ """Generates a project file and creates a zip archive if specified
+
+ Positional Arguments:
+ src_paths - a list of paths from which to find source files
+ export_path - a path specifying the location of generated project files
+ target - the mbed board/mcu for which to generate the executable
+ ide - the ide for which to generate the project fields
+
+ Keyword Arguments:
+ libraries_paths - paths to additional libraries
+ linker_script - path to the linker script for the specified target
+ notify - function is passed all events, and expected to handle notification
+ of the user, emit the events to a log, etc.
+ verbose - assigns the notify function to toolchains print_notify_verbose
+ name - project name
+ inc_dirs - additional include directories
+ jobs - number of threads
+ silent - silent build - no output
+ extra_verbose - assigns the notify function to toolchains
+ print_notify_verbose
+ config - toolchain's config object
+ macros - User-defined macros
+ zip_proj - string name of the zip archive you wish to creat (exclude arg
+ if you do not wish to create an archive
+ """
+
+ # Convert src_path to a list if needed
+ if isinstance(src_paths, dict):
+ paths = sum(src_paths.values(), [])
+ elif isinstance(src_paths, list):
+ paths = src_paths[:]
+ else:
+ paths = [src_paths]
+
+ # Extend src_paths wit libraries_paths
+ if libraries_paths is not None:
+ paths.extend(libraries_paths)
+
+ if not isinstance(src_paths, dict):
+ src_paths = {"": paths}
+
+ # Export Directory
+ if not exists(export_path):
+ makedirs(export_path)
+
+ _, toolchain_name = get_exporter_toolchain(ide)
+
+ ###################################
+ # mbed Classic/2.0/libary support #
+
+ # Find build system profile
+ profile = None
+ targets_json = None
+ for path in paths:
+ profile = find_build_profile(path) or profile
+ if profile:
+ targets_json = join(dirname(dirname(abspath(__file__))), 'legacy_targets.json')
+ else:
+ targets_json = find_targets_json(path) or targets_json
+
+ # Apply targets.json to active targets
+ if targets_json:
+ if not silent:
+ print("Using targets from %s" % targets_json)
+ set_targets_json_location(targets_json)
+
+ # Apply profile to toolchains
+ if profile:
+ def init_hook(self):
+ profile_data = get_toolchain_profile(self.name, profile)
+ if not profile_data:
+ return
+ if not silent:
+ self.info("Using toolchain %s profile %s" % (self.name, profile))
+
+ for k,v in profile_data.items():
+ if self.flags.has_key(k):
+ self.flags[k] = v
+ else:
+ setattr(self, k, v)
+
+ mbedToolchain.init = init_hook
+
+ # mbed Classic/2.0/libary support #
+ ###################################
+
+ # Pass all params to the unified prepare_resources()
+ toolchain = prepare_toolchain(
+ paths, "", target, toolchain_name, macros=macros, jobs=jobs,
+ notify=notify, silent=silent, verbose=verbose,
+ extra_verbose=extra_verbose, config=config, build_profile=build_profile,
+ app_config=app_config)
+ # The first path will give the name to the library
+ if name is None:
+ name = basename(normpath(abspath(src_paths[0])))
+
+ # Call unified scan_resources
+ resource_dict = {loc: scan_resources(path, toolchain, inc_dirs=inc_dirs)
+ for loc, path in src_paths.iteritems()}
+ resources = Resources()
+ toolchain.build_dir = export_path
+ config_header = toolchain.get_config_header()
+ resources.headers.append(config_header)
+ resources.file_basepath[config_header] = dirname(config_header)
+
+ if zip_proj:
+ subtract_basepath(resources, ".")
+ for loc, res in resource_dict.iteritems():
+ temp = copy.deepcopy(res)
+ subtract_basepath(temp, ".", loc)
+ resources.add(temp)
+ else:
+ for _, res in resource_dict.iteritems():
+ resources.add(res)
+
+ # Change linker script if specified
+ if linker_script is not None:
+ resources.linker_script = linker_script
+
+ files, exporter = generate_project_files(resources, export_path,
+ target, name, toolchain, ide,
+ macros=macros)
+ files.append(config_header)
+ if zip_proj:
+ for resource in resource_dict.values():
+ for label, res in resource.features.iteritems():
+ if label not in toolchain.target.features:
+ resource.add(res)
+ if isinstance(zip_proj, basestring):
+ zip_export(join(export_path, zip_proj), name, resource_dict, files,
+ inc_repos)
+ else:
+ zip_export(zip_proj, name, resource_dict, files, inc_repos)
+ else:
+ for exported in files:
+ if not exists(join(export_path, basename(exported))):
+ copyfile(exported, join(export_path, basename(exported)))
+
+ return exporter
