@@ -130,7 +130,100 @@ def clean():
130130 subrun (["make" , "clean" ], silent = True )
131131
132132
133- def toolchain (target ):
133+ def toolchain_exes (target ):
134+ compiler_exe = target .compiler
135+
136+ # construct triple needed in gcc and objdump executable name
137+ triple_abi = "gnu"
138+ triple_arch = target .arch
139+ if target .arch == "x86" :
140+ triple_arch = "i686"
141+ elif target .isa == "aarch64" :
142+ triple_arch = "aarch64"
143+ elif target .arch .startswith ("armv" ):
144+ triple_arch = "arm"
145+ triple_abi = "gnueabi"
146+ if target .arch in ["mips64" , "mips64el" ]:
147+ triple_abi = "gnuabi64"
148+ triple = f"{ triple_arch } -linux-{ triple_abi } "
149+
150+ if target .compiler == "gcc" :
151+ if not target .is_native :
152+ # see https://gcc.gnu.org/onlinedocs/gcc/ARM-Options.html
153+ if "-march" in target .cflags or "-mcpu" in target .cflags :
154+ # user-specified arch/isa/cpu
155+ triple = "aarch64-linux-gnu"
156+ for v in range (1 ,7 ):
157+ if f"-march=armv{ v } " in target .cflags : triple = "arm-linux-gnueabi"
158+ if "-mthumb" in target .cflags : triple = "arm-linux-gnueabi"
159+ m = re .search (r"-mcpu=cortex-(\S+)" , target .cflags )
160+ if m :
161+ v = m .group (1 )
162+ if (v [0 ] == 'a' and int (v [1 :]) < 34 ): triple = "arm-linux-gnueabi"
163+ if (v [0 ] == 'm' ): triple = "arm-linux-gnueabi"
164+ if "-mcpu=arm" in target .cflags : triple = "arm-linux-gnueabi"
165+
166+ compiler_exe = f"{ triple } -gcc"
167+ for i in range (25 , 1 , - 1 ):
168+ if shutil .which (compiler_exe ) is not None : break
169+ compiler_exe = f"{ triple } -gcc-{ i } "
170+
171+ if shutil .which (compiler_exe ) is None :
172+ compiler_exe = None
173+ if target .compiler == "gcc" :
174+ compiler_error = f"could not locate gcc executable { triple } -gcc or { triple } -gcc-<majorversion>"
175+ else :
176+ compiler_error = f"could not locate { target .compiler } executable"
177+
178+ # non-arch-specific size should work in all cases, but may as well prefer <triple>-size
179+ if args .size :
180+ size_exe = triple + "-size"
181+ if shutil .which (size_exe ) is None :
182+ size_exe = "size"
183+ if shutil .which (size_exe ) is None :
184+ size_exe = None
185+ else :
186+ size_exe = None
187+ size_error = f"could not locate size executable { triple } -size or size"
188+
189+ # we need an architecture-specific obj-dump for disassembly (unless it's a native build)
190+ if args .disassemble :
191+ objdump_exe = triple + "-objdump"
192+ if shutil .which (objdump_exe ) is None :
193+ if target .is_native :
194+ objdump_exe = "objdump"
195+ if shutil .which (objdump_exe ) is None :
196+ objdump_exe = None
197+ else :
198+ objdump_exe = None
199+ if target .is_native :
200+ objdump_error = f"could not locate size executable { triple } -objdump or objdump"
201+ else :
202+ objdump_error = f"could not locate size executable { triple } -objdump"
203+
204+ if target .arch .startswith ("armv" ):
205+ qemu_arch = "arm"
206+ else :
207+ qemu_arch = QEMU_NAME_MAP .get (target .arch , target .arch )
208+ qemu_exe = f"qemu-{ qemu_arch } -static"
209+ qemu_error = f"could not locate qemu executable { qemu_exe } "
210+ if shutil .which (qemu_exe ) is None :
211+ qemu_exe = None
212+
213+ return {
214+ "compiler" : compiler_exe ,
215+ "objdump" : objdump_exe ,
216+ "size" : size_exe ,
217+ "triple" : triple ,
218+ "qemu" : qemu_exe ,
219+ "compiler_error" : compiler_error ,
220+ "size_error" : size_error ,
221+ "objdump_error" : objdump_error ,
222+ "qemu_error" : qemu_error
223+ }
224+
225+
226+ def toolchain (target , exit_on_failure = True ):
134227 # basic CFLAGS setup
135228 c_flags = f"-I{ ROOT } /include"
136229 if "-O" not in target .cflags :
@@ -147,21 +240,10 @@ def toolchain(target):
147240 c_flags += " " + target .cflags .strip ()
148241 c_flags = c_flags .strip ()
149242
150- compiler_exe = target .compiler
151-
152- # construct triple needed in gcc and objdump executable name
153- triple_abi = "gnu"
154- triple_arch = target .arch
155- if target .arch == "x86" :
156- triple_arch = "i686"
157- elif target .isa == "aarch64" :
158- triple_arch = "aarch64"
159- elif target .arch .startswith ("armv" ):
160- triple_arch = "arm"
161- triple_abi = "gnueabi"
162- if target .arch in ["mips64" , "mips64el" ]:
163- triple_abi = "gnuabi64"
164- triple = f"{ triple_arch } -linux-{ triple_abi } "
243+ if args .memsan :
244+ c_flags += " " + MEMSAN_CFLAGS
245+ elif args .asan :
246+ c_flags += " " + ASAN_CFLAGS
165247
166248 if target .compiler == "armclang" :
167249 if target .isa == "thumb1" :
@@ -174,24 +256,13 @@ def toolchain(target):
174256 elif target .isa == "aarch64" :
175257 c_flags += " --target=aarch64-arm-none-eabi -mcpu=cortex-a78"
176258 else :
177- error (f"unsupported ISA { target .isa } for armclang" )
259+ if exit_on_failure : error (f"unsupported ISA { target .isa } for armclang" )
178260
179261 elif target .compiler == "gcc" :
180262 if not target .is_native :
181263 # see https://gcc.gnu.org/onlinedocs/gcc/ARM-Options.html
182- if "-march" in c_flags or "-mcpu" in c_flags :
183- # user-specified arch/isa/cpu
184- triple = "aarch64-linux-gnu"
185- for v in range (1 ,7 ):
186- if f"-march=armv{ v } " in c_flags : triple = "arm-linux-gnueabi"
187- if "-mthumb" in c_flags : triple = "arm-linux-gnueabi"
188- m = re .search (r"-mcpu=cortex-(\S+)" , c_flags )
189- if m :
190- v = m .group (1 )
191- if (v [0 ] == 'a' and int (v [1 :]) < 34 ): triple = "arm-linux-gnueabi"
192- if (v [0 ] == 'm' ): triple = "arm-linux-gnueabi"
193- if "-mcpu=arm" in c_flags : triple = "arm-linux-gnueabi"
194- else :
264+ if not ("-march" in c_flags or "-mcpu" in c_flags ):
265+ # not user-specified arch/isa/cpu
195266 if target .arch == "armv5" and target .isa == "thumb1" :
196267 c_flags += " -mcpu=arm926ej-s -mthumb"
197268 elif target .arch == "armv5" and target .isa == "arm" :
@@ -217,13 +288,6 @@ def toolchain(target):
217288 if target .arch == "x86_64" :
218289 # Support AESNI intrinsics
219290 c_flags += " -mpclmul -msse2 -maes"
220- # search for compiler exe (highest version available)
221- compiler_exe = f"{ triple } -gcc"
222- for i in range (25 , 1 , - 1 ):
223- if shutil .which (compiler_exe ) is not None : break
224- compiler_exe = f"{ triple } -gcc-{ i } "
225- else :
226- error (f"could not locate gcc executable { triple } -gcc or { triple } -gcc-<majorversion>" )
227291
228292 elif target .compiler == "clang" :
229293 if not target .is_native :
@@ -257,44 +321,20 @@ def toolchain(target):
257321 else :
258322 error (f"unsupported target { target .arch } { target .isa } for clang" )
259323
260- if args .memsan :
261- c_flags += " " + MEMSAN_CFLAGS
262- ld_flags = target .ldflags
263- elif args .asan :
264- c_flags += " " + ASAN_CFLAGS
265- ld_flags = target .ldflags + " " + ASAN_LDFLAGS
266- else :
267- ld_flags = target .ldflags
268-
324+ ld_flags = target .ldflags
325+ if args .asan :
326+ ld_flags += " " + ASAN_LDFLAGS
269327 if not target .is_native :
270328 ld_flags += " --static"
271329
272- # non-arch-specific size should work in all cases, but may as well prefer <triple>-size
273- size_exe = triple + "-size"
274- if args .size :
275- if shutil .which (size_exe ) is None :
276- size_exe = "size"
277- if shutil .which (size_exe ) is None :
278- error (f"could not locate size executable { triple } -size or size" )
279-
280- # we need an architecture-specific obj-dump for disassembly (unless it's a native build)
281- objdump_exe = triple + "-objdump"
282- if args .disassemble and shutil .which (objdump_exe ) is None :
283- if target .is_native :
284- objdump_exe = "objdump"
285- if shutil .which (objdump_exe ) is None :
286- error (f"could not locate objdump executable { objdump_exe } " )
287-
288- # check for compiler exe
289- if shutil .which (compiler_exe ) is None :
290- error (f"could not locate compiler executable { compiler_exe } " )
330+ exes = toolchain_exes (target )
291331
292332 return {
293333 "CFLAGS" : c_flags .strip (),
294334 "LDFLAGS" : ld_flags .strip (),
295- "CC" : compiler_exe ,
296- "OBJDUMP" : objdump_exe ,
297- "SIZE" : size_exe
335+ "CC" : exes [ "compiler" ] ,
336+ "OBJDUMP" : exes [ "objdump" ] ,
337+ "SIZE" : exes [ "size" ]
298338 }
299339
300340
@@ -373,6 +413,10 @@ def flags_to_hr_str(flags):
373413 return hrs .strip ()
374414
375415
416+ def can_disassemble (target ):
417+ return toolchain_exes (target )["objdump" ] is not None
418+
419+
376420def disassemble (target ):
377421 # note: clang seems to want "-gdwarf-4" passed to CFLAGS to show source with --source properly
378422 # run objdump -d to disassemble
@@ -401,6 +445,10 @@ def disassemble(target):
401445 return "\n " .join (diss )
402446
403447
448+ def can_build (target ):
449+ return toolchain_exes (target )["compiler" ] is not None
450+
451+
404452def build (target , tests ):
405453 log ("building" )
406454 try :
@@ -438,6 +486,10 @@ def build(target, tests):
438486 log (indent_adjust = - 4 )
439487
440488
489+ def can_size (target ):
490+ return toolchain_exes (target )["size" ] is not None
491+
492+
441493def size (target ):
442494 log ("size" )
443495 try :
@@ -465,6 +517,13 @@ def size(target):
465517 log (indent_adjust = - 4 )
466518
467519
520+ def can_run (target ):
521+ if target .is_native :
522+ return True
523+ else :
524+ return toolchain_exes (target )["qemu" ] is not None
525+
526+
468527def run (target , tests , quiet = False ):
469528 if target .baremetal or not tests : return
470529
@@ -476,11 +535,8 @@ def run(target, tests, quiet=False):
476535 if target .is_native :
477536 output , _ = subrun (f"{ TEST_DIR } /" + t , test_dir = True , silent = quiet )
478537 else :
479- if target .arch .startswith ("armv" ):
480- qemu_arch = "arm"
481- else :
482- qemu_arch = QEMU_NAME_MAP .get (target .arch , target .arch )
483- output , _ = subrun ([f"qemu-{ qemu_arch } -static" , t ], test_dir = True , silent = quiet )
538+ qemu_exe = toolchain_exes (target )["qemu" ]
539+ output , _ = subrun ([qemu_exe , t ], test_dir = True , silent = quiet )
484540 if quiet and output :
485541 log (output .splitlines ()[- 1 ])
486542 finally :
@@ -526,15 +582,15 @@ mtest -k alignment
526582
527583Report library size, as built by armclang -Oz with TF-M configuration for armv8 thumb2:
528584mtest -S
529- mtest -S clang # as above, but use clang instead of the default armclang
585+ mtest -S clang # as above, but use clang instead of the default armclang
530586
531587Build aes.o multiple times, with every combination of the given options:
532588mtest aes.o MBEDTLS_AES_SETKEY_ENC_ALT,MBEDTLS_AES_DECRYPT_ALT,MBEDTLS_AES_ROM_TABLES,MBEDTLS_AES_ENCRYPT_ALT,MBEDTLS_AES_SETKEY_DEC_ALT,MBEDTLS_AES_FEWER_TABLES,MBEDTLS_PADLOCK_C
533589
534590Disassemble cmac.o
535591mtest cmac.o -d
536592
537- Disassemble mbedtls_xor, built with clang -Os for arm
593+ Disassemble mbedtls_xor for arm , built with clang -Os
538594mtest -d mbedtls_xor -Os clang arm
539595'''
540596
@@ -770,16 +826,30 @@ def main():
770826 try :
771827 log (indent_adjust = 4 )
772828 backup_config_options (restore = True , delete_backup = False )
773- build (target , args .tests )
829+ if can_build (target ):
830+ build (target , args .tests )
831+ else :
832+ log ("skipping target: " + toolchain_exes (target )["compiler_error" ])
833+ continue
774834 if args .size :
775- size (target )
776- if (args .disassemble ):
777- d = disassemble (target )
778- log (f"Disassembly for { args .disassemble } :" )
779- print (d )
780- print ()
781- run (target , args .tests , quiet = quiet )
782- first = False
835+ if can_size (target ):
836+ size (target )
837+ else :
838+ log ("skipping size: " + toolchain_exes (target )["size_error" ])
839+ if args .disassemble :
840+ if can_disassemble (target ):
841+ d = disassemble (target )
842+ distgt = '' if args .disassemble == True else ' for ' + args .disassemble
843+ log (f"Disassembly{ distgt } :" )
844+ print (d )
845+ print ()
846+ else :
847+ log ("skipping disassemble: " + toolchain_exes (target )["objdump_error" ])
848+ if args .tests :
849+ if can_run (target ):
850+ run (target , args .tests , quiet = quiet )
851+ else :
852+ log ("skipping running tests: " + toolchain_exes (target )["qemu_error" ])
783853 finally :
784854 log (indent_adjust = - 4 )
785855 finally :
0 commit comments