Skip to content

Commit 6f5a3c3

Browse files
committed
Add functions to enable ARM fallback to ARMC5.
There are two new functions: get_valid_toolchain_names and find_valid_toolchain. These functions are used to figure out if a fallback is possible and necessary. find_valid_toolchain is expected to be used by the front-end scripts. get_toolchain_name was updated with some different logic and comments.
1 parent 08d9e32 commit 6f5a3c3

File tree

2 files changed

+120
-10
lines changed

2 files changed

+120
-10
lines changed

tools/build_api.py

Lines changed: 114 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
from .arm_pack_manager import Cache
3535
from .utils import (mkdir, run_cmd, run_cmd_ext, NotSupportedException,
3636
ToolException, InvalidReleaseTargetException,
37-
copy_when_different)
37+
copy_when_different, NoValidToolchainException)
3838
from .paths import (MBED_CMSIS_PATH, MBED_TARGETS_PATH, MBED_LIBRARIES,
3939
MBED_HEADER, MBED_DRIVERS, MBED_PLATFORM, MBED_HAL,
4040
MBED_CONFIG_FILE, MBED_LIBRARIES_DRIVERS,
@@ -44,7 +44,8 @@
4444
from .notifier.mock import MockNotifier
4545
from .targets import TARGET_NAMES, TARGET_MAP, CORE_ARCH, Target
4646
from .libraries import Library
47-
from .toolchains import TOOLCHAIN_CLASSES
47+
from .toolchains import TOOLCHAIN_CLASSES, TOOLCHAIN_PATHS
48+
from .toolchains.arm import ARMC5_MIGRATION_WARNING
4849
from .config import Config
4950

5051
RELEASE_VERSIONS = ['2', '5']
@@ -120,18 +121,76 @@ def add_result_to_report(report, result):
120121
result_wrap = {0: result}
121122
report[target][toolchain][id_name].append(result_wrap)
122123

124+
def get_valid_toolchain_names(target, toolchain_name):
125+
"""Return the list of toolchains with which a build should be attempted. This
126+
list usually contains one element, however there may be multiple entries if
127+
a toolchain is expected to fallback to different versions depending on the
128+
environment configuration. If an invalid supported_toolchain configuration
129+
is detected, an Exception will be raised.
130+
131+
Positional arguments:
132+
target - Target object (not the string name) of the device we are building for
133+
toolchain_name - the string that identifies the build toolchain as supplied by
134+
the front-end scripts
135+
"""
136+
if int(target.build_tools_metadata["version"]) > 0:
137+
all_arm_toolchain_names = ["ARMC6", "ARMC5", "ARM"]
138+
arm_st = set(target.supported_toolchains).intersection(
139+
set(all_arm_toolchain_names)
140+
)
141+
if len(arm_st) > 1:
142+
raise Exception(
143+
"Targets may only specify one of the following in "
144+
"supported_toolchains: {}\n"
145+
"The following toolchains were present: {}".format(
146+
", ".join(all_arm_toolchain_names),
147+
", ".join(arm_st),
148+
)
149+
)
150+
if toolchain_name == "ARM":
151+
# The order matters here
152+
all_arm_toolchain_names = ["ARMC6", "ARMC5"]
153+
if "ARM" in target.supported_toolchains:
154+
return all_arm_toolchain_names
155+
156+
result_list = []
157+
for tc_name in all_arm_toolchain_names:
158+
if tc_name in target.supported_toolchains:
159+
result_list.append(tc_name)
160+
return result_list
161+
162+
return [toolchain_name]
163+
123164
def get_toolchain_name(target, toolchain_name):
165+
"""Get the internal toolchain name given the toolchain_name provided by
166+
the front-end scripts (usually by the -t/--toolchain argument) and the target
167+
168+
Positional arguments:
169+
target - Target object (not the string name) of the device we are building for
170+
toolchain_name - the string that identifies the build toolchain as supplied by
171+
the front-end scripts
172+
173+
Overview of what the current return values should be for the "ARM" family of
174+
toolchains (since the behavior is fairly complex). Top row header represents
175+
the argument "toolchain_name", Left column header represents the attribute
176+
"supported_toolchains" of the "target" argument.
177+
178+
| supported_toolchains/toolchain_name |+| ARMC5 | ARMC6 | ARM |
179+
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
180+
| ARMC5 |+| ARM* | ARMC6 | ARM |
181+
| ARMC6 |+| ARM* | ARMC6 | ARMC6* |
182+
| ARM |+| ARM* | ARMC6 | ARMC6* |
183+
184+
* Denotes that the input "toolchain_name" changes in the return value
185+
"""
124186
if int(target.build_tools_metadata["version"]) > 0:
125-
if toolchain_name == "ARM" or toolchain_name == "ARMC6" :
126-
if("ARM" in target.supported_toolchains or "ARMC6" in target.supported_toolchains):
187+
if toolchain_name == "ARMC5":
188+
return "ARM"
189+
elif toolchain_name == "ARM":
190+
if set(target.supported_toolchains).intersection(set(["ARMC6", "ARM"])):
127191
return "ARMC6"
128-
elif ("ARMC5" in target.supported_toolchains):
129-
if toolchain_name == "ARM":
130-
return "ARM" #note that returning ARM here means, use ARMC5 toolchain
131-
else:
132-
return "ARMC6" #ARMC6 explicitly specified by user, try ARMC6 anyway although the target doesnt explicitly specify ARMC6, as ARMC6 is our default ARM toolchain
133192
elif toolchain_name == "uARM":
134-
if ("ARMC5" in target.supported_toolchains):
193+
if "ARMC5" in target.supported_toolchains:
135194
return "uARM" #use ARM_MICRO to use AC5+microlib
136195
else:
137196
return "ARMC6" #use AC6+microlib
@@ -144,6 +203,51 @@ def get_toolchain_name(target, toolchain_name):
144203

145204
return toolchain_name
146205

206+
def find_valid_toolchain(target, toolchain):
207+
"""Given a target and toolchain, get the names for the appropriate
208+
toolchain to use. The environment is also checked to see if the corresponding
209+
compiler is configured correctl. For the ARM compilers, there is an automatic
210+
fallback behavior if "ARM" is the specified toolchain, if the latest compiler
211+
(ARMC6) is not available, and the target supports building with both ARMC5
212+
and ARMC6. In the case where the environment configuration triggers the fallback
213+
to ARMC5, add a warning to the list that is returned in the results.
214+
215+
Returns:
216+
toolchain_name - The name of the toolchain. When "ARM" is supplied as the
217+
"toolchain", this be changed to either "ARMC5" or "ARMC6".
218+
internal_tc_name - This corresponds to that name of the class that will be
219+
used to actually complete the build. This is mostly used for accessing build
220+
profiles and just general legacy sections within the code.
221+
end_warnings - This is a list of warnings (strings) that were raised during
222+
the process of finding toolchain. This is used to warn the user of the ARM
223+
fallback mechanism mentioned above.
224+
225+
Positional arguments:
226+
target - Target object (not the string name) of the device we are building for
227+
toolchain_name - the string that identifies the build toolchain as supplied by
228+
the front-end scripts
229+
"""
230+
end_warnings = []
231+
toolchain_names = get_valid_toolchain_names(target, toolchain)
232+
last_error = None
233+
for index, toolchain_name in enumerate(toolchain_names):
234+
internal_tc_name = get_toolchain_name(target, toolchain_name)
235+
if toolchain == "ARM" and toolchain_name == "ARMC5" and index != 0:
236+
end_warnings.append(ARMC5_MIGRATION_WARNING)
237+
if not TOOLCHAIN_CLASSES[internal_tc_name].check_executable():
238+
search_path = TOOLCHAIN_PATHS[internal_tc_name] or "No path set"
239+
last_error = (
240+
"Could not find executable for {}.\n"
241+
"Currently set search path: {}"
242+
).format(toolchain_name, search_path)
243+
else:
244+
return toolchain_name, internal_tc_name, end_warnings
245+
else:
246+
if last_error:
247+
e = NoValidToolchainException(last_error)
248+
e.end_warnings = end_warnings
249+
raise e
250+
147251
def get_config(src_paths, target, toolchain_name=None, app_config=None):
148252
"""Get the configuration object for a target-toolchain combination
149253

tools/toolchains/arm.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,12 @@
3030
from tools.toolchains.mbed_toolchain import mbedToolchain, TOOLCHAIN_PATHS
3131
from tools.utils import mkdir, NotSupportedException, ToolException, run_cmd
3232

33+
ARMC5_MIGRATION_WARNING = (
34+
"Warning: We noticed that you are using Arm Compiler 5. "
35+
"We are deprecating the use of Arm Compiler 5 soon. "
36+
"Please upgrade your environment to Arm Compiler 6 "
37+
"which is free to use with Mbed OS."
38+
)
3339

3440
class ARM(mbedToolchain):
3541
LINKER_EXT = '.sct'

0 commit comments

Comments
 (0)