4
4
from datetime import timedelta
5
5
import json
6
6
import os
7
+ from packaging import version
7
8
import re
8
9
import shutil
9
10
import subprocess
52
53
arch = arch_default
53
54
arduino_platform = arduino_platform_default
54
55
arduino_cli = ""
56
+ arduino_cli_default_version = "0.10.0"
57
+ arduino_cli_version = arduino_cli_default_version
55
58
56
59
# List
57
60
sketch_list = []
@@ -117,9 +120,8 @@ def create_output_log_tree():
117
120
file .write (build_separator + "\n " )
118
121
# Folders
119
122
for board in board_fqbn :
123
+ createFolder (os .path .join (output_dir , board , bin_dir ))
120
124
createFolder (os .path .join (output_dir , board ))
121
- if args .bin :
122
- createFolder (os .path .join (output_dir , board , bin_dir ))
123
125
createFolder (os .path .join (build_output_dir , board ))
124
126
125
127
@@ -152,6 +154,7 @@ def create_config():
152
154
153
155
def check_config ():
154
156
global arduino_cli
157
+ global arduino_cli_version
155
158
global arduino_cli_path
156
159
global sketches_path_list
157
160
global build_output_dir
@@ -193,37 +196,66 @@ def check_config():
193
196
else :
194
197
arduino_cli = "arduino-cli"
195
198
199
+ try :
200
+ output = subprocess .check_output (
201
+ [arduino_cli , "version" ], stderr = subprocess .DEVNULL ,
202
+ )
203
+ except subprocess .CalledProcessError as e :
204
+ print ('"' + " " .join (e .cmd ) + '" failed with code: {}!' .format (e .returncode ))
205
+ print (e .stdout )
206
+ quit (e .returncode )
207
+ else :
208
+ res = re .match (r".*Version:\s+(\d+\.\d+\.\d+).*" , output .decode ("utf-8" ))
209
+ if res :
210
+ arduino_cli_version = res .group (1 )
211
+ print ("Arduino CLI version used: " + arduino_cli_version )
212
+ else :
213
+ print (
214
+ "Unable to define Arduino CLI version, use default: "
215
+ + arduino_cli_default_version
216
+ )
217
+
196
218
try :
197
219
output = subprocess .check_output (
198
220
[arduino_cli , "core" , "search" , "stm32" , "--additional-urls" , stm32_url ],
199
221
stderr = subprocess .DEVNULL ,
200
222
)
223
+ except subprocess .CalledProcessError as e :
224
+ print ('"' + " " .join (e .cmd ) + '" failed with code: {}!' .format (e .returncode ))
225
+ print (e .stdout )
226
+ quit (e .returncode )
227
+ else :
201
228
if arduino_platform not in output .decode ("utf-8" ):
202
- raise subprocess .CalledProcessError (1 , "re" )
229
+ print (arduino_platform + " is not installed!" )
230
+ quit (1 )
203
231
# Add core and library path to sketches_path_list
204
232
try :
205
233
output = subprocess .check_output (
206
234
[arduino_cli , "config" , "dump" , "--format" , "json" ],
207
235
stderr = subprocess .DEVNULL ,
208
236
).decode ("utf-8" )
237
+ except subprocess .CalledProcessError as e :
238
+ print (
239
+ '"' + " " .join (e .cmd ) + '" failed with code: {}!' .format (e .returncode )
240
+ )
241
+ print (e .stdout )
242
+ quit (e .returncode )
243
+ else :
209
244
cli_config = json .loads (output )
210
245
if cli_config is not None :
211
246
if cli_config ["directories" ]["data" ] is not None :
212
247
sketches_path_list .append (cli_config ["directories" ]["data" ])
213
248
else :
214
- raise subprocess .CalledProcessError (3 , "No data directory" )
249
+ print ("No data directory" )
250
+ quit (1 )
215
251
if cli_config ["directories" ]["user" ] is not None :
216
252
sketches_path_list .append (cli_config ["directories" ]["user" ])
217
253
else :
218
- raise subprocess .CalledProcessError (2 , "No user directory" )
254
+ print ("No user directory!" )
255
+ quit (1 )
219
256
else :
220
- raise subprocess .CalledProcessError (1 , "No fqbn" )
221
- except subprocess .CalledProcessError :
222
- print ("No arduino-cli config!" )
223
- quit ()
224
- except subprocess .CalledProcessError :
225
- print (arduino_platform + " is not installed!" )
226
- quit ()
257
+ print ("No arduino-cli config!" )
258
+ quit (1 )
227
259
228
260
229
261
def load_core_config ():
@@ -366,7 +398,7 @@ def manage_inos():
366
398
break
367
399
else :
368
400
print ("Sketch {} path does not exist!" .format (args .ino ))
369
- quit ()
401
+ quit (1 )
370
402
# Sketches listed in a file
371
403
elif args .file :
372
404
assert os .path .exists (args .file ), "Sketches list file does not exist"
@@ -397,7 +429,7 @@ def manage_inos():
397
429
sketch_list .append (sketch_default )
398
430
if len (sketch_list ) == 0 :
399
431
print ("No sketch to build for " + arduino_platform + "!" )
400
- quit ()
432
+ quit (1 )
401
433
402
434
403
435
# Find all .ino files and save directory
@@ -429,32 +461,41 @@ def find_board():
429
461
try :
430
462
output = subprocess .check_output (
431
463
[arduino_cli , "board" , "listall" , "--format" , "json" ],
432
- stderr = subprocess .DEVNULL ,
464
+ stderr = subprocess .STDOUT ,
433
465
).decode ("utf-8" )
466
+ except subprocess .CalledProcessError as e :
467
+ print ('"' + " " .join (e .cmd ) + '" failed with code: {}!' .format (e .returncode ))
468
+ print (e .stdout )
469
+ quit (e .returncode )
470
+ else :
434
471
boards_list = json .loads (output )
435
472
if boards_list is not None :
436
473
for board in boards_list ["boards" ]:
437
474
if arduino_platform in board ["FQBN" ]:
438
475
fqbn_list_tmp .append (board ["FQBN" ])
439
- if not len (fqbn_list_tmp ):
440
- raise subprocess .CalledProcessError (2 , "No fqbn" )
441
- else :
442
- raise subprocess .CalledProcessError (1 , "No fqbn" )
443
- except subprocess .CalledProcessError :
444
- print ("No fqbn found for " + arduino_platform + "!" )
445
- quit ()
476
+ if not len (fqbn_list_tmp ):
477
+ print ("No boards found for " + arduino_platform )
478
+ quit (1 )
446
479
447
480
# For STM32 core, pnum is requested
448
481
for fqbn in fqbn_list_tmp :
449
482
try :
450
483
output = subprocess .check_output (
451
484
[arduino_cli , "board" , "details" , "--format" , "json" , fqbn ],
452
- stderr = subprocess .DEVNULL ,
485
+ stderr = subprocess .STDOUT ,
453
486
).decode ("utf-8" )
487
+ except subprocess .CalledProcessError as e :
488
+ print (
489
+ '"' + " " .join (e .cmd ) + '" failed with code: {}!' .format (e .returncode )
490
+ )
491
+ print (e .stdout )
492
+ quit (e .returncode )
493
+ else :
454
494
board_detail = json .loads (output )
455
495
if board_detail is not None :
456
496
if "config_options" not in board_detail :
457
- raise subprocess .CalledProcessError (3 , "No config_options" )
497
+ print ("No config_options found for " + fqbn )
498
+ quit (1 )
458
499
for option in board_detail ["config_options" ]:
459
500
if option ["option" ] == "pnum" :
460
501
for value in option ["values" ]:
@@ -466,14 +507,12 @@ def find_board():
466
507
)
467
508
break
468
509
else :
469
- raise subprocess .CalledProcessError (1 , "No fqbn" )
470
- except subprocess .CalledProcessError as e :
471
- print ("No fqbn detail found for " + e .cmd + "!" )
510
+ print ('No detail found for:"' + fqbn + '"!' )
472
511
if board_found :
473
512
board_fqbn = collections .OrderedDict (sorted (board_found .items ()))
474
513
else :
475
514
print ("No board found for " + arduino_platform + "!" )
476
- quit ()
515
+ quit (1 )
477
516
478
517
479
518
# Check the status
@@ -484,14 +523,12 @@ def check_status(status, build_conf, boardKo):
484
523
485
524
if status [1 ] == 0 :
486
525
result = "\033 [32msucceeded\033 [0m"
487
- if args .bin :
488
- bin_copy (build_conf [0 ], sketch_name )
489
526
nb_build_passed += 1
490
527
elif status [1 ] == 1 :
491
528
# Check if failed due to a region overflowed
492
529
logFile = os .path .join (build_conf [3 ], sketch_name + ".log" )
493
530
# error or fatal error
494
- error_pattern = re .compile (r":\d+:\d+:\s.*error:\s" )
531
+ error_pattern = re .compile (r":\d+:\d+:\s.*error:\s|^Error: " )
495
532
ld_pattern = re .compile ("arm-none-eabi/bin/ld:" )
496
533
overflow_pattern = re .compile (
497
534
r"(will not fit in |section .+ is not within )?region( .+ overflowed by [\d]+ bytes)?"
@@ -514,8 +551,6 @@ def check_status(status, build_conf, boardKo):
514
551
else :
515
552
# else consider it succeeded
516
553
result = "\033 [32msucceeded*\033 [0m"
517
- if args .bin :
518
- empty_bin (build_conf [0 ], sketch_name )
519
554
nb_build_passed += 1
520
555
else :
521
556
result = "\033 [31merror\033 [0m"
@@ -645,34 +680,6 @@ def log_final_result():
645
680
print (output_dir )
646
681
647
682
648
- # Create an empty binary
649
- def empty_bin (board_name , sketch_name ):
650
- empty_path = os .path .abspath (os .path .join (output_dir , board_name , bin_dir ))
651
- createFolder (empty_path )
652
- empty_file = os .path .join (
653
- empty_path , sketch_name + "_COULD_NOT_FIT_IN_THIS_BOARD.bin"
654
- )
655
- try :
656
- f = open (empty_file , "w" )
657
- except IOError :
658
- print ("Cannot create empty binary: " , empty_file )
659
- else :
660
- f .close ()
661
-
662
-
663
- # Create a "bin" directory for each board and copy all binary files
664
- # from the builder output directory into it
665
- def bin_copy (board_name , sketch_name ):
666
- try :
667
- shutil .copy (
668
- os .path .join (build_output_dir , board_name , sketch_name + ".bin" ),
669
- os .path .abspath (os .path .join (output_dir , board_name , bin_dir )),
670
- )
671
- except OSError as e :
672
- print ("Cannot copy the binary from the arduino-cli output: " + e .strerror )
673
- raise
674
-
675
-
676
683
# Set up specific options to customise arduino builder command
677
684
def get_fqbn (b_name ):
678
685
if b_name in board_custom_fqbn and board_custom_fqbn [b_name ]:
@@ -696,8 +703,12 @@ def genBasicCommand(b_name):
696
703
cmd .append (build_output_cache_dir )
697
704
if args .verbose :
698
705
cmd .append ("--verbose" )
699
- cmd .append ("-o" )
700
- cmd .append (os .path .join (build_output_dir , b_name , "sketch" ))
706
+ if version .parse (arduino_cli_version ) <= version .parse (arduino_cli_default_version ):
707
+ cmd .append ("--output" )
708
+ cmd .append (os .path .join (output_dir , b_name , bin_dir , "dummy_sketch" ))
709
+ else :
710
+ cmd .append ("--output-dir" )
711
+ cmd .append (os .path .join (output_dir , b_name , bin_dir ))
701
712
cmd .append ("--fqbn" )
702
713
cmd .append (get_fqbn (b_name ))
703
714
cmd .append ("dummy_sketch" )
@@ -727,6 +738,9 @@ def build_config(sketch, boardSkipped):
727
738
728
739
for idx in reversed (range (len (build_conf_list ))):
729
740
build_conf_list [idx ][4 ][- 1 ] = sketch
741
+ build_conf_list [idx ][4 ][- 4 ] = build_conf_list [idx ][4 ][- 4 ].replace (
742
+ "dummy_sketch" , os .path .basename (sketch )
743
+ )
730
744
if na_sketch_pattern :
731
745
if build_conf_list [idx ][0 ] in na_sketch_pattern :
732
746
for pattern in na_sketch_pattern [build_conf_list [idx ][0 ]]:
@@ -865,7 +879,6 @@ def build(build_conf):
865
879
)
866
880
867
881
g1 = parser .add_mutually_exclusive_group ()
868
- g1 .add_argument ("--bin" , help = "save binaries" , action = "store_true" )
869
882
g1 .add_argument ("--ci" , help = "custom configuration for CI build" , action = "store_true" )
870
883
871
884
# Sketch options
0 commit comments