def test_arm_version_check(_run_cmd): set_targets_json_location() _run_cmd.return_value = (""" Product: ARM Compiler 5.06 Component: ARM Compiler 5.06 update 5 (build 528) Tool: armcc [4d3621] """, "", 0) notifier = MockNotifier() toolchain = TOOLCHAIN_CLASSES["ARM"](TARGET_MAP["K64F"], notify=notifier) toolchain.version_check() assert notifier.messages == [] _run_cmd.return_value = (""" Product: MDK Professional 5.22 Component: ARM Compiler 5.06 update 5 (build 528) Tool: armcc [4d3621] """, "", 0) toolchain.version_check() assert notifier.messages == [] _run_cmd.return_value = (""" Product: ARM Compiler Component: ARM Compiler Tool: armcc [4d3621] """, "", 0) toolchain.version_check() assert len(notifier.messages) == 1
def test_config(name): """Run a particular configuration test :param name: test name (same as directory name) """ test_dir = join(root_dir, name) test_data = json.load(open(data_path(test_dir))) targets_json = os.path.join(test_dir, "targets.json") set_targets_json_location(targets_json if isfile(targets_json) else None) for target, expected in test_data.items(): try: cfg, macros, features = get_config(test_dir, target, "GCC_ARM") res = compare_config(cfg, expected) assert not(res), res expected_macros = expected.get("expected_macros", None) expected_features = expected.get("expected_features", None) if expected_macros is not None: macros = Config.config_macros_to_macros(macros) assert sorted(expected_macros) == sorted(macros) if expected_features is not None: assert sorted(expected_features) == sorted(features) except ConfigException as e: err_msg = str(e) if "exception_msg" not in expected: assert not(err_msg), "Unexpected Error: %s" % e else: assert expected["exception_msg"] in err_msg
def test_gcc_version_check(_run_cmd): set_targets_json_location() _run_cmd.return_value = (""" arm-none-eabi-gcc (Arch Repository) 6.4.4 Copyright (C) 2018 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. """, "", 0) notifier = MockNotifier() toolchain = TOOLCHAIN_CLASSES["GCC_ARM"]( TARGET_MAP["K64F"], notify=notifier) toolchain.version_check() assert notifier.messages == [] _run_cmd.return_value = (""" arm-none-eabi-gcc (Arch Repository) 8.1.0 Copyright (C) 2018 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. """, "", 0) toolchain.version_check() assert len(notifier.messages) == 1 _run_cmd.return_value = (""" arm-none-eabi-gcc (Arch Repository) Copyright (C) 2018 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. """, "", 0) toolchain.version_check() assert len(notifier.messages) == 2
def test_find_tests_app_config(build_path, target, toolchain_name, app_config): """ Test find_tests for correct use of app_config :param base_dir: dummy value for the test base directory :param target: the target to "test" for :param toolchain_name: the toolchain to use for "testing" :param app_config: Application configuration parameter to find tests """ tests = {'test1': 'test1_path', 'test2': 'test2_path'} src_paths = ['.'] set_targets_json_location() with patch('tools.test_api.scan_resources') as mock_scan_resources,\ patch('tools.test_api.build_project') as mock_build_project: mock_build_project.return_value = "build_project" mock_scan_resources().inc_dirs.return_value = [] build_tests(tests, src_paths, build_path, target, toolchain_name, app_config=app_config) arg_list = mock_build_project.call_args_list for args in arg_list: assert 'app_config' in args[1],\ "build_tests was not called with app_config" assert args[1]['app_config'] == app_config,\ "build_tests was called with an incorrect app_config"
def test_armc5_version_check(_run_cmd): set_targets_json_location() _run_cmd.return_value = (""" Product: ARM Compiler 5.06 Component: ARM Compiler 5.06 update 5 (build 528) Tool: armcc [4d3621] """, "", 0) notifier = MockNotifier() target_map = TARGET_MAP["K64F"] #We have to add ARMC5 here to supported_toolchains, otherwise the creation of ARM class would fail as it wont find ARMC5 entry in supported_toolchains target_map.supported_toolchains.append("ARMC5") toolchain = TOOLCHAIN_CLASSES["ARM"](target_map, notify=notifier) toolchain.version_check() assert notifier.messages == [] _run_cmd.return_value = (""" Product: MDK Professional 5.22 Component: ARM Compiler 5.06 update 5 (build 528) Tool: armcc [4d3621] """, "", 0) toolchain.version_check() assert notifier.messages == [] _run_cmd.return_value = (""" Product: ARM Compiler Component: ARM Compiler Tool: armcc [4d3621] """, "", 0) toolchain.version_check() assert len(notifier.messages) == 1
def test_config(name): """Run a particular configuration test :param name: test name (same as directory name) """ test_dir = join(root_dir, name) test_data = json.load(open(data_path(test_dir))) targets_json = os.path.join(test_dir, "targets.json") set_targets_json_location(targets_json if isfile(targets_json) else None) for target, expected in test_data.items(): try: cfg, macros, features = get_config(test_dir, target, "GCC_ARM") res = compare_config(cfg, expected) assert not (res), res expected_macros = expected.get("expected_macros", None) expected_features = expected.get("expected_features", None) if expected_macros is not None: macros = Config.config_macros_to_macros(macros) assert sorted(expected_macros) == sorted(macros) if expected_features is not None: assert sorted(expected_features) == sorted(features) except ConfigException as e: err_msg = str(e) if "exception_msg" not in expected: assert not (err_msg), "Unexpected Error: %s" % e else: assert expected["exception_msg"] in err_msg
def test_PSA_overrides(target_start_size): target, start, size = target_start_size set_targets_json_location() config = Config(target) roms = config.get_all_active_memories(ROM_ALL_MEMORIES) assert("ROM" in roms) assert(roms["ROM"] == [start, size])
def test_toolchain_profile_c(profile, source_file): """Test that the appropriate profile parameters are passed to the C compiler""" filename = deepcopy(source_file) filename[-1] += ".c" to_compile = os.path.join(*filename) set_targets_json_location() with patch('os.mkdir') as _mkdir: for _, tc_class in TOOLCHAIN_CLASSES.items(): toolchain = tc_class(test_target_map, build_profile=profile, notify=MockNotifier()) toolchain.inc_md5 = "" toolchain.build_dir = "" toolchain.config = MagicMock(app_config_location=None) for parameter in profile['c'] + profile['common']: assert any(parameter in cmd for cmd in toolchain.cc), \ "Toolchain %s did not propagate arg %s" % (toolchain.name, parameter) compile_command = toolchain.compile_command( to_compile, to_compile + ".o", []) for parameter in profile['c'] + profile['common']: assert any(parameter in cmd for cmd in compile_command), \ "Toolchain %s did not propagate arg %s" % (toolchain.name, parameter)
def test_armc6_version_check(_run_cmd): set_targets_json_location() notifier = MockNotifier() print(TARGET_MAP["K64F"]) toolchain = TOOLCHAIN_CLASSES["ARMC6"](TARGET_MAP["K64F"], notify=notifier) print(toolchain) _run_cmd.return_value = (""" Product: ARM Compiler 6.11 Professional Component: ARM Compiler 6.11 Tool: armclang [5d3b4200] """, "", 0) toolchain.version_check() assert notifier.messages == []
def test_init_no_app_config(target): """ Test that the initialisation works without app config :param target: The target to use """ set_targets_json_location() with patch.object(Config, '_process_config_and_overrides'),\ patch('tools.config.json_file_to_dict') as mock_json_file_to_dict: config = Config(target) mock_json_file_to_dict.assert_not_called() assert config.app_config_data == {}
def test_basic_regions(target, overrides): """ Test that the region lists are sane with various configurations """ set_targets_json_location() config = Config(target) for o, v in overrides.items(): setattr(config.target, o, v) try: if config.has_regions: regions = list(config.regions) for r in regions: assert r.size >= 0 except ConfigException: pass
def test_config(name): """Run a particular configuration test :param name: test name (same as directory name) """ test_dir = join(root_dir, name) test_data = json.load(open(data_path(test_dir))) targets_json = os.path.join(test_dir, "targets.json") set_targets_json_location(targets_json if isfile(targets_json) else None) for target, expected in test_data.items(): try: cfg, macros, features, resources = get_config( test_dir, target, "GCC_ARM") res = compare_config(cfg, expected) assert not (res), res expected_macros = expected.get("expected_macros", None) expected_features = expected.get("expected_features", None) if expected_macros is not None: macros = Config.config_macros_to_macros(macros) assert sorted(expected_macros) == sorted(macros) if expected_features is not None: assert sorted(expected_features) == sorted(features) included_source = [ normpath(join(test_dir, src)) for src in expected.get("included_source", []) ] excluded_source = [ normpath(join(test_dir, src)) for src in expected.get("excluded_source", []) ] for typ in Resources.ALL_FILE_TYPES: for _, path in resources.get_file_refs(typ): path = normpath(path) if included_source and path in included_source: included_source.remove(path) if excluded_source: assert (path not in excluded_source) assert (not included_source) if included_source: assert (False) except ConfigException as e: err_msg = str(e) if "exception_msg" not in expected: assert not (err_msg), "Unexpected Error: %s" % e else: assert expected["exception_msg"] in err_msg
def test_init_app_config(target): """ Test that the initialisation correctly uses app_config :param target: The target to use """ set_targets_json_location() with patch.object(Config, '_process_config_and_overrides'),\ patch('tools.config.json_file_to_dict') as mock_json_file_to_dict: app_config = "app_config" mock_return = {'config': {'test': False}} mock_json_file_to_dict.return_value = mock_return config = Config(target, app_config=app_config) mock_json_file_to_dict.assert_called_with(app_config) assert config.app_config_data == mock_return
def test_init_app_config(target): """ Test that the initialisation correctly uses app_config :param target: The target to use """ set_targets_json_location() with patch.object(Config, '_process_config_and_overrides'),\ patch('tools.config.json_file_to_dict') as mock_json_file_to_dict: app_config = "app_config" mock_return = {'config': {'test': False}} mock_json_file_to_dict.return_value = mock_return config = Config(target, app_config=app_config) mock_json_file_to_dict.assert_any_call("app_config") assert config.app_config_data == mock_return
def test_init_override_app_config(target): """ Test that the initialisation uses app_config instead of top_level_dir when both are specified :param target: The target to use """ set_targets_json_location() with patch.object(Config, '_process_config_and_overrides'),\ patch('tools.config.json_file_to_dict') as mock_json_file_to_dict: app_config = "app_config" directory = '.' mock_return = {'config': {'test': False}} mock_json_file_to_dict.return_value = mock_return config = Config(target, [directory], app_config=app_config) mock_json_file_to_dict.assert_any_call(app_config) assert config.app_config_data == mock_return
def test_iar_version_check(_run_cmd): set_targets_json_location() _run_cmd.return_value = (""" IAR ANSI C/C++ Compiler V7.80.1.28/LNX for ARM """, "", 0) notifier = MockNotifier() toolchain = TOOLCHAIN_CLASSES["IAR"](TARGET_MAP["K64F"], notify=notifier) toolchain.version_check() assert notifier.messages == [] _run_cmd.return_value = (""" IAR ANSI C/C++ Compiler V/LNX for ARM """, "", 0) toolchain.version_check() assert len(notifier.messages) == 1 _run_cmd.return_value = (""" IAR ANSI C/C++ Compiler V/8.80LNX for ARM """, "", 0) toolchain.version_check() assert len(notifier.messages) == 2
def test_find_tests_app_config(base_dir, target, toolchain_name, app_config): """ Test find_tests for correct use of app_config :param base_dir: dummy value for the test base directory :param target: the target to "test" for :param toolchain_name: the toolchain to use for "testing" :param app_config: Application configuration parameter to find tests """ set_targets_json_location() with patch('tools.test_api.scan_resources') as mock_scan_resources,\ patch('tools.test_api.prepare_toolchain') as mock_prepare_toolchain: mock_scan_resources().inc_dirs.return_value = [] find_tests(base_dir, target, toolchain_name, app_config=app_config) args = mock_prepare_toolchain.call_args assert 'app_config' in args[1],\ "prepare_toolchain was not called with app_config" assert args[1]['app_config'] == app_config,\ "prepare_toolchain was called with an incorrect app_config"
def test_init_no_app_config_with_dir(target): """ Test that the initialisation works without app config and with a specified top level directory :param target: The target to use """ set_targets_json_location() with patch.object(Config, '_process_config_and_overrides'),\ patch('os.path.isfile') as mock_isfile, \ patch('tools.config.json_file_to_dict') as mock_json_file_to_dict: directory = '.' path = os.path.join('.', 'mbed_app.json') mock_return = {'config': {'test': False}} mock_json_file_to_dict.return_value = mock_return mock_isfile.return_value = True config = Config(target, [directory]) mock_isfile.assert_called_with(path) mock_json_file_to_dict.assert_any_call(path) assert config.app_config_data == mock_return
def test_armc6_version_check(_run_cmd): set_targets_json_location() notifier = MockNotifier() toolchain = TOOLCHAIN_CLASSES["ARMC6"](TARGET_MAP["K64F"], notify=notifier) _run_cmd.return_value = (""" Product: ARM Compiler 6.11 Professional Component: ARM Compiler 6.11 Tool: armclang [5d3b4200] """, "", 0) toolchain.version_check() assert notifier.messages == [] assert not toolchain.is_mbed_studio_armc6 _run_cmd.return_value = (""" armclang: error: Failed to check out a license. The provided license does not enable these tools. Information about this error is available at: http://ds.arm.com/support/lic56/m5 General licensing information is available at: http://ds.arm.com/support/licensing/ If you need further help, provide this complete error report to your supplier or [email protected]. - ARMLMD_LICENSE_FILE: unset - LM_LICENSE_FILE: unset - ARM_TOOL_VARIANT: unset - ARM_PRODUCT_PATH: unset - Product location: C:\MbedStudio\tools\ac6\sw\mappings - Toolchain location: C:\MbedStudio\tools\ac6\bin - Selected tool variant: product - Checkout feature: mbed_armcompiler - Feature version: 5.0201810 - Flex error code: -5 Product: ARM Compiler 6.11 for Mbed Studio Component: ARM Compiler 6.11 Tool: armclang [5d3b3c00] """, "", 0) toolchain.version_check() assert notifier.messages == [] assert toolchain.is_mbed_studio_armc6
def test_gcc_version_check(_run_cmd): set_targets_json_location() _run_cmd.return_value = (""" arm-none-eabi-gcc (Arch Repository) 6.4.4 Copyright (C) 2018 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. """, "", 0) notifier = MockNotifier() toolchain = TOOLCHAIN_CLASSES["GCC_ARM"](TARGET_MAP["K64F"], notify=notifier) toolchain.version_check() assert len(notifier.messages) == 1 _run_cmd.return_value = (""" arm-none-eabi-gcc (GNU Tools for Arm Embedded Processors 9-2019-q4-major) 9.2.1 20191025 (release) [ARM/arm-9-branch revision 277599] Copyright (C) 2019 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. """, "", 0) toolchain.version_check() assert len(notifier.messages) == 1 _run_cmd.return_value = (""" arm-none-eabi-gcc (GNU Tools for Arm Embedded Processors 10-2020-q4-major) 10.2.1 20201025 (release) [ARM/arm-10-branch revision 377599] Copyright (C) 2020 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. """, "", 0) toolchain.version_check() assert len(notifier.messages) == 2 _run_cmd.return_value = (""" arm-none-eabi-gcc (Arch Repository) Copyright (C) 2018 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. """, "", 0) toolchain.version_check() assert len(notifier.messages) == 3
def export(target, ide, build=None, src=None, macros=None, project_id=None, zip_proj=False, build_profile=None, export_path=None, notify=None, app_config=None, ignore=None): """Do an export of a project. Positional arguments: target - MCU that the project will compile for ide - the IDE or project structure to export to Keyword arguments: build - to use the compiled mbed libraries or not src - directory or directories that contain the source to export macros - extra macros to add to the project project_id - the name of the project clean - start from a clean state before exporting zip_proj - create a zip file or not ignore - list of paths to add to mbedignore Returns an object of type Exporter (tools/exports/exporters.py) """ ################################### # mbed Classic/2.0/libary support # # Find build system profile profile = None targets_json = None for path in src: 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: notify.info("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 notify.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 # ################################### project_dir, name, src, lib = setup_project( ide, target, bool(zip_proj), program=project_id, source_dir=src, build=build, export_path=export_path, ) zip_name = name + ".zip" if zip_proj else None return export_project(src, project_dir, target, ide, name=name, macros=macros, libraries_paths=lib, zip_proj=zip_name, build_profile=build_profile, notify=TerminalNotifier(), app_config=app_config, ignore=ignore)
def test_tree(full_name, name): failed = 0 sys.path.append(full_name) if "test_data" in sys.modules: del sys.modules["test_data"] import test_data for target, expected in test_data.expected_results.items(): sys.stdout.write("%s:'%s'(%s) " % (name, expected["desc"], target)) sys.stdout.flush() err_msg = None try: # Use 'set_targets_json_location' to remove the previous custom targets from the target list set_targets_json_location(Target._Target__targets_json_location) cfg, macros, features = get_config(full_name, target, "GCC_ARM") macros = Config.config_macros_to_macros(macros) except ConfigException as e: err_msg = e.message if err_msg: if expected.has_key("exception_msg"): if err_msg.find(expected["exception_msg"]) == -1: print "FAILED!" sys.stderr.write(" Unexpected error message!\n") sys.stderr.write(" Expected: '%s'\n" % expected["exception_msg"]) sys.stderr.write(" Got: '%s'\n" % err_msg) failed += 1 else: print "OK" else: print "FAILED!" sys.stderr.write(" Error while getting configuration!\n") sys.stderr.write(" " + err_msg + "\n") failed += 1 else: res = compare_config(cfg, expected) expected_macros = expected.get("expected_macros", None) expected_features = expected.get("expected_features", None) if res: print "FAILED!" sys.stdout.write(" " + res + "\n") failed += 1 elif expected_macros is not None: if sorted(expected_macros) != sorted(macros): print "FAILED!" sys.stderr.write(" List of macros doesn't match\n") sys.stderr.write(" Expected: '%s'\n" % ",".join(sorted(expected_macros))) sys.stderr.write(" Got: '%s'\n" % ",".join(sorted(expected_macros))) failed += 1 else: print "OK" elif expected_features is not None: if sorted(expected_features) != sorted(features): print "FAILED!" sys.stderr.write(" List of features doesn't match\n") sys.stderr.write(" Expected: '%s'\n" % ",".join(sorted(expected_features))) sys.stderr.write(" Got: '%s'\n" % ",".join(sorted(expected_features))) failed += 1 else: print "OK" else: print "OK" sys.path.remove(full_name) return failed
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
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