1
1
#!/usr/bin/env python3
2
2
3
3
# This script manages the use of a file with a unique name, like
4
- # `SketchName .ino.globals.h`, in the Sketch source directory to provide compiler
4
+ # `Sketch .ino.globals.h`, in the Sketch source directory to provide compiler
5
5
# command-line options (build options) and sketch global defines. The build
6
6
# option data is encapsulated in a unique "C" comment block and extracted into
7
7
# the build tree during prebuild.
31
31
"""
32
32
Operation
33
33
34
- "SketchName .ino.globals.h" - A global h file in the Source Sketch directory. The
35
- string SketchName is the actual name of the sketch. A matching copy is kept in
36
- the build path/core directory. The file is empty when it does not exist in the
37
- source directory.
34
+ "Sketch .ino.globals.h" - A global h file in the Source Sketch directory. The
35
+ string Sketch.ino is the actual name of the sketch program . A matching copy is
36
+ kept in the build path/core directory. The file is empty when it does not exist
37
+ in the source directory.
38
38
39
- Using SketchName .ino.globals.h as a container to hold build.opt, gives implicit
40
- dependency tracking for build.opt by way of SketchName .ino.globals.h's
39
+ Using Sketch .ino.globals.h as a container to hold build.opt, gives implicit
40
+ dependency tracking for build.opt by way of Sketch .ino.globals.h's
41
41
dependencies.
42
42
Example:
43
43
gcc ... @{build.path}/core/build.opt -include "{build.path}/core/{build.project_name}.globals.h" ...
48
48
49
49
At each build cycle, "{build.project_name}.globals.h" is conditoinally copied to
50
50
"{build.path}/core/" at prebuild, and build.opt is extraction as needed. The
51
- SketchName .ino.globals.h's dependencies will trigger "rebuild all" as needed.
51
+ Sketch .ino.globals.h's dependencies will trigger "rebuild all" as needed.
52
52
53
- If SketchName .ino.globals.h is not in the source sketch folder, an empty
53
+ If Sketch .ino.globals.h is not in the source sketch folder, an empty
54
54
versions is created in the build tree. The file build.opt always contains a
55
55
"-include ..." entry so that file dependencies are generated for
56
- SketchName .ino.globals.h. This allows for change detection when the file is
56
+ Sketch .ino.globals.h. This allows for change detection when the file is
57
57
added.
58
58
"""
59
59
136
136
issues when replacing files by renaming and rebuilding.
137
137
138
138
A good example of this problem is when you correct the spelling of file
139
- SketchName .ino.globals.h. You need to touch (update time stampt) the file so a
139
+ Sketch .ino.globals.h. You need to touch (update time stampt) the file so a
140
140
rebuild all is performed.
141
141
142
- 3) During the build two identical copies of SketchName .ino.globals.h will exist.
143
- #ifndef fencing will be needed for non comment blocks in SketchName .ino.globals.h.
142
+ 3) During the build two identical copies of Sketch .ino.globals.h will exist.
143
+ #ifndef fencing will be needed for non comment blocks in Sketch .ino.globals.h.
144
144
145
145
4) By using a .h file to encapsulate "build.opt" options, the information is not
146
146
lost after a save-as. Before with an individual "build.opt" file, the file was
@@ -249,9 +249,9 @@ def add_include_line(build_opt_fqfn, include_fqfn):
249
249
250
250
def extract_create_build_opt_file (globals_h_fqfn , file_name , build_opt_fqfn ):
251
251
"""
252
- Extract the embedded build.opt from SketchName .ino.globals.h into build
252
+ Extract the embedded build.opt from Sketch .ino.globals.h into build
253
253
path/core/build.opt. The subdirectory path must already exist as well as the
254
- copy of SketchName .ino.globals.h.
254
+ copy of Sketch .ino.globals.h.
255
255
"""
256
256
global build_opt_signature
257
257
@@ -263,7 +263,7 @@ def extract_create_build_opt_file(globals_h_fqfn, file_name, build_opt_fqfn):
263
263
complete_comment = False
264
264
build_opt_error = False
265
265
line_no = 0
266
- # If the source sketch did not have the file SketchName .ino.globals.h, an empty
266
+ # If the source sketch did not have the file Sketch .ino.globals.h, an empty
267
267
# file was created in the ./core/ folder.
268
268
# By using the copy, open will always succeed.
269
269
with open (globals_h_fqfn , 'r' ) as src :
@@ -329,35 +329,53 @@ def enable_override(enable, commonhfile_fqfn):
329
329
# enabled when getsize(commonhfile_fqfn) is non-zero, disabled when zero
330
330
331
331
332
- def find_preferences_txt ():
332
+ def find_preferences_txt (runtime_ide_path ):
333
333
platform_name = platform .system ()
334
- # OS Path list from:
335
- # https://www.arduino.cc/en/hacking/preferences
334
+ # OS Path list for Arduino IDE 1.6.0 and newer
335
+ # from: https://www.arduino.cc/en/hacking/preferences
336
336
if "Linux" == platform_name :
337
337
# Test for portable 1ST
338
338
# <Arduino IDE installation folder>/portable/preferences.txt (when used in portable mode)
339
339
# For more on portable mode see https://docs.arduino.cc/software/ide-v1/tutorials/PortableIDE
340
- # Working directory must be set to the location of the Arduino IDE executable.
341
- fqfn = "./portable/preferences.txt" # Linux portable - verified
340
+ fqfn = os . path . normpath ( runtime_ide_path + "/portable/preferences.txt" )
341
+ # Linux - verified with Arduino IDE 1.8.19
342
342
if os .path .exists (fqfn ):
343
343
return fqfn
344
- fqfn = os .path .expanduser ("~/.arduino15/preferences.txt" ) # Linux - verified
344
+ fqfn = os .path .expanduser ("~/.arduino15/preferences.txt" )
345
+ # Linux - verified with Arduino IDE 1.8.18 and 2.0 RC5 64bit and AppImage
345
346
if os .path .exists (fqfn ):
346
347
return fqfn
347
348
elif "Windows" == platform_name :
348
- fqfn = ".\portable\preferences.txt"
349
+ fqfn = os .path .normpath (runtime_ide_path + "\portable\preferences.txt" )
350
+ # verified on Windows 10 with Arduino IDE 1.8.19
349
351
if os .path .exists (fqfn ):
350
352
return fqfn
351
- fqfn = os .path .expanduser ("~\Documents\ArduinoData\preferences.txt" ) # Windows app version - verified
353
+ # It is never simple. Arduino from the Windows APP store or the download
354
+ # Windows 8 and up option will save "preferences.txt" in one location.
355
+ # The downloaded Windows 7 (and up version) will put "preferences.txt"
356
+ # in a different location. When both are present due to various possible
357
+ # scenarios, use the more modern.
358
+ # Note, I am ignoring any permutations you might get into with storing
359
+ # and running applications off Network servers.
360
+ fqfn = os .path .expanduser ("~\Documents\ArduinoData\preferences.txt" )
361
+ # Path for "Windows app" - verified on Windows 10 with Arduino IDE 1.8.19
362
+ fqfn2 = os .path .expanduser ("~\AppData\local\Arduino15\preferences.txt" )
363
+ # Path for Windows 7 and up - verified on Windows 10 with Arduino IDE 1.8.19
352
364
if os .path .exists (fqfn ):
353
- return fqfn
354
- fqfn = os .path .expanduser ("~\Arduino15\preferences.txt" ) # Windows
355
- if os .path .exists (fqfn ):
356
- return fqfn
365
+ if os .path .exists (fqfn2 ):
366
+ print_err ("Multiple 'preferences.txt' files found:" )
367
+ print_err (" " + fqfn )
368
+ print_err (" " + fqfn2 )
369
+ return fqfn
370
+ else :
371
+ return fqfn
372
+ elif os .path .exists (fqfn2 ):
373
+ return fqfn2
357
374
elif "Darwin" == platform_name :
358
- # Skip portable on Macs. Portable is not compatable with Macs
375
+ # Portable is not compatable with Mac OS X
359
376
# see https://docs.arduino.cc/software/ide-v1/tutorials/PortableIDE
360
- fqfn = os .path .expanduser ("~/Library/Arduino15/preferences.txt" ) # Max OS X
377
+ fqfn = os .path .expanduser ("~/Library/Arduino15/preferences.txt" )
378
+ # Mac OS X - unverified
361
379
if os .path .exists (fqfn ):
362
380
return fqfn
363
381
@@ -378,8 +396,8 @@ def get_preferences_txt(file_fqfn, key):
378
396
return True # If we don't find it just assume it is set True
379
397
380
398
381
- def check_preferences_txt ():
382
- file_fqfn = find_preferences_txt ()
399
+ def check_preferences_txt (runtime_ide_path ):
400
+ file_fqfn = find_preferences_txt (runtime_ide_path )
383
401
if file_fqfn == "" :
384
402
return True # cannot find file assume enabled
385
403
print_msg ("Using preferences from " + file_fqfn )
@@ -403,16 +421,17 @@ def main():
403
421
global build_opt_signature
404
422
global docs_url
405
423
num_include_lines = 1
406
- use_aggressive_caching_workaround = check_preferences_txt ()
407
424
408
- if len (sys .argv ) >= 5 :
425
+ if len (sys .argv ) >= 6 :
409
426
source_globals_h_fqfn = os .path .normpath (sys .argv [1 ])
410
427
globals_name = os .path .basename (source_globals_h_fqfn )
411
428
globals_h_fqfn = os .path .normpath (sys .argv [2 ])
412
429
build_path = os .path .dirname (globals_h_fqfn )
413
430
# Assumption: globals_h_fqfn and build_opt_fqfn have the same dirname
414
431
build_opt_fqfn = os .path .normpath (sys .argv [3 ])
415
432
commonhfile_fqfn = os .path .normpath (sys .argv [4 ])
433
+ runtime_ide_path = os .path .normpath (sys .argv [5 ])
434
+ use_aggressive_caching_workaround = check_preferences_txt (runtime_ide_path )
416
435
417
436
if os .path .exists (commonhfile_fqfn ):
418
437
if os .path .getsize (commonhfile_fqfn ) and \
@@ -488,7 +507,7 @@ def main():
488
507
489
508
else :
490
509
print_err ("Too few arguments. Add arguments:" )
491
- print_err (" Source FQFN SketchName .ino.globals.h, Build FQFN SketchName .ino.globals.h, Build FQFN build.opt" )
510
+ print_err (" Source FQFN Sketch .ino.globals.h, Build FQFN Sketch .ino.globals.h, Build FQFN build.opt" )
492
511
493
512
if __name__ == '__main__' :
494
513
sys .exit (main ())
0 commit comments