2525import subprocess
2626import sys
2727import os
28+ import pkg_resources
2829
2930import click
3031import semantic_version
4950mcu = board .get ("build.mcu" , "esp32" )
5051idf_variant = mcu .lower ()
5152
53+ # Required until Arduino switches to v5
54+ IDF5 = platform .get_package_version (
55+ "framework-espidf" ).split ("." )[1 ].startswith ("5" )
5256FRAMEWORK_DIR = platform .get_package_dir ("framework-espidf" )
5357TOOLCHAIN_DIR = platform .get_package_dir (
5458 "toolchain-%s" % ("riscv32-esp" if mcu == "esp32c3" else ("xtensa-%s" % mcu ))
@@ -576,6 +580,16 @@ def generate_project_ld_script(sdk_config, ignore_targets=None):
576580 )
577581
578582
583+ # A temporary workaround to avoid modifying CMake mainly for the "heap" library.
584+ # The "tlsf.c" source file in this library has an include flag relative
585+ # to CMAKE_CURRENT_SOURCE_DIR which breaks PlatformIO builds that have a
586+ # different working directory
587+ def _fix_component_relative_include (config , build_flags , source_index ):
588+ source_file_path = config ["sources" ][source_index ]["path" ]
589+ build_flags = build_flags .replace (".." , os .path .dirname (source_file_path ) + "/.." )
590+ return build_flags
591+
592+
579593def prepare_build_envs (config , default_env , debug_allowed = True ):
580594 build_envs = []
581595 target_compile_groups = config .get ("compileGroups" )
@@ -597,6 +611,10 @@ def prepare_build_envs(config, default_env, debug_allowed=True):
597611 for cc in compile_commands :
598612 build_flags = cc .get ("fragment" )
599613 if not build_flags .startswith ("-D" ):
614+ if build_flags .startswith ("-include" ) and ".." in build_flags :
615+ source_index = cg .get ("sourceIndexes" )[0 ]
616+ build_flags = _fix_component_relative_include (
617+ config , build_flags , source_index )
600618 build_env .AppendUnique (** build_env .ParseFlags (build_flags ))
601619 build_env .AppendUnique (CPPDEFINES = defines , CPPPATH = includes )
602620 if sys_includes :
@@ -639,9 +657,17 @@ def compile_source_files(
639657 else :
640658 obj_path = os .path .join (obj_path , os .path .basename (src_path ))
641659
660+ preserve_source_file_extension = board .get (
661+ "build.esp-idf.preserve_source_file_extension" , False
662+ )
663+
642664 objects .append (
643665 build_envs [compile_group_idx ].StaticObject (
644- target = os .path .splitext (obj_path )[0 ] + ".o" ,
666+ target = (
667+ obj_path
668+ if preserve_source_file_extension
669+ else os .path .splitext (obj_path )[0 ]
670+ ) + ".o" ,
645671 source = os .path .realpath (src_path ),
646672 )
647673 )
@@ -1029,7 +1055,14 @@ def _get_installed_pip_packages():
10291055 result = {}
10301056 packages = {}
10311057 pip_output = subprocess .check_output (
1032- [env .subst ("$PYTHONEXE" ), "-m" , "pip" , "list" , "--format=json" ]
1058+ [
1059+ env .subst ("$PYTHONEXE" ),
1060+ "-m" ,
1061+ "pip" ,
1062+ "list" ,
1063+ "--format=json" ,
1064+ "--disable-pip-version-check" ,
1065+ ]
10331066 )
10341067 try :
10351068 packages = json .loads (pip_output )
@@ -1047,15 +1080,19 @@ def _get_installed_pip_packages():
10471080 "future" : ">=0.15.2" ,
10481081 "pyparsing" : ">=2.0.3,<2.4.0" ,
10491082 "kconfiglib" : "==13.7.1" ,
1050- "idf-component-manager" : "~=1.0"
1083+ "idf-component-manager" : "~=1.0" ,
10511084 }
10521085
1086+ if IDF5 :
1087+ # Remove specific versions for IDF5 as not required
1088+ deps = {dep : "" for dep in deps }
1089+
10531090 installed_packages = _get_installed_pip_packages ()
10541091 packages_to_install = []
10551092 for package , spec in deps .items ():
10561093 if package not in installed_packages :
10571094 packages_to_install .append (package )
1058- else :
1095+ elif spec :
10591096 version_spec = semantic_version .Spec (spec )
10601097 if not version_spec .match (installed_packages [package ]):
10611098 packages_to_install .append (package )
@@ -1064,21 +1101,34 @@ def _get_installed_pip_packages():
10641101 env .Execute (
10651102 env .VerboseAction (
10661103 (
1067- '"$PYTHONEXE" -m pip install -U --force-reinstall '
1068- + " " .join (['"%s%s"' % (p , deps [p ]) for p in packages_to_install ])
1104+ '"$PYTHONEXE" -m pip install -U '
1105+ + " " .join (
1106+ [
1107+ '"%s%s"' % (p , deps [p ])
1108+ for p in packages_to_install
1109+ ]
1110+ )
10691111 ),
10701112 "Installing ESP-IDF's Python dependencies" ,
10711113 )
10721114 )
10731115
1074- # a special "esp-windows-curses" python package is required on Windows for Menuconfig
1075- if "windows" in get_systype ():
1076- import pkg_resources
1116+ if "windows" in get_systype () and "windows-curses" not in installed_packages :
1117+ env .Execute (
1118+ env .VerboseAction (
1119+ "$PYTHONEXE -m pip install windows-curses" ,
1120+ "Installing windows-curses package" ,
1121+ )
1122+ )
10771123
1078- if "esp-windows-curses" not in {pkg .key for pkg in pkg_resources .working_set }:
1124+ # A special "esp-windows-curses" python package is required on Windows
1125+ # for Menuconfig on IDF <5
1126+ if not IDF5 and "esp-windows-curses" not in {
1127+ pkg .key for pkg in pkg_resources .working_set
1128+ }:
10791129 env .Execute (
10801130 env .VerboseAction (
1081- '$PYTHONEXE -m pip install "file://%s/tools/kconfig_new/esp-windows-curses" windows-curses '
1131+ '$PYTHONEXE -m pip install "file://%s/tools/kconfig_new/esp-windows-curses"'
10821132 % FRAMEWORK_DIR ,
10831133 "Installing windows-curses package" ,
10841134 )
@@ -1471,4 +1521,6 @@ def _skip_prj_source_files(node):
14711521)
14721522
14731523# Propagate application offset to debug configurations
1474- env ["INTEGRATION_EXTRA_DATA" ].update ({"application_offset" : env .subst ("$ESP32_APP_OFFSET" )})
1524+ env ["INTEGRATION_EXTRA_DATA" ].update (
1525+ {"application_offset" : env .subst ("$ESP32_APP_OFFSET" )}
1526+ )
0 commit comments