mirror of https://github.com/ARMmbed/mbed-os.git
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.pull/10193/head
parent
08d9e32e63
commit
6f5a3c3e8d
|
@ -34,7 +34,7 @@ from jinja2.environment import Environment
|
|||
from .arm_pack_manager import Cache
|
||||
from .utils import (mkdir, run_cmd, run_cmd_ext, NotSupportedException,
|
||||
ToolException, InvalidReleaseTargetException,
|
||||
copy_when_different)
|
||||
copy_when_different, NoValidToolchainException)
|
||||
from .paths import (MBED_CMSIS_PATH, MBED_TARGETS_PATH, MBED_LIBRARIES,
|
||||
MBED_HEADER, MBED_DRIVERS, MBED_PLATFORM, MBED_HAL,
|
||||
MBED_CONFIG_FILE, MBED_LIBRARIES_DRIVERS,
|
||||
|
@ -44,7 +44,8 @@ from .resources import Resources, FileType, FileRef
|
|||
from .notifier.mock import MockNotifier
|
||||
from .targets import TARGET_NAMES, TARGET_MAP, CORE_ARCH, Target
|
||||
from .libraries import Library
|
||||
from .toolchains import TOOLCHAIN_CLASSES
|
||||
from .toolchains import TOOLCHAIN_CLASSES, TOOLCHAIN_PATHS
|
||||
from .toolchains.arm import ARMC5_MIGRATION_WARNING
|
||||
from .config import Config
|
||||
|
||||
RELEASE_VERSIONS = ['2', '5']
|
||||
|
@ -120,18 +121,76 @@ def add_result_to_report(report, result):
|
|||
result_wrap = {0: result}
|
||||
report[target][toolchain][id_name].append(result_wrap)
|
||||
|
||||
def get_toolchain_name(target, toolchain_name):
|
||||
def get_valid_toolchain_names(target, toolchain_name):
|
||||
"""Return the list of toolchains with which a build should be attempted. This
|
||||
list usually contains one element, however there may be multiple entries if
|
||||
a toolchain is expected to fallback to different versions depending on the
|
||||
environment configuration. If an invalid supported_toolchain configuration
|
||||
is detected, an Exception will be raised.
|
||||
|
||||
Positional arguments:
|
||||
target - Target object (not the string name) of the device we are building for
|
||||
toolchain_name - the string that identifies the build toolchain as supplied by
|
||||
the front-end scripts
|
||||
"""
|
||||
if int(target.build_tools_metadata["version"]) > 0:
|
||||
if toolchain_name == "ARM" or toolchain_name == "ARMC6" :
|
||||
if("ARM" in target.supported_toolchains or "ARMC6" in target.supported_toolchains):
|
||||
all_arm_toolchain_names = ["ARMC6", "ARMC5", "ARM"]
|
||||
arm_st = set(target.supported_toolchains).intersection(
|
||||
set(all_arm_toolchain_names)
|
||||
)
|
||||
if len(arm_st) > 1:
|
||||
raise Exception(
|
||||
"Targets may only specify one of the following in "
|
||||
"supported_toolchains: {}\n"
|
||||
"The following toolchains were present: {}".format(
|
||||
", ".join(all_arm_toolchain_names),
|
||||
", ".join(arm_st),
|
||||
)
|
||||
)
|
||||
if toolchain_name == "ARM":
|
||||
# The order matters here
|
||||
all_arm_toolchain_names = ["ARMC6", "ARMC5"]
|
||||
if "ARM" in target.supported_toolchains:
|
||||
return all_arm_toolchain_names
|
||||
|
||||
result_list = []
|
||||
for tc_name in all_arm_toolchain_names:
|
||||
if tc_name in target.supported_toolchains:
|
||||
result_list.append(tc_name)
|
||||
return result_list
|
||||
|
||||
return [toolchain_name]
|
||||
|
||||
def get_toolchain_name(target, toolchain_name):
|
||||
"""Get the internal toolchain name given the toolchain_name provided by
|
||||
the front-end scripts (usually by the -t/--toolchain argument) and the target
|
||||
|
||||
Positional arguments:
|
||||
target - Target object (not the string name) of the device we are building for
|
||||
toolchain_name - the string that identifies the build toolchain as supplied by
|
||||
the front-end scripts
|
||||
|
||||
Overview of what the current return values should be for the "ARM" family of
|
||||
toolchains (since the behavior is fairly complex). Top row header represents
|
||||
the argument "toolchain_name", Left column header represents the attribute
|
||||
"supported_toolchains" of the "target" argument.
|
||||
|
||||
| supported_toolchains/toolchain_name |+| ARMC5 | ARMC6 | ARM |
|
||||
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
| ARMC5 |+| ARM* | ARMC6 | ARM |
|
||||
| ARMC6 |+| ARM* | ARMC6 | ARMC6* |
|
||||
| ARM |+| ARM* | ARMC6 | ARMC6* |
|
||||
|
||||
* Denotes that the input "toolchain_name" changes in the return value
|
||||
"""
|
||||
if int(target.build_tools_metadata["version"]) > 0:
|
||||
if toolchain_name == "ARMC5":
|
||||
return "ARM"
|
||||
elif toolchain_name == "ARM":
|
||||
if set(target.supported_toolchains).intersection(set(["ARMC6", "ARM"])):
|
||||
return "ARMC6"
|
||||
elif ("ARMC5" in target.supported_toolchains):
|
||||
if toolchain_name == "ARM":
|
||||
return "ARM" #note that returning ARM here means, use ARMC5 toolchain
|
||||
else:
|
||||
return "ARMC6" #ARMC6 explicitly specified by user, try ARMC6 anyway although the target doesnt explicitly specify ARMC6, as ARMC6 is our default ARM toolchain
|
||||
elif toolchain_name == "uARM":
|
||||
if ("ARMC5" in target.supported_toolchains):
|
||||
if "ARMC5" in target.supported_toolchains:
|
||||
return "uARM" #use ARM_MICRO to use AC5+microlib
|
||||
else:
|
||||
return "ARMC6" #use AC6+microlib
|
||||
|
@ -144,6 +203,51 @@ def get_toolchain_name(target, toolchain_name):
|
|||
|
||||
return toolchain_name
|
||||
|
||||
def find_valid_toolchain(target, toolchain):
|
||||
"""Given a target and toolchain, get the names for the appropriate
|
||||
toolchain to use. The environment is also checked to see if the corresponding
|
||||
compiler is configured correctl. For the ARM compilers, there is an automatic
|
||||
fallback behavior if "ARM" is the specified toolchain, if the latest compiler
|
||||
(ARMC6) is not available, and the target supports building with both ARMC5
|
||||
and ARMC6. In the case where the environment configuration triggers the fallback
|
||||
to ARMC5, add a warning to the list that is returned in the results.
|
||||
|
||||
Returns:
|
||||
toolchain_name - The name of the toolchain. When "ARM" is supplied as the
|
||||
"toolchain", this be changed to either "ARMC5" or "ARMC6".
|
||||
internal_tc_name - This corresponds to that name of the class that will be
|
||||
used to actually complete the build. This is mostly used for accessing build
|
||||
profiles and just general legacy sections within the code.
|
||||
end_warnings - This is a list of warnings (strings) that were raised during
|
||||
the process of finding toolchain. This is used to warn the user of the ARM
|
||||
fallback mechanism mentioned above.
|
||||
|
||||
Positional arguments:
|
||||
target - Target object (not the string name) of the device we are building for
|
||||
toolchain_name - the string that identifies the build toolchain as supplied by
|
||||
the front-end scripts
|
||||
"""
|
||||
end_warnings = []
|
||||
toolchain_names = get_valid_toolchain_names(target, toolchain)
|
||||
last_error = None
|
||||
for index, toolchain_name in enumerate(toolchain_names):
|
||||
internal_tc_name = get_toolchain_name(target, toolchain_name)
|
||||
if toolchain == "ARM" and toolchain_name == "ARMC5" and index != 0:
|
||||
end_warnings.append(ARMC5_MIGRATION_WARNING)
|
||||
if not TOOLCHAIN_CLASSES[internal_tc_name].check_executable():
|
||||
search_path = TOOLCHAIN_PATHS[internal_tc_name] or "No path set"
|
||||
last_error = (
|
||||
"Could not find executable for {}.\n"
|
||||
"Currently set search path: {}"
|
||||
).format(toolchain_name, search_path)
|
||||
else:
|
||||
return toolchain_name, internal_tc_name, end_warnings
|
||||
else:
|
||||
if last_error:
|
||||
e = NoValidToolchainException(last_error)
|
||||
e.end_warnings = end_warnings
|
||||
raise e
|
||||
|
||||
def get_config(src_paths, target, toolchain_name=None, app_config=None):
|
||||
"""Get the configuration object for a target-toolchain combination
|
||||
|
||||
|
|
|
@ -30,6 +30,12 @@ from tools.targets import CORE_ARCH
|
|||
from tools.toolchains.mbed_toolchain import mbedToolchain, TOOLCHAIN_PATHS
|
||||
from tools.utils import mkdir, NotSupportedException, ToolException, run_cmd
|
||||
|
||||
ARMC5_MIGRATION_WARNING = (
|
||||
"Warning: We noticed that you are using Arm Compiler 5. "
|
||||
"We are deprecating the use of Arm Compiler 5 soon. "
|
||||
"Please upgrade your environment to Arm Compiler 6 "
|
||||
"which is free to use with Mbed OS."
|
||||
)
|
||||
|
||||
class ARM(mbedToolchain):
|
||||
LINKER_EXT = '.sct'
|
||||
|
|
Loading…
Reference in New Issue