mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-09 20:41:14 +00:00
make supported in find_apps/build_apps
This commit is contained in:
@@ -1,7 +1,9 @@
|
||||
# coding=utf-8
|
||||
|
||||
import re
|
||||
import shutil
|
||||
import sys
|
||||
import os
|
||||
from abc import abstractmethod
|
||||
from collections import namedtuple
|
||||
import logging
|
||||
import json
|
||||
@@ -43,6 +45,7 @@ class BuildItem(object):
|
||||
Instance of this class represents one build of an application.
|
||||
The parameters which distinguish the build are passed to the constructor.
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
app_path,
|
||||
@@ -194,18 +197,149 @@ class BuildSystem(object):
|
||||
"""
|
||||
|
||||
NAME = "undefined"
|
||||
SUPPORTED_TARGETS_REGEX = re.compile(r'Supported [Tt]argets((?:[\s|]+(?:ESP[0-9A-Z\-]+))+)')
|
||||
|
||||
@staticmethod
|
||||
def build(self):
|
||||
raise NotImplementedError()
|
||||
def build_prepare(build_item):
|
||||
app_path = build_item.app_dir
|
||||
work_path = build_item.work_dir or app_path
|
||||
if not build_item.build_dir:
|
||||
build_path = os.path.join(work_path, "build")
|
||||
elif os.path.isabs(build_item.build_dir):
|
||||
build_path = build_item.build_dir
|
||||
else:
|
||||
build_path = os.path.join(work_path, build_item.build_dir)
|
||||
|
||||
if work_path != app_path:
|
||||
if os.path.exists(work_path):
|
||||
logging.debug("Work directory {} exists, removing".format(work_path))
|
||||
if not build_item.dry_run:
|
||||
shutil.rmtree(work_path)
|
||||
logging.debug("Copying app from {} to {}".format(app_path, work_path))
|
||||
if not build_item.dry_run:
|
||||
shutil.copytree(app_path, work_path)
|
||||
|
||||
if os.path.exists(build_path):
|
||||
logging.debug("Build directory {} exists, removing".format(build_path))
|
||||
if not build_item.dry_run:
|
||||
shutil.rmtree(build_path)
|
||||
|
||||
if not build_item.dry_run:
|
||||
os.makedirs(build_path)
|
||||
|
||||
# Prepare the sdkconfig file, from the contents of sdkconfig.defaults (if exists) and the contents of
|
||||
# build_info.sdkconfig_path, i.e. the config-specific sdkconfig file.
|
||||
#
|
||||
# Note: the build system supports taking multiple sdkconfig.defaults files via SDKCONFIG_DEFAULTS
|
||||
# CMake variable. However here we do this manually to perform environment variable expansion in the
|
||||
# sdkconfig files.
|
||||
sdkconfig_defaults_list = ["sdkconfig.defaults", "sdkconfig.defaults." + build_item.target]
|
||||
if build_item.sdkconfig_path:
|
||||
sdkconfig_defaults_list.append(build_item.sdkconfig_path)
|
||||
|
||||
sdkconfig_file = os.path.join(work_path, "sdkconfig")
|
||||
if os.path.exists(sdkconfig_file):
|
||||
logging.debug("Removing sdkconfig file: {}".format(sdkconfig_file))
|
||||
if not build_item.dry_run:
|
||||
os.unlink(sdkconfig_file)
|
||||
|
||||
logging.debug("Creating sdkconfig file: {}".format(sdkconfig_file))
|
||||
if not build_item.dry_run:
|
||||
with open(sdkconfig_file, "w") as f_out:
|
||||
for sdkconfig_name in sdkconfig_defaults_list:
|
||||
sdkconfig_path = os.path.join(work_path, sdkconfig_name)
|
||||
if not sdkconfig_path or not os.path.exists(sdkconfig_path):
|
||||
continue
|
||||
logging.debug("Appending {} to sdkconfig".format(sdkconfig_name))
|
||||
with open(sdkconfig_path, "r") as f_in:
|
||||
for line in f_in:
|
||||
if not line.endswith("\n"):
|
||||
line += "\n"
|
||||
f_out.write(os.path.expandvars(line))
|
||||
# Also save the sdkconfig file in the build directory
|
||||
shutil.copyfile(
|
||||
os.path.join(work_path, "sdkconfig"),
|
||||
os.path.join(build_path, "sdkconfig"),
|
||||
)
|
||||
|
||||
else:
|
||||
for sdkconfig_name in sdkconfig_defaults_list:
|
||||
sdkconfig_path = os.path.join(app_path, sdkconfig_name)
|
||||
if not sdkconfig_path:
|
||||
continue
|
||||
logging.debug("Considering sdkconfig {}".format(sdkconfig_path))
|
||||
if not os.path.exists(sdkconfig_path):
|
||||
continue
|
||||
logging.debug("Appending {} to sdkconfig".format(sdkconfig_name))
|
||||
|
||||
# The preparation of build is finished. Implement the build part in sub classes.
|
||||
return build_path, work_path
|
||||
|
||||
@staticmethod
|
||||
@abstractmethod
|
||||
def build(build_item):
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
@abstractmethod
|
||||
def is_app(path):
|
||||
raise NotImplementedError()
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
def _read_readme(app_path):
|
||||
# Markdown supported targets should be:
|
||||
# e.g. | Supported Targets | ESP32 |
|
||||
# | ----------------- | ----- |
|
||||
# reStructuredText supported targets should be:
|
||||
# e.g. ================= =====
|
||||
# Supported Targets ESP32
|
||||
# ================= =====
|
||||
def get_md_or_rst(app_path):
|
||||
readme_path = os.path.join(app_path, 'README.md')
|
||||
if not os.path.exists(readme_path):
|
||||
readme_path = os.path.join(app_path, 'README.rst')
|
||||
if not os.path.exists(readme_path):
|
||||
return None
|
||||
return readme_path
|
||||
|
||||
readme_path = get_md_or_rst(app_path)
|
||||
# Handle sub apps situation, e.g. master-slave
|
||||
if not readme_path:
|
||||
readme_path = get_md_or_rst(os.path.dirname(app_path))
|
||||
if not readme_path:
|
||||
return None
|
||||
with open(readme_path, "r") as readme_file:
|
||||
return readme_file.read()
|
||||
|
||||
@staticmethod
|
||||
def supported_targets(app_path):
|
||||
raise NotImplementedError()
|
||||
formal_to_usual = {
|
||||
'ESP32': 'esp32',
|
||||
'ESP32-S2': 'esp32s2',
|
||||
}
|
||||
|
||||
readme_file_content = BuildSystem._read_readme(app_path)
|
||||
if not readme_file_content:
|
||||
return None
|
||||
match = re.findall(BuildSystem.SUPPORTED_TARGETS_REGEX, readme_file_content)
|
||||
if not match:
|
||||
return None
|
||||
if len(match) > 1:
|
||||
raise NotImplementedError("Can't determine the value of SUPPORTED_TARGETS in {}".format(app_path))
|
||||
support_str = match[0].strip()
|
||||
|
||||
targets = []
|
||||
for part in support_str.split('|'):
|
||||
for inner in part.split(' '):
|
||||
inner = inner.strip()
|
||||
if not inner:
|
||||
continue
|
||||
elif inner in formal_to_usual:
|
||||
targets.append(formal_to_usual[inner])
|
||||
else:
|
||||
raise NotImplementedError("Can't recognize value of target {} in {}, now we only support '{}'"
|
||||
.format(inner, app_path, ', '.join(formal_to_usual.keys())))
|
||||
return targets
|
||||
|
||||
|
||||
class BuildError(RuntimeError):
|
||||
|
Reference in New Issue
Block a user