diff options
author | Anthony DiGirolamo <tonymd@google.com> | 2020-11-04 11:57:27 -0800 |
---|---|---|
committer | CQ Bot Account <pigweed-scoped@luci-project-accounts.iam.gserviceaccount.com> | 2020-11-06 01:16:45 +0000 |
commit | 00e773eafb943b25643d2e32b0d0af2f032426b3 (patch) | |
tree | aa99ed3352866c71c9a5b8774976d8f602dcec9f /pw_arduino_build | |
parent | 27b3700050f6440ad09b5253e857f31771aff2c8 (diff) | |
download | pigweed-00e773eafb943b25643d2e32b0d0af2f032426b3.tar.gz |
pw_arduino_build: Arduino library searching support
- Adds commands to return arduino library source files and include dirs.
- Example GN rule in targets/arduino/target_docs.rst
- Show error if a .elf doesn't exist in the unit_test_runner
Change-Id: Ic317c5c061799a7e02fdad834c685d8cb37ba9ce
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/23460
Reviewed-by: Keir Mierle <keir@google.com>
Reviewed-by: David Rogers <davidrogers@google.com>
Commit-Queue: Anthony DiGirolamo <tonymd@google.com>
Diffstat (limited to 'pw_arduino_build')
-rw-r--r-- | pw_arduino_build/py/pw_arduino_build/__main__.py | 46 | ||||
-rwxr-xr-x | pw_arduino_build/py/pw_arduino_build/builder.py | 22 | ||||
-rwxr-xr-x | pw_arduino_build/py/pw_arduino_build/unit_test_runner.py | 13 |
3 files changed, 62 insertions, 19 deletions
diff --git a/pw_arduino_build/py/pw_arduino_build/__main__.py b/pw_arduino_build/py/pw_arduino_build/__main__.py index 503630a41..4a170723f 100644 --- a/pw_arduino_build/py/pw_arduino_build/__main__.py +++ b/pw_arduino_build/py/pw_arduino_build/__main__.py @@ -77,10 +77,9 @@ def list_menu_options_command(args, builder): def show_command_print_string_list(args, string_list: List[str]): - join_token = " " - if args.delimit_with_newlines: - join_token = "\n" - print(join_token.join(string_list)) + if string_list: + join_token = "\n" if args.delimit_with_newlines else " " + print(join_token.join(string_list)) def show_command_print_flag_string(args, flag_string): @@ -241,12 +240,18 @@ def show_command(args, builder): for tool_name in tools: print(tool_name) + elif args.library_include_dirs: + show_command_print_string_list(args, builder.library_include_dirs()) + elif args.library_includes: show_command_print_string_list(args, builder.library_includes()) elif args.library_c_files: show_command_print_string_list(args, builder.library_c_files()) + elif args.library_s_files: + show_command_print_string_list(args, builder.library_s_files()) + elif args.library_cpp_files: show_command_print_string_list(args, builder.library_cpp_files()) @@ -294,6 +299,9 @@ def add_common_parser_args(parser, serial_port, build_path, build_project_name, "--project-source-path", default=project_source_path, help="Project directory. Default: '{}'".format(project_source_path)) + parser.add_argument("--library-path", + default="libraries", + help="Path to Arduino Library directory.") parser.add_argument( "--build-project-name", default=build_project_name, @@ -341,7 +349,7 @@ def get_default_options(): return defaults -def load_config_file(args, default_options): +def load_config_file(args): """Load a config file and merge with command line options. Command line takes precedence over values loaded from a config file.""" @@ -353,6 +361,8 @@ def load_config_file(args, default_options): if not args.config_file: return + default_options = get_default_options() + commandline_options = { # Global option "arduino_package_path": args.arduino_package_path, @@ -397,11 +407,8 @@ def load_config_file(args, default_options): jfile.write(encoded_json) -def main(): - """Main command line function. - - Parses command line args and dispatches to sub `*_command()` functions. - """ +def _parse_args() -> argparse.Namespace: + """Setup argparse and parse command line args.""" def log_level(arg: str) -> int: try: return getattr(logging, arg.upper()) @@ -481,6 +488,7 @@ def main(): show_parser.add_argument("--delimit-with-newlines", help="Separate flag output with newlines.", action="store_true") + show_parser.add_argument("--library-names", nargs="+", type=str) output_group = show_parser.add_mutually_exclusive_group(required=True) output_group.add_argument("--c-compile", action="store_true") @@ -513,7 +521,9 @@ def main(): output_group.add_argument("--upload-tools", action="store_true") output_group.add_argument("--upload-command") output_group.add_argument("--library-includes", action="store_true") + output_group.add_argument("--library-include-dirs", action="store_true") output_group.add_argument("--library-c-files", action="store_true") + output_group.add_argument("--library-s-files", action="store_true") output_group.add_argument("--library-cpp-files", action="store_true") output_group.add_argument("--core-c-files", action="store_true") output_group.add_argument("--core-s-files", action="store_true") @@ -543,8 +553,16 @@ def main(): run_parser.set_defaults(func=run_command) + return parser.parse_args() + + +def main(): + """Main command line function. + + Dispatches command line invocations to sub `*_command()` functions. + """ # Parse command line arguments. - args = parser.parse_args() + args = _parse_args() _LOG.debug(_pretty_format(args)) log.install(args.loglevel) @@ -557,7 +575,7 @@ def main(): args.compiler_path_override))) args.compiler_path_override = compiler_path_override - load_config_file(args, default_options) + load_config_file(args) if args.subcommand == "install-core": args.func(args) @@ -567,7 +585,7 @@ def main(): args.arduino_package_name) builder.load_board_definitions() args.func(args, builder) - else: + else: # args.subcommand in ["run", "show"] check_for_missing_args(args) builder = ArduinoBuilder( args.arduino_package_path, @@ -576,6 +594,8 @@ def main(): build_project_name=args.build_project_name, project_path=args.project_path, project_source_path=args.project_source_path, + library_path=getattr(args, 'library_path', None), + library_names=getattr(args, 'library_names', None), compiler_path_override=args.compiler_path_override) builder.load_board_definitions() builder.select_board(args.board, args.menu_options) diff --git a/pw_arduino_build/py/pw_arduino_build/builder.py b/pw_arduino_build/py/pw_arduino_build/builder.py index 43b5ac3f7..fce58b6fc 100755 --- a/pw_arduino_build/py/pw_arduino_build/builder.py +++ b/pw_arduino_build/py/pw_arduino_build/builder.py @@ -75,6 +75,8 @@ class ArduinoBuilder: build_path=None, project_path=None, project_source_path=None, + library_path=None, + library_names=None, build_project_name=None, compiler_path_override=False): self.arduino_path = arduino_path @@ -87,6 +89,9 @@ class ArduinoBuilder: self.compiler_path_override = compiler_path_override self.variant_includes = "" self.build_variant_path = False + self.library_names = library_names + self.library_path = os.path.realpath( + os.path.expanduser(os.path.expandvars(library_path))) self.compiler_path_override_binaries = [] if self.compiler_path_override: @@ -958,9 +963,13 @@ class ArduinoBuilder: # - Else lib folder as root include -Ilibraries/libname # (exclude source files in the examples folder in this case) - library_path = os.path.join(self.project_path, "libraries") + library_path = self.library_path + folder_patterns = ["*"] + if self.library_names: + folder_patterns = self.library_names - library_folders = file_operations.find_files(library_path, ["*"], + library_folders = file_operations.find_files(library_path, + folder_patterns, directories_only=True) library_source_root_folders = [] for lib in library_folders: @@ -973,6 +982,9 @@ class ArduinoBuilder: return library_source_root_folders + def library_include_dirs(self): + return [Path(lib).as_posix() for lib in self.library_folders()] + def library_includes(self): include_args = [] library_folders = self.library_folders() @@ -986,13 +998,15 @@ class ArduinoBuilder: for lib_dir in library_folders: for file_path in file_operations.find_files(lib_dir, [pattern]): if not file_path.startswith("examples"): - sources.append( - os.path.relpath(os.path.join(lib_dir, file_path))) + sources.append((Path(lib_dir) / file_path).as_posix()) return sources def library_c_files(self): return self.library_files("**/*.c") + def library_s_files(self): + return self.library_files("**/*.S") + def library_cpp_files(self): return self.library_files("**/*.cpp") diff --git a/pw_arduino_build/py/pw_arduino_build/unit_test_runner.py b/pw_arduino_build/py/pw_arduino_build/unit_test_runner.py index 0ef5d8fb3..4fa601162 100755 --- a/pw_arduino_build/py/pw_arduino_build/unit_test_runner.py +++ b/pw_arduino_build/py/pw_arduino_build/unit_test_runner.py @@ -58,11 +58,20 @@ class ArduinoCoreNotSupported(Exception): """Exception raised when a given core does not support unit testing.""" +def valid_file_name(arg): + file_path = Path(os.path.expandvars(arg)).absolute() + if not file_path.is_file(): + raise argparse.ArgumentTypeError(f"'{arg}' does not exist.") + return file_path + + def parse_args(): """Parses command-line arguments.""" parser = argparse.ArgumentParser(description=__doc__) - parser.add_argument('binary', help='The target test binary to run') + parser.add_argument('binary', + help='The target test binary to run', + type=valid_file_name) parser.add_argument('--port', help='The name of the serial port to connect to when ' 'running tests') @@ -327,7 +336,7 @@ def main(): ] # .elf file location args. - binary = Path(os.path.expandvars(args.binary)).absolute() + binary = args.binary build_path = binary.parent.as_posix() arduino_builder_args += ["--build-path", build_path] build_project_name = binary.name |