Skip to content

Commit aca0f2f

Browse files
authored
Merge pull request #10114 from bridadan/armc6_mbed_ide
Allow the use of Mbed Studio's version of ARMC6
2 parents f76436c + e382b50 commit aca0f2f

File tree

3 files changed

+118
-22
lines changed

3 files changed

+118
-22
lines changed

tools/build_api.py

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,7 @@ def transform_release_toolchains(target, version):
263263
if version == '5':
264264
if 'ARMC5' in target.supported_toolchains:
265265
return ['ARMC5', 'GCC_ARM', 'IAR']
266-
else:
266+
else:
267267
return ['ARM', 'ARMC6', 'GCC_ARM', 'IAR']
268268
else:
269269
return target.supported_toolchains
@@ -356,19 +356,19 @@ def prepare_toolchain(src_paths, build_dir, target, toolchain_name,
356356
# If the configuration object was not yet created, create it now
357357
config = config or Config(target, src_paths, app_config=app_config)
358358
target = config.target
359-
359+
360360
if not target_supports_toolchain(target, toolchain_name):
361361
raise NotSupportedException(
362362
"Target {} is not supported by toolchain {}".format(
363363
target.name, toolchain_name))
364364

365365
selected_toolchain_name = get_toolchain_name(target, toolchain_name)
366366

367-
#If a target supports ARMC6 and we want to build UARM with it,
367+
#If a target supports ARMC6 and we want to build UARM with it,
368368
#then set the default_toolchain to uARM to link AC6 microlib.
369369
if(selected_toolchain_name == "ARMC6" and toolchain_name == "uARM"):
370370
target.default_toolchain = "uARM"
371-
toolchain_name = selected_toolchain_name
371+
toolchain_name = selected_toolchain_name
372372

373373
try:
374374
cur_tc = TOOLCHAIN_CLASSES[toolchain_name]
@@ -607,6 +607,7 @@ def build_library(src_paths, build_path, target, toolchain_name,
607607
src_paths, build_path, target, toolchain_name, macros=macros,
608608
clean=clean, jobs=jobs, notify=notify, app_config=app_config,
609609
build_profile=build_profile, ignore=ignore)
610+
toolchain.version_check()
610611

611612
# The first path will give the name to the library
612613
if name is None:
@@ -781,6 +782,7 @@ def build_lib(lib_id, target, toolchain_name, clean=False, macros=None,
781782
src_paths, tmp_path, target, toolchain_name, macros=macros,
782783
notify=notify, build_profile=build_profile, jobs=jobs, clean=clean,
783784
ignore=ignore)
785+
toolchain.version_check()
784786

785787
notify.info("Building library %s (%s, %s)" %
786788
(name.upper(), target.name, toolchain_name))
@@ -871,7 +873,7 @@ def build_mbed_libs(target, toolchain_name, clean=False, macros=None,
871873

872874
selected_toolchain_name = get_toolchain_name(target, toolchain_name)
873875

874-
#If a target supports ARMC6 and we want to build UARM with it,
876+
#If a target supports ARMC6 and we want to build UARM with it,
875877
#then set the default_toolchain to uARM to link AC6 microlib.
876878
if(selected_toolchain_name == "ARMC6" and toolchain_name == "uARM"):
877879
target.default_toolchain = "uARM"
@@ -925,6 +927,7 @@ def build_mbed_libs(target, toolchain_name, clean=False, macros=None,
925927
toolchain = prepare_toolchain(
926928
[""], tmp_path, target, toolchain_name, macros=macros, notify=notify,
927929
build_profile=build_profile, jobs=jobs, clean=clean, ignore=ignore)
930+
toolchain.version_check()
928931

929932
config = toolchain.config
930933
config.add_config_files([MBED_CONFIG_FILE])
@@ -1118,10 +1121,10 @@ def mcu_toolchain_matrix(verbose_html=False, platform_filter=None,
11181121
unique_supported_toolchains = get_unique_supported_toolchains(
11191122
release_targets)
11201123
#Add ARMC5 column as well to the matrix to help with showing which targets are in ARMC5
1121-
#ARMC5 is not a toolchain class but yet we use that as a toolchain id in supported_toolchains in targets.json
1124+
#ARMC5 is not a toolchain class but yet we use that as a toolchain id in supported_toolchains in targets.json
11221125
#capture that info in a separate column
11231126
unique_supported_toolchains.append('ARMC5')
1124-
1127+
11251128
prepend_columns = ["Target"] + ["mbed OS %s" % x for x in RELEASE_VERSIONS]
11261129

11271130
# All tests status table print

tools/test/toolchains/api_test.py

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
distributed under the License is distributed on an "AS IS" BASIS,
1414
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1515
See the License for the specific language governing permissions and
16-
limitations
16+
limitations
1717
"""
1818

1919
import sys
@@ -84,16 +84,41 @@ def test_armc5_version_check(_run_cmd):
8484
def test_armc6_version_check(_run_cmd):
8585
set_targets_json_location()
8686
notifier = MockNotifier()
87-
print(TARGET_MAP["K64F"])
8887
toolchain = TOOLCHAIN_CLASSES["ARMC6"](TARGET_MAP["K64F"], notify=notifier)
89-
print(toolchain)
9088
_run_cmd.return_value = ("""
9189
Product: ARM Compiler 6.11 Professional
9290
Component: ARM Compiler 6.11
9391
Tool: armclang [5d3b4200]
9492
""", "", 0)
93+
9594
toolchain.version_check()
96-
assert notifier.messages == []
95+
assert notifier.messages == []
96+
assert not toolchain.is_mbed_studio_armc6
97+
98+
_run_cmd.return_value = ("""
99+
armclang: error: Failed to check out a license.
100+
The provided license does not enable these tools.
101+
Information about this error is available at: http://ds.arm.com/support/lic56/m5
102+
General licensing information is available at: http://ds.arm.com/support/licensing/
103+
If you need further help, provide this complete error report to your supplier or [email protected].
104+
- ARMLMD_LICENSE_FILE: unset
105+
- LM_LICENSE_FILE: unset
106+
- ARM_TOOL_VARIANT: unset
107+
- ARM_PRODUCT_PATH: unset
108+
- Product location: C:\MbedStudio\tools\ac6\sw\mappings
109+
- Toolchain location: C:\MbedStudio\tools\ac6\bin
110+
- Selected tool variant: product
111+
- Checkout feature: mbed_armcompiler
112+
- Feature version: 5.0201810
113+
- Flex error code: -5
114+
Product: ARM Compiler 6.11 for Mbed Studio
115+
Component: ARM Compiler 6.11
116+
Tool: armclang [5d3b3c00]
117+
""", "", 0)
118+
119+
toolchain.version_check()
120+
assert notifier.messages == []
121+
assert toolchain.is_mbed_studio_armc6
97122

98123
@patch('tools.toolchains.iar.run_cmd')
99124
def test_iar_version_check(_run_cmd):

tools/toolchains/arm.py

Lines changed: 79 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,17 @@
1818
from builtins import str # noqa: F401
1919

2020
import re
21+
import os
2122
from copy import copy
22-
from os.path import join, dirname, splitext, basename, exists, isfile
23+
from os.path import join, dirname, splitext, basename, exists, isfile, split
2324
from os import makedirs, write, remove
2425
from tempfile import mkstemp
2526
from shutil import rmtree
2627
from distutils.version import LooseVersion
2728

2829
from tools.targets import CORE_ARCH
2930
from tools.toolchains.mbed_toolchain import mbedToolchain, TOOLCHAIN_PATHS
30-
from tools.utils import mkdir, NotSupportedException, run_cmd
31+
from tools.utils import mkdir, NotSupportedException, ToolException, run_cmd
3132

3233

3334
class ARM(mbedToolchain):
@@ -44,6 +45,7 @@ class ARM(mbedToolchain):
4445
"Cortex-M7", "Cortex-M7F", "Cortex-M7FD", "Cortex-A9"
4546
]
4647
ARMCC_RANGE = (LooseVersion("5.06"), LooseVersion("5.07"))
48+
ARMCC_PRODUCT_RE = re.compile(b"Product: (.*)")
4749
ARMCC_VERSION_RE = re.compile(b"Component: ARM Compiler (\d+\.\d+)")
4850

4951
@staticmethod
@@ -103,11 +105,20 @@ def __init__(self, target, notify=None, macros=None,
103105

104106
self.SHEBANG += " --cpu=%s" % cpu
105107

108+
self.product_name = None
109+
106110
def version_check(self):
107-
stdout, _, retcode = run_cmd([self.cc[0], "--vsn"], redirect=True)
111+
# The --ide=mbed removes an instability with checking the version of
112+
# the ARMC6 binary that comes with Mbed Studio.
113+
# NOTE: the --ide=mbed argument is only for use with Mbed OS
114+
stdout, _, retcode = run_cmd(
115+
[self.cc[0], "--vsn", "--ide=mbed"],
116+
redirect=True
117+
)
108118
msg = None
109119
min_ver, max_ver = self.ARMCC_RANGE
110-
match = self.ARMCC_VERSION_RE.search(stdout.encode("utf-8"))
120+
output = stdout.encode("utf-8")
121+
match = self.ARMCC_VERSION_RE.search(output)
111122
if match:
112123
found_version = LooseVersion(match.group(1).decode("utf-8"))
113124
else:
@@ -132,6 +143,19 @@ def version_check(self):
132143
"severity": "WARNING",
133144
})
134145

146+
msg = None
147+
match = self.ARMCC_PRODUCT_RE.search(output)
148+
if match:
149+
self.product_name = match.group(1).decode("utf-8")
150+
else:
151+
self.product_name = None
152+
153+
if not match or len(match.groups()) != 1:
154+
msg = (
155+
"Could not detect product name: defaulting to professional "
156+
"version of ARMC6"
157+
)
158+
135159
def _get_toolchain_labels(self):
136160
if getattr(self.target, "default_toolchain", "ARM") == "uARM":
137161
return ["ARM", "ARM_MICRO"]
@@ -275,7 +299,7 @@ def correct_scatter_shebang(self, scatter_file, cur_dir_name=None):
275299

276300
return new_scatter
277301

278-
def link(self, output, objects, libraries, lib_dirs, scatter_file):
302+
def get_link_command(self, output, objects, libraries, lib_dirs, scatter_file):
279303
base, _ = splitext(output)
280304
map_file = base + ".map"
281305
args = ["-o", output, "--info=totals", "--map", "--list=%s" % map_file]
@@ -294,6 +318,13 @@ def link(self, output, objects, libraries, lib_dirs, scatter_file):
294318
link_files = self.get_link_file(cmd[1:])
295319
cmd = [cmd_linker, '--via', link_files]
296320

321+
return cmd
322+
323+
def link(self, output, objects, libraries, lib_dirs, scatter_file):
324+
cmd = self.get_link_command(
325+
output, objects, libraries, lib_dirs, scatter_file
326+
)
327+
297328
self.notify.cc_verbose("Link: %s" % ' '.join(cmd))
298329
self.default_cmd(cmd)
299330

@@ -304,12 +335,15 @@ def archive(self, objects, lib_path):
304335
param = objects
305336
self.default_cmd([self.ar, '-r', lib_path] + param)
306337

338+
def get_binary_commands(self, bin_arg, bin, elf):
339+
return [self.elf2bin, bin_arg, '-o', bin, elf]
340+
307341
def binary(self, resources, elf, bin):
308342
_, fmt = splitext(bin)
309343
# On .hex format, combine multiple .hex files (for multiple load
310344
# regions) into one
311345
bin_arg = {".bin": "--bin", ".hex": "--i32combined"}[fmt]
312-
cmd = [self.elf2bin, bin_arg, '-o', bin, elf]
346+
cmd = self.get_binary_commands(bin_arg, bin, elf)
313347

314348
# remove target binary file/path
315349
if exists(bin):
@@ -337,7 +371,6 @@ def redirect_symbol(source, sync, build_dir):
337371
write(handle, "RESOLVE %s AS %s\n" % (source, sync))
338372
return "--edit=%s" % filename
339373

340-
341374
class ARM_STD(ARM):
342375

343376
OFFICIALLY_SUPPORTED = True
@@ -359,7 +392,7 @@ def __init__(
359392
build_profile=build_profile
360393
)
361394
if int(target.build_tools_metadata["version"]) > 0:
362-
#check only for ARMC5 because ARM_STD means using ARMC5, and thus
395+
#check only for ARMC5 because ARM_STD means using ARMC5, and thus
363396
# supported_toolchains must include ARMC5
364397
if "ARMC5" not in target.supported_toolchains:
365398
raise NotSupportedException(
@@ -546,12 +579,21 @@ def __init__(self, target, *args, **kwargs):
546579
self.ar = join(TOOLCHAIN_PATHS["ARMC6"], "armar")
547580
self.elf2bin = join(TOOLCHAIN_PATHS["ARMC6"], "fromelf")
548581

582+
# Adding this for safety since this inherits the `version_check` function
583+
# but does not call the constructor of ARM_STD, so the `product_name` variable
584+
# is not initialized.
585+
self.product_name = None
586+
549587
def _get_toolchain_labels(self):
550588
if getattr(self.target, "default_toolchain", "ARM") == "uARM":
551589
return ["ARM", "ARM_MICRO", "ARMC6"]
552590
else:
553591
return ["ARM", "ARM_STD", "ARMC6"]
554592

593+
@property
594+
def is_mbed_studio_armc6(self):
595+
return self.product_name and "Mbed Studio" in self.product_name
596+
555597
def parse_dependencies(self, dep_path):
556598
return mbedToolchain.parse_dependencies(self, dep_path)
557599

@@ -565,21 +607,27 @@ def get_config_option(self, config_header):
565607
return ["-include", config_header]
566608

567609
def get_compile_options(self, defines, includes, for_asm=False):
568-
610+
569611
opts = ['-D%s' % d for d in defines]
612+
570613
if self.RESPONSE_FILES:
571614
opts += ['@{}'.format(self.get_inc_file(includes))]
572615
else:
573616
opts += ["-I%s" % i for i in includes if i]
574-
617+
575618
config_header = self.get_config_header()
576619
if config_header:
577620
opts.extend(self.get_config_option(config_header))
578621
if for_asm:
579-
return [
622+
opts = [
580623
"--cpreproc",
581624
"--cpreproc_opts=%s" % ",".join(self.flags['common'] + opts)
582625
]
626+
627+
if self.is_mbed_studio_armc6:
628+
# NOTE: the --ide=mbed argument is only for use with Mbed OS
629+
opts.insert(0, "--ide=mbed")
630+
583631
return opts
584632

585633
def assemble(self, source, object, includes):
@@ -594,3 +642,23 @@ def compile(self, cc, source, object, includes):
594642
cmd.extend(self.get_compile_options(self.get_symbols(), includes))
595643
cmd.extend(["-o", object, source])
596644
return [cmd]
645+
646+
def get_link_command(self, output, objects, libraries, lib_dirs, scatter_file):
647+
cmd = ARM.get_link_command(
648+
self, output, objects, libraries, lib_dirs, scatter_file
649+
)
650+
651+
if self.is_mbed_studio_armc6:
652+
# NOTE: the --ide=mbed argument is only for use with Mbed OS
653+
cmd.insert(1, "--ide=mbed")
654+
655+
return cmd
656+
657+
def get_binary_commands(self, bin_arg, bin, elf):
658+
cmd = ARM.get_binary_commands(self, bin_arg, bin, elf)
659+
660+
if self.is_mbed_studio_armc6:
661+
# NOTE: the --ide=mbed argument is only for use with Mbed OS
662+
cmd.insert(1, "--ide=mbed")
663+
664+
return cmd

0 commit comments

Comments
 (0)