fbuild 1.2.8__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- fbuild/__init__.py +390 -0
- fbuild/assets/example.txt +1 -0
- fbuild/build/__init__.py +117 -0
- fbuild/build/archive_creator.py +186 -0
- fbuild/build/binary_generator.py +444 -0
- fbuild/build/build_component_factory.py +131 -0
- fbuild/build/build_info_generator.py +624 -0
- fbuild/build/build_state.py +325 -0
- fbuild/build/build_utils.py +93 -0
- fbuild/build/compilation_executor.py +422 -0
- fbuild/build/compiler.py +165 -0
- fbuild/build/compiler_avr.py +574 -0
- fbuild/build/configurable_compiler.py +664 -0
- fbuild/build/configurable_linker.py +637 -0
- fbuild/build/flag_builder.py +214 -0
- fbuild/build/library_dependency_processor.py +185 -0
- fbuild/build/linker.py +708 -0
- fbuild/build/orchestrator.py +67 -0
- fbuild/build/orchestrator_avr.py +651 -0
- fbuild/build/orchestrator_esp32.py +878 -0
- fbuild/build/orchestrator_rp2040.py +719 -0
- fbuild/build/orchestrator_stm32.py +696 -0
- fbuild/build/orchestrator_teensy.py +580 -0
- fbuild/build/source_compilation_orchestrator.py +218 -0
- fbuild/build/source_scanner.py +516 -0
- fbuild/cli.py +717 -0
- fbuild/cli_utils.py +314 -0
- fbuild/config/__init__.py +16 -0
- fbuild/config/board_config.py +542 -0
- fbuild/config/board_loader.py +92 -0
- fbuild/config/ini_parser.py +369 -0
- fbuild/config/mcu_specs.py +88 -0
- fbuild/daemon/__init__.py +42 -0
- fbuild/daemon/async_client.py +531 -0
- fbuild/daemon/client.py +1505 -0
- fbuild/daemon/compilation_queue.py +293 -0
- fbuild/daemon/configuration_lock.py +865 -0
- fbuild/daemon/daemon.py +585 -0
- fbuild/daemon/daemon_context.py +293 -0
- fbuild/daemon/error_collector.py +263 -0
- fbuild/daemon/file_cache.py +332 -0
- fbuild/daemon/firmware_ledger.py +546 -0
- fbuild/daemon/lock_manager.py +508 -0
- fbuild/daemon/logging_utils.py +149 -0
- fbuild/daemon/messages.py +957 -0
- fbuild/daemon/operation_registry.py +288 -0
- fbuild/daemon/port_state_manager.py +249 -0
- fbuild/daemon/process_tracker.py +366 -0
- fbuild/daemon/processors/__init__.py +18 -0
- fbuild/daemon/processors/build_processor.py +248 -0
- fbuild/daemon/processors/deploy_processor.py +664 -0
- fbuild/daemon/processors/install_deps_processor.py +431 -0
- fbuild/daemon/processors/locking_processor.py +777 -0
- fbuild/daemon/processors/monitor_processor.py +285 -0
- fbuild/daemon/request_processor.py +457 -0
- fbuild/daemon/shared_serial.py +819 -0
- fbuild/daemon/status_manager.py +238 -0
- fbuild/daemon/subprocess_manager.py +316 -0
- fbuild/deploy/__init__.py +21 -0
- fbuild/deploy/deployer.py +67 -0
- fbuild/deploy/deployer_esp32.py +310 -0
- fbuild/deploy/docker_utils.py +315 -0
- fbuild/deploy/monitor.py +519 -0
- fbuild/deploy/qemu_runner.py +603 -0
- fbuild/interrupt_utils.py +34 -0
- fbuild/ledger/__init__.py +52 -0
- fbuild/ledger/board_ledger.py +560 -0
- fbuild/output.py +352 -0
- fbuild/packages/__init__.py +66 -0
- fbuild/packages/archive_utils.py +1098 -0
- fbuild/packages/arduino_core.py +412 -0
- fbuild/packages/cache.py +256 -0
- fbuild/packages/concurrent_manager.py +510 -0
- fbuild/packages/downloader.py +518 -0
- fbuild/packages/fingerprint.py +423 -0
- fbuild/packages/framework_esp32.py +538 -0
- fbuild/packages/framework_rp2040.py +349 -0
- fbuild/packages/framework_stm32.py +459 -0
- fbuild/packages/framework_teensy.py +346 -0
- fbuild/packages/github_utils.py +96 -0
- fbuild/packages/header_trampoline_cache.py +394 -0
- fbuild/packages/library_compiler.py +203 -0
- fbuild/packages/library_manager.py +549 -0
- fbuild/packages/library_manager_esp32.py +725 -0
- fbuild/packages/package.py +163 -0
- fbuild/packages/platform_esp32.py +383 -0
- fbuild/packages/platform_rp2040.py +400 -0
- fbuild/packages/platform_stm32.py +581 -0
- fbuild/packages/platform_teensy.py +312 -0
- fbuild/packages/platform_utils.py +131 -0
- fbuild/packages/platformio_registry.py +369 -0
- fbuild/packages/sdk_utils.py +231 -0
- fbuild/packages/toolchain.py +436 -0
- fbuild/packages/toolchain_binaries.py +196 -0
- fbuild/packages/toolchain_esp32.py +489 -0
- fbuild/packages/toolchain_metadata.py +185 -0
- fbuild/packages/toolchain_rp2040.py +436 -0
- fbuild/packages/toolchain_stm32.py +417 -0
- fbuild/packages/toolchain_teensy.py +404 -0
- fbuild/platform_configs/esp32.json +150 -0
- fbuild/platform_configs/esp32c2.json +144 -0
- fbuild/platform_configs/esp32c3.json +143 -0
- fbuild/platform_configs/esp32c5.json +151 -0
- fbuild/platform_configs/esp32c6.json +151 -0
- fbuild/platform_configs/esp32p4.json +149 -0
- fbuild/platform_configs/esp32s3.json +151 -0
- fbuild/platform_configs/imxrt1062.json +56 -0
- fbuild/platform_configs/rp2040.json +70 -0
- fbuild/platform_configs/rp2350.json +76 -0
- fbuild/platform_configs/stm32f1.json +59 -0
- fbuild/platform_configs/stm32f4.json +63 -0
- fbuild/py.typed +0 -0
- fbuild-1.2.8.dist-info/METADATA +468 -0
- fbuild-1.2.8.dist-info/RECORD +121 -0
- fbuild-1.2.8.dist-info/WHEEL +5 -0
- fbuild-1.2.8.dist-info/entry_points.txt +5 -0
- fbuild-1.2.8.dist-info/licenses/LICENSE +21 -0
- fbuild-1.2.8.dist-info/top_level.txt +2 -0
- fbuild_lint/__init__.py +0 -0
- fbuild_lint/ruff_plugins/__init__.py +0 -0
- fbuild_lint/ruff_plugins/keyboard_interrupt_checker.py +158 -0
|
@@ -0,0 +1,431 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Install Dependencies Processor - Handles dependency installation operations.
|
|
3
|
+
|
|
4
|
+
This module implements the InstallDependenciesProcessor which downloads and
|
|
5
|
+
caches all dependencies (toolchain, platform, framework, libraries) without
|
|
6
|
+
performing actual compilation. Useful for:
|
|
7
|
+
- Pre-warming the cache before builds
|
|
8
|
+
- Ensuring dependencies are available offline
|
|
9
|
+
- Separating dependency installation from compilation
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
import importlib
|
|
13
|
+
import logging
|
|
14
|
+
import sys
|
|
15
|
+
from pathlib import Path
|
|
16
|
+
from typing import TYPE_CHECKING
|
|
17
|
+
|
|
18
|
+
from fbuild.daemon.messages import OperationType
|
|
19
|
+
from fbuild.daemon.request_processor import RequestProcessor
|
|
20
|
+
|
|
21
|
+
if TYPE_CHECKING:
|
|
22
|
+
from fbuild.daemon.daemon_context import DaemonContext
|
|
23
|
+
from fbuild.daemon.messages import DaemonState, InstallDependenciesRequest
|
|
24
|
+
from fbuild.packages.cache import Cache
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class InstallDependenciesProcessor(RequestProcessor):
|
|
28
|
+
"""Processor for install dependencies requests.
|
|
29
|
+
|
|
30
|
+
This processor handles downloading and caching of build dependencies
|
|
31
|
+
without performing actual compilation. It:
|
|
32
|
+
1. Reloads build modules to pick up code changes (for development)
|
|
33
|
+
2. Detects platform type from platformio.ini
|
|
34
|
+
3. Downloads and caches platform, toolchain, framework
|
|
35
|
+
4. Installs library dependencies
|
|
36
|
+
5. Returns success/failure based on installation result
|
|
37
|
+
|
|
38
|
+
Example:
|
|
39
|
+
>>> processor = InstallDependenciesProcessor()
|
|
40
|
+
>>> success = processor.process_request(install_deps_request, daemon_context)
|
|
41
|
+
"""
|
|
42
|
+
|
|
43
|
+
def get_operation_type(self) -> OperationType:
|
|
44
|
+
"""Return BUILD operation type (dependencies are part of build)."""
|
|
45
|
+
return OperationType.BUILD
|
|
46
|
+
|
|
47
|
+
def get_required_locks(self, request: "InstallDependenciesRequest", context: "DaemonContext") -> dict[str, str]:
|
|
48
|
+
"""Install dependencies requires only a project lock.
|
|
49
|
+
|
|
50
|
+
Args:
|
|
51
|
+
request: The install dependencies request
|
|
52
|
+
context: The daemon context
|
|
53
|
+
|
|
54
|
+
Returns:
|
|
55
|
+
Dictionary with project lock requirement
|
|
56
|
+
"""
|
|
57
|
+
return {"project": request.project_dir}
|
|
58
|
+
|
|
59
|
+
def get_starting_state(self) -> "DaemonState":
|
|
60
|
+
"""Get the daemon state when operation starts."""
|
|
61
|
+
from fbuild.daemon.messages import DaemonState
|
|
62
|
+
|
|
63
|
+
return DaemonState.BUILDING
|
|
64
|
+
|
|
65
|
+
def get_starting_message(self, request: "InstallDependenciesRequest") -> str:
|
|
66
|
+
"""Get the status message when operation starts."""
|
|
67
|
+
return f"Installing dependencies for {request.environment}"
|
|
68
|
+
|
|
69
|
+
def get_success_message(self, request: "InstallDependenciesRequest") -> str:
|
|
70
|
+
"""Get the status message on success."""
|
|
71
|
+
return "Dependencies installed successfully"
|
|
72
|
+
|
|
73
|
+
def get_failure_message(self, request: "InstallDependenciesRequest") -> str:
|
|
74
|
+
"""Get the status message on failure."""
|
|
75
|
+
return "Dependency installation failed"
|
|
76
|
+
|
|
77
|
+
def execute_operation(self, request: "InstallDependenciesRequest", context: "DaemonContext") -> bool:
|
|
78
|
+
"""Execute the dependency installation operation.
|
|
79
|
+
|
|
80
|
+
This installs all build dependencies without compiling:
|
|
81
|
+
- Platform package
|
|
82
|
+
- Toolchain (compiler, linker, etc.)
|
|
83
|
+
- Framework (Arduino core, etc.)
|
|
84
|
+
- Library dependencies from lib_deps
|
|
85
|
+
|
|
86
|
+
Args:
|
|
87
|
+
request: The install dependencies request
|
|
88
|
+
context: The daemon context with all subsystems
|
|
89
|
+
|
|
90
|
+
Returns:
|
|
91
|
+
True if all dependencies installed successfully, False otherwise
|
|
92
|
+
"""
|
|
93
|
+
logging.info(f"Installing dependencies for project: {request.project_dir}")
|
|
94
|
+
|
|
95
|
+
# Reload build modules to pick up code changes
|
|
96
|
+
self._reload_build_modules()
|
|
97
|
+
|
|
98
|
+
# Detect platform type from platformio.ini
|
|
99
|
+
try:
|
|
100
|
+
from fbuild.config.ini_parser import PlatformIOConfig
|
|
101
|
+
|
|
102
|
+
project_path = Path(request.project_dir)
|
|
103
|
+
ini_path = project_path / "platformio.ini"
|
|
104
|
+
|
|
105
|
+
if not ini_path.exists():
|
|
106
|
+
logging.error(f"platformio.ini not found at {ini_path}")
|
|
107
|
+
return False
|
|
108
|
+
|
|
109
|
+
config = PlatformIOConfig(ini_path)
|
|
110
|
+
env_config = config.get_env_config(request.environment)
|
|
111
|
+
platform = env_config.get("platform", "").lower()
|
|
112
|
+
board_id = env_config.get("board", "")
|
|
113
|
+
lib_deps = config.get_lib_deps(request.environment)
|
|
114
|
+
|
|
115
|
+
logging.info(f"Detected platform: {platform}, board: {board_id}")
|
|
116
|
+
|
|
117
|
+
except KeyboardInterrupt as ke:
|
|
118
|
+
from fbuild.interrupt_utils import handle_keyboard_interrupt_properly
|
|
119
|
+
|
|
120
|
+
handle_keyboard_interrupt_properly(ke)
|
|
121
|
+
raise
|
|
122
|
+
except Exception as e:
|
|
123
|
+
logging.error(f"Failed to parse platformio.ini: {e}")
|
|
124
|
+
return False
|
|
125
|
+
|
|
126
|
+
# Normalize platform name
|
|
127
|
+
platform_name = self._normalize_platform_name(platform)
|
|
128
|
+
logging.info(f"Normalized platform: {platform_name}")
|
|
129
|
+
|
|
130
|
+
# Install dependencies based on platform
|
|
131
|
+
try:
|
|
132
|
+
from fbuild.packages.cache import Cache
|
|
133
|
+
|
|
134
|
+
cache = Cache(project_dir=Path(request.project_dir))
|
|
135
|
+
|
|
136
|
+
if platform_name == "espressif32":
|
|
137
|
+
return self._install_esp32_dependencies(cache, env_config, board_id, lib_deps, project_path, request.verbose)
|
|
138
|
+
elif platform_name == "atmelavr":
|
|
139
|
+
return self._install_avr_dependencies(cache, env_config, request.verbose)
|
|
140
|
+
elif platform_name == "raspberrypi":
|
|
141
|
+
return self._install_rp2040_dependencies(cache, env_config, request.verbose)
|
|
142
|
+
elif platform_name == "ststm32":
|
|
143
|
+
return self._install_stm32_dependencies(cache, env_config, request.verbose)
|
|
144
|
+
else:
|
|
145
|
+
logging.error(f"Unsupported platform: {platform_name}")
|
|
146
|
+
return False
|
|
147
|
+
|
|
148
|
+
except KeyboardInterrupt as ke:
|
|
149
|
+
from fbuild.interrupt_utils import handle_keyboard_interrupt_properly
|
|
150
|
+
|
|
151
|
+
handle_keyboard_interrupt_properly(ke)
|
|
152
|
+
raise
|
|
153
|
+
except Exception as e:
|
|
154
|
+
logging.error(f"Failed to install dependencies: {e}")
|
|
155
|
+
import traceback
|
|
156
|
+
|
|
157
|
+
logging.error(f"Traceback:\n{traceback.format_exc()}")
|
|
158
|
+
return False
|
|
159
|
+
|
|
160
|
+
def _normalize_platform_name(self, platform: str) -> str:
|
|
161
|
+
"""Normalize platform name from various formats.
|
|
162
|
+
|
|
163
|
+
Args:
|
|
164
|
+
platform: Raw platform string from platformio.ini
|
|
165
|
+
|
|
166
|
+
Returns:
|
|
167
|
+
Normalized platform name
|
|
168
|
+
"""
|
|
169
|
+
if "platform-espressif32" in platform or "platformio/espressif32" in platform or platform == "espressif32":
|
|
170
|
+
return "espressif32"
|
|
171
|
+
elif "platform-atmelavr" in platform or "platformio/atmelavr" in platform or platform == "atmelavr":
|
|
172
|
+
return "atmelavr"
|
|
173
|
+
elif "platform-raspberrypi" in platform or "platformio/raspberrypi" in platform or platform == "raspberrypi":
|
|
174
|
+
return "raspberrypi"
|
|
175
|
+
elif "platform-ststm32" in platform or "platformio/ststm32" in platform or platform == "ststm32":
|
|
176
|
+
return "ststm32"
|
|
177
|
+
return platform
|
|
178
|
+
|
|
179
|
+
def _install_esp32_dependencies(
|
|
180
|
+
self,
|
|
181
|
+
cache: "Cache",
|
|
182
|
+
env_config: dict,
|
|
183
|
+
board_id: str,
|
|
184
|
+
lib_deps: list[str],
|
|
185
|
+
project_dir: Path,
|
|
186
|
+
verbose: bool,
|
|
187
|
+
) -> bool:
|
|
188
|
+
"""Install ESP32 platform dependencies.
|
|
189
|
+
|
|
190
|
+
Args:
|
|
191
|
+
cache: Cache instance for package management
|
|
192
|
+
env_config: Environment configuration from platformio.ini
|
|
193
|
+
board_id: Board identifier
|
|
194
|
+
lib_deps: Library dependencies
|
|
195
|
+
project_dir: Project directory
|
|
196
|
+
verbose: Enable verbose output
|
|
197
|
+
|
|
198
|
+
Returns:
|
|
199
|
+
True if successful, False otherwise
|
|
200
|
+
"""
|
|
201
|
+
from fbuild.packages.framework_esp32 import FrameworkESP32
|
|
202
|
+
from fbuild.packages.library_manager_esp32 import LibraryManagerESP32
|
|
203
|
+
from fbuild.packages.platform_esp32 import PlatformESP32
|
|
204
|
+
from fbuild.packages.toolchain_esp32 import ToolchainESP32
|
|
205
|
+
|
|
206
|
+
# Get platform URL
|
|
207
|
+
platform_url = env_config.get("platform")
|
|
208
|
+
if not platform_url:
|
|
209
|
+
logging.error("No platform URL specified in platformio.ini")
|
|
210
|
+
return False
|
|
211
|
+
|
|
212
|
+
# Resolve platform shorthand to actual URL
|
|
213
|
+
platform_url = self._resolve_platform_url(platform_url)
|
|
214
|
+
|
|
215
|
+
# 1. Initialize platform
|
|
216
|
+
logging.info("Installing ESP32 platform...")
|
|
217
|
+
platform = PlatformESP32(cache, platform_url, show_progress=True)
|
|
218
|
+
platform.ensure_platform()
|
|
219
|
+
logging.info(f"Platform installed: version {platform.version}")
|
|
220
|
+
|
|
221
|
+
# Get board configuration
|
|
222
|
+
board_json = platform.get_board_json(board_id)
|
|
223
|
+
mcu = board_json.get("build", {}).get("mcu", "esp32c6")
|
|
224
|
+
|
|
225
|
+
# Get required packages (returns Dict[str, str] of package_name -> url)
|
|
226
|
+
packages = platform.get_required_packages(mcu)
|
|
227
|
+
|
|
228
|
+
# 2. Initialize toolchain
|
|
229
|
+
logging.info("Installing ESP32 toolchain...")
|
|
230
|
+
# Determine toolchain type based on MCU
|
|
231
|
+
toolchain_type: str | None = None
|
|
232
|
+
toolchain_url: str | None = None
|
|
233
|
+
if "toolchain-riscv32-esp" in packages:
|
|
234
|
+
toolchain_url = packages["toolchain-riscv32-esp"]
|
|
235
|
+
toolchain_type = "riscv32-esp"
|
|
236
|
+
elif "toolchain-xtensa-esp-elf" in packages:
|
|
237
|
+
toolchain_url = packages["toolchain-xtensa-esp-elf"]
|
|
238
|
+
toolchain_type = "xtensa-esp-elf"
|
|
239
|
+
|
|
240
|
+
if toolchain_url and toolchain_type:
|
|
241
|
+
toolchain = ToolchainESP32(cache, toolchain_url, toolchain_type, show_progress=True)
|
|
242
|
+
toolchain.ensure_toolchain()
|
|
243
|
+
logging.info(f"Toolchain installed: version {toolchain.version}")
|
|
244
|
+
else:
|
|
245
|
+
logging.warning("No toolchain package found for MCU")
|
|
246
|
+
|
|
247
|
+
# 3. Initialize framework
|
|
248
|
+
logging.info("Installing Arduino framework...")
|
|
249
|
+
framework_url = packages.get("framework-arduinoespressif32")
|
|
250
|
+
libs_url = packages.get("framework-arduinoespressif32-libs")
|
|
251
|
+
if framework_url and libs_url:
|
|
252
|
+
# Check for MCU-specific skeleton library
|
|
253
|
+
mcu_suffix = mcu.replace("esp32", "")
|
|
254
|
+
skeleton_lib_name = f"framework-arduino-{mcu_suffix}-skeleton-lib"
|
|
255
|
+
skeleton_lib_url = packages.get(skeleton_lib_name)
|
|
256
|
+
framework = FrameworkESP32(cache, framework_url, libs_url, skeleton_lib_url=skeleton_lib_url, show_progress=True)
|
|
257
|
+
framework.ensure_framework()
|
|
258
|
+
logging.info(f"Framework installed: version {framework.version}")
|
|
259
|
+
else:
|
|
260
|
+
logging.warning("No framework package found or missing libs URL")
|
|
261
|
+
|
|
262
|
+
# 4. Install library dependencies
|
|
263
|
+
if lib_deps:
|
|
264
|
+
logging.info(f"Installing {len(lib_deps)} library dependencies...")
|
|
265
|
+
from fbuild.packages.platformio_registry import LibrarySpec
|
|
266
|
+
|
|
267
|
+
build_dir = cache.project_dir / ".fbuild" / "build" / board_id
|
|
268
|
+
lib_manager = LibraryManagerESP32(build_dir, project_dir=project_dir)
|
|
269
|
+
for lib_dep in lib_deps:
|
|
270
|
+
logging.info(f" Installing: {lib_dep}")
|
|
271
|
+
try:
|
|
272
|
+
spec = LibrarySpec.parse(lib_dep)
|
|
273
|
+
lib_manager.download_library(spec, show_progress=True)
|
|
274
|
+
except KeyboardInterrupt as ke:
|
|
275
|
+
from fbuild.interrupt_utils import (
|
|
276
|
+
handle_keyboard_interrupt_properly,
|
|
277
|
+
)
|
|
278
|
+
|
|
279
|
+
handle_keyboard_interrupt_properly(ke)
|
|
280
|
+
raise
|
|
281
|
+
except Exception as e:
|
|
282
|
+
logging.error(f"Failed to install library {lib_dep}: {e}")
|
|
283
|
+
return False
|
|
284
|
+
logging.info("All libraries installed successfully")
|
|
285
|
+
else:
|
|
286
|
+
logging.info("No library dependencies to install")
|
|
287
|
+
|
|
288
|
+
return True
|
|
289
|
+
|
|
290
|
+
def _install_avr_dependencies(
|
|
291
|
+
self,
|
|
292
|
+
cache: "Cache",
|
|
293
|
+
env_config: dict,
|
|
294
|
+
verbose: bool,
|
|
295
|
+
) -> bool:
|
|
296
|
+
"""Install AVR platform dependencies.
|
|
297
|
+
|
|
298
|
+
Args:
|
|
299
|
+
cache: Cache instance
|
|
300
|
+
env_config: Environment configuration
|
|
301
|
+
verbose: Enable verbose output
|
|
302
|
+
|
|
303
|
+
Returns:
|
|
304
|
+
True if successful, False otherwise
|
|
305
|
+
"""
|
|
306
|
+
# AVR platform support - minimal implementation
|
|
307
|
+
# TODO: Implement full AVR dependency installation
|
|
308
|
+
logging.info("AVR dependency installation not yet fully implemented")
|
|
309
|
+
logging.info("AVR builds will install dependencies on first build")
|
|
310
|
+
return True
|
|
311
|
+
|
|
312
|
+
def _install_rp2040_dependencies(
|
|
313
|
+
self,
|
|
314
|
+
cache: "Cache",
|
|
315
|
+
env_config: dict,
|
|
316
|
+
verbose: bool,
|
|
317
|
+
) -> bool:
|
|
318
|
+
"""Install RP2040 platform dependencies.
|
|
319
|
+
|
|
320
|
+
Args:
|
|
321
|
+
cache: Cache instance
|
|
322
|
+
env_config: Environment configuration
|
|
323
|
+
verbose: Enable verbose output
|
|
324
|
+
|
|
325
|
+
Returns:
|
|
326
|
+
True if successful, False otherwise
|
|
327
|
+
"""
|
|
328
|
+
# RP2040 platform support - minimal implementation
|
|
329
|
+
# TODO: Implement full RP2040 dependency installation
|
|
330
|
+
logging.info("RP2040 dependency installation not yet fully implemented")
|
|
331
|
+
logging.info("RP2040 builds will install dependencies on first build")
|
|
332
|
+
return True
|
|
333
|
+
|
|
334
|
+
def _install_stm32_dependencies(
|
|
335
|
+
self,
|
|
336
|
+
cache: "Cache",
|
|
337
|
+
env_config: dict,
|
|
338
|
+
verbose: bool,
|
|
339
|
+
) -> bool:
|
|
340
|
+
"""Install STM32 platform dependencies.
|
|
341
|
+
|
|
342
|
+
Args:
|
|
343
|
+
cache: Cache instance
|
|
344
|
+
env_config: Environment configuration
|
|
345
|
+
verbose: Enable verbose output
|
|
346
|
+
|
|
347
|
+
Returns:
|
|
348
|
+
True if successful, False otherwise
|
|
349
|
+
"""
|
|
350
|
+
# STM32 platform support - minimal implementation
|
|
351
|
+
# TODO: Implement full STM32 dependency installation
|
|
352
|
+
logging.info("STM32 dependency installation not yet fully implemented")
|
|
353
|
+
logging.info("STM32 builds will install dependencies on first build")
|
|
354
|
+
return True
|
|
355
|
+
|
|
356
|
+
def _resolve_platform_url(self, platform_url: str) -> str:
|
|
357
|
+
"""Resolve platform shorthand to actual download URL.
|
|
358
|
+
|
|
359
|
+
Args:
|
|
360
|
+
platform_url: Platform URL or shorthand from platformio.ini
|
|
361
|
+
|
|
362
|
+
Returns:
|
|
363
|
+
Resolved platform URL
|
|
364
|
+
"""
|
|
365
|
+
# If it's already a full URL, return as-is
|
|
366
|
+
if platform_url.startswith("http://") or platform_url.startswith("https://"):
|
|
367
|
+
return platform_url
|
|
368
|
+
|
|
369
|
+
# Handle PlatformIO shorthand formats - use default GitHub URLs
|
|
370
|
+
# PlatformIO registry doesn't provide platform URLs, so we use known defaults
|
|
371
|
+
platform_defaults = {
|
|
372
|
+
"espressif32": "https://github.com/platformio/platform-espressif32.git",
|
|
373
|
+
"atmelavr": "https://github.com/platformio/platform-atmelavr.git",
|
|
374
|
+
"raspberrypi": "https://github.com/platformio/platform-raspberrypi.git",
|
|
375
|
+
"ststm32": "https://github.com/platformio/platform-ststm32.git",
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
# Normalize the platform name
|
|
379
|
+
normalized = platform_url.lower()
|
|
380
|
+
if normalized.startswith("platformio/"):
|
|
381
|
+
normalized = normalized.replace("platformio/", "")
|
|
382
|
+
|
|
383
|
+
if normalized in platform_defaults:
|
|
384
|
+
return platform_defaults[normalized]
|
|
385
|
+
|
|
386
|
+
# If we can't resolve, return as-is and let the caller handle the error
|
|
387
|
+
return platform_url
|
|
388
|
+
|
|
389
|
+
def _reload_build_modules(self) -> None:
|
|
390
|
+
"""Reload build-related modules to pick up code changes.
|
|
391
|
+
|
|
392
|
+
This is critical for development on Windows where daemon caching prevents
|
|
393
|
+
testing code changes.
|
|
394
|
+
"""
|
|
395
|
+
modules_to_reload = [
|
|
396
|
+
# Package modules (reload first - no dependencies)
|
|
397
|
+
"fbuild.packages.cache",
|
|
398
|
+
"fbuild.packages.downloader",
|
|
399
|
+
"fbuild.packages.archive_utils",
|
|
400
|
+
"fbuild.packages.platformio_registry",
|
|
401
|
+
"fbuild.packages.toolchain",
|
|
402
|
+
"fbuild.packages.toolchain_esp32",
|
|
403
|
+
"fbuild.packages.arduino_core",
|
|
404
|
+
"fbuild.packages.framework_esp32",
|
|
405
|
+
"fbuild.packages.platform_esp32",
|
|
406
|
+
"fbuild.packages.library_manager",
|
|
407
|
+
"fbuild.packages.library_manager_esp32",
|
|
408
|
+
# Config system
|
|
409
|
+
"fbuild.config.ini_parser",
|
|
410
|
+
"fbuild.config.board_config",
|
|
411
|
+
"fbuild.config.board_loader",
|
|
412
|
+
]
|
|
413
|
+
|
|
414
|
+
reloaded_count = 0
|
|
415
|
+
for module_name in modules_to_reload:
|
|
416
|
+
try:
|
|
417
|
+
if module_name in sys.modules:
|
|
418
|
+
importlib.reload(sys.modules[module_name])
|
|
419
|
+
reloaded_count += 1
|
|
420
|
+
else:
|
|
421
|
+
__import__(module_name)
|
|
422
|
+
reloaded_count += 1
|
|
423
|
+
except KeyboardInterrupt as ke:
|
|
424
|
+
from fbuild.interrupt_utils import handle_keyboard_interrupt_properly
|
|
425
|
+
|
|
426
|
+
handle_keyboard_interrupt_properly(ke)
|
|
427
|
+
except Exception as e:
|
|
428
|
+
logging.warning(f"Failed to reload/import module {module_name}: {e}")
|
|
429
|
+
|
|
430
|
+
if reloaded_count > 0:
|
|
431
|
+
logging.info(f"Loaded/reloaded {reloaded_count} package modules")
|