mirror of
https://github.com/esphome/esphome.git
synced 2026-08-24 07:06:20 +00:00
Close the native CI trigger gap and log the remaining silent library skips
This commit is contained in:
@@ -90,7 +90,16 @@ def _library_info(name: str, read_path: Path, data: dict) -> ArduinoLibrary:
|
||||
if tok.startswith("-I"):
|
||||
include_flags.append(tok[2:])
|
||||
elif tok.startswith("-L"):
|
||||
lib.link_dirs.append((read_path / tok[2:]).resolve())
|
||||
link_dir = (read_path / tok[2:]).resolve()
|
||||
if not link_dir.is_dir():
|
||||
# Kept anyway (the linker ignores missing -L dirs); the
|
||||
# warning names the culprit before a bare "cannot find -lfoo"
|
||||
_LOGGER.warning(
|
||||
"Library %s declares library dir %s which does not exist",
|
||||
name,
|
||||
tok[2:],
|
||||
)
|
||||
lib.link_dirs.append(link_dir)
|
||||
elif tok.startswith("-l"):
|
||||
lib.link_libs.append(tok[2:])
|
||||
elif tok.startswith("-Wl,"):
|
||||
|
||||
@@ -15,6 +15,7 @@ from the build flags with the same precedence as the PlatformIO builder.
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass, field
|
||||
import logging
|
||||
import os
|
||||
from pathlib import Path
|
||||
import re
|
||||
@@ -41,6 +42,8 @@ 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
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
# 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).
|
||||
_RULE_FOR_SUFFIX = {
|
||||
@@ -607,6 +610,12 @@ def write_project(paths: dict[str, Path]) -> bool:
|
||||
|
||||
for lib in libraries:
|
||||
if not lib.sources:
|
||||
# Header-only libraries are legitimate; the log makes an empty
|
||||
# srcFilter or broken tree traceable before link errors do.
|
||||
_LOGGER.debug(
|
||||
"Library %s has no source files; contributing includes only",
|
||||
lib.name,
|
||||
)
|
||||
continue
|
||||
lib_root = _common_parent(lib.sources)
|
||||
objs = _ninja_compile_edges(
|
||||
|
||||
@@ -652,7 +652,10 @@ ESP8266_NATIVE_TRIGGER_FILES = frozenset(
|
||||
|
||||
def _esp8266_native_path_or_file_trigger(files: list[str]) -> bool:
|
||||
"""Whether any changed file is native-ESP8266 infrastructure / harness."""
|
||||
return _path_or_file_trigger(
|
||||
# base_python_changed covers the top-level esphome/*.py modules the
|
||||
# native backend imports directly (framework_helpers, helpers, writer,
|
||||
# __main__); without it a change there would silently skip this job.
|
||||
return base_python_changed(files) or _path_or_file_trigger(
|
||||
files, ESP8266_NATIVE_TRIGGER_FILES, ESP8266_NATIVE_TRIGGER_PATH_PREFIXES
|
||||
)
|
||||
|
||||
|
||||
@@ -3083,6 +3083,9 @@ def test_esp8266_native_components_full_list_on_infra_change() -> None:
|
||||
# Shared modules the native build depends on
|
||||
["esphome/espidf/idedata.py"],
|
||||
["esphome/platformio/library.py"],
|
||||
# Top-level esphome/*.py modules the backend imports directly
|
||||
["esphome/framework_helpers.py"],
|
||||
["esphome/writer.py"],
|
||||
):
|
||||
with (
|
||||
patch.object(determine_jobs, "changed_files", return_value=changed),
|
||||
|
||||
@@ -11,6 +11,7 @@ PlatformIO toolchain produces for the same configuration.
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import Generator
|
||||
import logging
|
||||
from pathlib import Path
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
@@ -454,7 +455,9 @@ def test_generate_ld_scripts_testing_mode(tmp_path: Path) -> None:
|
||||
assert "len = 0x2000000" in patched
|
||||
|
||||
|
||||
def test_write_project_libraries_and_variant(tmp_path: Path) -> None:
|
||||
def test_write_project_libraries_and_variant(
|
||||
tmp_path: Path, caplog: pytest.LogCaptureFixture
|
||||
) -> None:
|
||||
from esphome.arduino8266.component import ArduinoLibrary
|
||||
|
||||
paths = _make_framework(tmp_path)
|
||||
@@ -477,14 +480,17 @@ def test_write_project_libraries_and_variant(tmp_path: Path) -> None:
|
||||
)
|
||||
_set_flags("-DPIO_FRAMEWORK_ARDUINO_ENABLE_EXCEPTIONS")
|
||||
|
||||
content = _write_ninja(
|
||||
paths, libraries=[library, headers_only], ccache="/cc/ccache"
|
||||
)
|
||||
with caplog.at_level(logging.DEBUG, logger="esphome.build_gen.arduino8266"):
|
||||
content = _write_ninja(
|
||||
paths, libraries=[library, headers_only], ccache="/cc/ccache"
|
||||
)
|
||||
|
||||
assert "build libFrameworkArduinoVariant.a: ar" in content
|
||||
assert "build libMyLib.a: ar" in content
|
||||
# A headers-only library contributes includes but no archive
|
||||
# A headers-only library contributes includes but no archive, with a
|
||||
# debug log distinguishing it from a resolution failure
|
||||
assert "libHeadersOnly.a" not in content
|
||||
assert "Library HeadersOnly has no source files" in caplog.text
|
||||
assert " flags = -DMYLIB=1" in content
|
||||
assert "-lalgobsec" in content
|
||||
# Library link flags reach the firmware link line; .cc compiles as C++
|
||||
|
||||
@@ -84,6 +84,18 @@ def test_library_info_flags_parsing(tmp_path: Path) -> None:
|
||||
assert lib.link_flags == ["-Wl,--wrap=malloc"]
|
||||
|
||||
|
||||
def test_library_info_missing_link_dir_warns(
|
||||
tmp_path: Path, caplog: pytest.LogCaptureFixture
|
||||
) -> None:
|
||||
read_path = tmp_path / "lib"
|
||||
read_path.mkdir()
|
||||
data = {"build": {"flags": ["-Lmissing_blobs"]}}
|
||||
lib = component._library_info("x", read_path, data)
|
||||
assert "declares library dir missing_blobs which does not exist" in caplog.text
|
||||
# Kept anyway: the linker ignores missing -L dirs
|
||||
assert lib.link_dirs == [(read_path / "missing_blobs").resolve()]
|
||||
|
||||
|
||||
def test_library_info_no_src_dir(tmp_path: Path) -> None:
|
||||
read_path = tmp_path / "empty"
|
||||
read_path.mkdir()
|
||||
|
||||
Reference in New Issue
Block a user