18
18
from builtins import str # noqa: F401
19
19
20
20
import re
21
+ import os
21
22
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
23
24
from os import makedirs , write , remove
24
25
from tempfile import mkstemp
25
26
from shutil import rmtree
26
27
from distutils .version import LooseVersion
27
28
28
29
from tools .targets import CORE_ARCH
29
30
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
31
32
32
33
33
34
class ARM (mbedToolchain ):
@@ -44,6 +45,7 @@ class ARM(mbedToolchain):
44
45
"Cortex-M7" , "Cortex-M7F" , "Cortex-M7FD" , "Cortex-A9"
45
46
]
46
47
ARMCC_RANGE = (LooseVersion ("5.06" ), LooseVersion ("5.07" ))
48
+ ARMCC_PRODUCT_RE = re .compile (b"Product: (.*)" )
47
49
ARMCC_VERSION_RE = re .compile (b"Component: ARM Compiler (\d+\.\d+)" )
48
50
49
51
@staticmethod
@@ -103,11 +105,20 @@ def __init__(self, target, notify=None, macros=None,
103
105
104
106
self .SHEBANG += " --cpu=%s" % cpu
105
107
108
+ self .product_name = None
109
+
106
110
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
+ )
108
118
msg = None
109
119
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 )
111
122
if match :
112
123
found_version = LooseVersion (match .group (1 ).decode ("utf-8" ))
113
124
else :
@@ -132,6 +143,19 @@ def version_check(self):
132
143
"severity" : "WARNING" ,
133
144
})
134
145
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
+
135
159
def _get_toolchain_labels (self ):
136
160
if getattr (self .target , "default_toolchain" , "ARM" ) == "uARM" :
137
161
return ["ARM" , "ARM_MICRO" ]
@@ -275,7 +299,7 @@ def correct_scatter_shebang(self, scatter_file, cur_dir_name=None):
275
299
276
300
return new_scatter
277
301
278
- def link (self , output , objects , libraries , lib_dirs , scatter_file ):
302
+ def get_link_command (self , output , objects , libraries , lib_dirs , scatter_file ):
279
303
base , _ = splitext (output )
280
304
map_file = base + ".map"
281
305
args = ["-o" , output , "--info=totals" , "--map" , "--list=%s" % map_file ]
@@ -294,6 +318,13 @@ def link(self, output, objects, libraries, lib_dirs, scatter_file):
294
318
link_files = self .get_link_file (cmd [1 :])
295
319
cmd = [cmd_linker , '--via' , link_files ]
296
320
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
+
297
328
self .notify .cc_verbose ("Link: %s" % ' ' .join (cmd ))
298
329
self .default_cmd (cmd )
299
330
@@ -304,12 +335,15 @@ def archive(self, objects, lib_path):
304
335
param = objects
305
336
self .default_cmd ([self .ar , '-r' , lib_path ] + param )
306
337
338
+ def get_binary_commands (self , bin_arg , bin , elf ):
339
+ return [self .elf2bin , bin_arg , '-o' , bin , elf ]
340
+
307
341
def binary (self , resources , elf , bin ):
308
342
_ , fmt = splitext (bin )
309
343
# On .hex format, combine multiple .hex files (for multiple load
310
344
# regions) into one
311
345
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 )
313
347
314
348
# remove target binary file/path
315
349
if exists (bin ):
@@ -337,7 +371,6 @@ def redirect_symbol(source, sync, build_dir):
337
371
write (handle , "RESOLVE %s AS %s\n " % (source , sync ))
338
372
return "--edit=%s" % filename
339
373
340
-
341
374
class ARM_STD (ARM ):
342
375
343
376
OFFICIALLY_SUPPORTED = True
@@ -359,7 +392,7 @@ def __init__(
359
392
build_profile = build_profile
360
393
)
361
394
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
363
396
# supported_toolchains must include ARMC5
364
397
if "ARMC5" not in target .supported_toolchains :
365
398
raise NotSupportedException (
@@ -546,12 +579,21 @@ def __init__(self, target, *args, **kwargs):
546
579
self .ar = join (TOOLCHAIN_PATHS ["ARMC6" ], "armar" )
547
580
self .elf2bin = join (TOOLCHAIN_PATHS ["ARMC6" ], "fromelf" )
548
581
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
+
549
587
def _get_toolchain_labels (self ):
550
588
if getattr (self .target , "default_toolchain" , "ARM" ) == "uARM" :
551
589
return ["ARM" , "ARM_MICRO" , "ARMC6" ]
552
590
else :
553
591
return ["ARM" , "ARM_STD" , "ARMC6" ]
554
592
593
+ @property
594
+ def is_mbed_studio_armc6 (self ):
595
+ return self .product_name and "Mbed Studio" in self .product_name
596
+
555
597
def parse_dependencies (self , dep_path ):
556
598
return mbedToolchain .parse_dependencies (self , dep_path )
557
599
@@ -565,21 +607,27 @@ def get_config_option(self, config_header):
565
607
return ["-include" , config_header ]
566
608
567
609
def get_compile_options (self , defines , includes , for_asm = False ):
568
-
610
+
569
611
opts = ['-D%s' % d for d in defines ]
612
+
570
613
if self .RESPONSE_FILES :
571
614
opts += ['@{}' .format (self .get_inc_file (includes ))]
572
615
else :
573
616
opts += ["-I%s" % i for i in includes if i ]
574
-
617
+
575
618
config_header = self .get_config_header ()
576
619
if config_header :
577
620
opts .extend (self .get_config_option (config_header ))
578
621
if for_asm :
579
- return [
622
+ opts = [
580
623
"--cpreproc" ,
581
624
"--cpreproc_opts=%s" % "," .join (self .flags ['common' ] + opts )
582
625
]
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
+
583
631
return opts
584
632
585
633
def assemble (self , source , object , includes ):
@@ -594,3 +642,23 @@ def compile(self, cc, source, object, includes):
594
642
cmd .extend (self .get_compile_options (self .get_symbols (), includes ))
595
643
cmd .extend (["-o" , object , source ])
596
644
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