🧑‍💻 Support files updates

This commit is contained in:
Scott Lahteine
2023-12-15 17:37:36 -06:00
parent 5f84e7f43b
commit a18045a96a
53 changed files with 5504 additions and 332 deletions

View File

@@ -9,7 +9,7 @@ if pioutil.is_pio_build():
board = marlin.env.BoardConfig()
def calculate_crc(contents, seed):
accumulating_xor_value = seed;
accumulating_xor_value = seed
for i in range(0, len(contents), 4):
value = struct.unpack('<I', contents[ i : i + 4])[0]
@@ -68,7 +68,7 @@ if pioutil.is_pio_build():
uid_value = uuid.uuid4()
file_key = int(uid_value.hex[0:8], 16)
xor_crc = 0xEF3D4323;
xor_crc = 0xEF3D4323
# the input file is exepcted to be in chunks of 0x800
# so round the size
@@ -123,4 +123,4 @@ if pioutil.is_pio_build():
fwpath.unlink()
marlin.relocate_firmware("0x08008800")
marlin.add_post_action(encrypt);
marlin.add_post_action(encrypt)

View File

@@ -53,10 +53,11 @@ if pioutil.is_pio_build():
# Get a reference to the FEATURE_CONFIG under construction
feat = FEATURE_CONFIG[feature]
# Split up passed lines on commas or newlines and iterate
# Add common options to the features config under construction
# For lib_deps replace a previous instance of the same library
atoms = re.sub(r',\s*', '\n', flines).strip().split('\n')
# Split up passed lines on commas or newlines and iterate.
# Take care to convert Windows '\' paths to Unix-style '/'.
# Add common options to the features config under construction.
# For lib_deps replace a previous instance of the same library.
atoms = re.sub(r',\s*', '\n', flines.replace('\\', '/')).strip().split('\n')
for line in atoms:
parts = line.split('=')
name = parts.pop(0)
@@ -91,7 +92,7 @@ if pioutil.is_pio_build():
val = None
if val:
opt = mat[1].upper()
blab("%s.custom_marlin.%s = '%s'" % ( env['PIOENV'], opt, val ))
blab("%s.custom_marlin.%s = '%s'" % ( env['PIOENV'], opt, val ), 2)
add_to_feat_cnf(opt, val)
def get_all_known_libs():
@@ -213,7 +214,7 @@ if pioutil.is_pio_build():
#
def MarlinHas(env, feature):
load_marlin_features()
r = re.compile('^' + feature + '$')
r = re.compile('^' + feature + '$', re.IGNORECASE)
found = list(filter(r.match, env['MARLIN_FEATURES']))
# Defines could still be 'false' or '0', so check
@@ -226,6 +227,8 @@ if pioutil.is_pio_build():
elif val in env['MARLIN_FEATURES']:
some_on = env.MarlinHas(val)
#blab("%s is %s" % (feature, str(some_on)), 2)
return some_on
validate_pio()

51
buildroot/share/PlatformIO/scripts/configuration.py Normal file → Executable file
View File

@@ -1,8 +1,9 @@
#!/usr/bin/env python3
#
# configuration.py
# Apply options from config.ini to the existing Configuration headers
#
import re, shutil, configparser
import re, shutil, configparser, datetime
from pathlib import Path
verbose = 0
@@ -43,6 +44,7 @@ def apply_opt(name, val, conf=None):
if val in ("on", "", None):
newline = re.sub(r'^(\s*)//+\s*(#define)(\s{1,3})?(\s*)', r'\1\2 \4', line)
elif val == "off":
# TODO: Comment more lines in a multi-line define with \ continuation
newline = re.sub(r'^(\s*)(#define)(\s{1,3})?(\s*)', r'\1//\2 \4', line)
else:
# For options with values, enable and set the value
@@ -88,9 +90,38 @@ def apply_opt(name, val, conf=None):
elif not isdef:
break
linenum += 1
lines.insert(linenum, f"{prefix}#define {added:30} // Added by config.ini\n")
currtime = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
lines.insert(linenum, f"{prefix}#define {added:30} // Added by config.ini {currtime}\n")
fullpath.write_text(''.join(lines), encoding='utf-8')
# Disable all (most) defined options in the configuration files.
# Everything in the named sections. Section hint for exceptions may be added.
def disable_all_options():
# Create a regex to match the option and capture parts of the line
regex = re.compile(r'^(\s*)(#define\s+)([A-Z0-9_]+\b)(\s?)(\s*)(.*?)(\s*)(//.*)?$', re.IGNORECASE)
# Disable all enabled options in both Config files
for file in ("Configuration.h", "Configuration_adv.h"):
fullpath = config_path(file)
lines = fullpath.read_text(encoding='utf-8').split('\n')
found = False
for i in range(len(lines)):
line = lines[i]
match = regex.match(line)
if match:
name = match[3].upper()
if name in ('CONFIGURATION_H_VERSION', 'CONFIGURATION_ADV_H_VERSION'): continue
if name.startswith('_'): continue
found = True
# Comment out the define
# TODO: Comment more lines in a multi-line define with \ continuation
lines[i] = re.sub(r'^(\s*)(#define)(\s{1,3})?(\s*)', r'\1//\2 \4', line)
blab(f"Disable {name}")
# If the option was found, write the modified lines
if found:
fullpath.write_text('\n'.join(lines), encoding='utf-8')
# Fetch configuration files from GitHub given the path.
# Return True if any files were fetched.
def fetch_example(url):
@@ -130,7 +161,7 @@ def fetch_example(url):
def section_items(cp, sectkey):
return cp.items(sectkey) if sectkey in cp.sections() else []
# Apply all items from a config section
# Apply all items from a config section. Ignore ini_ items outside of config:base and config:root.
def apply_ini_by_name(cp, sect):
iniok = True
if sect in ('config:base', 'config:root'):
@@ -194,7 +225,7 @@ def apply_config_ini(cp):
cp2 = configparser.ConfigParser()
cp2.read(config_path(ckey))
apply_sections(cp2, sect)
ckey = 'base';
ckey = 'base'
# (Allow 'example/' as a shortcut for 'examples/')
elif ckey.startswith('example/'):
@@ -206,7 +237,17 @@ def apply_config_ini(cp):
fetch_example(ckey)
ckey = 'base'
if ckey == 'all':
#
# [flatten] Write out Configuration.h and Configuration_adv.h files with
# just the enabled options and all other content removed.
#
#if ckey == '[flatten]':
# write_flat_configs()
if ckey == '[disable]':
disable_all_options()
elif ckey == 'all':
apply_sections(cp)
else:

View File

@@ -14,7 +14,7 @@ if pioutil.is_pio_build():
assets_path = Path(env.Dictionary("PROJECT_BUILD_DIR"), env.Dictionary("PIOENV"), "assets")
def download_mks_assets():
print("Downloading MKS Assets")
print("Downloading MKS Assets for TFT_LVGL_UI")
r = requests.get(url, stream=True)
# the user may have a very clean workspace,
# so create the PROJECT_LIBDEPS_DIR directory if not exits
@@ -25,7 +25,7 @@ if pioutil.is_pio_build():
fd.write(chunk)
def copy_mks_assets():
print("Copying MKS Assets")
print("Copying MKS Assets for TFT_LVGL_UI")
output_path = Path(tempfile.mkdtemp())
zip_obj = zipfile.ZipFile(zip_path, 'r')
zip_obj.extractall(output_path)

View File

@@ -23,7 +23,7 @@ if pioutil.is_pio_build():
assert isfile(original_file) and isfile(src_file)
shutil.copyfile(original_file, backup_file)
shutil.copyfile(src_file, original_file);
shutil.copyfile(src_file, original_file)
def _touch(path):
with open(path, "w") as fp:

View File

@@ -5,7 +5,8 @@
# the appropriate framework variants folder, so that its contents
# will be picked up by PlatformIO just like any other variant.
#
import pioutil
import pioutil, re
marlin_variant_pattern = re.compile("marlin_.*")
if pioutil.is_pio_build():
import shutil,marlin
from pathlib import Path
@@ -30,10 +31,11 @@ if pioutil.is_pio_build():
}
platform_name = framewords[platform.__class__.__name__]
else:
platform_name = PackageSpec(platform_packages[0]).name
if platform_name in [ "usb-host-msc", "usb-host-msc-cdc-msc", "usb-host-msc-cdc-msc-2", "usb-host-msc-cdc-msc-3", "tool-stm32duino", "biqu-bx-workaround", "main" ]:
platform_name = "framework-arduinoststm32"
spec = PackageSpec(platform_packages[0])
if spec.uri and '@' in spec.uri:
platform_name = re.sub(r'@.+', '', spec.uri)
else:
platform_name = spec.name
FRAMEWORK_DIR = Path(platform.get_package_dir(platform_name))
assert FRAMEWORK_DIR.is_dir()
@@ -44,15 +46,20 @@ if pioutil.is_pio_build():
variant = board.get("build.variant")
#series = mcu_type[:7].upper() + "xx"
# Prepare a new empty folder at the destination
variant_dir = FRAMEWORK_DIR / "variants" / variant
if variant_dir.is_dir():
shutil.rmtree(variant_dir)
if not variant_dir.is_dir():
variant_dir.mkdir()
# Only prepare a new variant if the PlatformIO configuration provides it (board_build.variant).
# This check is important to avoid deleting official board config variants.
if marlin_variant_pattern.match(str(variant).lower()):
# Prepare a new empty folder at the destination
variant_dir = FRAMEWORK_DIR / "variants" / variant
if variant_dir.is_dir():
shutil.rmtree(variant_dir)
if not variant_dir.is_dir():
variant_dir.mkdir()
# Source dir is a local variant sub-folder
source_dir = Path("buildroot/share/PlatformIO/variants", variant)
assert source_dir.is_dir()
# Source dir is a local variant sub-folder
source_dir = Path("buildroot/share/PlatformIO/variants", variant)
assert source_dir.is_dir()
marlin.copytree(source_dir, variant_dir)
print("Copying variant " + str(variant) + " to framework directory...")
marlin.copytree(source_dir, variant_dir)

View File

@@ -32,4 +32,4 @@ if pioutil.is_pio_build():
fw_path.rename(fws_path)
import marlin
marlin.add_post_action(addboot);
marlin.add_post_action(addboot)

View File

@@ -70,4 +70,4 @@ def encrypt_mks(source, target, env, new_name):
fwpath.unlink()
def add_post_action(action):
env.AddPostAction(str(Path("$BUILD_DIR", "${PROGNAME}.bin")), action);
env.AddPostAction(str(Path("$BUILD_DIR", "${PROGNAME}.bin")), action)

View File

@@ -1,7 +1,7 @@
#
# offset_and_rename.py
#
# - If 'build.offset' is provided, either by JSON or by the environment...
# - If 'board_build.offset' is provided, either by JSON or by the environment...
# - Set linker flag LD_FLASH_OFFSET and relocate the VTAB based on 'build.offset'.
# - Set linker flag LD_MAX_DATA_SIZE based on 'build.maximum_ram_size'.
# - Define STM32_FLASH_SIZE from 'upload.maximum_size' for use by Flash-based EEPROM emulation.
@@ -60,6 +60,10 @@ if pioutil.is_pio_build():
def rename_target(source, target, env):
from pathlib import Path
Path(target[0].path).replace(Path(target[0].dir.path, new_name))
from datetime import datetime
from os import path
_newpath = Path(target[0].dir.path, datetime.now().strftime(new_name.replace('{date}', '%Y%m%d').replace('{time}', '%H%M%S')))
Path(target[0].path).replace(_newpath)
env['PROGNAME'] = path.splitext(_newpath)[0]
marlin.add_post_action(rename_target)

View File

@@ -72,7 +72,7 @@ if pioutil.is_pio_build():
result = check_envs("env:"+build_env, board_envs, config)
if not result:
err = "Error: Build environment '%s' is incompatible with %s. Use one of these: %s" % \
err = "Error: Build environment '%s' is incompatible with %s. Use one of these environments: %s" % \
( build_env, motherboard, ", ".join([ e[4:] for e in board_envs if e.startswith("env:") ]) )
raise SystemExit(err)
@@ -90,7 +90,7 @@ if pioutil.is_pio_build():
# Find the name.cpp.o or name.o and remove it
#
def rm_ofile(subdir, name):
build_dir = Path(env['PROJECT_BUILD_DIR'], build_env);
build_dir = Path(env['PROJECT_BUILD_DIR'], build_env)
for outdir in (build_dir, build_dir / "debug"):
for ext in (".cpp.o", ".o"):
fpath = outdir / "src/src" / subdir / (name + ext)

View File

@@ -2,8 +2,14 @@
#
# schema.py
#
# Used by signature.py via common-dependencies.py to generate a schema file during the PlatformIO build.
# This script can also be run standalone from within the Marlin repo to generate all schema files.
# Used by signature.py via common-dependencies.py to generate a schema file during the PlatformIO build
# when CONFIG_EXPORT is defined in the configuration.
#
# This script can also be run standalone from within the Marlin repo to generate JSON and YAML schema files.
#
# This script is a companion to abm/js/schema.js in the MarlinFirmware/AutoBuildMarlin project, which has
# been extended to evaluate conditions and can determine what options are actually enabled, not just which
# options are uncommented. That will be migrated to this script for standalone migration.
#
import re,json
from pathlib import Path
@@ -85,7 +91,8 @@ def extract():
NORMAL = 0 # No condition yet
BLOCK_COMMENT = 1 # Looking for the end of the block comment
EOL_COMMENT = 2 # EOL comment started, maybe add the next comment?
GET_SENSORS = 3 # Gathering temperature sensor options
SLASH_COMMENT = 3 # Block-like comment, starting with aligned //
GET_SENSORS = 4 # Gathering temperature sensor options
ERROR = 9 # Syntax error
# List of files to process, with shorthand
@@ -94,6 +101,8 @@ def extract():
sch_out = { 'basic':{}, 'advanced':{} }
# Regex for #define NAME [VALUE] [COMMENT] with sanitized line
defgrep = re.compile(r'^(//)?\s*(#define)\s+([A-Za-z0-9_]+)\s*(.*?)\s*(//.+)?$')
# Pattern to match a float value
flt = r'[-+]?\s*(\d+\.|\d*\.\d+)([eE][-+]?\d+)?[fF]?'
# Defines to ignore
ignore = ('CONFIGURATION_H_VERSION', 'CONFIGURATION_ADV_H_VERSION', 'CONFIG_EXAMPLES_DIR', 'CONFIG_EXPORT')
# Start with unknown state
@@ -107,6 +116,7 @@ def extract():
line_number = 0 # Counter for the line number of the file
conditions = [] # Create a condition stack for the current file
comment_buff = [] # A temporary buffer for comments
prev_comment = '' # Copy before reset for an EOL comment
options_json = '' # A buffer for the most recent options JSON found
eol_options = False # The options came from end of line, so only apply once
join_line = False # A flag that the line should be joined with the previous one
@@ -143,9 +153,13 @@ def extract():
if not defmatch and the_line.startswith('//'):
comment_buff.append(the_line[2:].strip())
else:
last_added_ref['comment'] = ' '.join(comment_buff)
comment_buff = []
state = Parse.NORMAL
cline = ' '.join(comment_buff)
comment_buff = []
if cline != '':
# A (block or slash) comment was already added
cfield = 'notes' if 'comment' in last_added_ref else 'comment'
last_added_ref[cfield] = cline
def use_comment(c, opt, sec, bufref):
if c.startswith(':'): # If the comment starts with : then it has magic JSON
@@ -162,6 +176,15 @@ def extract():
bufref.append(c)
return opt, sec
# For slash comments, capture consecutive slash comments.
# The comment will be applied to the next #define.
if state == Parse.SLASH_COMMENT:
if not defmatch and the_line.startswith('//'):
use_comment(the_line[2:].strip(), options_json, section, comment_buff)
continue
else:
state = Parse.NORMAL
# In a block comment, capture lines up to the end of the comment.
# Assume nothing follows the comment closure.
if state in (Parse.BLOCK_COMMENT, Parse.GET_SENSORS):
@@ -178,19 +201,19 @@ def extract():
state = Parse.NORMAL
# Strip the leading '*' from block comments
if cline.startswith('*'): cline = cline[1:].strip()
cline = re.sub(r'^\* ?', '', cline)
# Collect temperature sensors
if state == Parse.GET_SENSORS:
sens = re.match(r'^(-?\d+)\s*:\s*(.+)$', cline)
if sens:
s2 = sens[2].replace("'","''")
options_json += f"{sens[1]}:'{s2}', "
options_json += f"{sens[1]}:'{sens[1]} - {s2}', "
elif state == Parse.BLOCK_COMMENT:
# Look for temperature sensors
if cline == "Temperature sensors available:":
if re.match(r'temperature sensors.*:', cline, re.IGNORECASE):
state, cline = Parse.GET_SENSORS, "Temperature Sensors"
options_json, section = use_comment(cline, options_json, section, comment_buff)
@@ -216,15 +239,19 @@ def extract():
# Comment after a define may be continued on the following lines
if defmatch != None and cpos > 10:
state = Parse.EOL_COMMENT
prev_comment = '\n'.join(comment_buff)
comment_buff = []
else:
state = Parse.SLASH_COMMENT
# Process the start of a new comment
if cpos != -1:
comment_buff = []
cline, line = line[cpos+2:].strip(), line[:cpos].strip()
if state == Parse.BLOCK_COMMENT:
# Strip leading '*' from block comments
if cline.startswith('*'): cline = cline[1:].strip()
cline = re.sub(r'^\* ?', '', cline)
else:
# Expire end-of-line options after first use
if cline.startswith(':'): eol_options = True
@@ -295,32 +322,33 @@ def extract():
}
# Type is based on the value
if val == '':
value_type = 'switch'
elif re.match(r'^(true|false)$', val):
value_type = 'bool'
val = val == 'true'
elif re.match(r'^[-+]?\s*\d+$', val):
value_type = 'int'
val = int(val)
elif re.match(r'[-+]?\s*(\d+\.|\d*\.\d+)([eE][-+]?\d+)?[fF]?', val):
value_type = 'float'
val = float(val.replace('f',''))
else:
value_type = 'string' if val[0] == '"' \
else 'char' if val[0] == "'" \
else 'state' if re.match(r'^(LOW|HIGH)$', val) \
else 'enum' if re.match(r'^[A-Za-z0-9_]{3,}$', val) \
else 'int[]' if re.match(r'^{(\s*[-+]?\s*\d+\s*(,\s*)?)+}$', val) \
else 'float[]' if re.match(r'^{(\s*[-+]?\s*(\d+\.|\d*\.\d+)([eE][-+]?\d+)?[fF]?\s*(,\s*)?)+}$', val) \
else 'array' if val[0] == '{' \
else ''
value_type = \
'switch' if val == '' \
else 'bool' if re.match(r'^(true|false)$', val) \
else 'int' if re.match(r'^[-+]?\s*\d+$', val) \
else 'ints' if re.match(r'^([-+]?\s*\d+)(\s*,\s*[-+]?\s*\d+)+$', val) \
else 'floats' if re.match(rf'({flt}(\s*,\s*{flt})+)', val) \
else 'float' if re.match(f'^({flt})$', val) \
else 'string' if val[0] == '"' \
else 'char' if val[0] == "'" \
else 'state' if re.match(r'^(LOW|HIGH)$', val) \
else 'enum' if re.match(r'^[A-Za-z0-9_]{3,}$', val) \
else 'int[]' if re.match(r'^{\s*[-+]?\s*\d+(\s*,\s*[-+]?\s*\d+)*\s*}$', val) \
else 'float[]' if re.match(r'^{{\s*{flt}(\s*,\s*{flt})*\s*}}$', val) \
else 'array' if val[0] == '{' \
else ''
val = (val == 'true') if value_type == 'bool' \
else int(val) if value_type == 'int' \
else val.replace('f','') if value_type == 'floats' \
else float(val.replace('f','')) if value_type == 'float' \
else val
if val != '': define_info['value'] = val
if value_type != '': define_info['type'] = value_type
# Join up accumulated conditions with &&
if conditions: define_info['requires'] = ' && '.join(sum(conditions, []))
if conditions: define_info['requires'] = '(' + ') && ('.join(sum(conditions, [])) + ')'
# If the comment_buff is not empty, add the comment to the info
if comment_buff:
@@ -383,25 +411,35 @@ def main():
if schema:
# Get the first command line argument
# Get the command line arguments after the script name
import sys
if len(sys.argv) > 1:
arg = sys.argv[1]
else:
arg = 'some'
args = sys.argv[1:]
if len(args) == 0: args = ['some']
# Does the given array intersect at all with args?
def inargs(c): return len(set(args) & set(c)) > 0
# Help / Unknown option
unk = not inargs(['some','json','jsons','group','yml','yaml'])
if (unk): print(f"Unknown option: '{args[0]}'")
if inargs(['-h', '--help']) or unk:
print("Usage: schema.py [some|json|jsons|group|yml|yaml]...")
print(" some = json + yml")
print(" jsons = json + group")
return
# JSON schema
if arg in ['some', 'json', 'jsons']:
if inargs(['some', 'json', 'jsons']):
print("Generating JSON ...")
dump_json(schema, Path('schema.json'))
# JSON schema (wildcard names)
if arg in ['group', 'jsons']:
if inargs(['group', 'jsons']):
group_options(schema)
dump_json(schema, Path('schema_grouped.json'))
# YAML
if arg in ['some', 'yml', 'yaml']:
if inargs(['some', 'yml', 'yaml']):
try:
import yaml
except ImportError:

47
buildroot/share/PlatformIO/scripts/signature.py Normal file → Executable file
View File

@@ -1,3 +1,4 @@
#!/usr/bin/env python3
#
# signature.py
#
@@ -44,35 +45,35 @@ def compress_file(filepath, storedname, outpath):
zipf.write(filepath, arcname=storedname, compress_type=zipfile.ZIP_BZIP2, compresslevel=9)
#
# Compute the build signature. The idea is to extract all defines in the configuration headers
# to build a unique reversible signature from this build so it can be included in the binary
# We can reverse the signature to get a 1:1 equivalent configuration file
# Compute the build signature by extracting all configuration settings and
# building a unique reversible signature that can be included in the binary.
# The signature can be reversed to get a 1:1 equivalent configuration file.
#
def compute_build_signature(env):
if 'BUILD_SIGNATURE' in env:
return
build_path = Path(env['PROJECT_BUILD_DIR'], env['PIOENV'])
marlin_json = build_path / 'marlin_config.json'
marlin_zip = build_path / 'mc.zip'
# Definitions from these files will be kept
files_to_keep = [ 'Marlin/Configuration.h', 'Marlin/Configuration_adv.h' ]
build_path = Path(env['PROJECT_BUILD_DIR'], env['PIOENV'])
# Check if we can skip processing
hashes = ''
for header in files_to_keep:
hashes += get_file_sha256sum(header)[0:10]
marlin_json = build_path / 'marlin_config.json'
marlin_zip = build_path / 'mc.zip'
# Read existing config file
# Read a previously exported JSON file
# Same configuration, skip recomputing the build signature
same_hash = False
try:
with marlin_json.open() as infile:
conf = json.load(infile)
if conf['__INITIAL_HASH'] == hashes:
# Same configuration, skip recomputing the building signature
same_hash = conf['__INITIAL_HASH'] == hashes
if same_hash:
compress_file(marlin_json, 'marlin_config.json', marlin_zip)
return
except:
pass
@@ -125,9 +126,6 @@ def compute_build_signature(env):
# Remove all boards now
if key.startswith("BOARD_") and key != "BOARD_INFO_NAME":
continue
# Remove all keys ending by "_NAME" as it does not make a difference to the configuration
if key.endswith("_NAME") and key != "CUSTOM_MACHINE_NAME":
continue
# Remove all keys ending by "_T_DECLARED" as it's a copy of extraneous system stuff
if key.endswith("_T_DECLARED"):
continue
@@ -196,7 +194,7 @@ def compute_build_signature(env):
outfile.write(ini_fmt.format(key.lower(), ' = ' + val))
#
# Produce a schema.json file if CONFIG_EXPORT == 3
# CONFIG_EXPORT 3 = schema.json, 4 = schema.yml
#
if config_dump >= 3:
try:
@@ -207,7 +205,7 @@ def compute_build_signature(env):
if conf_schema:
#
# Produce a schema.json file if CONFIG_EXPORT == 3
# 3 = schema.json
#
if config_dump in (3, 13):
print("Generating schema.json ...")
@@ -217,7 +215,7 @@ def compute_build_signature(env):
schema.dump_json(conf_schema, build_path / 'schema_grouped.json')
#
# Produce a schema.yml file if CONFIG_EXPORT == 4
# 4 = schema.yml
#
elif config_dump == 4:
print("Generating schema.yml ...")
@@ -243,8 +241,9 @@ def compute_build_signature(env):
#
# Produce a JSON file for CONFIGURATION_EMBEDDING or CONFIG_EXPORT == 1
# Skip if an identical JSON file was already present.
#
if config_dump == 1 or 'CONFIGURATION_EMBEDDING' in defines:
if not same_hash and (config_dump == 1 or 'CONFIGURATION_EMBEDDING' in defines):
with marlin_json.open('w') as outfile:
json.dump(data, outfile, separators=(',', ':'))
@@ -255,9 +254,10 @@ def compute_build_signature(env):
return
# Compress the JSON file as much as we can
compress_file(marlin_json, 'marlin_config.json', marlin_zip)
if not same_hash:
compress_file(marlin_json, 'marlin_config.json', marlin_zip)
# Generate a C source file for storing this array
# Generate a C source file containing the entire ZIP file as an array
with open('Marlin/src/mczip.h','wb') as result_file:
result_file.write(
b'#ifndef NO_CONFIGURATION_EMBEDDING_WARNING\n'
@@ -274,3 +274,8 @@ def compute_build_signature(env):
if count % 16:
result_file.write(b'\n')
result_file.write(b'};\n')
if __name__ == "__main__":
# Build required. From command line just explain usage.
print("Use schema.py to export JSON and YAML from the command-line.")
print("Build Marlin with CONFIG_EXPORT 2 to export 'config.ini'.")