idf_build_apps package

class idf_build_apps.app.App(app_dir: str, target: str, *, work_dir: Optional[str] = None, build_dir: str = 'build', build_log_filename: Optional[str] = None, size_json_filename: Optional[str] = None, build_system: typing_extensions.Literal[unknown] = 'unknown', sdkconfig_path: Optional[str] = None, config_name: Optional[str] = None, sdkconfig_defaults_str: Optional[str] = None, dry_run: bool = False, verbose: bool = False, check_warnings: bool = False, preserve: bool = True, copy_sdkconfig: bool = False, build_apps_args: Optional[BuildAppsArgs] = None, index: Optional[int] = None, build_status: BuildStatus = BuildStatus.UNKNOWN, build_comment: Optional[str] = None)

Bases: BaseModel

FULL_NAME_PLACEHOLDER: ClassVar[str] = '@f'
IDF_VERSION_PLACEHOLDER: ClassVar[str] = '@v'
IGNORE_WARNS_REGEXES: ClassVar[List[Pattern]] = []
INDEX_PLACEHOLDER: ClassVar[str] = '@i'
LOG_DEBUG_LINES: ClassVar[int] = 25
LOG_ERROR_WARNING_REGEX: ClassVar[Pattern] = re.compile('(?:error|warning):', re.IGNORECASE|re.MULTILINE)
MANIFEST: ClassVar[Optional[Manifest]] = None
NAME_PLACEHOLDER: ClassVar[str] = '@n'
SDKCONFIG_LINE_REGEX: ClassVar[Pattern] = re.compile('^([^=]+)=\\"?([^\\"\\n]*)\\"?\\n*$')
TARGET_PLACEHOLDER: ClassVar[str] = '@t'
WILDCARD_PLACEHOLDER: ClassVar[str] = '@w'
app_dir: str
build(*, manifest_rootpath: Optional[str] = None, modified_components: Optional[Union[List[str], str]] = None, modified_files: Optional[Union[List[str], str]] = None, check_app_dependencies: bool = False) None
build_apps_args: Optional[BuildAppsArgs]
build_comment: Optional[str]
property build_dir: str
Returns:

build directory, either relative to the work directory (if relative path is used) or absolute path.

property build_log_filename: Optional[str]
property build_log_path: str
property build_path: str
build_status: BuildStatus
build_system: typing_extensions.Literal[unknown]
check_warnings: bool
config_name: Optional[str]
copy_sdkconfig: bool
property depends_components: List[str]
property depends_filepatterns: List[str]
dry_run: bool
classmethod from_another(other: App, **kwargs) App

Init New App from another, with different parameters.

eg: new_app = [Cmake]App.from_another(app, config=’debug’)

index: Optional[int]
classmethod is_app(path: str) bool
is_error_or_warning(line: str) Tuple[bool, bool]
is_modified(modified_files: Optional[List[str]]) bool
model_config: ClassVar[ConfigDict] = {}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

model_fields: ClassVar[dict[str, FieldInfo]] = {'app_dir': FieldInfo(annotation=str, required=True), 'build_apps_args': FieldInfo(annotation=Union[BuildAppsArgs, NoneType], required=False), 'build_comment': FieldInfo(annotation=Union[str, NoneType], required=False), 'build_status': FieldInfo(annotation=BuildStatus, required=False, default=<BuildStatus.UNKNOWN: 'unknown'>), 'build_system': FieldInfo(annotation=Literal['unknown'], required=False, default='unknown'), 'check_warnings': FieldInfo(annotation=bool, required=False, default=False), 'config_name': FieldInfo(annotation=Union[str, NoneType], required=False), 'copy_sdkconfig': FieldInfo(annotation=bool, required=False, default=False), 'dry_run': FieldInfo(annotation=bool, required=False, default=False), 'index': FieldInfo(annotation=Union[int, NoneType], required=False), 'preserve': FieldInfo(annotation=bool, required=False, default=True), 'sdkconfig_defaults_str': FieldInfo(annotation=Union[str, NoneType], required=False), 'sdkconfig_path': FieldInfo(annotation=Union[str, NoneType], required=False), 'target': FieldInfo(annotation=str, required=True), 'verbose': FieldInfo(annotation=bool, required=False, default=False)}

Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].

This replaces Model.__fields__ from Pydantic V1.

model_post_init(__context: Any) None

This function is meant to behave like a BaseModel method to initialise private attributes.

It takes context as an argument since that’s what pydantic-core passes when calling it.

Args:

self: The BaseModel instance. __context: The context.

property name: str
preserve: bool
record_build_duration()
property sdkconfig_defaults_candidates: List[str]
sdkconfig_defaults_str: Optional[str]
property sdkconfig_files: List[str]
property sdkconfig_files_defined_idf_target: Optional[str]
sdkconfig_path: Optional[str]
property size_json_filename: Optional[str]
property size_json_path: Optional[str]
property supported_targets: List[str]
target: str
to_json() str
verbose: bool
property verified_targets: List[str]
property work_dir: str
Returns:

directory where the app should be copied to, prior to the build.

write_size_json() None
class idf_build_apps.app.AppDeserializer(*, app: Union[App, CMakeApp, MakeApp])

Bases: BaseModel

app: Union[App, CMakeApp, MakeApp]
classmethod from_json(json_data: Union[str, bytes, bytearray]) App
model_config: ClassVar[ConfigDict] = {}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

model_fields: ClassVar[dict[str, FieldInfo]] = {'app': FieldInfo(annotation=Union[App, CMakeApp, MakeApp], required=True, discriminator='build_system')}

Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].

This replaces Model.__fields__ from Pydantic V1.

class idf_build_apps.app.CMakeApp(app_dir: str, target: str, *, work_dir: Optional[str] = None, build_dir: str = 'build', build_log_filename: Optional[str] = None, size_json_filename: Optional[str] = None, build_system: typing_extensions.Literal[cmake] = 'cmake', sdkconfig_path: Optional[str] = None, config_name: Optional[str] = None, sdkconfig_defaults_str: Optional[str] = None, dry_run: bool = False, verbose: bool = False, check_warnings: bool = False, preserve: bool = True, copy_sdkconfig: bool = False, build_apps_args: Optional[BuildAppsArgs] = None, index: Optional[int] = None, build_status: BuildStatus = BuildStatus.UNKNOWN, build_comment: Optional[str] = None, cmake_vars: Dict[str, str] = {})

Bases: App

CMAKE_PROJECT_LINE: ClassVar[str] = 'include($ENV{IDF_PATH}/tools/cmake/project.cmake)'
SDKCONFIG_IGNORE_OPTS: ClassVar[List[str]] = ['TEST_GROUPS']
SDKCONFIG_TEST_OPTS: ClassVar[List[str]] = ['EXCLUDE_COMPONENTS', 'TEST_EXCLUDE_COMPONENTS', 'TEST_COMPONENTS']
build_system: typing_extensions.Literal[cmake]
cmake_vars: Dict[str, str]
classmethod is_app(path: str) bool
model_config: ClassVar[ConfigDict] = {}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

model_fields: ClassVar[dict[str, FieldInfo]] = {'app_dir': FieldInfo(annotation=str, required=True), 'build_apps_args': FieldInfo(annotation=Union[BuildAppsArgs, NoneType], required=False), 'build_comment': FieldInfo(annotation=Union[str, NoneType], required=False), 'build_status': FieldInfo(annotation=BuildStatus, required=False, default=<BuildStatus.UNKNOWN: 'unknown'>), 'build_system': FieldInfo(annotation=Literal['cmake'], required=False, default='cmake'), 'check_warnings': FieldInfo(annotation=bool, required=False, default=False), 'cmake_vars': FieldInfo(annotation=Dict[str, str], required=False, default={}), 'config_name': FieldInfo(annotation=Union[str, NoneType], required=False), 'copy_sdkconfig': FieldInfo(annotation=bool, required=False, default=False), 'dry_run': FieldInfo(annotation=bool, required=False, default=False), 'index': FieldInfo(annotation=Union[int, NoneType], required=False), 'preserve': FieldInfo(annotation=bool, required=False, default=True), 'sdkconfig_defaults_str': FieldInfo(annotation=Union[str, NoneType], required=False), 'sdkconfig_path': FieldInfo(annotation=Union[str, NoneType], required=False), 'target': FieldInfo(annotation=str, required=True), 'verbose': FieldInfo(annotation=bool, required=False, default=False)}

Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].

This replaces Model.__fields__ from Pydantic V1.

class idf_build_apps.app.MakeApp(app_dir: str, target: str, *, work_dir: Optional[str] = None, build_dir: str = 'build', build_log_filename: Optional[str] = None, size_json_filename: Optional[str] = None, build_system: typing_extensions.Literal[make] = 'make', sdkconfig_path: Optional[str] = None, config_name: Optional[str] = None, sdkconfig_defaults_str: Optional[str] = None, dry_run: bool = False, verbose: bool = False, check_warnings: bool = False, preserve: bool = True, copy_sdkconfig: bool = False, build_apps_args: Optional[BuildAppsArgs] = None, index: Optional[int] = None, build_status: BuildStatus = BuildStatus.UNKNOWN, build_comment: Optional[str] = None)

Bases: App

MAKE_PROJECT_LINE: ClassVar[str] = 'include $(IDF_PATH)/make/project.mk'
build_system: typing_extensions.Literal[make]
classmethod is_app(path: str) bool
model_config: ClassVar[ConfigDict] = {}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

model_fields: ClassVar[dict[str, FieldInfo]] = {'app_dir': FieldInfo(annotation=str, required=True), 'build_apps_args': FieldInfo(annotation=Union[BuildAppsArgs, NoneType], required=False), 'build_comment': FieldInfo(annotation=Union[str, NoneType], required=False), 'build_status': FieldInfo(annotation=BuildStatus, required=False, default=<BuildStatus.UNKNOWN: 'unknown'>), 'build_system': FieldInfo(annotation=Literal['make'], required=False, default='make'), 'check_warnings': FieldInfo(annotation=bool, required=False, default=False), 'config_name': FieldInfo(annotation=Union[str, NoneType], required=False), 'copy_sdkconfig': FieldInfo(annotation=bool, required=False, default=False), 'dry_run': FieldInfo(annotation=bool, required=False, default=False), 'index': FieldInfo(annotation=Union[int, NoneType], required=False), 'preserve': FieldInfo(annotation=bool, required=False, default=True), 'sdkconfig_defaults_str': FieldInfo(annotation=Union[str, NoneType], required=False), 'sdkconfig_path': FieldInfo(annotation=Union[str, NoneType], required=False), 'target': FieldInfo(annotation=str, required=True), 'verbose': FieldInfo(annotation=bool, required=False, default=False)}

Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].

This replaces Model.__fields__ from Pydantic V1.

property supported_targets: List[str]
class idf_build_apps.build_apps_args.BuildAppsArgs(*, collect_app_info: Optional[str] = None, collect_size_info: Optional[str] = None, junitxml: Optional[str] = None, parallel_index: int = 1, parallel_count: int = 1)

Bases: BaseModel

PARALLEL_INDEX_PLACEHOLDER: ClassVar[str] = '@p'
property collect_app_info: Optional[str]
property collect_size_info: Optional[str]
expand(path)
property junitxml: Optional[str]
model_config: ClassVar[ConfigDict] = {}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

model_fields: ClassVar[dict[str, FieldInfo]] = {'parallel_count': FieldInfo(annotation=int, required=False, default=1), 'parallel_index': FieldInfo(annotation=int, required=False, default=1)}

Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].

This replaces Model.__fields__ from Pydantic V1.

model_post_init(__context: Any) None

This function is meant to behave like a BaseModel method to initialise private attributes.

It takes context as an argument since that’s what pydantic-core passes when calling it.

Args:

self: The BaseModel instance. __context: The context.

parallel_count: int
parallel_index: int
exception idf_build_apps.config.InvalidTomlError(filepath: Union[str, Path], msg: str)

Bases: SystemExit

idf_build_apps.config.get_valid_config(starts_from: str = '/home/docs/checkouts/readthedocs.org/user_builds/espressif-idf-build-apps/checkouts/latest/docs', custom_path: Optional[str] = None) Optional[dict]
idf_build_apps.config.load_toml(filepath: Union[str, Path]) dict
class idf_build_apps.constants.BuildStage(value)

Bases: str, Enum

An enumeration.

BUILD = 'Build'
DRY_RUN = 'Dry Run'
POST_BUILD = 'Post Build'
PRE_BUILD = 'Pre Build'
classmethod max_length() int
class idf_build_apps.constants.BuildStatus(value)

Bases: str, Enum

An enumeration.

FAILED = 'build failed'
SHOULD_BE_BUILT = 'should be built'
SKIPPED = 'skipped'
SUCCESS = 'build success'
UNKNOWN = 'unknown'
class idf_build_apps.log.ColoredFormatter(colored: bool = True)

Bases: Formatter

FORMATS: Dict[int, str] = {10: '\x1b[37;20m{}\x1b[0m', 20: '{}', 30: '\x1b[33;20m{}\x1b[0m', 40: '\x1b[31;20m{}\x1b[0m', 50: '\x1b[31;1m{}\x1b[0m'}
app_fmt: str = '%(asctime)s %(levelname)8s [%(build_stage)10s] %(message)s'
bold_red: str = '\x1b[31;1m'
datefmt: str = '%Y-%m-%d %H:%M:%S'
fmt: str = '%(asctime)s %(levelname)8s %(message)s'
format(record: LogRecord) str

Format the specified record as text.

The record’s attribute dictionary is used as the operand to a string formatting operation which yields the returned string. Before formatting the dictionary, a couple of preparatory steps are carried out. The message attribute of the record is computed using LogRecord.getMessage(). If the formatting string uses the time (as determined by a call to usesTime(), formatTime() is called to format the event time. If there is exception information, it is formatted using formatException() and appended to the message.

grey: str = '\x1b[37;20m'
red: str = '\x1b[31;20m'
reset: str = '\x1b[0m'
yellow: str = '\x1b[33;20m'
idf_build_apps.log.setup_logging(verbose: int = 0, log_file: Optional[str] = None, colored: bool = True) None

Setup logging stream handler

Parameters:
  • verbose – 0 - WARNING, 1 - INFO, 2 - DEBUG

  • log_file – log file path

  • colored – colored output or not

Returns:

None

class idf_build_apps.main.IdfBuildAppsCliFormatter(prog, indent_increment=2, max_help_position=24, width=None)

Bases: HelpFormatter

LINE_SEP = '$LINE_SEP$'
idf_build_apps.main.apply_config_args(args: Namespace) None
idf_build_apps.main.build_apps(apps: Union[List[App], App], *, build_verbose: bool = False, dry_run: bool = False, keep_going: bool = False, ignore_warning_strs: Optional[List[str]] = None, ignore_warning_file: Optional[TextIO] = None, copy_sdkconfig: bool = False, manifest_rootpath: Optional[str] = None, modified_components: Optional[Union[List[str], str]] = None, modified_files: Optional[Union[List[str], str]] = None, ignore_app_dependencies_components: Optional[Union[List[str], str]] = None, ignore_app_dependencies_filepatterns: Optional[Union[List[str], str]] = None, check_app_dependencies: Optional[bool] = None, parallel_count: int = 1, parallel_index: int = 1, collect_size_info: Optional[str] = None, collect_app_info: Optional[str] = None, junitxml: Optional[str] = None) int

Build all the specified apps

Parameters:
  • apps – list of apps to be built

  • build_verbose – call --verbose in idf.py build or not

  • dry_run – simulate this run or not

  • keep_going – keep building or not if one app’s build failed

  • ignore_warning_strs – ignore build warnings that matches any of the specified regex patterns

  • ignore_warning_file – ignore build warnings that matches any of the lines of the regex patterns in the specified file

  • copy_sdkconfig – copy the sdkconfig file to the build directory or not

  • manifest_rootpath – The root path of the manifest files. Usually the folders specified in the manifest files are relative paths. Use the current directory if not specified

  • modified_components – modified components

  • modified_files – modified files

  • ignore_app_dependencies_components – components used for ignoring checking the app dependencies

  • ignore_app_dependencies_filepatterns – file patterns used for ignoring checking the app dependencies

  • check_app_dependencies – check app dependencies or not. if not set, will be calculated by modified_components, modified_files, and ignore_app_dependencies_filepatterns

  • parallel_count – number of parallel tasks to run

  • parallel_index – index of the parallel task to run

  • collect_size_info – file path to record all generated size files’ paths if specified

  • collect_app_info – file path to record all the built apps’ info if specified

  • junitxml – path of the junitxml file

Returns:

exit code

idf_build_apps.main.find_apps(paths: ~typing.Union[~typing.List[str], str], target: str, *, build_system: ~typing.Union[~typing.Type[~idf_build_apps.app.App], str] = <class 'idf_build_apps.app.CMakeApp'>, recursive: bool = False, exclude_list: ~typing.Optional[~typing.List[str]] = None, work_dir: ~typing.Optional[str] = None, build_dir: str = 'build', config_rules_str: ~typing.Optional[~typing.Union[~typing.List[str], str]] = None, build_log_filename: ~typing.Optional[str] = None, size_json_filename: ~typing.Optional[str] = None, check_warnings: bool = False, preserve: bool = True, manifest_rootpath: ~typing.Optional[str] = None, manifest_files: ~typing.Optional[~typing.Union[~typing.List[str], str]] = None, check_manifest_rules: bool = False, default_build_targets: ~typing.Optional[~typing.Union[~typing.List[str], str]] = None, modified_components: ~typing.Optional[~typing.Union[~typing.List[str], str]] = None, modified_files: ~typing.Optional[~typing.Union[~typing.List[str], str]] = None, ignore_app_dependencies_components: ~typing.Optional[~typing.Union[~typing.List[str], str]] = None, ignore_app_dependencies_filepatterns: ~typing.Optional[~typing.Union[~typing.List[str], str]] = None, sdkconfig_defaults: ~typing.Optional[str] = None, include_skipped_apps: bool = False) List[App]

Find app directories in paths (possibly recursively), which contain apps for the given build system, compatible with the given target

Parameters:
  • paths – list of app directories (can be / usually will be a relative path)

  • target – desired value of IDF_TARGET; apps incompatible with the given target are skipped.

  • build_system – class of the build system, default CMakeApp

  • recursive – Recursively search into the nested sub-folders if no app is found or not

  • exclude_list – list of paths to be excluded from the recursive search

  • work_dir – directory where the app should be copied before building. Support placeholders

  • build_dir – directory where the build will be done. Support placeholders.

  • config_rules_str – mapping of sdkconfig file name patterns to configuration names

  • build_log_filename – filename of the build log. Will be placed under the app.build_path. Support placeholders. The logs will go to stdout/stderr if not specified

  • size_json_filename – filename to collect the app’s size information. Will be placed under the app.build_path. Support placeholders. The app’s size information won’t be collected if not specified

  • check_warnings – Check for warnings in the build log or not

  • preserve – Preserve the built binaries or not

  • manifest_rootpath – The root path of the manifest files. Usually the folders specified in the manifest files are relative paths. Use the current directory if not specified

  • manifest_files – paths of the manifest files

  • check_manifest_rules – check the manifest rules or not

  • default_build_targets – default build targets used in manifest files

  • modified_components – modified components

  • modified_files – modified files

  • ignore_app_dependencies_components – components used for ignoring checking the app dependencies

  • ignore_app_dependencies_filepatterns – file patterns used for ignoring checking the app dependencies

  • sdkconfig_defaults – semicolon-separated string, pass to idf.py -DSDKCONFIG_DEFAULTS if specified, also could be set via environment variables “SDKCONFIG_DEFAULTS”

  • include_skipped_apps – include skipped apps or not

Returns:

list of found apps

idf_build_apps.main.get_parser() ArgumentParser
idf_build_apps.main.json_to_app(json_str: str, extra_classes: Optional[List[Type[App]]] = None) App

Deserialize json string to App object

Note

You can pass extra_cls to support custom App class. A custom App class must be a subclass of App, and have a different value of build_system. For example, a custom CMake app

>>> class CustomApp(CMakeApp):
>>>    build_system: Literal['custom_cmake'] = 'custom_cmake'

Then you can pass the CustomApp class to the extra_cls argument

>>> json_str = CustomApp('.', 'esp32').to_json()
>>> json_to_app(json_str, extra_classes=[CustomApp])
Parameters:
  • json_str – json string

  • extra_classes – extra App class

Returns:

App object

idf_build_apps.main.main()
idf_build_apps.main.validate_args(parser: ArgumentParser, args: Namespace) None
class idf_build_apps.session_args.SessionArgs

Bases: object

clean()
override_sdkconfig_file_path: Optional[str] = None
override_sdkconfig_items: Dict[str, Any] = {}
set(parsed_args, *, workdir=None)
workdir: str = '/home/docs/checkouts/readthedocs.org/user_builds/espressif-idf-build-apps/checkouts/latest/docs'
class idf_build_apps.utils.BaseModel

Bases: BaseModel

BaseModel that is hashable

model_config: ClassVar[ConfigDict] = {}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

model_fields: ClassVar[dict[str, FieldInfo]] = {}

Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].

This replaces Model.__fields__ from Pydantic V1.

exception idf_build_apps.utils.BuildError

Bases: RuntimeError

class idf_build_apps.utils.ConfigRule(file_name: str, config_name: str = '')

Bases: object

exception idf_build_apps.utils.InvalidCommand(msg: str)

Bases: SystemExit

exception idf_build_apps.utils.InvalidIfClause

Bases: SystemExit

Invalid if clause in manifest file

exception idf_build_apps.utils.InvalidInput

Bases: SystemExit

Invalid input from user

exception idf_build_apps.utils.InvalidManifest

Bases: SystemExit

Invalid manifest file

idf_build_apps.utils.config_rules_from_str(rule_strings: Optional[List[str]]) List[ConfigRule]

Helper function to convert strings like ‘file_name=config_name’ into ConfigRule objects

Parameters:

rule_strings – list of rules as strings or a single rule string

Returns:

list of ConfigRules

idf_build_apps.utils.files_matches_patterns(files: Union[List[str], str], patterns: Union[List[str], str], rootpath: Optional[str] = None) bool
idf_build_apps.utils.find_first_match(pattern: str, path: str) Optional[str]
idf_build_apps.utils.get_parallel_start_stop(total: int, parallel_count: int, parallel_index: int) Tuple[int, int]

Calculate the start and stop indices for a parallel task (1-based).

Parameters:
  • total – total number of tasks

  • parallel_count – number of parallel tasks to run

  • parallel_index – index of the parallel task to run

Returns:

start and stop indices, [start, stop]

idf_build_apps.utils.rmdir(path: str, exclude_file_patterns: Optional[Union[List[str], str]] = None) None
idf_build_apps.utils.semicolon_separated_str_to_list(s: Optional[str]) Optional[List[str]]

Split a string by semicolon and strip each part

Args:

s: string to split

Returns:

list of strings

idf_build_apps.utils.subprocess_run(cmd: List[str], log_terminal: bool = True, log_fs: Optional[Union[IO[str], str]] = None, check: bool = False, additional_env_dict: Optional[Dict[str, str]] = None, **kwargs) int

Subprocess.run for older python versions

Parameters:
  • cmd – cmd

  • log_terminal – print to sys.stdout if set to True

  • log_fs – write to this file stream if not None

  • check – raise BuildError when return code is non-zero

  • additional_env_dict – additional environment variables

Returns:

return code

idf_build_apps.utils.to_absolute_path(s: str, rootpath: Optional[str] = None) str
idf_build_apps.utils.to_list(s: None) None
idf_build_apps.utils.to_list(s: Iterable[_T]) List[_T]
idf_build_apps.utils.to_list(s: _T) List[_T]

Turn all objects to lists

Parameters:

s – anything

Returns:

  • None, if s is None

  • itself, if s is a list

  • list(s), if s is a tuple or a set

  • [s], if s is other type

idf_build_apps.utils.to_set(s: None) None
idf_build_apps.utils.to_set(s: Iterable[_T]) Set[_T]
idf_build_apps.utils.to_set(s: _T) Set[_T]

Turn all objects to sets

Parameters:

s – anything

Returns:

  • None, if s is None

  • itself, if s is a set

  • set(to_list(s)), if s is other type

idf_build_apps.utils.to_version(s: Any) Version

Tools for building ESP-IDF related apps.

class idf_build_apps.App(app_dir: str, target: str, *, work_dir: Optional[str] = None, build_dir: str = 'build', build_log_filename: Optional[str] = None, size_json_filename: Optional[str] = None, build_system: typing_extensions.Literal[unknown] = 'unknown', sdkconfig_path: Optional[str] = None, config_name: Optional[str] = None, sdkconfig_defaults_str: Optional[str] = None, dry_run: bool = False, verbose: bool = False, check_warnings: bool = False, preserve: bool = True, copy_sdkconfig: bool = False, build_apps_args: Optional[BuildAppsArgs] = None, index: Optional[int] = None, build_status: BuildStatus = BuildStatus.UNKNOWN, build_comment: Optional[str] = None)

Bases: BaseModel

FULL_NAME_PLACEHOLDER: ClassVar[str] = '@f'
IDF_VERSION_PLACEHOLDER: ClassVar[str] = '@v'
IGNORE_WARNS_REGEXES: ClassVar[List[Pattern]] = []
INDEX_PLACEHOLDER: ClassVar[str] = '@i'
LOG_DEBUG_LINES: ClassVar[int] = 25
LOG_ERROR_WARNING_REGEX: ClassVar[Pattern] = re.compile('(?:error|warning):', re.IGNORECASE|re.MULTILINE)
MANIFEST: ClassVar[Optional[Manifest]] = None
NAME_PLACEHOLDER: ClassVar[str] = '@n'
SDKCONFIG_LINE_REGEX: ClassVar[Pattern] = re.compile('^([^=]+)=\\"?([^\\"\\n]*)\\"?\\n*$')
TARGET_PLACEHOLDER: ClassVar[str] = '@t'
WILDCARD_PLACEHOLDER: ClassVar[str] = '@w'
app_dir: str
build(*, manifest_rootpath: Optional[str] = None, modified_components: Optional[Union[List[str], str]] = None, modified_files: Optional[Union[List[str], str]] = None, check_app_dependencies: bool = False) None
build_apps_args: Optional[BuildAppsArgs]
build_comment: Optional[str]
property build_dir: str
Returns:

build directory, either relative to the work directory (if relative path is used) or absolute path.

property build_log_filename: Optional[str]
property build_log_path: str
property build_path: str
build_status: BuildStatus
build_system: typing_extensions.Literal[unknown]
check_warnings: bool
config_name: Optional[str]
copy_sdkconfig: bool
property depends_components: List[str]
property depends_filepatterns: List[str]
dry_run: bool
classmethod from_another(other: App, **kwargs) App

Init New App from another, with different parameters.

eg: new_app = [Cmake]App.from_another(app, config=’debug’)

index: Optional[int]
classmethod is_app(path: str) bool
is_error_or_warning(line: str) Tuple[bool, bool]
is_modified(modified_files: Optional[List[str]]) bool
model_config: ClassVar[ConfigDict] = {}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

model_fields: ClassVar[dict[str, FieldInfo]] = {'app_dir': FieldInfo(annotation=str, required=True), 'build_apps_args': FieldInfo(annotation=Union[BuildAppsArgs, NoneType], required=False), 'build_comment': FieldInfo(annotation=Union[str, NoneType], required=False), 'build_status': FieldInfo(annotation=BuildStatus, required=False, default=<BuildStatus.UNKNOWN: 'unknown'>), 'build_system': FieldInfo(annotation=Literal['unknown'], required=False, default='unknown'), 'check_warnings': FieldInfo(annotation=bool, required=False, default=False), 'config_name': FieldInfo(annotation=Union[str, NoneType], required=False), 'copy_sdkconfig': FieldInfo(annotation=bool, required=False, default=False), 'dry_run': FieldInfo(annotation=bool, required=False, default=False), 'index': FieldInfo(annotation=Union[int, NoneType], required=False), 'preserve': FieldInfo(annotation=bool, required=False, default=True), 'sdkconfig_defaults_str': FieldInfo(annotation=Union[str, NoneType], required=False), 'sdkconfig_path': FieldInfo(annotation=Union[str, NoneType], required=False), 'target': FieldInfo(annotation=str, required=True), 'verbose': FieldInfo(annotation=bool, required=False, default=False)}

Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].

This replaces Model.__fields__ from Pydantic V1.

model_post_init(__context: Any) None

This function is meant to behave like a BaseModel method to initialise private attributes.

It takes context as an argument since that’s what pydantic-core passes when calling it.

Args:

self: The BaseModel instance. __context: The context.

property name: str
preserve: bool
record_build_duration()
property sdkconfig_defaults_candidates: List[str]
sdkconfig_defaults_str: Optional[str]
property sdkconfig_files: List[str]
property sdkconfig_files_defined_idf_target: Optional[str]
sdkconfig_path: Optional[str]
property size_json_filename: Optional[str]
property size_json_path: Optional[str]
property supported_targets: List[str]
target: str
to_json() str
verbose: bool
property verified_targets: List[str]
property work_dir: str
Returns:

directory where the app should be copied to, prior to the build.

write_size_json() None
class idf_build_apps.AppDeserializer(*, app: Union[App, CMakeApp, MakeApp])

Bases: BaseModel

app: Union[App, CMakeApp, MakeApp]
classmethod from_json(json_data: Union[str, bytes, bytearray]) App
model_config: ClassVar[ConfigDict] = {}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

model_fields: ClassVar[dict[str, FieldInfo]] = {'app': FieldInfo(annotation=Union[App, CMakeApp, MakeApp], required=True, discriminator='build_system')}

Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].

This replaces Model.__fields__ from Pydantic V1.

class idf_build_apps.CMakeApp(app_dir: str, target: str, *, work_dir: Optional[str] = None, build_dir: str = 'build', build_log_filename: Optional[str] = None, size_json_filename: Optional[str] = None, build_system: typing_extensions.Literal[cmake] = 'cmake', sdkconfig_path: Optional[str] = None, config_name: Optional[str] = None, sdkconfig_defaults_str: Optional[str] = None, dry_run: bool = False, verbose: bool = False, check_warnings: bool = False, preserve: bool = True, copy_sdkconfig: bool = False, build_apps_args: Optional[BuildAppsArgs] = None, index: Optional[int] = None, build_status: BuildStatus = BuildStatus.UNKNOWN, build_comment: Optional[str] = None, cmake_vars: Dict[str, str] = {})

Bases: App

CMAKE_PROJECT_LINE: ClassVar[str] = 'include($ENV{IDF_PATH}/tools/cmake/project.cmake)'
SDKCONFIG_IGNORE_OPTS: ClassVar[List[str]] = ['TEST_GROUPS']
SDKCONFIG_TEST_OPTS: ClassVar[List[str]] = ['EXCLUDE_COMPONENTS', 'TEST_EXCLUDE_COMPONENTS', 'TEST_COMPONENTS']
app_dir: str
build_apps_args: t.Optional[BuildAppsArgs]
build_comment: t.Optional[str]
build_status: BuildStatus
build_system: typing_extensions.Literal[cmake]
check_warnings: bool
cmake_vars: Dict[str, str]
config_name: t.Optional[str]
copy_sdkconfig: bool
dry_run: bool
index: t.Optional[int]
classmethod is_app(path: str) bool
model_config: ClassVar[ConfigDict] = {}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

model_fields: ClassVar[dict[str, FieldInfo]] = {'app_dir': FieldInfo(annotation=str, required=True), 'build_apps_args': FieldInfo(annotation=Union[BuildAppsArgs, NoneType], required=False), 'build_comment': FieldInfo(annotation=Union[str, NoneType], required=False), 'build_status': FieldInfo(annotation=BuildStatus, required=False, default=<BuildStatus.UNKNOWN: 'unknown'>), 'build_system': FieldInfo(annotation=Literal['cmake'], required=False, default='cmake'), 'check_warnings': FieldInfo(annotation=bool, required=False, default=False), 'cmake_vars': FieldInfo(annotation=Dict[str, str], required=False, default={}), 'config_name': FieldInfo(annotation=Union[str, NoneType], required=False), 'copy_sdkconfig': FieldInfo(annotation=bool, required=False, default=False), 'dry_run': FieldInfo(annotation=bool, required=False, default=False), 'index': FieldInfo(annotation=Union[int, NoneType], required=False), 'preserve': FieldInfo(annotation=bool, required=False, default=True), 'sdkconfig_defaults_str': FieldInfo(annotation=Union[str, NoneType], required=False), 'sdkconfig_path': FieldInfo(annotation=Union[str, NoneType], required=False), 'target': FieldInfo(annotation=str, required=True), 'verbose': FieldInfo(annotation=bool, required=False, default=False)}

Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].

This replaces Model.__fields__ from Pydantic V1.

preserve: bool
sdkconfig_defaults_str: t.Optional[str]
sdkconfig_path: t.Optional[str]
target: str
verbose: bool
class idf_build_apps.MakeApp(app_dir: str, target: str, *, work_dir: Optional[str] = None, build_dir: str = 'build', build_log_filename: Optional[str] = None, size_json_filename: Optional[str] = None, build_system: typing_extensions.Literal[make] = 'make', sdkconfig_path: Optional[str] = None, config_name: Optional[str] = None, sdkconfig_defaults_str: Optional[str] = None, dry_run: bool = False, verbose: bool = False, check_warnings: bool = False, preserve: bool = True, copy_sdkconfig: bool = False, build_apps_args: Optional[BuildAppsArgs] = None, index: Optional[int] = None, build_status: BuildStatus = BuildStatus.UNKNOWN, build_comment: Optional[str] = None)

Bases: App

MAKE_PROJECT_LINE: ClassVar[str] = 'include $(IDF_PATH)/make/project.mk'
app_dir: str
build_apps_args: t.Optional[BuildAppsArgs]
build_comment: t.Optional[str]
build_status: BuildStatus
build_system: typing_extensions.Literal[make]
check_warnings: bool
config_name: t.Optional[str]
copy_sdkconfig: bool
dry_run: bool
index: t.Optional[int]
classmethod is_app(path: str) bool
model_config: ClassVar[ConfigDict] = {}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

model_fields: ClassVar[dict[str, FieldInfo]] = {'app_dir': FieldInfo(annotation=str, required=True), 'build_apps_args': FieldInfo(annotation=Union[BuildAppsArgs, NoneType], required=False), 'build_comment': FieldInfo(annotation=Union[str, NoneType], required=False), 'build_status': FieldInfo(annotation=BuildStatus, required=False, default=<BuildStatus.UNKNOWN: 'unknown'>), 'build_system': FieldInfo(annotation=Literal['make'], required=False, default='make'), 'check_warnings': FieldInfo(annotation=bool, required=False, default=False), 'config_name': FieldInfo(annotation=Union[str, NoneType], required=False), 'copy_sdkconfig': FieldInfo(annotation=bool, required=False, default=False), 'dry_run': FieldInfo(annotation=bool, required=False, default=False), 'index': FieldInfo(annotation=Union[int, NoneType], required=False), 'preserve': FieldInfo(annotation=bool, required=False, default=True), 'sdkconfig_defaults_str': FieldInfo(annotation=Union[str, NoneType], required=False), 'sdkconfig_path': FieldInfo(annotation=Union[str, NoneType], required=False), 'target': FieldInfo(annotation=str, required=True), 'verbose': FieldInfo(annotation=bool, required=False, default=False)}

Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].

This replaces Model.__fields__ from Pydantic V1.

preserve: bool
sdkconfig_defaults_str: t.Optional[str]
sdkconfig_path: t.Optional[str]
property supported_targets: List[str]
target: str
verbose: bool
idf_build_apps.build_apps(apps: Union[List[App], App], *, build_verbose: bool = False, dry_run: bool = False, keep_going: bool = False, ignore_warning_strs: Optional[List[str]] = None, ignore_warning_file: Optional[TextIO] = None, copy_sdkconfig: bool = False, manifest_rootpath: Optional[str] = None, modified_components: Optional[Union[List[str], str]] = None, modified_files: Optional[Union[List[str], str]] = None, ignore_app_dependencies_components: Optional[Union[List[str], str]] = None, ignore_app_dependencies_filepatterns: Optional[Union[List[str], str]] = None, check_app_dependencies: Optional[bool] = None, parallel_count: int = 1, parallel_index: int = 1, collect_size_info: Optional[str] = None, collect_app_info: Optional[str] = None, junitxml: Optional[str] = None) int

Build all the specified apps

Parameters:
  • apps – list of apps to be built

  • build_verbose – call --verbose in idf.py build or not

  • dry_run – simulate this run or not

  • keep_going – keep building or not if one app’s build failed

  • ignore_warning_strs – ignore build warnings that matches any of the specified regex patterns

  • ignore_warning_file – ignore build warnings that matches any of the lines of the regex patterns in the specified file

  • copy_sdkconfig – copy the sdkconfig file to the build directory or not

  • manifest_rootpath – The root path of the manifest files. Usually the folders specified in the manifest files are relative paths. Use the current directory if not specified

  • modified_components – modified components

  • modified_files – modified files

  • ignore_app_dependencies_components – components used for ignoring checking the app dependencies

  • ignore_app_dependencies_filepatterns – file patterns used for ignoring checking the app dependencies

  • check_app_dependencies – check app dependencies or not. if not set, will be calculated by modified_components, modified_files, and ignore_app_dependencies_filepatterns

  • parallel_count – number of parallel tasks to run

  • parallel_index – index of the parallel task to run

  • collect_size_info – file path to record all generated size files’ paths if specified

  • collect_app_info – file path to record all the built apps’ info if specified

  • junitxml – path of the junitxml file

Returns:

exit code

idf_build_apps.find_apps(paths: ~typing.Union[~typing.List[str], str], target: str, *, build_system: ~typing.Union[~typing.Type[~idf_build_apps.app.App], str] = <class 'idf_build_apps.app.CMakeApp'>, recursive: bool = False, exclude_list: ~typing.Optional[~typing.List[str]] = None, work_dir: ~typing.Optional[str] = None, build_dir: str = 'build', config_rules_str: ~typing.Optional[~typing.Union[~typing.List[str], str]] = None, build_log_filename: ~typing.Optional[str] = None, size_json_filename: ~typing.Optional[str] = None, check_warnings: bool = False, preserve: bool = True, manifest_rootpath: ~typing.Optional[str] = None, manifest_files: ~typing.Optional[~typing.Union[~typing.List[str], str]] = None, check_manifest_rules: bool = False, default_build_targets: ~typing.Optional[~typing.Union[~typing.List[str], str]] = None, modified_components: ~typing.Optional[~typing.Union[~typing.List[str], str]] = None, modified_files: ~typing.Optional[~typing.Union[~typing.List[str], str]] = None, ignore_app_dependencies_components: ~typing.Optional[~typing.Union[~typing.List[str], str]] = None, ignore_app_dependencies_filepatterns: ~typing.Optional[~typing.Union[~typing.List[str], str]] = None, sdkconfig_defaults: ~typing.Optional[str] = None, include_skipped_apps: bool = False) List[App]

Find app directories in paths (possibly recursively), which contain apps for the given build system, compatible with the given target

Parameters:
  • paths – list of app directories (can be / usually will be a relative path)

  • target – desired value of IDF_TARGET; apps incompatible with the given target are skipped.

  • build_system – class of the build system, default CMakeApp

  • recursive – Recursively search into the nested sub-folders if no app is found or not

  • exclude_list – list of paths to be excluded from the recursive search

  • work_dir – directory where the app should be copied before building. Support placeholders

  • build_dir – directory where the build will be done. Support placeholders.

  • config_rules_str – mapping of sdkconfig file name patterns to configuration names

  • build_log_filename – filename of the build log. Will be placed under the app.build_path. Support placeholders. The logs will go to stdout/stderr if not specified

  • size_json_filename – filename to collect the app’s size information. Will be placed under the app.build_path. Support placeholders. The app’s size information won’t be collected if not specified

  • check_warnings – Check for warnings in the build log or not

  • preserve – Preserve the built binaries or not

  • manifest_rootpath – The root path of the manifest files. Usually the folders specified in the manifest files are relative paths. Use the current directory if not specified

  • manifest_files – paths of the manifest files

  • check_manifest_rules – check the manifest rules or not

  • default_build_targets – default build targets used in manifest files

  • modified_components – modified components

  • modified_files – modified files

  • ignore_app_dependencies_components – components used for ignoring checking the app dependencies

  • ignore_app_dependencies_filepatterns – file patterns used for ignoring checking the app dependencies

  • sdkconfig_defaults – semicolon-separated string, pass to idf.py -DSDKCONFIG_DEFAULTS if specified, also could be set via environment variables “SDKCONFIG_DEFAULTS”

  • include_skipped_apps – include skipped apps or not

Returns:

list of found apps

idf_build_apps.json_to_app(json_str: str, extra_classes: Optional[List[Type[App]]] = None) App

Deserialize json string to App object

Note

You can pass extra_cls to support custom App class. A custom App class must be a subclass of App, and have a different value of build_system. For example, a custom CMake app

>>> class CustomApp(CMakeApp):
>>>    build_system: Literal['custom_cmake'] = 'custom_cmake'

Then you can pass the CustomApp class to the extra_cls argument

>>> json_str = CustomApp('.', 'esp32').to_json()
>>> json_to_app(json_str, extra_classes=[CustomApp])
Parameters:
  • json_str – json string

  • extra_classes – extra App class

Returns:

App object

idf_build_apps.setup_logging(verbose: int = 0, log_file: Optional[str] = None, colored: bool = True) None

Setup logging stream handler

Parameters:
  • verbose – 0 - WARNING, 1 - INFO, 2 - DEBUG

  • log_file – log file path

  • colored – colored output or not

Returns:

None