13
13
# limitations under the License.
14
14
15
15
import os
16
- import urllib
16
+ import subprocess
17
17
import sys
18
- import json
19
- import re
20
- import requests
18
+ import shutil
19
+ from os .path import join
21
20
22
21
from platformio .public import PlatformBase , to_unix_path
22
+ from platformio .proc import get_pythonexe_path
23
+ from platformio .project .config import ProjectConfig
24
+ from platformio .package .manager .tool import ToolPackageManager
23
25
24
26
25
27
IS_WINDOWS = sys .platform .startswith ("win" )
26
28
# Set Platformio env var to use windows_amd64 for all windows architectures
27
29
# only windows_amd64 native espressif toolchains are available
28
- # needs platformio core >= 6.1.16b2 or pioarduino core 6.1.16+test
30
+ # needs platformio/pioarduino core >= 6.1.17
29
31
if IS_WINDOWS :
30
32
os .environ ["PLATFORMIO_SYSTEM_TYPE" ] = "windows_amd64"
31
33
34
+ python_exe = get_pythonexe_path ()
35
+ pm = ToolPackageManager ()
32
36
33
37
class Espressif32Platform (PlatformBase ):
34
38
def configure_default_packages (self , variables , targets ):
@@ -38,11 +42,55 @@ def configure_default_packages(self, variables, targets):
38
42
board_config = self .board_config (variables .get ("board" ))
39
43
mcu = variables .get ("board_build.mcu" , board_config .get ("build.mcu" , "esp32" ))
40
44
board_sdkconfig = variables .get ("board_espidf.custom_sdkconfig" , board_config .get ("espidf.custom_sdkconfig" , "" ))
41
- core_variant_board = '' .join (variables .get ("board_build.extra_flags" , board_config .get ("build.extra_flags" , "" )))
42
- core_variant_board = core_variant_board .replace ("-D" , " " )
43
- core_variant_build = ('' .join (variables .get ("build_flags" , []))).replace ("-D" , " " )
44
45
frameworks = variables .get ("pioframework" , [])
45
46
47
+ def install_tool (TOOL ):
48
+ self .packages [TOOL ]["optional" ] = False
49
+ TOOL_PATH = os .path .join (ProjectConfig .get_instance ().get ("platformio" , "packages_dir" ), TOOL )
50
+ TOOL_PACKAGE_PATH = os .path .join (TOOL_PATH , "package.json" )
51
+ TOOLS_PATH_DEFAULT = os .path .join (os .path .expanduser ("~" ), ".platformio" )
52
+ IDF_TOOLS = os .path .join (ProjectConfig .get_instance ().get ("platformio" , "packages_dir" ), "tl-install" , "tools" , "idf_tools.py" )
53
+ TOOLS_JSON_PATH = os .path .join (TOOL_PATH , "tools.json" )
54
+ TOOLS_PIO_PATH = os .path .join (TOOL_PATH , ".piopm" )
55
+ IDF_TOOLS_CMD = (
56
+ python_exe ,
57
+ IDF_TOOLS ,
58
+ "--quiet" ,
59
+ "--non-interactive" ,
60
+ "--tools-json" ,
61
+ TOOLS_JSON_PATH ,
62
+ "install"
63
+ )
64
+
65
+ tl_flag = bool (os .path .exists (IDF_TOOLS ))
66
+ json_flag = bool (os .path .exists (TOOLS_JSON_PATH ))
67
+ pio_flag = bool (os .path .exists (TOOLS_PIO_PATH ))
68
+ if tl_flag and json_flag :
69
+ rc = subprocess .run (IDF_TOOLS_CMD ).returncode
70
+ if rc != 0 :
71
+ sys .stderr .write ("Error: Couldn't execute 'idf_tools.py install'\n " )
72
+ else :
73
+ tl_path = "file://" + join (TOOLS_PATH_DEFAULT , "tools" , TOOL )
74
+ if not os .path .exists (join (TOOLS_PATH_DEFAULT , "tools" , TOOL , "package.json" )):
75
+ shutil .copyfile (TOOL_PACKAGE_PATH , join (TOOLS_PATH_DEFAULT , "tools" , TOOL , "package.json" ))
76
+ self .packages .pop (TOOL , None )
77
+ if os .path .exists (TOOL_PATH ) and os .path .isdir (TOOL_PATH ):
78
+ try :
79
+ shutil .rmtree (TOOL_PATH )
80
+ except Exception as e :
81
+ print (f"Error while removing the tool folder: { e } " )
82
+ pm .install (tl_path )
83
+ # tool is already installed, just activate it
84
+ if tl_flag and pio_flag and not json_flag :
85
+ self .packages [TOOL ]["version" ] = TOOL_PATH
86
+ self .packages [TOOL ]["optional" ] = False
87
+
88
+ return
89
+
90
+ # Installer only needed for setup, deactivate when installed
91
+ if bool (os .path .exists (os .path .join (ProjectConfig .get_instance ().get ("platformio" , "packages_dir" ), "tl-install" , "tools" , "idf_tools.py" ))):
92
+ self .packages ["tl-install" ]["optional" ] = True
93
+
46
94
if "arduino" in frameworks :
47
95
self .packages ["framework-arduinoespressif32" ]["optional" ] = False
48
96
self .packages ["framework-arduinoespressif32-libs" ]["optional" ] = False
@@ -73,8 +121,7 @@ def configure_default_packages(self, variables, targets):
73
121
self .packages ["tool-mkfatfs" ]["optional" ] = False
74
122
else :
75
123
self .packages ["tool-mkspiffs" ]["optional" ] = False
76
- if variables .get ("upload_protocol" ):
77
- self .packages ["tool-openocd-esp32" ]["optional" ] = False
124
+
78
125
if os .path .isdir ("ulp" ):
79
126
self .packages ["toolchain-esp32ulp" ]["optional" ] = False
80
127
@@ -90,37 +137,31 @@ def configure_default_packages(self, variables, targets):
90
137
else :
91
138
del self .packages ["tool-dfuutil-arduino" ]
92
139
93
- # Starting from v12, Espressif's toolchains are shipped without
94
- # bundled GDB. Instead, it's distributed as separate packages for Xtensa
95
- # and RISC-V targets.
96
- for gdb_package in ("tool-xtensa-esp-elf-gdb" , "tool-riscv32-esp-elf-gdb" ):
97
- self .packages [gdb_package ]["optional" ] = False
98
- # if IS_WINDOWS:
99
- # Note: On Windows GDB v12 is not able to
100
- # launch a GDB server in pipe mode while v11 works fine
101
- # self.packages[gdb_package]["version"] = "~11.2.0"
140
+ # install GDB and OpenOCD when debug mode or upload_protocol is set
141
+ if (variables .get ("build_type" ) or "debug" in "" .join (targets )) or variables .get ("upload_protocol" ):
142
+ for gdb_package in ("tool-xtensa-esp-elf-gdb" , "tool-riscv32-esp-elf-gdb" ):
143
+ self .packages [gdb_package ]["optional" ] = False
144
+ install_tool ("tool-openocd-esp32" )
102
145
103
146
# Common packages for IDF and mixed Arduino+IDF projects
104
147
if "espidf" in frameworks :
105
148
self .packages ["toolchain-esp32ulp" ]["optional" ] = False
106
149
for p in self .packages :
107
150
if p in (
108
- "tool-scons" ,
109
151
"tool-cmake" ,
110
152
"tool-ninja" ,
153
+ "tool-scons" ,
111
154
"tool-esp-rom-elfs" ,
112
155
):
113
156
self .packages [p ]["optional" ] = False
114
- # elif p in ("tool-mconf", "tool-idf") and IS_WINDOWS:
115
- # self.packages[p]["optional"] = False
116
157
117
158
if mcu in ("esp32" , "esp32s2" , "esp32s3" ):
118
159
self .packages ["toolchain-xtensa-esp-elf" ]["optional" ] = False
119
160
else :
120
161
self .packages .pop ("toolchain-xtensa-esp-elf" , None )
121
162
122
- if mcu in ("esp32s2" , "esp32s3" , "esp32c2" , "esp32c3" , "esp32c6" , "esp32h2" , "esp32p4" ):
123
- if mcu in ("esp32c2" , "esp32c3" , "esp32c6" , "esp32h2" , "esp32p4" ):
163
+ if mcu in ("esp32s2" , "esp32s3" , "esp32c2" , "esp32c3" , "esp32c5" , " esp32c6" , "esp32h2" , "esp32p4" ):
164
+ if mcu in ("esp32c2" , "esp32c3" , "esp32c5" , " esp32c6" , "esp32h2" , "esp32p4" ):
124
165
self .packages .pop ("toolchain-esp32ulp" , None )
125
166
# RISC-V based toolchain for ESP32C3, ESP32C6 ESP32S2, ESP32S3 ULP
126
167
self .packages ["toolchain-riscv32-esp" ]["optional" ] = False
0 commit comments