Skip to content

Commit 8debf7b

Browse files
authored
Remove use of pip in espidf.py to create the venv (#265)
1 parent b46d6b1 commit 8debf7b

File tree

1 file changed

+27
-20
lines changed

1 file changed

+27
-20
lines changed

builder/frameworks/espidf.py

Lines changed: 27 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
"""
2222

2323
import copy
24+
import importlib.util
2425
import json
2526
import subprocess
2627
import sys
@@ -44,12 +45,18 @@
4445
from platformio.compat import IS_WINDOWS
4546
from platformio.proc import exec_command
4647
from platformio.builder.tools.piolib import ProjectAsLibBuilder
47-
from platformio.project.config import ProjectConfig
4848
from platformio.package.version import get_original_version, pepver_to_semver
4949

5050

5151
env = DefaultEnvironment()
5252
env.SConscript("_embed_files.py", exports="env")
53+
platform = env.PioPlatform()
54+
55+
_penv_setup_file = os.path.join(platform.get_dir(), "builder", "penv_setup.py")
56+
_spec = importlib.util.spec_from_file_location("penv_setup", _penv_setup_file)
57+
_penv_setup = importlib.util.module_from_spec(_spec)
58+
_spec.loader.exec_module(_penv_setup) # type: ignore[attr-defined]
59+
get_executable_path = _penv_setup.get_executable_path
5360

5461
# remove maybe existing old map file in project root
5562
map_file = os.path.join(env.subst("$PROJECT_DIR"), env.subst("$PROGNAME") + ".map")
@@ -59,7 +66,6 @@
5966
# Allow changes in folders of managed components
6067
os.environ["IDF_COMPONENT_OVERWRITE_MANAGED_COMPONENTS"] = "1"
6168

62-
platform = env.PioPlatform()
6369
config = env.GetProjectConfig()
6470
board = env.BoardConfig()
6571
mcu = board.get("build.mcu", "esp32")
@@ -83,11 +89,12 @@
8389
if mcu in ("esp32", "esp32s2", "esp32s3")
8490
else "toolchain-riscv32-esp"
8591
)
86-
92+
PLATFORMIO_DIR = env.subst("$PROJECT_CORE_DIR")
8793

8894
assert os.path.isdir(FRAMEWORK_DIR)
8995
assert os.path.isdir(TOOLCHAIN_DIR)
9096

97+
9198
def create_silent_action(action_func):
9299
"""Create a silent SCons action that suppresses output"""
93100
silent_action = env.Action(action_func)
@@ -351,7 +358,7 @@ def HandleCOMPONENTsettings(env):
351358

352359
if flag_custom_sdkonfig == True and "arduino" in env.subst("$PIOFRAMEWORK") and "espidf" not in env.subst("$PIOFRAMEWORK"):
353360
HandleArduinoIDFsettings(env)
354-
LIB_SOURCE = os.path.join(ProjectConfig.get_instance().get("platformio", "platforms_dir"), "espressif32", "builder", "build_lib")
361+
LIB_SOURCE = os.path.join(platform.get_dir(), "builder", "build_lib")
355362
if not bool(os.path.exists(os.path.join(PROJECT_DIR, ".dummy"))):
356363
shutil.copytree(LIB_SOURCE, os.path.join(PROJECT_DIR, ".dummy"))
357364
PROJECT_SRC_DIR = os.path.join(PROJECT_DIR, ".dummy")
@@ -1488,9 +1495,13 @@ def generate_mbedtls_bundle(sdk_config):
14881495
)
14891496

14901497

1498+
def _get_uv_exe():
1499+
return get_executable_path(os.path.join(PLATFORMIO_DIR, "penv"), "uv")
1500+
1501+
14911502
def install_python_deps():
1492-
PYTHON_EXE = env.subst("$PYTHONEXE")
1493-
UV_EXE = os.path.join(os.path.dirname(PYTHON_EXE), "uv" + (".exe" if IS_WINDOWS else ""))
1503+
UV_EXE = _get_uv_exe()
1504+
14941505
def _get_installed_uv_packages(python_exe_path):
14951506
result = {}
14961507
try:
@@ -1512,7 +1523,6 @@ def _get_installed_uv_packages(python_exe_path):
15121523
return
15131524

15141525
deps = {
1515-
"uv": ">=0.1.0",
15161526
# https://github.com/platformio/platformio-core/issues/4614
15171527
"urllib3": "<2",
15181528
# https://github.com/platformio/platform-espressif32/issues/635
@@ -1563,9 +1573,7 @@ def get_idf_venv_dir():
15631573
# as an IDF component requires a different version of the IDF package and
15641574
# hence a different set of Python deps or their versions
15651575
idf_version = get_framework_version()
1566-
return os.path.join(
1567-
env.subst("$PROJECT_CORE_DIR"), "penv", ".espidf-" + idf_version
1568-
)
1576+
return os.path.join(PLATFORMIO_DIR, "penv", f".espidf-{idf_version}")
15691577

15701578

15711579
def ensure_python_venv_available():
@@ -1607,11 +1615,7 @@ def _is_venv_outdated(venv_data_file):
16071615
return True
16081616

16091617
def _create_venv(venv_dir):
1610-
pip_path = os.path.join(
1611-
venv_dir,
1612-
"Scripts" if IS_WINDOWS else "bin",
1613-
"pip" + (".exe" if IS_WINDOWS else ""),
1614-
)
1618+
uv_path = _get_uv_exe()
16151619

16161620
if os.path.isdir(venv_dir):
16171621
try:
@@ -1624,17 +1628,20 @@ def _create_venv(venv_dir):
16241628
)
16251629
env.Exit(1)
16261630

1627-
# Use the built-in PlatformIO Python to create a standalone IDF virtual env
1631+
# Use uv to create a standalone IDF virtual env
16281632
env.Execute(
16291633
env.VerboseAction(
1630-
'"$PYTHONEXE" -m venv --clear "%s"' % venv_dir,
1631-
"Creating a new virtual environment for IDF Python dependencies",
1634+
'"%s" venv --clear --quiet --python "%s" "%s"' % (uv_path, env.subst("$PYTHONEXE"), venv_dir),
1635+
"Creating a new virtual environment for IDF Python dependencies using uv",
16321636
)
16331637
)
16341638

1639+
# Verify that the venv was created successfully by checking for Python executable
1640+
python_path = get_executable_path(venv_dir, "python")
1641+
16351642
assert os.path.isfile(
1636-
pip_path
1637-
), "Error: Failed to create a proper virtual environment. Missing the `pip` binary!"
1643+
python_path
1644+
), "Error: Failed to create a proper virtual environment. Missing the Python executable!"
16381645

16391646
venv_dir = get_idf_venv_dir()
16401647
venv_data_file = os.path.join(venv_dir, "pio-idf-venv.json")

0 commit comments

Comments
 (0)