mirror of
https://github.com/xoseperez/espurna.git
synced 2026-03-03 06:54:16 +01:00
Convert .ino -> .cpp (#2228)
- general conversion from .ino modules into a separate .cpp files - clean-up internal headers, place libraries into .h. guard .cpp with _SUPPORT flags - fix some instances of shared variables instead of public methods - tweak build system to still build a single source file via os environment variable ESPURNA_BUILD_SINGLE_SOURCE
This commit is contained in:
@@ -1,5 +1,17 @@
|
||||
import atexit
|
||||
import os
|
||||
import shutil
|
||||
import tempfile
|
||||
|
||||
from .display import print_warning
|
||||
|
||||
|
||||
def try_remove(path):
|
||||
try:
|
||||
os.remove(path)
|
||||
except: # pylint: disable=bare-except
|
||||
print_warning("Please manually remove the file `{}`".format(path))
|
||||
|
||||
|
||||
def copy_release(target, source, env):
|
||||
# target filename and subdir for release files
|
||||
@@ -20,3 +32,18 @@ def copy_release(target, source, env):
|
||||
|
||||
shutil.copy(src, dest)
|
||||
|
||||
|
||||
# emulate .ino concatenation to speed up compilation times
|
||||
def merge_cpp(sources, output):
|
||||
with tempfile.TemporaryFile() as tmp:
|
||||
tmp.write(b"// !!! Automatically generated file; DO NOT EDIT !!! \n")
|
||||
tmp.write(b'#include "espurna.h"\n')
|
||||
for source in sources:
|
||||
with open(source, "rb") as fobj:
|
||||
shutil.copyfileobj(fobj, tmp)
|
||||
|
||||
tmp.seek(0)
|
||||
|
||||
with open(output, "wb") as fobj:
|
||||
shutil.copyfileobj(tmp, fobj)
|
||||
atexit.register(try_remove, output)
|
||||
|
||||
@@ -97,6 +97,7 @@ def generate_lines(builds, ignore):
|
||||
if build.src_build_flags:
|
||||
flags.append('ESPURNA_FLAGS="{}"'.format(build.src_build_flags))
|
||||
flags.append('ESPURNA_RELEASE_NAME="{env}"'.format(env=build.env))
|
||||
flags.append("ESPURNA_BUILD_SINGLE_SOURCE=1")
|
||||
|
||||
cmd = ["env"]
|
||||
cmd.extend(flags)
|
||||
|
||||
@@ -20,9 +20,11 @@ from espurna_utils import (
|
||||
copy_release,
|
||||
)
|
||||
|
||||
|
||||
Import("env", "projenv")
|
||||
|
||||
import os
|
||||
|
||||
CI = any([os.environ.get("TRAVIS"), os.environ.get("CI")])
|
||||
|
||||
# Always show warnings for project code
|
||||
|
||||
@@ -19,6 +19,8 @@ import sys
|
||||
|
||||
from SCons.Script import ARGUMENTS
|
||||
|
||||
from espurna_utils.release import merge_cpp
|
||||
|
||||
|
||||
CI = any([os.environ.get("TRAVIS"), os.environ.get("CI")])
|
||||
PIO_PLATFORM = env.PioPlatform()
|
||||
@@ -99,7 +101,7 @@ def ensure_platform_updated():
|
||||
env.Append(
|
||||
ESPURNA_BOARD=os.environ.get("ESPURNA_BOARD", ""),
|
||||
ESPURNA_AUTH=os.environ.get("ESPURNA_AUTH", ""),
|
||||
ESPURNA_FLAGS=os.environ.get("ESPURNA_FLAGS", "")
|
||||
ESPURNA_FLAGS=os.environ.get("ESPURNA_FLAGS", ""),
|
||||
)
|
||||
|
||||
ESPURNA_OTA_PORT = os.environ.get("ESPURNA_IP")
|
||||
@@ -115,7 +117,7 @@ if CI:
|
||||
env.Append(
|
||||
ESPURNA_RELEASE_NAME=os.environ.get("ESPURNA_RELEASE_NAME", ""),
|
||||
ESPURNA_RELEASE_VERSION=os.environ.get("ESPURNA_RELEASE_VERSION", ""),
|
||||
ESPURNA_RELEASE_DESTINATION=os.environ.get("ESPURNA_RELEASE_DESTINATION", "")
|
||||
ESPURNA_RELEASE_DESTINATION=os.environ.get("ESPURNA_RELEASE_DESTINATION", ""),
|
||||
)
|
||||
|
||||
# updates arduino core git to the latest master commit
|
||||
@@ -136,3 +138,25 @@ if os.environ.get("ESPURNA_PIO_SHARED_LIBRARIES"):
|
||||
log("using shared library storage: {}".format(storage))
|
||||
|
||||
subprocess_libdeps(env.GetProjectOption("lib_deps"), storage)
|
||||
|
||||
# tweak build system to ignore espurna.ino, but include user code
|
||||
# ref: platformio-core/platformio/tools/piomisc.py::ConvertInoToCpp()
|
||||
def ConvertInoToCpp(env):
|
||||
pass
|
||||
|
||||
|
||||
ino = env.Glob("$PROJECT_DIR/espurna/*.ino") + env.Glob("$PROJECT_DIR/espurna/*.pde")
|
||||
if len(ino) == 1 and ino[0].name == "espurna.ino":
|
||||
env.AddMethod(ConvertInoToCpp)
|
||||
|
||||
# merge every .cpp into a single file and **only** build that single file
|
||||
if os.environ.get("ESPURNA_BUILD_SINGLE_SOURCE"):
|
||||
cpp_files = []
|
||||
for root, dirs, filenames in os.walk("espurna"):
|
||||
for name in filenames:
|
||||
if not name.endswith(".cpp"):
|
||||
continue
|
||||
path = os.path.join(root, name)
|
||||
env.AddBuildMiddleware(lambda node: None, "*?/{}".format(path))
|
||||
cpp_files.append(path)
|
||||
merge_cpp(cpp_files, "espurna/espurna_single_source.cpp")
|
||||
|
||||
@@ -25,52 +25,45 @@ import subprocess
|
||||
import os
|
||||
import sys
|
||||
import datetime
|
||||
from espurna_utils.display import Color, clr, print_warning
|
||||
|
||||
CUSTOM_HEADER = "espurna/config/custom.h"
|
||||
if os.path.exists(CUSTOM_HEADER):
|
||||
raise SystemExit(
|
||||
clr(
|
||||
Color.YELLOW,
|
||||
"{} already exists, please run this script in a git-worktree(1) or a separate directory".format(
|
||||
CUSTOM_HEADER
|
||||
),
|
||||
)
|
||||
)
|
||||
from espurna_utils.display import clr, print_warning, Color
|
||||
|
||||
|
||||
def restore_source_tree(files):
|
||||
cmd = ["git", "checkout", "-f", "--"]
|
||||
cmd.extend(files)
|
||||
subprocess.check_call(cmd)
|
||||
|
||||
|
||||
def try_remove(path):
|
||||
try:
|
||||
os.remove(path)
|
||||
except: # pylint: disable=bare-except
|
||||
except: # pylint: disable=bare-except
|
||||
print_warning("Please manually remove the file `{}`".format(path))
|
||||
|
||||
|
||||
atexit.register(try_remove, CUSTOM_HEADER)
|
||||
total_time = 0
|
||||
|
||||
|
||||
def main(args):
|
||||
configurations = []
|
||||
if not args.no_default:
|
||||
configurations = list(glob.glob(args.default_configurations))
|
||||
def print_total_time():
|
||||
print()
|
||||
print(
|
||||
clr(
|
||||
Color.BOLD,
|
||||
"> Total time: {}".format(datetime.timedelta(seconds=total_time)),
|
||||
)
|
||||
)
|
||||
|
||||
configurations.extend(x for x in (args.add or []))
|
||||
if not configurations:
|
||||
raise SystemExit(clr(Color.YELLOW, "No configurations selected"))
|
||||
|
||||
print(clr(Color.BOLD, "> Selected configurations:"))
|
||||
for cfg in configurations:
|
||||
print(cfg)
|
||||
if args.list:
|
||||
return
|
||||
|
||||
if not args.environment:
|
||||
raise SystemExit(clr(Color.YELLOW, "No environment selected"))
|
||||
print(clr(Color.BOLD, "> Selected environment: {}".format(args.environment)))
|
||||
def run_configurations(args, configurations):
|
||||
cmd = ["platformio", "run"]
|
||||
if not args.no_silent:
|
||||
cmd.extend(["-s"])
|
||||
cmd.extend(["-e", args.environment])
|
||||
|
||||
for cfg in configurations:
|
||||
print(clr(Color.BOLD, "> Building {}".format(cfg)))
|
||||
with open(CUSTOM_HEADER, "w") as custom_h:
|
||||
with open(args.custom_h, "w") as custom_h:
|
||||
|
||||
def write(line):
|
||||
sys.stdout.write(line)
|
||||
@@ -87,11 +80,15 @@ def main(args):
|
||||
os_env = os.environ.copy()
|
||||
os_env["PLATFORMIO_SRC_BUILD_FLAGS"] = "-DUSE_CUSTOM_H"
|
||||
os_env["PLATFORMIO_BUILD_CACHE_DIR"] = "test/pio_cache"
|
||||
cmd = ["platformio", "run", "-s", "-e", args.environment]
|
||||
os_env["ESPURNA_BUILD_SINGLE_SOURCE"] = "1"
|
||||
|
||||
start = time.time()
|
||||
subprocess.check_call(cmd, env=os_env)
|
||||
end = time.time()
|
||||
diff = time.time() - start
|
||||
|
||||
global total_time
|
||||
total_time += diff
|
||||
|
||||
print(
|
||||
clr(
|
||||
Color.BOLD,
|
||||
@@ -100,17 +97,59 @@ def main(args):
|
||||
os.stat(
|
||||
os.path.join(".pio", "build", args.environment, "firmware.bin")
|
||||
).st_size,
|
||||
datetime.timedelta(seconds=(end - start)),
|
||||
datetime.timedelta(seconds=diff),
|
||||
),
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def main(args):
|
||||
if os.path.exists(args.custom_h):
|
||||
raise SystemExit(
|
||||
clr(
|
||||
Color.YELLOW,
|
||||
"{} already exists, please run this script in a git-worktree(1) or a separate directory".format(
|
||||
args.custom_h
|
||||
),
|
||||
)
|
||||
)
|
||||
|
||||
configurations = []
|
||||
if not args.no_default:
|
||||
configurations = list(glob.glob(args.default_configurations))
|
||||
|
||||
configurations.extend(x for x in (args.add or []))
|
||||
if not configurations:
|
||||
raise SystemExit(clr(Color.YELLOW, "No configurations selected"))
|
||||
|
||||
if len(configurations) > 1:
|
||||
atexit.register(print_total_time)
|
||||
|
||||
print(clr(Color.BOLD, "> Selected configurations:"))
|
||||
for cfg in configurations:
|
||||
print(cfg)
|
||||
if args.list:
|
||||
return
|
||||
|
||||
if not args.environment:
|
||||
raise SystemExit(clr(Color.YELLOW, "No environment selected"))
|
||||
print(clr(Color.BOLD, "> Selected environment: {}".format(args.environment)))
|
||||
|
||||
atexit.register(try_remove, args.custom_h)
|
||||
|
||||
run_configurations(args, configurations)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument(
|
||||
"-l", "--list", action="store_true", help="List selected configurations"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--custom-h",
|
||||
default="espurna/config/custom.h",
|
||||
help="Header that will be included in by the config/all.h",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-n",
|
||||
"--no-default",
|
||||
@@ -129,5 +168,8 @@ if __name__ == "__main__":
|
||||
default="test/build/*.h",
|
||||
help="(glob) default configuration headers",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--no-silent", action="store_true", help="Do not silence pio-run"
|
||||
)
|
||||
|
||||
main(parser.parse_args())
|
||||
|
||||
Reference in New Issue
Block a user