Merge pull request #10114 from bridadan/armc6_mbed_ide

Allow the use of Mbed Studio's version of ARMC6
pull/10202/head
Martin Kojtal 2019-03-23 16:30:01 +01:00 committed by GitHub
commit aca0f2f48e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 118 additions and 22 deletions

View File

@ -263,7 +263,7 @@ def transform_release_toolchains(target, version):
if version == '5':
if 'ARMC5' in target.supported_toolchains:
return ['ARMC5', 'GCC_ARM', 'IAR']
else:
else:
return ['ARM', 'ARMC6', 'GCC_ARM', 'IAR']
else:
return target.supported_toolchains
@ -356,7 +356,7 @@ def prepare_toolchain(src_paths, build_dir, target, toolchain_name,
# If the configuration object was not yet created, create it now
config = config or Config(target, src_paths, app_config=app_config)
target = config.target
if not target_supports_toolchain(target, toolchain_name):
raise NotSupportedException(
"Target {} is not supported by toolchain {}".format(
@ -364,11 +364,11 @@ def prepare_toolchain(src_paths, build_dir, target, toolchain_name,
selected_toolchain_name = get_toolchain_name(target, toolchain_name)
#If a target supports ARMC6 and we want to build UARM with it,
#If a target supports ARMC6 and we want to build UARM with it,
#then set the default_toolchain to uARM to link AC6 microlib.
if(selected_toolchain_name == "ARMC6" and toolchain_name == "uARM"):
target.default_toolchain = "uARM"
toolchain_name = selected_toolchain_name
toolchain_name = selected_toolchain_name
try:
cur_tc = TOOLCHAIN_CLASSES[toolchain_name]
@ -607,6 +607,7 @@ def build_library(src_paths, build_path, target, toolchain_name,
src_paths, build_path, target, toolchain_name, macros=macros,
clean=clean, jobs=jobs, notify=notify, app_config=app_config,
build_profile=build_profile, ignore=ignore)
toolchain.version_check()
# The first path will give the name to the library
if name is None:
@ -781,6 +782,7 @@ def build_lib(lib_id, target, toolchain_name, clean=False, macros=None,
src_paths, tmp_path, target, toolchain_name, macros=macros,
notify=notify, build_profile=build_profile, jobs=jobs, clean=clean,
ignore=ignore)
toolchain.version_check()
notify.info("Building library %s (%s, %s)" %
(name.upper(), target.name, toolchain_name))
@ -871,7 +873,7 @@ def build_mbed_libs(target, toolchain_name, clean=False, macros=None,
selected_toolchain_name = get_toolchain_name(target, toolchain_name)
#If a target supports ARMC6 and we want to build UARM with it,
#If a target supports ARMC6 and we want to build UARM with it,
#then set the default_toolchain to uARM to link AC6 microlib.
if(selected_toolchain_name == "ARMC6" and toolchain_name == "uARM"):
target.default_toolchain = "uARM"
@ -925,6 +927,7 @@ def build_mbed_libs(target, toolchain_name, clean=False, macros=None,
toolchain = prepare_toolchain(
[""], tmp_path, target, toolchain_name, macros=macros, notify=notify,
build_profile=build_profile, jobs=jobs, clean=clean, ignore=ignore)
toolchain.version_check()
config = toolchain.config
config.add_config_files([MBED_CONFIG_FILE])
@ -1118,10 +1121,10 @@ def mcu_toolchain_matrix(verbose_html=False, platform_filter=None,
unique_supported_toolchains = get_unique_supported_toolchains(
release_targets)
#Add ARMC5 column as well to the matrix to help with showing which targets are in ARMC5
#ARMC5 is not a toolchain class but yet we use that as a toolchain id in supported_toolchains in targets.json
#ARMC5 is not a toolchain class but yet we use that as a toolchain id in supported_toolchains in targets.json
#capture that info in a separate column
unique_supported_toolchains.append('ARMC5')
prepend_columns = ["Target"] + ["mbed OS %s" % x for x in RELEASE_VERSIONS]
# All tests status table print

View File

@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations
limitations
"""
import sys
@ -84,16 +84,41 @@ def test_armc5_version_check(_run_cmd):
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 == []
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 license.support@arm.com.
- 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
@patch('tools.toolchains.iar.run_cmd')
def test_iar_version_check(_run_cmd):

View File

@ -18,8 +18,9 @@ from __future__ import print_function, absolute_import
from builtins import str # noqa: F401
import re
import os
from copy import copy
from os.path import join, dirname, splitext, basename, exists, isfile
from os.path import join, dirname, splitext, basename, exists, isfile, split
from os import makedirs, write, remove
from tempfile import mkstemp
from shutil import rmtree
@ -27,7 +28,7 @@ from distutils.version import LooseVersion
from tools.targets import CORE_ARCH
from tools.toolchains.mbed_toolchain import mbedToolchain, TOOLCHAIN_PATHS
from tools.utils import mkdir, NotSupportedException, run_cmd
from tools.utils import mkdir, NotSupportedException, ToolException, run_cmd
class ARM(mbedToolchain):
@ -44,6 +45,7 @@ class ARM(mbedToolchain):
"Cortex-M7", "Cortex-M7F", "Cortex-M7FD", "Cortex-A9"
]
ARMCC_RANGE = (LooseVersion("5.06"), LooseVersion("5.07"))
ARMCC_PRODUCT_RE = re.compile(b"Product: (.*)")
ARMCC_VERSION_RE = re.compile(b"Component: ARM Compiler (\d+\.\d+)")
@staticmethod
@ -103,11 +105,20 @@ class ARM(mbedToolchain):
self.SHEBANG += " --cpu=%s" % cpu
self.product_name = None
def version_check(self):
stdout, _, retcode = run_cmd([self.cc[0], "--vsn"], redirect=True)
# The --ide=mbed removes an instability with checking the version of
# the ARMC6 binary that comes with Mbed Studio.
# NOTE: the --ide=mbed argument is only for use with Mbed OS
stdout, _, retcode = run_cmd(
[self.cc[0], "--vsn", "--ide=mbed"],
redirect=True
)
msg = None
min_ver, max_ver = self.ARMCC_RANGE
match = self.ARMCC_VERSION_RE.search(stdout.encode("utf-8"))
output = stdout.encode("utf-8")
match = self.ARMCC_VERSION_RE.search(output)
if match:
found_version = LooseVersion(match.group(1).decode("utf-8"))
else:
@ -132,6 +143,19 @@ class ARM(mbedToolchain):
"severity": "WARNING",
})
msg = None
match = self.ARMCC_PRODUCT_RE.search(output)
if match:
self.product_name = match.group(1).decode("utf-8")
else:
self.product_name = None
if not match or len(match.groups()) != 1:
msg = (
"Could not detect product name: defaulting to professional "
"version of ARMC6"
)
def _get_toolchain_labels(self):
if getattr(self.target, "default_toolchain", "ARM") == "uARM":
return ["ARM", "ARM_MICRO"]
@ -275,7 +299,7 @@ class ARM(mbedToolchain):
return new_scatter
def link(self, output, objects, libraries, lib_dirs, scatter_file):
def get_link_command(self, output, objects, libraries, lib_dirs, scatter_file):
base, _ = splitext(output)
map_file = base + ".map"
args = ["-o", output, "--info=totals", "--map", "--list=%s" % map_file]
@ -294,6 +318,13 @@ class ARM(mbedToolchain):
link_files = self.get_link_file(cmd[1:])
cmd = [cmd_linker, '--via', link_files]
return cmd
def link(self, output, objects, libraries, lib_dirs, scatter_file):
cmd = self.get_link_command(
output, objects, libraries, lib_dirs, scatter_file
)
self.notify.cc_verbose("Link: %s" % ' '.join(cmd))
self.default_cmd(cmd)
@ -304,12 +335,15 @@ class ARM(mbedToolchain):
param = objects
self.default_cmd([self.ar, '-r', lib_path] + param)
def get_binary_commands(self, bin_arg, bin, elf):
return [self.elf2bin, bin_arg, '-o', bin, elf]
def binary(self, resources, elf, bin):
_, fmt = splitext(bin)
# On .hex format, combine multiple .hex files (for multiple load
# regions) into one
bin_arg = {".bin": "--bin", ".hex": "--i32combined"}[fmt]
cmd = [self.elf2bin, bin_arg, '-o', bin, elf]
cmd = self.get_binary_commands(bin_arg, bin, elf)
# remove target binary file/path
if exists(bin):
@ -337,7 +371,6 @@ class ARM(mbedToolchain):
write(handle, "RESOLVE %s AS %s\n" % (source, sync))
return "--edit=%s" % filename
class ARM_STD(ARM):
OFFICIALLY_SUPPORTED = True
@ -359,7 +392,7 @@ class ARM_STD(ARM):
build_profile=build_profile
)
if int(target.build_tools_metadata["version"]) > 0:
#check only for ARMC5 because ARM_STD means using ARMC5, and thus
#check only for ARMC5 because ARM_STD means using ARMC5, and thus
# supported_toolchains must include ARMC5
if "ARMC5" not in target.supported_toolchains:
raise NotSupportedException(
@ -546,12 +579,21 @@ class ARMC6(ARM_STD):
self.ar = join(TOOLCHAIN_PATHS["ARMC6"], "armar")
self.elf2bin = join(TOOLCHAIN_PATHS["ARMC6"], "fromelf")
# Adding this for safety since this inherits the `version_check` function
# but does not call the constructor of ARM_STD, so the `product_name` variable
# is not initialized.
self.product_name = None
def _get_toolchain_labels(self):
if getattr(self.target, "default_toolchain", "ARM") == "uARM":
return ["ARM", "ARM_MICRO", "ARMC6"]
else:
return ["ARM", "ARM_STD", "ARMC6"]
@property
def is_mbed_studio_armc6(self):
return self.product_name and "Mbed Studio" in self.product_name
def parse_dependencies(self, dep_path):
return mbedToolchain.parse_dependencies(self, dep_path)
@ -565,21 +607,27 @@ class ARMC6(ARM_STD):
return ["-include", config_header]
def get_compile_options(self, defines, includes, for_asm=False):
opts = ['-D%s' % d for d in defines]
if self.RESPONSE_FILES:
opts += ['@{}'.format(self.get_inc_file(includes))]
else:
opts += ["-I%s" % i for i in includes if i]
config_header = self.get_config_header()
if config_header:
opts.extend(self.get_config_option(config_header))
if for_asm:
return [
opts = [
"--cpreproc",
"--cpreproc_opts=%s" % ",".join(self.flags['common'] + opts)
]
if self.is_mbed_studio_armc6:
# NOTE: the --ide=mbed argument is only for use with Mbed OS
opts.insert(0, "--ide=mbed")
return opts
def assemble(self, source, object, includes):
@ -594,3 +642,23 @@ class ARMC6(ARM_STD):
cmd.extend(self.get_compile_options(self.get_symbols(), includes))
cmd.extend(["-o", object, source])
return [cmd]
def get_link_command(self, output, objects, libraries, lib_dirs, scatter_file):
cmd = ARM.get_link_command(
self, output, objects, libraries, lib_dirs, scatter_file
)
if self.is_mbed_studio_armc6:
# NOTE: the --ide=mbed argument is only for use with Mbed OS
cmd.insert(1, "--ide=mbed")
return cmd
def get_binary_commands(self, bin_arg, bin, elf):
cmd = ARM.get_binary_commands(self, bin_arg, bin, elf)
if self.is_mbed_studio_armc6:
# NOTE: the --ide=mbed argument is only for use with Mbed OS
cmd.insert(1, "--ide=mbed")
return cmd