Skip to content

Commit e49e312

Browse files
committed
Improve the process of installing Python deps for IDF
1 parent 99362a4 commit e49e312

File tree

1 file changed

+47
-13
lines changed

1 file changed

+47
-13
lines changed

builder/frameworks/espidf.py

Lines changed: 47 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import json
2525
import subprocess
2626
import sys
27+
import shutil
2728
import os
2829
import pkg_resources
2930

@@ -58,6 +59,7 @@
5859

5960
# Required until Arduino switches to v5
6061
IDF5 = platform.get_package_version("framework-espidf").split(".")[1].startswith("5")
62+
IDF_ENV_VERSION = "1.0.0"
6163
FRAMEWORK_DIR = platform.get_package_dir("framework-espidf")
6264
TOOLCHAIN_DIR = platform.get_package_dir(
6365
"toolchain-%s" % ("riscv32-esp" if mcu == "esp32c3" else ("xtensa-%s" % mcu))
@@ -1147,40 +1149,71 @@ def _get_installed_pip_packages(python_exe_path):
11471149
)
11481150
)
11491151

1152+
def get_idf_venv_dir():
1153+
# The name of the IDF venv contains the IDF version to avoid possible conflicts and
1154+
# unnecessary reinstallation of Python dependencies in cases when Arduino
1155+
# as an IDF component requires a different version of the IDF package and
1156+
# hence a different set of Python deps or their versions
1157+
idf_version = get_original_version(platform.get_package_version("framework-espidf"))
1158+
return os.path.join(
1159+
env.subst("$PROJECT_CORE_DIR"), "penv", ".espidf-" + idf_version
1160+
)
1161+
1162+
def ensure_python_venv_available():
1163+
1164+
def _is_venv_outdated(venv_data_file):
1165+
try:
1166+
with open(venv_data_file, "r", encoding="utf8") as fp:
1167+
venv_data = json.load(fp)
1168+
if venv_data.get("version", "") != IDF_ENV_VERSION:
1169+
return True
1170+
return False
1171+
except:
1172+
return True
11501173

1151-
def get_python_exe():
11521174
def _create_venv(venv_dir):
11531175
pip_path = os.path.join(
11541176
venv_dir,
11551177
"Scripts" if IS_WINDOWS else "bin",
11561178
"pip" + (".exe" if IS_WINDOWS else ""),
11571179
)
1158-
if not os.path.isfile(pip_path):
1180+
1181+
if os.path.isdir(venv_dir):
1182+
try:
1183+
print("Removing an oudated IDF virtual environment")
1184+
shutil.rmtree(venv_dir)
1185+
except OSError:
1186+
print(
1187+
"Error: Cannot remove an outdated IDF virtual environment. " \
1188+
"Please remove the `%s` folder manually!" % venv_dir
1189+
)
1190+
env.Exit(1)
1191+
11591192
# Use the built-in PlatformIO Python to create a standalone IDF virtual env
11601193
env.Execute(
11611194
env.VerboseAction(
11621195
'"$PYTHONEXE" -m venv --clear "%s"' % venv_dir,
1163-
"Creating a virtual environment for IDF Python dependencies",
1196+
"Creating a new virtual environment for IDF Python dependencies",
11641197
)
11651198
)
11661199

11671200
assert os.path.isfile(
11681201
pip_path
1169-
), "Error: Failed to create a proper virtual environment. Missing the pip binary!"
1202+
), "Error: Failed to create a proper virtual environment. Missing the `pip` binary!"
11701203

1171-
# The name of the IDF venv contains the IDF version to avoid possible conflicts and
1172-
# unnecessary reinstallation of Python dependencies in cases when Arduino
1173-
# as an IDF component requires a different version of the IDF package and
1174-
# hence a different set of Python deps or their versions
1175-
idf_version = get_original_version(platform.get_package_version("framework-espidf"))
1176-
venv_dir = os.path.join(
1177-
env.subst("$PROJECT_CORE_DIR"), "penv", ".espidf-" + idf_version)
11781204

1179-
if not os.path.isdir(venv_dir):
1205+
venv_dir = get_idf_venv_dir()
1206+
venv_data_file = os.path.join(venv_dir, "pio-idf-venv.json")
1207+
if not os.path.isfile(venv_data_file) or _is_venv_outdated(venv_data_file):
11801208
_create_venv(venv_dir)
1209+
with open(venv_data_file, "w", encoding="utf8") as fp:
1210+
venv_info = {"version": IDF_ENV_VERSION}
1211+
json.dump(venv_info, fp, indent=2)
1212+
11811213

1214+
def get_python_exe():
11821215
python_exe_path = os.path.join(
1183-
venv_dir,
1216+
get_idf_venv_dir(),
11841217
"Scripts" if IS_WINDOWS else "bin",
11851218
"python" + (".exe" if IS_WINDOWS else ""),
11861219
)
@@ -1196,6 +1229,7 @@ def _create_venv(venv_dir):
11961229
# ESP-IDF requires Python packages with specific versions in a virtual environment
11971230
#
11981231

1232+
ensure_python_venv_available()
11991233
install_python_deps()
12001234

12011235
# ESP-IDF package doesn't contain .git folder, instead package version is specified

0 commit comments

Comments
 (0)