-
Notifications
You must be signed in to change notification settings - Fork 28
/
Copy pathbuild.py
140 lines (124 loc) · 5.31 KB
/
build.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
#
# Copyright (c) 2020-2021 Arm Limited and Contributors. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
#
"""Command to build/compile an Mbed project using CMake."""
import os
import pathlib
import shutil
from typing import Optional, Tuple
import click
from mbed_tools.build import build_project, generate_build_system, generate_config, flash_binary
from mbed_tools.devices import find_connected_device, find_all_connected_devices
from mbed_tools.project import MbedProgram
from mbed_tools.sterm import terminal
@click.command(name="compile", help="Build an Mbed project.")
@click.option(
"-t",
"--toolchain",
type=click.Choice(["ARM", "GCC_ARM"], case_sensitive=False),
required=True,
help="The toolchain you are using to build your app.",
)
@click.option("-m", "--mbed-target", required=True, help="A build target for an Mbed-enabled device, e.g. K64F.")
@click.option("-b", "--profile", default="develop", help="The build type (release, develop or debug).")
@click.option("-c", "--clean", is_flag=True, default=False, help="Perform a clean build.")
@click.option(
"-p",
"--program-path",
default=os.getcwd(),
help="Path to local Mbed program. By default it is the current working directory.",
)
@click.option(
"--mbed-os-path", type=click.Path(), default=None, help="Path to local Mbed OS directory.",
)
@click.option(
"--custom-targets-json", type=click.Path(), default=None, help="Path to custom_targets.json.",
)
@click.option(
"--app-config", type=click.Path(), default=None, help="Path to application configuration file.",
)
@click.option(
"-f", "--flash", is_flag=True, default=False, help="Flash the binary onto a device",
)
@click.option(
"-s", "--sterm", is_flag=True, default=False, help="Launch a serial terminal to the device.",
)
@click.option(
"--baudrate",
default=9600,
show_default=True,
help="Change the serial baud rate (ignored unless --sterm is also given).",
)
def build(
program_path: str,
profile: str,
toolchain: str,
mbed_target: str,
clean: bool,
flash: bool,
sterm: bool,
baudrate: int,
mbed_os_path: str,
custom_targets_json: str,
app_config: str,
) -> None:
"""Configure and build an Mbed project using CMake and Ninja.
If the CMake configuration step has already been run previously (i.e a CMake build tree exists), then just try to
build the project immediately using Ninja.
Args:
program_path: Path to the Mbed project.
mbed_os_path: The path to the local Mbed OS directory.
profile: The Mbed build profile (debug, develop or release).
custom_targets_json: Path to custom_targets.json.
toolchain: The toolchain to use for the build.
mbed_target: The name of the Mbed target to build for.
app_config: the path to the application configuration file
clean: Perform a clean build.
flash: Flash the binary onto a device.
sterm: Open a serial terminal to the connected target.
baudrate: Change the serial baud rate (ignored unless --sterm is also given).
"""
mbed_target, target_id = _get_target_id(mbed_target)
cmake_build_subdir = pathlib.Path(mbed_target.upper(), profile.lower(), toolchain.upper())
if mbed_os_path is None:
program = MbedProgram.from_existing(pathlib.Path(program_path), cmake_build_subdir)
else:
program = MbedProgram.from_existing(pathlib.Path(program_path), cmake_build_subdir, pathlib.Path(mbed_os_path))
build_tree = program.files.cmake_build_dir
if clean and build_tree.exists():
shutil.rmtree(build_tree)
click.echo("Configuring project and generating build system...")
if custom_targets_json is not None:
program.files.custom_targets_json = pathlib.Path(custom_targets_json)
if app_config is not None:
program.files.app_config_file = pathlib.Path(app_config)
config, _ = generate_config(mbed_target.upper(), toolchain, program)
generate_build_system(program.root, build_tree, profile)
click.echo("Building Mbed project...")
build_project(build_tree)
if flash or sterm:
if target_id is not None or sterm:
devices = [find_connected_device(mbed_target, target_id)]
else:
devices = find_all_connected_devices(mbed_target)
if flash:
for dev in devices:
hex_file = "OUTPUT_EXT" in config and config["OUTPUT_EXT"] == "hex"
flashed_path = flash_binary(dev.mount_points[0].resolve(), program.root, build_tree, mbed_target, hex_file)
click.echo(f"Copied {str(flashed_path.resolve())} to {len(devices)} device(s).")
if sterm:
dev = devices[0]
if dev.serial_port is None:
raise click.ClickException(
f"The connected device {dev.mbed_board.board_name} does not have an associated serial port."
" Reconnect the device and try again."
)
terminal.run(dev.serial_port, baudrate)
def _get_target_id(target: str) -> Tuple[str, Optional[int]]:
if "[" in target:
target_name, target_id = target.replace("]", "").split("[", maxsplit=1)
if target_id.isdigit() and int(target_id) >= 0:
return (target_name, int(target_id))
raise click.ClickException("When using the format mbed-target[ID], ID must be a positive integer or 0.")
return (target, None)