N17BLDC/fw/platformio-nunavut.py
2025-06-14 11:46:38 +02:00

98 lines
3.4 KiB
Python

import os
import hashlib
import pathlib
import shlex
import subprocess
import SCons.Action
from platformio import fs
from pathlib import Path
Import("env")
# We don't use `env.Execute` because it does not handle spaces in path
# See https://github.com/nanopb/nanopb/pull/834
# So, we resolve the path to the executable and then use `subprocess.run`
python_exe = env.subst("$PYTHONEXE")
try:
import nunavut
except ImportError:
print("[nunavut] Installing")
subprocess.run([python_exe, '-m', 'pip', 'install', "nunavut"])
import nunavut
import pydsdl
import subprocess
def run_nnvg(asset, lookup, generated_src_dir):
# Define the command as a list of arguments
cmd = [
"nnvg",
"--target-language", "c",
"--enable-serialization-asserts",
f"{asset}", # The input DSDL namespace directory
"--outdir", f"{generated_src_dir}",
]
if len(lookup) > 0:
cmd.extend(["--lookup-dir", f"{lookup}"])
result = subprocess.run(cmd, text=True, capture_output=True)
print("running", " ".join(cmd))
err = str(result.stderr)
if len(err.strip()) > 0:
print("nnvg ERROR:\n", result.stderr)
project_dir = env.subst("$PROJECT_DIR")
build_dir = env.subst("$BUILD_DIR")
generated_src_dir = os.path.join(build_dir, 'nunavut', 'generated-src')
generated_src_dir = os.path.join(project_dir, 'include')
print("generated_src_dir",generated_src_dir)
generated_build_dir = os.path.join(build_dir, 'nunavut', 'generated-build')
md5_dir = os.path.join(build_dir, 'nunavut', 'md5')
dsdl_folders = [x for x in env.subst(env.GetProjectOption("custom_dsdl_folders", "")).split("\n") if x != ""]
print(dsdl_folders)
from pathlib import Path
def generate_dsdl_files(*args, **kwargs):
if not dsdl_folders:
print("[nunavut] No generation needed.")
else:
parent_folder = Path(project_dir)
print("parent_folder", parent_folder)
uavcan_dir = None
for path in parent_folder.rglob("*"):
#if path.is_dir() and path.name in dsdl_folders:
if path.is_dir() and path.name in ["uavcan"]:
uavcan_dir = (str(path.absolute()))
#uavcan_dir = (str(path.relative_to(project_dir)))
print("found uavcan dir:", uavcan_dir)
for path in parent_folder.rglob("*"):
#if path.is_dir() and path.name in dsdl_folders:
if path.is_dir() and any([str(path.absolute()).endswith(d) for d in dsdl_folders]) :
run_nnvg(path.absolute(), uavcan_dir, generated_src_dir)
#
# Add generated includes and sources to build environment
#
run_nnvg(uavcan_dir, "", generated_src_dir)
env.Append(CPPPATH=[generated_src_dir])
env.Append(CXXFLAGS=[f"-I{generated_src_dir}", "flag2"])
#env.BuildSources(generated_build_dir, generated_src_dir)
# # Fix for ESP32 ESP-IDF https://github.com/nanopb/nanopb/issues/734#issuecomment-1001544447
# global_env = DefaultEnvironment()
# already_called_env_name = "_PROTOBUF_GENERATOR_ALREADY_CALLED_" + env['PIOENV'].replace("-", "_")
# if not global_env.get(already_called_env_name, False):
# env.BuildSources(generated_build_dir, generated_src_dir)
# global_env[already_called_env_name] = True
#env.AddCustomTarget("gen_dsdl", None, generate_dsdl_files)
generate_dsdl_files()
#env.AddPreAction("buildprog", generate_dsdl_files)