mirror of https://github.com/arendst/Tasmota.git
Build system: allow easy solidification of external Berry (#21430)
* custom solidification * solidify-from-url * forgot folders --------- Co-authored-by: Radio Loge <radiologe@MacBook-Pro-von-Radio.local>
This commit is contained in:
parent
1ca91a8170
commit
e5521bb763
|
@ -6,6 +6,7 @@
|
||||||
** https://github.com/Skiars/berry/blob/master/LICENSE
|
** https://github.com/Skiars/berry/blob/master/LICENSE
|
||||||
********************************************************************/
|
********************************************************************/
|
||||||
#include "berry.h"
|
#include "berry.h"
|
||||||
|
#include "../../berry_custom/src/modules.h"
|
||||||
|
|
||||||
/* this file contains the declaration of the module table. */
|
/* this file contains the declaration of the module table. */
|
||||||
|
|
||||||
|
@ -189,6 +190,7 @@ BERRY_LOCAL const bntvmodule_t* const be_module_table[] = {
|
||||||
&be_native_module(matter),
|
&be_native_module(matter),
|
||||||
#endif // USE_MATTER_DEVICE
|
#endif // USE_MATTER_DEVICE
|
||||||
#endif // TASMOTA
|
#endif // TASMOTA
|
||||||
|
CUSTOM_NATIVE_MODULES
|
||||||
/* user-defined modules register end */
|
/* user-defined modules register end */
|
||||||
NULL /* do not remove */
|
NULL /* do not remove */
|
||||||
};
|
};
|
||||||
|
@ -313,6 +315,7 @@ BERRY_LOCAL bclass_array be_class_table = {
|
||||||
#if defined(USE_BERRY_INT64) || defined(USE_MATTER_DEVICE)
|
#if defined(USE_BERRY_INT64) || defined(USE_MATTER_DEVICE)
|
||||||
&be_native_class(int64),
|
&be_native_class(int64),
|
||||||
#endif
|
#endif
|
||||||
|
CUSTOM_NATIVE_CLASSES
|
||||||
NULL, /* do not remove */
|
NULL, /* do not remove */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
{
|
||||||
|
"name": "Berry custom template",
|
||||||
|
"version": "0.1",
|
||||||
|
"description": "Berry library to solidify external scripts in the build process",
|
||||||
|
"license": "MIT",
|
||||||
|
"homepage": "https://github.com/arendst/Tasmota",
|
||||||
|
"frameworks": "arduino",
|
||||||
|
"platforms": "espressif32",
|
||||||
|
"authors":
|
||||||
|
{
|
||||||
|
"name": "Christian Baars",
|
||||||
|
"maintainer": true
|
||||||
|
},
|
||||||
|
"build": {
|
||||||
|
"flags": [ "-I$PROJECT_DIR/include", "-includetasmota_options.h" ]
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,2 @@
|
||||||
|
# empty module
|
||||||
|
# allows stand-alone `import path`
|
|
@ -0,0 +1,99 @@
|
||||||
|
#!/usr/bin/env -S ../berry/berry -s -g
|
||||||
|
#
|
||||||
|
# Berry solidify files
|
||||||
|
|
||||||
|
import os
|
||||||
|
import global
|
||||||
|
import solidify
|
||||||
|
import string as string2
|
||||||
|
import re
|
||||||
|
|
||||||
|
import sys
|
||||||
|
sys.path().push('src/embedded') # allow to import from src/embedded
|
||||||
|
|
||||||
|
# globals that need to exist to make compilation succeed
|
||||||
|
var globs = "path,ctypes_bytes_dyn,tasmota,ccronexpr,gpio,light,webclient,load,MD5,lv,light_state,udp,tcpclientasync,"
|
||||||
|
"lv_clock,lv_clock_icon,lv_signal_arcs,lv_signal_bars,lv_wifi_arcs_icon,lv_wifi_arcs,"
|
||||||
|
"lv_wifi_bars_icon,lv_wifi_bars,"
|
||||||
|
"_lvgl,"
|
||||||
|
"int64"
|
||||||
|
|
||||||
|
for g:string2.split(globs, ",")
|
||||||
|
global.(g) = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
var prefix_dir = "src/embedded/"
|
||||||
|
var prefix_out = "src/solidify/"
|
||||||
|
|
||||||
|
def sort(l)
|
||||||
|
# insertion sort
|
||||||
|
for i:1..size(l)-1
|
||||||
|
var k = l[i]
|
||||||
|
var j = i
|
||||||
|
while (j > 0) && (l[j-1] > k)
|
||||||
|
l[j] = l[j-1]
|
||||||
|
j -= 1
|
||||||
|
end
|
||||||
|
l[j] = k
|
||||||
|
end
|
||||||
|
return l
|
||||||
|
end
|
||||||
|
|
||||||
|
def clean_directory(dir)
|
||||||
|
var file_list = os.listdir(dir)
|
||||||
|
for f : file_list
|
||||||
|
if f[0] == '.' continue end # ignore files starting with `.`
|
||||||
|
os.remove(dir + f)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
var pattern = "#@\\s*solidify:([A-Za-z0-9_.,]+)"
|
||||||
|
|
||||||
|
def parse_file(fname, prefix_out)
|
||||||
|
print("Parsing: ", fname)
|
||||||
|
var f = open(prefix_dir + fname)
|
||||||
|
var src = f.read()
|
||||||
|
f.close()
|
||||||
|
# try to compile
|
||||||
|
var compiled = compile(src)
|
||||||
|
compiled() # run the compile code to instanciate the classes and modules
|
||||||
|
# output solidified
|
||||||
|
var fname_h = string2.split(fname, '.be')[0] + '.h' # take whatever is before the first '.be'
|
||||||
|
var fout = open(prefix_out + "solidified_" + fname_h, "w")
|
||||||
|
fout.write(f"/* Solidification of {fname_h} */\n")
|
||||||
|
fout.write("/********************************************************************\\\n")
|
||||||
|
fout.write("* Generated code, don't edit *\n")
|
||||||
|
fout.write("\\********************************************************************/\n")
|
||||||
|
fout.write('#include "be_constobj.h"\n')
|
||||||
|
|
||||||
|
var directives = re.searchall(pattern, src)
|
||||||
|
# print(directives)
|
||||||
|
|
||||||
|
for directive : directives
|
||||||
|
var object_list = string2.split(directive[1], ',')
|
||||||
|
var object_name = object_list[0]
|
||||||
|
var weak = (object_list.find('weak') != nil) # do we solidify with weak strings?
|
||||||
|
var o = global
|
||||||
|
var cl_name = nil
|
||||||
|
var obj_name = nil
|
||||||
|
for subname : string2.split(object_name, '.')
|
||||||
|
o = o.(subname)
|
||||||
|
cl_name = obj_name
|
||||||
|
obj_name = subname
|
||||||
|
end
|
||||||
|
solidify.dump(o, weak, fout, cl_name)
|
||||||
|
end
|
||||||
|
|
||||||
|
fout.write("/********************************************************************/\n")
|
||||||
|
fout.write("/* End of solidification */\n")
|
||||||
|
fout.close()
|
||||||
|
end
|
||||||
|
|
||||||
|
clean_directory(prefix_out)
|
||||||
|
|
||||||
|
var src_file_list = os.listdir(prefix_dir)
|
||||||
|
src_file_list = sort(src_file_list)
|
||||||
|
for src_file : src_file_list
|
||||||
|
if src_file[0] == '.' continue end
|
||||||
|
parse_file(src_file, prefix_out)
|
||||||
|
end
|
|
@ -0,0 +1 @@
|
||||||
|
_temp*
|
|
@ -0,0 +1,31 @@
|
||||||
|
/*
|
||||||
|
be_custom_module.c - allows solidification of external Berry files
|
||||||
|
|
||||||
|
Copyright (C) 2023 Stephan Hadinger, Christian Baars & Theo Arends
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*******************************************************************\
|
||||||
|
* `custom` modules and classes
|
||||||
|
\*******************************************************************/
|
||||||
|
|
||||||
|
#ifdef USE_BERRY
|
||||||
|
#include "be_constobj.h"
|
||||||
|
#include "be_mapping.h"
|
||||||
|
|
||||||
|
/*solidify*/
|
||||||
|
|
||||||
|
|
||||||
|
#endif // USE_BERRY
|
|
@ -0,0 +1,8 @@
|
||||||
|
// force compilation by including this file
|
||||||
|
|
||||||
|
#ifndef __BERRY_CUSTOM__
|
||||||
|
#define __BERRY_CUSTOM__
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif // __BERRY_CUSTOM__
|
|
@ -0,0 +1 @@
|
||||||
|
*
|
|
@ -0,0 +1,2 @@
|
||||||
|
#define CUSTOM_NATIVE_MODULES
|
||||||
|
#define CUSTOM_NATIVE_CLASSES
|
|
@ -0,0 +1 @@
|
||||||
|
*
|
|
@ -16,6 +16,6 @@ for filePath in fileList:
|
||||||
# print("Deleting file : ", filePath)
|
# print("Deleting file : ", filePath)
|
||||||
except:
|
except:
|
||||||
print("Error while deleting file : ", filePath)
|
print("Error while deleting file : ", filePath)
|
||||||
cmd = (env["PYTHONEXE"],join("tools","coc","coc"),"-o","generate","src","default",join("..","berry_tasmota","src"),join("..","berry_matter","src","solidify"),join("..","berry_matter","src"),join("..","berry_animate","src","solidify"),join("..","berry_animate","src"),join("..","berry_tasmota","src","solidify"),join("..","berry_mapping","src"),join("..","berry_int64","src"),join("..","..","libesp32_lvgl","lv_binding_berry","src"),join("..","..","libesp32_lvgl","lv_binding_berry","src","solidify"),join("..","..","libesp32_lvgl","lv_binding_berry","generate"),join("..","..","libesp32_lvgl","lv_haspmota","src","solidify"),"-c",join("default","berry_conf.h"))
|
cmd = (env["PYTHONEXE"],join("tools","coc","coc"),"-o","generate","src","default",join("..","berry_tasmota","src"),join("..","berry_matter","src","solidify"),join("..","berry_matter","src"),join("..","berry_custom","src","solidify"),join("..","berry_custom","src"),join("..","berry_animate","src","solidify"),join("..","berry_animate","src"),join("..","berry_tasmota","src","solidify"),join("..","berry_mapping","src"),join("..","berry_int64","src"),join("..","..","libesp32_lvgl","lv_binding_berry","src"),join("..","..","libesp32_lvgl","lv_binding_berry","src","solidify"),join("..","..","libesp32_lvgl","lv_binding_berry","generate"),join("..","..","libesp32_lvgl","lv_haspmota","src","solidify"),"-c",join("default","berry_conf.h"))
|
||||||
returncode = subprocess.call(cmd, shell=False)
|
returncode = subprocess.call(cmd, shell=False)
|
||||||
os.chdir(CURRENT_DIR)
|
os.chdir(CURRENT_DIR)
|
||||||
|
|
|
@ -0,0 +1,152 @@
|
||||||
|
# Little convenience script to solidify external berry files as embedded
|
||||||
|
|
||||||
|
Import("env")
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
from genericpath import exists
|
||||||
|
from os.path import join
|
||||||
|
import subprocess
|
||||||
|
from colorama import Fore, Back, Style
|
||||||
|
import requests
|
||||||
|
import re
|
||||||
|
|
||||||
|
IS_WINDOWS = sys.platform.startswith("win")
|
||||||
|
|
||||||
|
def ensureBerry():
|
||||||
|
BERRY_GEN_DIR = join(env.subst("$PROJECT_DIR"), "lib", "libesp32","berry")
|
||||||
|
os.chdir(BERRY_GEN_DIR)
|
||||||
|
BERRY_EXECUTABLE = join(BERRY_GEN_DIR,"berry")
|
||||||
|
if IS_WINDOWS:
|
||||||
|
berry_executable = join(BERRY_GEN_DIR,"berry.exe")
|
||||||
|
else:
|
||||||
|
if os.path.exists(BERRY_EXECUTABLE) == False:
|
||||||
|
print("Will compile Berry executable")
|
||||||
|
make_cmd = "make"
|
||||||
|
subprocess.call(make_cmd, shell=False)
|
||||||
|
|
||||||
|
if os.path.exists(BERRY_EXECUTABLE):
|
||||||
|
return BERRY_EXECUTABLE
|
||||||
|
else:
|
||||||
|
return Null
|
||||||
|
|
||||||
|
def cleanFolder():
|
||||||
|
with open(HEADER_FILE_PATH, 'w') as file:
|
||||||
|
code = "#define CUSTOM_NATIVE_MODULES\n#define CUSTOM_NATIVE_CLASSES"
|
||||||
|
file.write(code)
|
||||||
|
tempfiles = [f for f in os.listdir(join(BERRY_SOLIDIFY_DIR,"src")) if re.match(r'_temp', f)]
|
||||||
|
for file in tempfiles:
|
||||||
|
os.remove(join(BERRY_SOLIDIFY_DIR,"src",file))
|
||||||
|
tempfiles = [f for f in os.listdir(join(BERRY_SOLIDIFY_DIR,"src","embedded")) if ".gitignore" not in f]
|
||||||
|
for file in tempfiles:
|
||||||
|
os.remove(join(BERRY_SOLIDIFY_DIR,"src","embedded",file))
|
||||||
|
tempfiles = [f for f in os.listdir(join(BERRY_SOLIDIFY_DIR,"src","solidify")) if ".gitignore" not in f]
|
||||||
|
for file in tempfiles:
|
||||||
|
os.remove(join(BERRY_SOLIDIFY_DIR,"src","solidify",file))
|
||||||
|
|
||||||
|
|
||||||
|
def addEntryToModtab(source):
|
||||||
|
code = source.decode("utf-8")
|
||||||
|
class_name = None
|
||||||
|
is_module = False
|
||||||
|
|
||||||
|
|
||||||
|
pattern = (r'''(?<=module\()[^"].*''') # module??
|
||||||
|
result = re.findall(pattern,code)
|
||||||
|
if len(result) > 0:
|
||||||
|
class_name = result[0].replace("'","").replace('"','').replace(")","")
|
||||||
|
print(class_name+" is a module")
|
||||||
|
is_module = True
|
||||||
|
else: # just a class
|
||||||
|
pattern = (r'(?<=#@ solidify:).*')
|
||||||
|
result = re.findall(pattern,code)
|
||||||
|
if len(result) > 0:
|
||||||
|
class_name = result[0].split(",")[0]
|
||||||
|
if class_name == None:
|
||||||
|
print("Could not find class name - is '#@ solidify:' used in Berry file??")
|
||||||
|
print(Fore.RED + "Aborting build process!!")
|
||||||
|
quit()
|
||||||
|
MODTAB_PATH = join(env.subst("$PROJECT_DIR"), "lib", "libesp32","berry","default","be_modtab.c")
|
||||||
|
with open(HEADER_FILE_PATH, 'r') as file:
|
||||||
|
code = file.read() # reuse code var for modtab file
|
||||||
|
if is_module:
|
||||||
|
nmodule = f"&be_native_module({class_name}),"
|
||||||
|
if code.find(nmodule) == -1:
|
||||||
|
code = code.replace(
|
||||||
|
"CUSTOM_NATIVE_MODULES",
|
||||||
|
f'CUSTOM_NATIVE_MODULES {nmodule}'
|
||||||
|
)
|
||||||
|
enmodule = f"be_extern_native_module({class_name});"
|
||||||
|
if code.find(enmodule) == -1:
|
||||||
|
code += f'\n{enmodule}'
|
||||||
|
else:
|
||||||
|
nclass = f"&be_native_class({class_name}),"
|
||||||
|
if code.find(nclass) == -1:
|
||||||
|
code = code.replace(
|
||||||
|
"CUSTOM_NATIVE_CLASSES",
|
||||||
|
f'CUSTOM_NATIVE_CLASSES {nclass}'
|
||||||
|
)
|
||||||
|
enclass = f"be_extern_native_class({class_name});"
|
||||||
|
if code.find(enclass) == -1:
|
||||||
|
code += f'\n{enclass}'
|
||||||
|
|
||||||
|
with open(HEADER_FILE_PATH, 'w') as file:
|
||||||
|
file.write(code)
|
||||||
|
|
||||||
|
|
||||||
|
def addHeaderFile(name):
|
||||||
|
print("Will solidify ",name)
|
||||||
|
name = name.split(".")[0]
|
||||||
|
data = f"""
|
||||||
|
/********************************************************************
|
||||||
|
* {name} module
|
||||||
|
*
|
||||||
|
*******************************************************************/
|
||||||
|
#include "solidify/solidified_{name}.h"
|
||||||
|
"""
|
||||||
|
file_name = f"_temp_be_{name}_lib.c"
|
||||||
|
file_path = join(BERRY_SOLIDIFY_DIR,"src",file_name)
|
||||||
|
open(file_path,"w").write(data)
|
||||||
|
|
||||||
|
def prepareBerryFiles(files):
|
||||||
|
embedded_dir = join("src","embedded")
|
||||||
|
for file in files:
|
||||||
|
if "http" and "://" in file:
|
||||||
|
response = requests.get(file.split(" ")[0])
|
||||||
|
if response.ok:
|
||||||
|
target = join(embedded_dir,file.split(os.path.sep)[-1])
|
||||||
|
if len(file.split(" ")) > 1:
|
||||||
|
target = join(embedded_dir,file.split(" ")[1])
|
||||||
|
print("Renaming",(file.split(os.path.sep)[-1]).split(" ")[0],"to",file.split(" ")[1])
|
||||||
|
open(target, "wb").write(response.content)
|
||||||
|
addHeaderFile(file.split(os.path.sep)[-1])
|
||||||
|
addEntryToModtab(response.content)
|
||||||
|
else:
|
||||||
|
print(Fore.RED + "Failed to download: ",file)
|
||||||
|
continue
|
||||||
|
# maybe later ...
|
||||||
|
# if os.path.isdir(file):
|
||||||
|
# continue
|
||||||
|
# else:
|
||||||
|
# shutil.copy(file, embedded_dir)
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
BERRY_SOLIDIFY_DIR = join(env.subst("$PROJECT_DIR"), "lib", "libesp32","berry_custom")
|
||||||
|
HEADER_FILE_PATH = join(BERRY_SOLIDIFY_DIR,"src","modules.h")
|
||||||
|
cleanFolder() # always clean up this folder
|
||||||
|
try:
|
||||||
|
files = env.GetProjectOption("custom_berry_solidify")
|
||||||
|
except:
|
||||||
|
print("Nothing more to solidify")
|
||||||
|
else:
|
||||||
|
if env.IsCleanTarget() == False:
|
||||||
|
BERRY_EXECUTABLE = ensureBerry()
|
||||||
|
|
||||||
|
os.chdir(BERRY_SOLIDIFY_DIR)
|
||||||
|
|
||||||
|
if prepareBerryFiles(files.splitlines()):
|
||||||
|
solidify_command = BERRY_EXECUTABLE
|
||||||
|
solidify_flags = " -s -g solidify_all.be"
|
||||||
|
print("Start solidification for 'berry_custom':")
|
||||||
|
subprocess.call(solidify_command + solidify_flags, shell=True)
|
|
@ -46,6 +46,7 @@ lib_ignore =
|
||||||
Preferences
|
Preferences
|
||||||
ArduinoOTA
|
ArduinoOTA
|
||||||
extra_scripts = pre:pio-tools/add_c_flags.py
|
extra_scripts = pre:pio-tools/add_c_flags.py
|
||||||
|
pre:pio-tools/solidify-from-url.py
|
||||||
pre:pio-tools/gen-berry-structures.py
|
pre:pio-tools/gen-berry-structures.py
|
||||||
post:pio-tools/post_esp32.py
|
post:pio-tools/post_esp32.py
|
||||||
${esp_defaults.extra_scripts}
|
${esp_defaults.extra_scripts}
|
||||||
|
|
|
@ -37,6 +37,7 @@ extern "C" {
|
||||||
#include "be_vm.h"
|
#include "be_vm.h"
|
||||||
#include "ZipReadFS.h"
|
#include "ZipReadFS.h"
|
||||||
#include "ccronexpr.h"
|
#include "ccronexpr.h"
|
||||||
|
#include "berry_custom.h"
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
extern void be_load_custom_libs(bvm *vm);
|
extern void be_load_custom_libs(bvm *vm);
|
||||||
|
|
Loading…
Reference in New Issue