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
@@ -77,8 +125,7 @@ def configure_default_packages(self, variables, targets):
77
125
self .packages ["tool-mkfatfs" ]["optional" ] = False
78
126
else :
79
127
self .packages ["tool-mkspiffs" ]["optional" ] = False
80
- if variables .get ("upload_protocol" ):
81
- self .packages ["tool-openocd-esp32" ]["optional" ] = False
128
+
82
129
if os .path .isdir ("ulp" ):
83
130
self .packages ["toolchain-esp32ulp" ]["optional" ] = False
84
131
@@ -94,29 +141,23 @@ def configure_default_packages(self, variables, targets):
94
141
else :
95
142
del self .packages ["tool-dfuutil-arduino" ]
96
143
97
- # Starting from v12, Espressif's toolchains are shipped without
98
- # bundled GDB. Instead, it's distributed as separate packages for Xtensa
99
- # and RISC-V targets.
100
- for gdb_package in ("tool-xtensa-esp-elf-gdb" , "tool-riscv32-esp-elf-gdb" ):
101
- self .packages [gdb_package ]["optional" ] = False
102
- # if IS_WINDOWS:
103
- # Note: On Windows GDB v12 is not able to
104
- # launch a GDB server in pipe mode while v11 works fine
105
- # self.packages[gdb_package]["version"] = "~11.2.0"
144
+ # install GDB and OpenOCD when debug mode or upload_protocol is set
145
+ if (variables .get ("build_type" ) or "debug" in "" .join (targets )) or variables .get ("upload_protocol" ):
146
+ for gdb_package in ("tool-xtensa-esp-elf-gdb" , "tool-riscv32-esp-elf-gdb" ):
147
+ self .packages [gdb_package ]["optional" ] = False
148
+ install_tool ("tool-openocd-esp32" )
106
149
107
150
# Common packages for IDF and mixed Arduino+IDF projects
108
151
if "espidf" in frameworks :
109
152
self .packages ["toolchain-esp32ulp" ]["optional" ] = False
110
153
for p in self .packages :
111
154
if p in (
112
- "tool-scons" ,
113
155
"tool-cmake" ,
114
156
"tool-ninja" ,
157
+ "tool-scons" ,
115
158
"tool-esp-rom-elfs" ,
116
159
):
117
160
self .packages [p ]["optional" ] = False
118
- # elif p in ("tool-mconf", "tool-idf") and IS_WINDOWS:
119
- # self.packages[p]["optional"] = False
120
161
121
162
if mcu in ("esp32" , "esp32s2" , "esp32s3" ):
122
163
self .packages ["toolchain-xtensa-esp-elf" ]["optional" ] = False
0 commit comments