[core] Allow specifying custom library options
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
from os.path import join
|
||||
|
||||
import click
|
||||
from ltchiptool import Family, get_version
|
||||
from ltchiptool import Family
|
||||
from platformio.platform.base import PlatformBase
|
||||
from platformio.platform.board import PlatformBoardConfig
|
||||
from SCons.Errors import UserError
|
||||
@@ -14,11 +14,10 @@ board: PlatformBoardConfig = env.BoardConfig()
|
||||
platform: PlatformBase = env.PioPlatform()
|
||||
family: Family = env["FAMILY_OBJ"]
|
||||
|
||||
# Print information about installed core versions
|
||||
lt_version: str = env.ReadLTVersion(platform.get_dir(), platform.version)
|
||||
print("PLATFORM VERSIONS:")
|
||||
print(" - libretuya @", lt_version)
|
||||
print(" - ltchiptool @", get_version())
|
||||
# Print information about versions and custom options
|
||||
env.PrintInfo(platform)
|
||||
# Apply custom header options
|
||||
env.ApplyCustomOptions(platform)
|
||||
|
||||
# TODO remove include path prepending ("!<...>")
|
||||
# Move common core sources (env.AddCoreSources()) and Arduino libs
|
||||
@@ -114,7 +113,7 @@ queue.AppendPublic(
|
||||
],
|
||||
CPPDEFINES=[
|
||||
("LIBRETUYA", 1),
|
||||
("LT_VERSION", lt_version),
|
||||
("LT_VERSION", env["LT_VERSION"]),
|
||||
("LT_BOARD", "${VARIANT}"),
|
||||
("LT_VARIANT_H", r"\"${VARIANT}.h\""),
|
||||
("F_CPU", board.get("build.f_cpu")),
|
||||
|
||||
@@ -51,6 +51,8 @@ env.Replace(
|
||||
env.ConfigureEnvironment(platform, board)
|
||||
# Flash layout defines
|
||||
env.AddFlashLayout(board)
|
||||
# Parse custom options
|
||||
env.ParseCustomOptions(platform)
|
||||
|
||||
# Family builders details:
|
||||
# - call env.AddLibrary("lib name", "base dir", [sources]) to add lib sources
|
||||
|
||||
@@ -2,10 +2,12 @@
|
||||
|
||||
import json
|
||||
import sys
|
||||
from os import makedirs
|
||||
from os.path import isdir, join
|
||||
from subprocess import PIPE, Popen
|
||||
from typing import Dict
|
||||
|
||||
from ltchiptool import Family
|
||||
from ltchiptool import Family, get_version
|
||||
from platformio.platform.base import PlatformBase
|
||||
from platformio.platform.board import PlatformBoardConfig
|
||||
from SCons.Script import DefaultEnvironment, Environment
|
||||
@@ -13,7 +15,7 @@ from SCons.Script import DefaultEnvironment, Environment
|
||||
env: Environment = DefaultEnvironment()
|
||||
|
||||
|
||||
def env_read_version(env: Environment, platform_dir: str, version: str):
|
||||
def read_version(platform_dir: str, version: str):
|
||||
if not isdir(join(platform_dir, ".git")):
|
||||
sys.stderr.write("Warning! Non-Git installations are NOT SUPPORTED.\n")
|
||||
return version
|
||||
@@ -61,6 +63,7 @@ def env_configure(
|
||||
LT_DIR=platform.get_dir(),
|
||||
CORES_DIR=join("${LT_DIR}", "cores"),
|
||||
COMMON_DIR=join("${LT_DIR}", "cores", "common"),
|
||||
LT_VERSION=read_version(platform.get_dir(), platform.version),
|
||||
# Build directories & paths
|
||||
VARIANTS_DIR=join("${LT_DIR}", "boards", "variants"),
|
||||
FAMILY_DIR=join("${LT_DIR}", "cores", "${FAMILY_NAME}"),
|
||||
@@ -86,5 +89,90 @@ def env_configure(
|
||||
return family
|
||||
|
||||
|
||||
def env_print_info(env: Environment, platform: PlatformBase):
|
||||
TAB = " " * 4
|
||||
|
||||
def dump(k, v, indent=""):
|
||||
k = k.replace("#", ".")
|
||||
if isinstance(v, dict):
|
||||
print(f"{indent} - {k}:")
|
||||
for k, v in v.items():
|
||||
dump(k, v, indent + TAB)
|
||||
elif isinstance(v, list):
|
||||
print(f"{indent} - {k}:")
|
||||
for k, v in enumerate(v):
|
||||
dump(k, v, indent + TAB)
|
||||
else:
|
||||
print(f"{indent} - {k} = {v}")
|
||||
|
||||
# Print information about installed core versions
|
||||
print("PLATFORM VERSIONS:")
|
||||
print(" - libretuya @", env["LT_VERSION"])
|
||||
print(" - ltchiptool @", get_version())
|
||||
# Print custom platformio.ini options
|
||||
if platform.custom_opts:
|
||||
print("CUSTOM OPTIONS:")
|
||||
for k, v in platform.custom_opts.items():
|
||||
dump(k, v)
|
||||
|
||||
|
||||
def env_parse_custom_options(env: Environment, platform: PlatformBase):
|
||||
opts = platform.custom_opts.get("options", None)
|
||||
if not opts:
|
||||
return
|
||||
headers = {
|
||||
"lwip": "lwipopts.h",
|
||||
"freertos": "FreeRTOSConfig.h",
|
||||
}
|
||||
for header, options in list(opts.items()):
|
||||
if not isinstance(options, str):
|
||||
raise TypeError("Options value should be str")
|
||||
options = options.strip().splitlines()
|
||||
opts_dict = {}
|
||||
for line in options:
|
||||
if "=" not in line:
|
||||
raise ValueError(f"Invalid option: {line}")
|
||||
k, _, v = line.partition("=")
|
||||
k = k.strip()
|
||||
v = v.strip()
|
||||
opts_dict[k] = v
|
||||
# replace predefined header names
|
||||
opts.pop(header)
|
||||
header = headers.get(header, header)
|
||||
header = header.replace(".", "#")
|
||||
opts[header] = opts_dict
|
||||
|
||||
|
||||
def env_apply_custom_options(env: Environment, platform: PlatformBase):
|
||||
opts = platform.custom_opts.get("options", None)
|
||||
if not opts:
|
||||
return
|
||||
header_dir = join("${BUILD_DIR}", "include")
|
||||
real_dir = env.subst(header_dir)
|
||||
makedirs(real_dir, exist_ok=True)
|
||||
|
||||
for header, options in opts.items():
|
||||
header: str
|
||||
options: Dict[str, str]
|
||||
# open the header file for writing
|
||||
header = header.replace("#", ".")
|
||||
f = open(join(real_dir, header), "w")
|
||||
f.write(f'#include_next "{header}"\n' "\n" "#pragma once\n" "\n")
|
||||
# write all #defines
|
||||
for k, v in options.items():
|
||||
f.write(
|
||||
f"// {k} = {v}\n"
|
||||
f"#ifdef {k}\n"
|
||||
f"#undef {k}\n"
|
||||
f"#endif\n"
|
||||
f"#define {k} {v}\n"
|
||||
)
|
||||
f.close()
|
||||
# prepend newly created headers before any other
|
||||
env.Prepend(CPPPATH=[header_dir])
|
||||
|
||||
|
||||
env.AddMethod(env_configure, "ConfigureEnvironment")
|
||||
env.AddMethod(env_read_version, "ReadLTVersion")
|
||||
env.AddMethod(env_print_info, "PrintInfo")
|
||||
env.AddMethod(env_parse_custom_options, "ParseCustomOptions")
|
||||
env.AddMethod(env_apply_custom_options, "ApplyCustomOptions")
|
||||
|
||||
18
platform.py
18
platform.py
@@ -1,6 +1,7 @@
|
||||
# Copyright (c) Kuba Szczodrzyński 2022-04-20.
|
||||
|
||||
import importlib
|
||||
import json
|
||||
import platform
|
||||
import sys
|
||||
from os import system
|
||||
@@ -110,6 +111,11 @@ class LibretuyaPlatform(PlatformBase):
|
||||
self.custom_opts = {}
|
||||
self.versions = {}
|
||||
|
||||
def print(self, *args, **kwargs):
|
||||
if not self.verbose:
|
||||
return
|
||||
print(*args, **kwargs)
|
||||
|
||||
def get_package_spec(self, name, version=None):
|
||||
# make PlatformIO detach existing package versions instead of overwriting
|
||||
# TODO this is an ugly hack, it moves old packages to dirs like "library-lwip@src-21d717f2feaca73533f129ce05c9f4d4"
|
||||
@@ -121,6 +127,10 @@ class LibretuyaPlatform(PlatformBase):
|
||||
def configure_default_packages(self, options, targets):
|
||||
from ltchiptool.util.dict import RecursiveDict
|
||||
|
||||
self.verbose = (
|
||||
"-v" in sys.argv or "--verbose" in sys.argv or "PIOVERBOSE=1" in sys.argv
|
||||
)
|
||||
|
||||
pioframework = options.get("pioframework") or ["base"]
|
||||
if not pioframework:
|
||||
return
|
||||
@@ -131,7 +141,13 @@ class LibretuyaPlatform(PlatformBase):
|
||||
for key, value in options.items():
|
||||
if not key.startswith("custom_"):
|
||||
continue
|
||||
self.custom_opts[key[7:]] = value
|
||||
key = key[7:]
|
||||
parent, sep, child = key.partition(".")
|
||||
if parent == "options":
|
||||
# allow only one level of nesting ('child' may be a header name, which contains a dot)
|
||||
child = child.replace(".", "#")
|
||||
self.custom_opts[parent + sep + child] = value
|
||||
self.print("Custom options:", json.dumps(self.custom_opts, indent="\t"))
|
||||
|
||||
# update framework names to their new values since v1.0.0
|
||||
if framework.endswith("-sdk"):
|
||||
|
||||
Reference in New Issue
Block a user