1818from builtins import str # noqa: F401
1919
2020import re
21+ import os
2122from 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
2324from os import makedirs , write , remove
2425from tempfile import mkstemp
2526from shutil import rmtree
2627from distutils .version import LooseVersion
2728
2829from tools .targets import CORE_ARCH
2930from 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
3334class 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,19 @@ 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+ stdout , _ , retcode = run_cmd (
114+ [self .cc [0 ], "--vsn" , "--ide=mbed" ],
115+ redirect = True
116+ )
108117 msg = None
109118 min_ver , max_ver = self .ARMCC_RANGE
110- match = self .ARMCC_VERSION_RE .search (stdout .encode ("utf-8" ))
119+ output = stdout .encode ("utf-8" )
120+ match = self .ARMCC_VERSION_RE .search (output )
111121 if match :
112122 found_version = LooseVersion (match .group (1 ).decode ("utf-8" ))
113123 else :
@@ -132,6 +142,19 @@ def version_check(self):
132142 "severity" : "WARNING" ,
133143 })
134144
145+ msg = None
146+ match = self .ARMCC_PRODUCT_RE .search (output )
147+ if match :
148+ self .product_name = match .group (1 ).decode ("utf-8" )
149+ else :
150+ self .product_name = None
151+
152+ if not match or len (match .groups ()) != 1 :
153+ msg = (
154+ "Could not detect product name: defaulting to professional "
155+ "version of ARMC6"
156+ )
157+
135158 def _get_toolchain_labels (self ):
136159 if getattr (self .target , "default_toolchain" , "ARM" ) == "uARM" :
137160 return ["ARM" , "ARM_MICRO" ]
@@ -275,7 +298,7 @@ def correct_scatter_shebang(self, scatter_file, cur_dir_name=None):
275298
276299 return new_scatter
277300
278- def link (self , output , objects , libraries , lib_dirs , scatter_file ):
301+ def get_link_command (self , output , objects , libraries , lib_dirs , scatter_file ):
279302 base , _ = splitext (output )
280303 map_file = base + ".map"
281304 args = ["-o" , output , "--info=totals" , "--map" , "--list=%s" % map_file ]
@@ -294,6 +317,13 @@ def link(self, output, objects, libraries, lib_dirs, scatter_file):
294317 link_files = self .get_link_file (cmd [1 :])
295318 cmd = [cmd_linker , '--via' , link_files ]
296319
320+ return cmd
321+
322+ def link (self , output , objects , libraries , lib_dirs , scatter_file ):
323+ cmd = self .get_link_command (
324+ output , objects , libraries , lib_dirs , scatter_file
325+ )
326+
297327 self .notify .cc_verbose ("Link: %s" % ' ' .join (cmd ))
298328 self .default_cmd (cmd )
299329
@@ -304,12 +334,15 @@ def archive(self, objects, lib_path):
304334 param = objects
305335 self .default_cmd ([self .ar , '-r' , lib_path ] + param )
306336
337+ def get_binary_commands (self , bin_arg , bin , elf ):
338+ return [self .elf2bin , bin_arg , '-o' , bin , elf ]
339+
307340 def binary (self , resources , elf , bin ):
308341 _ , fmt = splitext (bin )
309342 # On .hex format, combine multiple .hex files (for multiple load
310343 # regions) into one
311344 bin_arg = {".bin" : "--bin" , ".hex" : "--i32combined" }[fmt ]
312- cmd = [ self .elf2bin , bin_arg , '-o' , bin , elf ]
345+ cmd = self .get_binary_commands ( bin_arg , bin , elf )
313346
314347 # remove target binary file/path
315348 if exists (bin ):
@@ -545,12 +578,21 @@ def __init__(self, target, *args, **kwargs):
545578 self .ar = join (TOOLCHAIN_PATHS ["ARMC6" ], "armar" )
546579 self .elf2bin = join (TOOLCHAIN_PATHS ["ARMC6" ], "fromelf" )
547580
581+ # Adding this for safety since this inherits the `version_check` function
582+ # but does not call the constructor of ARM_STD, so the `product_name` variable
583+ # is not initialized.
584+ self .product_name = None
585+
548586 def _get_toolchain_labels (self ):
549587 if getattr (self .target , "default_toolchain" , "ARM" ) == "uARM" :
550588 return ["ARM" , "ARM_MICRO" , "ARMC6" ]
551589 else :
552590 return ["ARM" , "ARM_STD" , "ARMC6" ]
553591
592+ @property
593+ def is_mbed_studio_armc6 (self ):
594+ return self .product_name and "Mbed Studio" in self .product_name
595+
554596 def parse_dependencies (self , dep_path ):
555597 return mbedToolchain .parse_dependencies (self , dep_path )
556598
@@ -576,10 +618,14 @@ def get_compile_options(self, defines, includes, for_asm=False):
576618 if config_header :
577619 opts .extend (self .get_config_option (config_header ))
578620 if for_asm :
579- return [
621+ opts = [
580622 "--cpreproc" ,
581623 "--cpreproc_opts=%s" % "," .join (self .flags ['common' ] + opts )
582624 ]
625+
626+ if self .is_mbed_studio_armc6 :
627+ opts .insert (0 , "--ide=mbed" )
628+
583629 return opts
584630
585631 def assemble (self , source , object , includes ):
@@ -594,3 +640,21 @@ def compile(self, cc, source, object, includes):
594640 cmd .extend (self .get_compile_options (self .get_symbols (), includes ))
595641 cmd .extend (["-o" , object , source ])
596642 return [cmd ]
643+
644+ def get_link_command (self , output , objects , libraries , lib_dirs , scatter_file ):
645+ cmd = ARM .get_link_command (
646+ self , output , objects , libraries , lib_dirs , scatter_file
647+ )
648+
649+ if self .is_mbed_studio_armc6 :
650+ cmd .insert (1 , "--ide=mbed" )
651+
652+ return cmd
653+
654+ def get_binary_commands (self , bin_arg , bin , elf ):
655+ cmd = ARM .get_binary_commands (self , bin_arg , bin , elf )
656+
657+ if self .is_mbed_studio_armc6 :
658+ cmd .insert (1 , "--ide=mbed" )
659+
660+ return cmd
0 commit comments