Skip to content

Commit 3b33f7e

Browse files
committed
🔨 Build script improvements
1 parent b94c75b commit 3b33f7e

File tree

4 files changed

+68
-39
lines changed

4 files changed

+68
-39
lines changed

buildroot/share/PlatformIO/scripts/configuration.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ def disable_all_options():
110110
match = regex.match(line)
111111
if match:
112112
name = match[3].upper()
113-
if name in ('CONFIGURATION_H_VERSION', 'CONFIGURATION_ADV_H_VERSION'): continue
113+
if name in ('CONFIGURATION_H_VERSION', 'CONFIGURATION_ADV_H_VERSION', 'CONFIG_EXAMPLES_DIR'): continue
114114
if name.startswith('_'): continue
115115
found = True
116116
# Comment out the define

buildroot/share/PlatformIO/scripts/schema.py

+19-8
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ def load_boards():
8080
return ''
8181

8282
#
83-
# Extract the current configuration files in the form of a structured schema.
83+
# Extract the specified configuration files in the form of a structured schema.
8484
# Contains the full schema for the configuration files, not just the enabled options,
8585
# Contains the current values of the options, not just data structure, so "schema" is a slight misnomer.
8686
#
@@ -99,9 +99,9 @@ def load_boards():
9999
# - requires = The conditions that must be met for the define to be enabled
100100
# - comment = The comment for the define, if it has one
101101
# - units = The units for the define, if it has one
102-
# - options = The options for the define, if it has one
102+
# - options = The options for the define, if it has any
103103
#
104-
def extract():
104+
def extract_files(filekey):
105105
# Load board names from boards.h
106106
boards = load_boards()
107107

@@ -114,10 +114,8 @@ class Parse:
114114
GET_SENSORS = 4 # Gathering temperature sensor options
115115
ERROR = 9 # Syntax error
116116

117-
# List of files to process, with shorthand
118-
filekey = { 'Configuration.h':'basic', 'Configuration_adv.h':'advanced' }
119117
# A JSON object to store the data
120-
sch_out = { 'basic':{}, 'advanced':{} }
118+
sch_out = { key:{} for key in filekey.values() }
121119
# Regex for #define NAME [VALUE] [COMMENT] with sanitized line
122120
defgrep = re.compile(r'^(//)?\s*(#define)\s+([A-Za-z0-9_]+)\s*(.*?)\s*(//.+)?$')
123121
# Pattern to match a float value
@@ -180,6 +178,12 @@ class Parse:
180178
cfield = 'notes' if 'comment' in last_added_ref else 'comment'
181179
last_added_ref[cfield] = cline
182180

181+
#
182+
# Add the given comment line to the comment buffer, unless:
183+
# - The line starts with ':' and JSON values to assign to 'opt'.
184+
# - The line starts with '@section' so a new section needs to be returned.
185+
# - The line starts with '======' so just skip it.
186+
#
183187
def use_comment(c, opt, sec, bufref):
184188
if c.startswith(':'): # If the comment starts with : then it has magic JSON
185189
d = c[1:].strip() # Strip the leading :
@@ -199,7 +203,7 @@ def use_comment(c, opt, sec, bufref):
199203
# The comment will be applied to the next #define.
200204
if state == Parse.SLASH_COMMENT:
201205
if not defmatch and the_line.startswith('//'):
202-
use_comment(the_line[2:].strip(), options_json, section, comment_buff)
206+
options_json, section = use_comment(the_line[2:].strip(), options_json, section, comment_buff)
203207
continue
204208
else:
205209
state = Parse.NORMAL
@@ -219,7 +223,7 @@ def use_comment(c, opt, sec, bufref):
219223

220224
state = Parse.NORMAL
221225

222-
# Strip the leading '*' from block comments
226+
# Strip the leading '* ' from block comments
223227
cline = re.sub(r'^\* ?', '', cline)
224228

225229
# Collect temperature sensors
@@ -412,6 +416,13 @@ def atomize(s):
412416

413417
return sch_out
414418

419+
#
420+
# Extract the current configuration files in the form of a structured schema.
421+
#
422+
def extract():
423+
# List of files to process, with shorthand
424+
return extract_files({ 'Configuration.h':'basic', 'Configuration_adv.h':'advanced' })
425+
415426
def dump_json(schema:dict, jpath:Path):
416427
with jpath.open('w') as jfile:
417428
json.dump(schema, jfile, ensure_ascii=False, indent=2)

buildroot/share/PlatformIO/scripts/signature.py

+47-29
Original file line numberDiff line numberDiff line change
@@ -35,18 +35,27 @@ def enabled_defines(filepath):
3535
'''
3636
outdict = {}
3737
section = "user"
38-
spatt = re.compile(r".*@section +([-a-zA-Z0-9_\s]+)$") # must match @section ...
38+
spatt = re.compile(r".*@section +([-a-zA-Z0-9_\s]+)$") # @section ...
3939

4040
f = open(filepath, encoding="utf8").read().split("\n")
4141

42-
# Get the full contents of the file and remove all block comments.
43-
# This will avoid false positives from #defines in comments
44-
f = re.sub(r'/\*.*?\*/', '', '\n'.join(f), flags=re.DOTALL).split("\n")
45-
42+
incomment = False
4643
for line in f:
4744
sline = line.strip()
45+
4846
m = re.match(spatt, sline) # @section ...
4947
if m: section = m.group(1).strip() ; continue
48+
49+
if incomment:
50+
if '*/' in sline:
51+
incomment = False
52+
continue
53+
else:
54+
mpos, spos = sline.find('/*'), sline.find('//')
55+
if mpos >= 0 and (spos < 0 or spos > mpos):
56+
incomment = True
57+
continue
58+
5059
if sline[:7] == "#define":
5160
# Extract the key here (we don't care about the value)
5261
kv = sline[8:].strip().split()
@@ -70,6 +79,11 @@ def compress_file(filepath, storedname, outpath):
7079
with zipfile.ZipFile(outpath, 'w', compression=zipfile.ZIP_BZIP2, compresslevel=9) as zipf:
7180
zipf.write(filepath, arcname=storedname, compress_type=zipfile.ZIP_BZIP2, compresslevel=9)
7281

82+
ignore = ('CONFIGURATION_H_VERSION', 'CONFIGURATION_ADV_H_VERSION', 'CONFIG_EXAMPLES_DIR', 'CONFIG_EXPORT')
83+
84+
#
85+
# Compute a build signature and/or export the configuration
86+
#
7387
def compute_build_signature(env):
7488
'''
7589
Compute the build signature by extracting all configuration settings and
@@ -81,11 +95,17 @@ def compute_build_signature(env):
8195
env.Append(BUILD_SIGNATURE=1)
8296

8397
build_path = Path(env['PROJECT_BUILD_DIR'], env['PIOENV'])
84-
marlin_json = build_path / 'marlin_config.json'
98+
json_name = 'marlin_config.json'
99+
marlin_json = build_path / json_name
85100
marlin_zip = build_path / 'mc.zip'
86101

102+
# ANSI colors
103+
green = "\u001b[32m"
104+
yellow = "\u001b[33m"
105+
red = "\u001b[31m"
106+
87107
# Definitions from these files will be kept
88-
header_paths = [ 'Marlin/Configuration.h', 'Marlin/Configuration_adv.h' ]
108+
header_paths = ('Marlin/Configuration.h', 'Marlin/Configuration_adv.h')
89109

90110
# Check if we can skip processing
91111
hashes = ''
@@ -100,7 +120,7 @@ def compute_build_signature(env):
100120
conf = json.load(infile)
101121
same_hash = conf['__INITIAL_HASH'] == hashes
102122
if same_hash:
103-
compress_file(marlin_json, 'marlin_config.json', marlin_zip)
123+
compress_file(marlin_json, json_name, marlin_zip)
104124
except:
105125
pass
106126

@@ -179,25 +199,28 @@ def tryint(key):
179199
extended_dump = config_dump > 100
180200
if extended_dump: config_dump -= 100
181201

202+
# Get the schema class for exports that require it
203+
if config_dump in (3, 4) or (extended_dump and config_dump in (2, 5)):
204+
try:
205+
conf_schema = schema.extract()
206+
except Exception as exc:
207+
print(red + "Error: " + str(exc))
208+
conf_schema = None
209+
182210
#
183211
# Produce an INI file if CONFIG_EXPORT == 2
184212
#
185213
if config_dump == 2:
186-
print("Generating config.ini ...")
214+
print(yellow + "Generating config.ini ...")
187215

188216
ini_fmt = '{0:40} = {1}'
189217
ext_fmt = '{0:40} {1}'
190-
ignore = ('CONFIGURATION_H_VERSION', 'CONFIGURATION_ADV_H_VERSION', 'CONFIG_EXAMPLES_DIR', 'CONFIG_EXPORT')
191218

192219
if extended_dump:
193220
# Extended export will dump config options by section
194221

195222
# We'll use Schema class to get the sections
196-
try:
197-
conf_schema = schema.extract()
198-
except Exception as exc:
199-
print("Error: " + str(exc))
200-
exit(1)
223+
if not conf_schema: exit(1)
201224

202225
# Then group options by schema @section
203226
sections = {}
@@ -305,27 +328,22 @@ def tryint(key):
305328
for header in real_config:
306329
outfile.write(f'\n[{filegrp[header]}]\n')
307330
for name in sorted(real_config[header]):
308-
if name not in ignore:
309-
val = real_config[header][name]['value']
310-
if val == '': val = 'on'
311-
outfile.write(ini_fmt.format(name.lower(), val) + '\n')
331+
if name in ignore: continue
332+
val = real_config[header][name]['value']
333+
if val == '': val = 'on'
334+
outfile.write(ini_fmt.format(name.lower(), val) + '\n')
312335

313336
#
314337
# CONFIG_EXPORT 3 = schema.json, 4 = schema.yml
315338
#
316-
if config_dump >= 3:
317-
try:
318-
conf_schema = schema.extract()
319-
except Exception as exc:
320-
print("Error: " + str(exc))
321-
conf_schema = None
339+
if config_dump in (3, 4):
322340

323341
if conf_schema:
324342
#
325343
# 3 = schema.json
326344
#
327345
if config_dump in (3, 13):
328-
print("Generating schema.json ...")
346+
print(yellow + "Generating schema.json ...")
329347
schema.dump_json(conf_schema, build_path / 'schema.json')
330348
if config_dump == 13:
331349
schema.group_options(conf_schema)
@@ -335,7 +353,7 @@ def tryint(key):
335353
# 4 = schema.yml
336354
#
337355
elif config_dump == 4:
338-
print("Generating schema.yml ...")
356+
print(yellow + "Generating schema.yml ...")
339357
try:
340358
import yaml
341359
except ImportError:
@@ -355,7 +373,7 @@ def tryint(key):
355373

356374
json_data = {}
357375
if extended_dump:
358-
print("Extended dump ...")
376+
print(yellow + "Extended dump ...")
359377
for header in real_config:
360378
confs = real_config[header]
361379
json_data[header] = {}
@@ -395,7 +413,7 @@ def tryint(key):
395413

396414
# Compress the JSON file as much as we can
397415
if not same_hash:
398-
compress_file(marlin_json, 'marlin_config.json', marlin_zip)
416+
compress_file(marlin_json, json_name, marlin_zip)
399417

400418
# Generate a C source file containing the entire ZIP file as an array
401419
with open('Marlin/src/mczip.h','wb') as result_file:

buildroot/share/extras/file_header.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/**
22
* Marlin 3D Printer Firmware
3-
* Copyright (c) 2023 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
3+
* Copyright (c) 2024 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
44
*
55
* Based on Sprinter and grbl.
66
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm

0 commit comments

Comments
 (0)