mirror of
https://github.com/esphome/esphome.git
synced 2026-06-24 11:07:33 +00:00
[core] Make set_cpp_standard work on the native IDF toolchain (#16907)
This commit is contained in:
@@ -162,3 +162,53 @@ def test_get_project_cmakelists_emits_managed_components_property(
|
||||
"idf_build_set_property(ESPHOME_PROJECT_MANAGED_COMPONENTS"
|
||||
" espressif__esp-dsp APPEND)"
|
||||
) in content
|
||||
|
||||
|
||||
def test_get_project_cmakelists_replaces_cpp_standard(tmp_path: Path) -> None:
|
||||
"""cg.set_cpp_standard() replaces the IDF default -std in
|
||||
CXX_COMPILE_OPTIONS between include(project.cmake) and project()."""
|
||||
with (
|
||||
patch("esphome.build_gen.espidf.get_esp32_variant", return_value="ESP32"),
|
||||
patch.object(CORE, "name", "test"),
|
||||
patch.object(CORE, "cpp_standard", "gnu++20"),
|
||||
):
|
||||
from esphome.build_gen.espidf import get_project_cmakelists
|
||||
|
||||
content = get_project_cmakelists(minimal=True)
|
||||
|
||||
assert (
|
||||
"idf_build_get_property(esphome_cxx_compile_options CXX_COMPILE_OPTIONS)"
|
||||
in content
|
||||
)
|
||||
assert 'list(FILTER esphome_cxx_compile_options EXCLUDE REGEX "^-std=")' in content
|
||||
assert 'list(APPEND esphome_cxx_compile_options "-std=gnu++20")' in content
|
||||
# The replacement must come after project.cmake (which appends the IDF
|
||||
# default) and before project() (which consumes the options).
|
||||
include_pos = content.index("tools/cmake/project.cmake")
|
||||
replace_pos = content.index("CXX_COMPILE_OPTIONS")
|
||||
project_pos = content.index("project(test)")
|
||||
assert include_pos < replace_pos < project_pos
|
||||
|
||||
|
||||
def test_get_project_cmakelists_no_cpp_standard(tmp_path: Path) -> None:
|
||||
with (
|
||||
patch("esphome.build_gen.espidf.get_esp32_variant", return_value="ESP32"),
|
||||
patch.object(CORE, "name", "test"),
|
||||
patch.object(CORE, "cpp_standard", None),
|
||||
):
|
||||
from esphome.build_gen.espidf import get_project_cmakelists
|
||||
|
||||
content = get_project_cmakelists(minimal=True)
|
||||
|
||||
assert "CXX_COMPILE_OPTIONS" not in content
|
||||
|
||||
|
||||
def test_get_component_cmakelists_no_compile_features() -> None:
|
||||
"""The C++ standard is pinned project-wide via CXX_COMPILE_OPTIONS in the
|
||||
top-level CMakeLists; the src component must not set its own."""
|
||||
with patch.object(CORE, "build_flags", set()):
|
||||
from esphome.build_gen.espidf import get_component_cmakelists
|
||||
|
||||
content = get_component_cmakelists()
|
||||
|
||||
assert "target_compile_features" not in content
|
||||
|
||||
@@ -160,3 +160,43 @@ def test_write_ini_no_change_when_content_same(
|
||||
call_args = mock_write_file_if_changed.call_args[0]
|
||||
assert call_args[0] == ini_file
|
||||
assert content in call_args[1]
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def clean_core(monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
monkeypatch.setattr(CORE, "name", "test")
|
||||
monkeypatch.setattr(CORE, "platformio_options", {})
|
||||
monkeypatch.setattr(CORE, "platformio_libraries", {})
|
||||
monkeypatch.setattr(CORE, "build_flags", set())
|
||||
monkeypatch.setattr(CORE, "build_unflags", set())
|
||||
|
||||
|
||||
def test_get_ini_content_pins_cpp_standard(
|
||||
clean_core: None, monkeypatch: pytest.MonkeyPatch
|
||||
) -> None:
|
||||
"""cg.set_cpp_standard() pins -std via build_flags and unflags every other
|
||||
known standard so the platform/framework default is stripped."""
|
||||
monkeypatch.setattr(CORE, "cpp_standard", "gnu++20")
|
||||
|
||||
content = platformio.get_ini_content()
|
||||
|
||||
flags_section = content.split("build_flags =")[1].split("build_unflags =")[0]
|
||||
unflags_section = content.split("build_unflags =")[1].split("extra_scripts")[0]
|
||||
assert "-std=gnu++20\n" in flags_section
|
||||
# Both the GNU and strict dialects of every other standard are stripped.
|
||||
for year in ("11", "14", "17", "23", "26", "2a", "2b", "2c"):
|
||||
assert f"-std=gnu++{year}\n" in unflags_section
|
||||
assert f"-std=c++{year}\n" in unflags_section
|
||||
assert "-std=c++20\n" in unflags_section
|
||||
# The selected standard must not unflag itself.
|
||||
assert "-std=gnu++20\n" not in unflags_section
|
||||
|
||||
|
||||
def test_get_ini_content_no_cpp_standard(
|
||||
clean_core: None, monkeypatch: pytest.MonkeyPatch
|
||||
) -> None:
|
||||
monkeypatch.setattr(CORE, "cpp_standard", None)
|
||||
|
||||
content = platformio.get_ini_content()
|
||||
|
||||
assert "-std=" not in content
|
||||
|
||||
Reference in New Issue
Block a user