mirror of
https://github.com/esphome/esphome.git
synced 2026-09-11 15:27:33 +00:00
Share the PlatformIO flag-lexing helper and flatten the build_flags classifier
This commit is contained in:
@@ -13,7 +13,6 @@ include path.
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import Iterable
|
||||
from dataclasses import dataclass, field
|
||||
import logging
|
||||
from pathlib import Path
|
||||
@@ -33,6 +32,7 @@ from esphome.platformio.library import (
|
||||
convert_libraries,
|
||||
ensure_list,
|
||||
is_lib_ignored,
|
||||
join_flag_args,
|
||||
lib_ignore_set,
|
||||
normalize_dependencies,
|
||||
parse_library_properties,
|
||||
@@ -59,21 +59,6 @@ class ArduinoLibrary:
|
||||
link_flags: list[str] = field(default_factory=list)
|
||||
|
||||
|
||||
def join_flag_args(tokens: Iterable[str], owner: str) -> list[str]:
|
||||
"""Join a bare ``-I``/``-L``/``-l`` with its following token (PIO lexing)."""
|
||||
out: list[str] = []
|
||||
it = iter(tokens)
|
||||
for tok in it:
|
||||
if tok in ("-I", "-L", "-l"):
|
||||
arg = next(it, None)
|
||||
if arg is None:
|
||||
_LOGGER.warning("Ignoring trailing '%s' in %s build flags", tok, owner)
|
||||
break
|
||||
tok += arg
|
||||
out.append(tok)
|
||||
return out
|
||||
|
||||
|
||||
def _library_info(name: str, read_path: Path, data: dict) -> ArduinoLibrary:
|
||||
"""Resolve one library's sources, include dirs, and flags (PIO semantics)."""
|
||||
build = data.get("build", {})
|
||||
@@ -90,7 +75,7 @@ def _library_info(name: str, read_path: Path, data: dict) -> ArduinoLibrary:
|
||||
|
||||
src_filter = ensure_list(build.get("srcFilter", DEFAULT_BUILD_SRC_FILTER))
|
||||
# PlatformIO shell-lexes each build.flags entry
|
||||
raw_flags = join_flag_args(
|
||||
flag_tokens = join_flag_args(
|
||||
(
|
||||
token
|
||||
for entry in ensure_list(build.get("flags", []))
|
||||
@@ -101,7 +86,7 @@ def _library_info(name: str, read_path: Path, data: dict) -> ArduinoLibrary:
|
||||
|
||||
lib = ArduinoLibrary(name=name)
|
||||
include_flags: list[str] = []
|
||||
for tok in raw_flags:
|
||||
for tok in flag_tokens:
|
||||
if tok.startswith("-I"):
|
||||
include_flags.append(tok[2:])
|
||||
elif tok.startswith("-L"):
|
||||
|
||||
@@ -22,7 +22,6 @@ import shlex
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
from esphome.arduino8266.component import join_flag_args
|
||||
from esphome.components.esp8266 import build_surgery
|
||||
from esphome.components.esp8266.boards import (
|
||||
BOARDS,
|
||||
@@ -40,6 +39,7 @@ from esphome.const import KEY_CORE, KEY_FRAMEWORK_VERSION
|
||||
from esphome.core import CORE, EsphomeError
|
||||
from esphome.framework_helpers import get_project_cxx_compile_flags
|
||||
from esphome.helpers import mkdir_p, write_file_if_changed
|
||||
from esphome.platformio.library import join_flag_args
|
||||
|
||||
# Compile rule per source suffix; keys must cover SRC_FILE_EXTENSIONS so any
|
||||
# source a library manifest selects has a rule (pinned by a drift test).
|
||||
@@ -308,23 +308,23 @@ def _project_flags() -> tuple[list[str], list[str], list[Path], list[str]]:
|
||||
lib_dirs: list[Path] = []
|
||||
libs: list[str] = []
|
||||
for flag in flags:
|
||||
if flag.startswith("-Wl,"):
|
||||
link_flags.append(flag)
|
||||
elif flag.startswith(("-L", "-l")):
|
||||
# Shell-lex only linker entries so forms like "-L /opt/blobs"
|
||||
# work as they do under PlatformIO. Other entries pass verbatim:
|
||||
# lexing them would strip the quotes in defines like -DBOARD="...".
|
||||
for tok in join_flag_args(shlex.split(flag), "esphome"):
|
||||
if tok.startswith("-L") and len(tok) > 2:
|
||||
lib_dirs.append(Path(tok[2:]))
|
||||
elif tok.startswith("-l") and len(tok) > 2:
|
||||
libs.append(tok[2:])
|
||||
elif tok.startswith("-Wl,"):
|
||||
link_flags.append(tok)
|
||||
else:
|
||||
compile_flags.append(tok)
|
||||
else:
|
||||
compile_flags.append(flag)
|
||||
# Shell-lex only linker entries so forms like "-L /opt/blobs" work as
|
||||
# they do under PlatformIO. Other entries pass verbatim: lexing them
|
||||
# would strip the quotes in defines like -DBOARD="...".
|
||||
tokens = (
|
||||
join_flag_args(shlex.split(flag), "esphome")
|
||||
if flag.startswith(("-L", "-l"))
|
||||
else [flag]
|
||||
)
|
||||
for tok in tokens:
|
||||
if tok.startswith("-Wl,"):
|
||||
link_flags.append(tok)
|
||||
elif tok.startswith("-L"):
|
||||
lib_dirs.append(Path(tok[2:]))
|
||||
elif tok.startswith("-l"):
|
||||
libs.append(tok[2:])
|
||||
else:
|
||||
compile_flags.append(tok)
|
||||
return compile_flags, link_flags, lib_dirs, libs
|
||||
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@ from esphome.platformio.library import (
|
||||
collect_filtered_files,
|
||||
convert_libraries,
|
||||
ensure_list,
|
||||
join_flag_args,
|
||||
split_list_by_condition,
|
||||
)
|
||||
|
||||
@@ -102,22 +103,13 @@ def generate_cmakelists_txt(component: IDFComponent) -> str:
|
||||
component.data.get("build", {}).get("flags", DEFAULT_BUILD_FLAGS)
|
||||
)
|
||||
# PlatformIO shell-lexes each build.flags entry, so one entry can carry a
|
||||
# flag and its argument (e.g. "-include cp_custom_alloc.h"). Split the
|
||||
# same way; emitting such an entry as a single quoted compile option
|
||||
# hands the compiler one argv with an embedded space.
|
||||
build_flags = [token for entry in build_flags for token in shlex.split(entry)]
|
||||
# Re-glue bare -I/-L/-l tokens to their argument ("-I foo" -> "-Ifoo") so
|
||||
# the prefix classifiers below still route them to INCLUDE_DIRS and the
|
||||
# link handling.
|
||||
tokens, build_flags = build_flags, []
|
||||
i = 0
|
||||
while i < len(tokens):
|
||||
if tokens[i] in ("-I", "-L", "-l") and i + 1 < len(tokens):
|
||||
build_flags.append(tokens[i] + tokens[i + 1])
|
||||
i += 2
|
||||
else:
|
||||
build_flags.append(tokens[i])
|
||||
i += 1
|
||||
# flag and its argument (e.g. "-include cp_custom_alloc.h"); bare
|
||||
# -I/-L/-l tokens re-glue to their argument ("-I foo" -> "-Ifoo") so the
|
||||
# prefix classifiers below still route them.
|
||||
build_flags = join_flag_args(
|
||||
(token for entry in build_flags for token in shlex.split(entry)),
|
||||
f"library {component.name}",
|
||||
)
|
||||
|
||||
# List all sources files
|
||||
build_src_files = collect_filtered_files(
|
||||
|
||||
@@ -13,7 +13,7 @@ regardless of which toolchain consumes the result.
|
||||
"""
|
||||
|
||||
from collections import deque
|
||||
from collections.abc import Callable
|
||||
from collections.abc import Callable, Iterable
|
||||
from dataclasses import dataclass, field
|
||||
import glob
|
||||
import hashlib
|
||||
@@ -553,6 +553,21 @@ def _resolve_registry_version(
|
||||
return owner, name, best["name"], pkgfile["download_url"]
|
||||
|
||||
|
||||
def join_flag_args(tokens: Iterable[str], owner: str) -> list[str]:
|
||||
"""Join a bare ``-I``/``-L``/``-l`` with its following token (PIO lexing)."""
|
||||
out: list[str] = []
|
||||
it = iter(tokens)
|
||||
for tok in it:
|
||||
if tok in ("-I", "-L", "-l"):
|
||||
arg = next(it, None)
|
||||
if arg is None:
|
||||
_LOGGER.warning("Ignoring trailing '%s' in %s build flags", tok, owner)
|
||||
break
|
||||
tok += arg
|
||||
out.append(tok)
|
||||
return out
|
||||
|
||||
|
||||
def normalize_dependencies(dependencies: Any) -> list[dict]:
|
||||
"""Normalize a library manifest's ``dependencies`` to a list of dicts.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user