fbuild 1.1.0__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.

Potentially problematic release.


This version of fbuild might be problematic. Click here for more details.

Files changed (93) hide show
  1. fbuild/__init__.py +0 -0
  2. fbuild/assets/example.txt +1 -0
  3. fbuild/build/__init__.py +117 -0
  4. fbuild/build/archive_creator.py +186 -0
  5. fbuild/build/binary_generator.py +444 -0
  6. fbuild/build/build_component_factory.py +131 -0
  7. fbuild/build/build_state.py +325 -0
  8. fbuild/build/build_utils.py +98 -0
  9. fbuild/build/compilation_executor.py +422 -0
  10. fbuild/build/compiler.py +165 -0
  11. fbuild/build/compiler_avr.py +574 -0
  12. fbuild/build/configurable_compiler.py +612 -0
  13. fbuild/build/configurable_linker.py +637 -0
  14. fbuild/build/flag_builder.py +186 -0
  15. fbuild/build/library_dependency_processor.py +185 -0
  16. fbuild/build/linker.py +708 -0
  17. fbuild/build/orchestrator.py +67 -0
  18. fbuild/build/orchestrator_avr.py +656 -0
  19. fbuild/build/orchestrator_esp32.py +797 -0
  20. fbuild/build/orchestrator_teensy.py +543 -0
  21. fbuild/build/source_compilation_orchestrator.py +220 -0
  22. fbuild/build/source_scanner.py +516 -0
  23. fbuild/cli.py +566 -0
  24. fbuild/cli_utils.py +312 -0
  25. fbuild/config/__init__.py +16 -0
  26. fbuild/config/board_config.py +457 -0
  27. fbuild/config/board_loader.py +92 -0
  28. fbuild/config/ini_parser.py +209 -0
  29. fbuild/config/mcu_specs.py +88 -0
  30. fbuild/daemon/__init__.py +34 -0
  31. fbuild/daemon/client.py +929 -0
  32. fbuild/daemon/compilation_queue.py +293 -0
  33. fbuild/daemon/daemon.py +474 -0
  34. fbuild/daemon/daemon_context.py +196 -0
  35. fbuild/daemon/error_collector.py +263 -0
  36. fbuild/daemon/file_cache.py +332 -0
  37. fbuild/daemon/lock_manager.py +270 -0
  38. fbuild/daemon/logging_utils.py +149 -0
  39. fbuild/daemon/messages.py +301 -0
  40. fbuild/daemon/operation_registry.py +288 -0
  41. fbuild/daemon/process_tracker.py +366 -0
  42. fbuild/daemon/processors/__init__.py +12 -0
  43. fbuild/daemon/processors/build_processor.py +157 -0
  44. fbuild/daemon/processors/deploy_processor.py +327 -0
  45. fbuild/daemon/processors/monitor_processor.py +146 -0
  46. fbuild/daemon/request_processor.py +401 -0
  47. fbuild/daemon/status_manager.py +216 -0
  48. fbuild/daemon/subprocess_manager.py +316 -0
  49. fbuild/deploy/__init__.py +17 -0
  50. fbuild/deploy/deployer.py +67 -0
  51. fbuild/deploy/deployer_esp32.py +314 -0
  52. fbuild/deploy/monitor.py +495 -0
  53. fbuild/interrupt_utils.py +34 -0
  54. fbuild/packages/__init__.py +53 -0
  55. fbuild/packages/archive_utils.py +1098 -0
  56. fbuild/packages/arduino_core.py +412 -0
  57. fbuild/packages/cache.py +249 -0
  58. fbuild/packages/downloader.py +366 -0
  59. fbuild/packages/framework_esp32.py +538 -0
  60. fbuild/packages/framework_teensy.py +346 -0
  61. fbuild/packages/github_utils.py +96 -0
  62. fbuild/packages/header_trampoline_cache.py +394 -0
  63. fbuild/packages/library_compiler.py +203 -0
  64. fbuild/packages/library_manager.py +549 -0
  65. fbuild/packages/library_manager_esp32.py +413 -0
  66. fbuild/packages/package.py +163 -0
  67. fbuild/packages/platform_esp32.py +383 -0
  68. fbuild/packages/platform_teensy.py +312 -0
  69. fbuild/packages/platform_utils.py +131 -0
  70. fbuild/packages/platformio_registry.py +325 -0
  71. fbuild/packages/sdk_utils.py +231 -0
  72. fbuild/packages/toolchain.py +436 -0
  73. fbuild/packages/toolchain_binaries.py +196 -0
  74. fbuild/packages/toolchain_esp32.py +484 -0
  75. fbuild/packages/toolchain_metadata.py +185 -0
  76. fbuild/packages/toolchain_teensy.py +404 -0
  77. fbuild/platform_configs/esp32.json +150 -0
  78. fbuild/platform_configs/esp32c2.json +144 -0
  79. fbuild/platform_configs/esp32c3.json +143 -0
  80. fbuild/platform_configs/esp32c5.json +151 -0
  81. fbuild/platform_configs/esp32c6.json +151 -0
  82. fbuild/platform_configs/esp32p4.json +149 -0
  83. fbuild/platform_configs/esp32s3.json +151 -0
  84. fbuild/platform_configs/imxrt1062.json +56 -0
  85. fbuild-1.1.0.dist-info/METADATA +447 -0
  86. fbuild-1.1.0.dist-info/RECORD +93 -0
  87. fbuild-1.1.0.dist-info/WHEEL +5 -0
  88. fbuild-1.1.0.dist-info/entry_points.txt +5 -0
  89. fbuild-1.1.0.dist-info/licenses/LICENSE +21 -0
  90. fbuild-1.1.0.dist-info/top_level.txt +2 -0
  91. fbuild_lint/__init__.py +0 -0
  92. fbuild_lint/ruff_plugins/__init__.py +0 -0
  93. fbuild_lint/ruff_plugins/keyboard_interrupt_checker.py +158 -0
@@ -0,0 +1,444 @@
1
+ """Binary Generation Utilities.
2
+
3
+ This module provides utilities for generating firmware binaries from ELF files,
4
+ including ESP32-specific bootloader and partition table generation.
5
+
6
+ Design:
7
+ - Separates binary generation logic from linker
8
+ - Supports both objcopy (AVR) and esptool (ESP32) workflows
9
+ - Handles ESP32 bootloader and partition table generation
10
+ """
11
+
12
+ import subprocess
13
+ import sys
14
+ from pathlib import Path
15
+ from typing import Any, Dict, Optional
16
+
17
+
18
+ class BinaryGeneratorError(Exception):
19
+ """Raised when binary generation operations fail."""
20
+ pass
21
+
22
+
23
+ class BinaryGenerator:
24
+ """Handles firmware binary generation from ELF files.
25
+
26
+ This class provides:
27
+ - ELF to BIN conversion using objcopy or esptool
28
+ - ESP32 bootloader.bin generation
29
+ - ESP32 partitions.bin generation
30
+ """
31
+
32
+ def __init__(
33
+ self,
34
+ mcu: str,
35
+ board_config: Dict[str, Any],
36
+ build_dir: Path,
37
+ toolchain: Any = None,
38
+ framework: Any = None,
39
+ show_progress: bool = True
40
+ ):
41
+ """Initialize binary generator.
42
+
43
+ Args:
44
+ mcu: MCU type (e.g., "esp32c6", "atmega328p")
45
+ board_config: Board configuration dictionary
46
+ build_dir: Directory for build artifacts
47
+ toolchain: Toolchain instance (required for objcopy)
48
+ framework: Framework instance (required for ESP32 bootloader/partitions)
49
+ show_progress: Whether to show generation progress
50
+ """
51
+ self.mcu = mcu
52
+ self.board_config = board_config
53
+ self.build_dir = build_dir
54
+ self.toolchain = toolchain
55
+ self.framework = framework
56
+ self.show_progress = show_progress
57
+
58
+ def generate_bin(self, elf_path: Path, output_bin: Optional[Path] = None) -> Path:
59
+ """Generate firmware.bin from firmware.elf.
60
+
61
+ Args:
62
+ elf_path: Path to firmware.elf
63
+ output_bin: Optional path for output .bin file
64
+
65
+ Returns:
66
+ Path to generated firmware.bin
67
+
68
+ Raises:
69
+ BinaryGeneratorError: If conversion fails
70
+ """
71
+ if not elf_path.exists():
72
+ raise BinaryGeneratorError(f"ELF file not found: {elf_path}")
73
+
74
+ # Generate output path if not provided
75
+ if output_bin is None:
76
+ output_bin = self.build_dir / "firmware.bin"
77
+
78
+ # For ESP32 platforms, use esptool.py elf2image instead of objcopy
79
+ # This generates a properly formatted ESP32 flash image without memory gaps
80
+ if self.mcu.startswith("esp32"):
81
+ return self._generate_bin_esp32(elf_path, output_bin)
82
+ else:
83
+ return self._generate_bin_objcopy(elf_path, output_bin)
84
+
85
+ def _generate_bin_esp32(self, elf_path: Path, output_bin: Path) -> Path:
86
+ """Generate firmware.bin for ESP32 using esptool.py elf2image.
87
+
88
+ Args:
89
+ elf_path: Path to firmware.elf
90
+ output_bin: Path for output .bin file
91
+
92
+ Returns:
93
+ Path to generated firmware.bin
94
+
95
+ Raises:
96
+ BinaryGeneratorError: If conversion fails
97
+ """
98
+ # Get chip type from MCU
99
+ chip = self.mcu # e.g., "esp32c6", "esp32s3"
100
+
101
+ # Get flash parameters from board config
102
+ flash_mode = self.board_config.get("build", {}).get("flash_mode", "dio")
103
+ flash_freq = self.board_config.get("build", {}).get("f_flash", "80m")
104
+ flash_size = self.board_config.get("build", {}).get("flash_size", "4MB")
105
+
106
+ # Convert frequency to esptool format if needed
107
+ flash_freq = self._normalize_flash_freq(flash_freq)
108
+
109
+ # Build esptool.py elf2image command
110
+ cmd = [
111
+ sys.executable,
112
+ "-m",
113
+ "esptool",
114
+ "--chip",
115
+ chip,
116
+ "elf2image",
117
+ "--flash-mode",
118
+ flash_mode,
119
+ "--flash-freq",
120
+ flash_freq,
121
+ "--flash-size",
122
+ flash_size,
123
+ "--elf-sha256-offset",
124
+ "0xb0",
125
+ "-o",
126
+ str(output_bin),
127
+ str(elf_path)
128
+ ]
129
+
130
+ if self.show_progress:
131
+ print("Generating firmware.bin using esptool.py elf2image...")
132
+
133
+ try:
134
+ result = subprocess.run(
135
+ cmd,
136
+ capture_output=True,
137
+ text=False, # Don't decode as text - esptool may output binary data
138
+ timeout=60
139
+ )
140
+
141
+ if result.returncode != 0:
142
+ error_msg = "Binary generation failed\n"
143
+ stderr = result.stderr.decode('utf-8', errors='replace') if result.stderr else ""
144
+ stdout = result.stdout.decode('utf-8', errors='replace') if result.stdout else ""
145
+ error_msg += f"stderr: {stderr}\n"
146
+ error_msg += f"stdout: {stdout}"
147
+ raise BinaryGeneratorError(error_msg)
148
+
149
+ if not output_bin.exists():
150
+ raise BinaryGeneratorError(f"firmware.bin was not created: {output_bin}")
151
+
152
+ if self.show_progress:
153
+ size = output_bin.stat().st_size
154
+ print(f"✓ Created firmware.bin: {size:,} bytes ({size / 1024:.2f} KB)")
155
+
156
+ return output_bin
157
+
158
+ except subprocess.TimeoutExpired as e:
159
+ raise BinaryGeneratorError("Binary generation timeout") from e
160
+ except KeyboardInterrupt as ke:
161
+ from fbuild.interrupt_utils import handle_keyboard_interrupt_properly
162
+ handle_keyboard_interrupt_properly(ke)
163
+ raise # Never reached, but satisfies type checker
164
+ except Exception as e:
165
+ raise BinaryGeneratorError(f"Failed to generate binary: {e}") from e
166
+
167
+ def _generate_bin_objcopy(self, elf_path: Path, output_bin: Path) -> Path:
168
+ """Generate firmware.bin using objcopy (for non-ESP32 platforms).
169
+
170
+ Args:
171
+ elf_path: Path to firmware.elf
172
+ output_bin: Path for output .bin file
173
+
174
+ Returns:
175
+ Path to generated firmware.bin
176
+
177
+ Raises:
178
+ BinaryGeneratorError: If conversion fails
179
+ """
180
+ if self.toolchain is None:
181
+ raise BinaryGeneratorError("Toolchain required for objcopy binary generation")
182
+
183
+ # Get objcopy tool
184
+ objcopy_path = self.toolchain.get_objcopy_path()
185
+ if objcopy_path is None or not objcopy_path.exists():
186
+ raise BinaryGeneratorError(
187
+ f"objcopy not found: {objcopy_path}. " +
188
+ "Ensure toolchain is installed."
189
+ )
190
+
191
+ # Build objcopy command
192
+ cmd = [
193
+ str(objcopy_path),
194
+ "-O", "binary",
195
+ str(elf_path),
196
+ str(output_bin)
197
+ ]
198
+
199
+ # Execute objcopy
200
+ if self.show_progress:
201
+ print("Generating firmware.bin...")
202
+
203
+ try:
204
+ result = subprocess.run(
205
+ cmd,
206
+ capture_output=True,
207
+ text=True,
208
+ timeout=30
209
+ )
210
+
211
+ if result.returncode != 0:
212
+ error_msg = "Binary generation failed\n"
213
+ error_msg += f"stderr: {result.stderr}\n"
214
+ error_msg += f"stdout: {result.stdout}"
215
+ raise BinaryGeneratorError(error_msg)
216
+
217
+ if not output_bin.exists():
218
+ raise BinaryGeneratorError(f"firmware.bin was not created: {output_bin}")
219
+
220
+ if self.show_progress:
221
+ size = output_bin.stat().st_size
222
+ print(f"✓ Created firmware.bin: {size:,} bytes ({size / 1024 / 1024:.2f} MB)")
223
+
224
+ return output_bin
225
+
226
+ except subprocess.TimeoutExpired as e:
227
+ raise BinaryGeneratorError("Binary generation timeout") from e
228
+ except KeyboardInterrupt as ke:
229
+ from fbuild.interrupt_utils import handle_keyboard_interrupt_properly
230
+ handle_keyboard_interrupt_properly(ke)
231
+ raise # Never reached, but satisfies type checker
232
+ except Exception as e:
233
+ raise BinaryGeneratorError(f"Failed to generate binary: {e}") from e
234
+
235
+ def generate_bootloader(self, output_bin: Optional[Path] = None) -> Path:
236
+ """Generate bootloader.bin from bootloader ELF file.
237
+
238
+ Args:
239
+ output_bin: Optional path for output bootloader.bin
240
+
241
+ Returns:
242
+ Path to generated bootloader.bin
243
+
244
+ Raises:
245
+ BinaryGeneratorError: If generation fails
246
+ """
247
+ if not self.mcu.startswith("esp32"):
248
+ raise BinaryGeneratorError(
249
+ f"Bootloader generation only supported for ESP32 platforms, not {self.mcu}"
250
+ )
251
+
252
+ if self.framework is None:
253
+ raise BinaryGeneratorError("Framework required for bootloader generation")
254
+
255
+ # Generate output path if not provided
256
+ if output_bin is None:
257
+ output_bin = self.build_dir / "bootloader.bin"
258
+
259
+ # Get flash parameters from board config
260
+ flash_mode = self.board_config.get("build", {}).get("flash_mode", "dio")
261
+ flash_freq = self.board_config.get("build", {}).get("f_flash", "80m")
262
+ flash_size = self.board_config.get("build", {}).get("flash_size", "4MB")
263
+
264
+ # Convert frequency to esptool format if needed
265
+ flash_freq = self._normalize_flash_freq(flash_freq)
266
+
267
+ # Find bootloader ELF file in framework SDK
268
+ bootloader_name = f"bootloader_{flash_mode}_{flash_freq.replace('m', 'm')}.elf"
269
+ sdk_bin_dir = self.framework.get_sdk_dir() / self.mcu / "bin"
270
+ bootloader_elf = sdk_bin_dir / bootloader_name
271
+
272
+ if not bootloader_elf.exists():
273
+ raise BinaryGeneratorError(
274
+ f"Bootloader ELF not found: {bootloader_elf}"
275
+ )
276
+
277
+ # CRITICAL FIX: ESP32-C6/C3/C2/H2 bootloaders MUST be generated in DIO mode
278
+ # even if the application uses QIO. The ROM bootloader can only load the
279
+ # second-stage bootloader in DIO mode. QIO is enabled later by the second-stage
280
+ # bootloader for the application. This is a known issue with esptool v4.7+.
281
+ # See: https://github.com/espressif/arduino-esp32/discussions/10418
282
+ bootloader_flash_mode = flash_mode
283
+ if self.mcu in ["esp32c6", "esp32c3", "esp32c2", "esp32h2"]:
284
+ bootloader_flash_mode = "dio"
285
+
286
+ # Generate bootloader.bin using esptool.py elf2image
287
+ cmd = [
288
+ sys.executable,
289
+ "-m",
290
+ "esptool",
291
+ "--chip",
292
+ self.mcu,
293
+ "elf2image",
294
+ "--flash-mode",
295
+ bootloader_flash_mode,
296
+ "--flash-freq",
297
+ flash_freq,
298
+ "--flash-size",
299
+ flash_size,
300
+ "-o",
301
+ str(output_bin),
302
+ str(bootloader_elf)
303
+ ]
304
+
305
+ if self.show_progress:
306
+ print("Generating bootloader.bin...")
307
+
308
+ try:
309
+ result = subprocess.run(
310
+ cmd,
311
+ capture_output=True,
312
+ text=False,
313
+ timeout=60
314
+ )
315
+
316
+ if result.returncode != 0:
317
+ error_msg = "Bootloader generation failed\n"
318
+ stderr = result.stderr.decode('utf-8', errors='replace') if result.stderr else ""
319
+ stdout = result.stdout.decode('utf-8', errors='replace') if result.stdout else ""
320
+ error_msg += f"stderr: {stderr}\n"
321
+ error_msg += f"stdout: {stdout}"
322
+ raise BinaryGeneratorError(error_msg)
323
+
324
+ if not output_bin.exists():
325
+ raise BinaryGeneratorError(f"bootloader.bin was not created: {output_bin}")
326
+
327
+ if self.show_progress:
328
+ size = output_bin.stat().st_size
329
+ print(f"✓ Created bootloader.bin: {size:,} bytes ({size / 1024:.2f} KB)")
330
+
331
+ return output_bin
332
+
333
+ except subprocess.TimeoutExpired as e:
334
+ raise BinaryGeneratorError("Bootloader generation timeout") from e
335
+ except KeyboardInterrupt as ke:
336
+ from fbuild.interrupt_utils import handle_keyboard_interrupt_properly
337
+ handle_keyboard_interrupt_properly(ke)
338
+ raise # Never reached, but satisfies type checker
339
+ except Exception as e:
340
+ raise BinaryGeneratorError(f"Failed to generate bootloader: {e}") from e
341
+
342
+ def generate_partition_table(self, output_bin: Optional[Path] = None) -> Path:
343
+ """Generate partitions.bin from partition CSV file.
344
+
345
+ Args:
346
+ output_bin: Optional path for output partitions.bin
347
+
348
+ Returns:
349
+ Path to generated partitions.bin
350
+
351
+ Raises:
352
+ BinaryGeneratorError: If generation fails
353
+ """
354
+ if not self.mcu.startswith("esp32"):
355
+ raise BinaryGeneratorError(
356
+ f"Partition table generation only supported for ESP32 platforms, not {self.mcu}"
357
+ )
358
+
359
+ if self.framework is None:
360
+ raise BinaryGeneratorError("Framework required for partition table generation")
361
+
362
+ # Generate output path if not provided
363
+ if output_bin is None:
364
+ output_bin = self.build_dir / "partitions.bin"
365
+
366
+ # Find partition CSV file - use default.csv from framework
367
+ partitions_csv = self.framework.framework_path / "tools" / "partitions" / "default.csv"
368
+
369
+ if not partitions_csv.exists():
370
+ raise BinaryGeneratorError(
371
+ f"Partition CSV not found: {partitions_csv}"
372
+ )
373
+
374
+ # Find gen_esp32part.py tool - also in framework
375
+ gen_tool = self.framework.framework_path / "tools" / "gen_esp32part.py"
376
+
377
+ if not gen_tool.exists():
378
+ raise BinaryGeneratorError(
379
+ f"Partition generation tool not found: {gen_tool}"
380
+ )
381
+
382
+ # Generate partition table using gen_esp32part.py
383
+ cmd = [
384
+ sys.executable,
385
+ str(gen_tool),
386
+ "-q",
387
+ str(partitions_csv),
388
+ str(output_bin)
389
+ ]
390
+
391
+ if self.show_progress:
392
+ print("Generating partitions.bin...")
393
+
394
+ try:
395
+ result = subprocess.run(
396
+ cmd,
397
+ capture_output=True,
398
+ text=True,
399
+ timeout=30
400
+ )
401
+
402
+ if result.returncode != 0:
403
+ error_msg = "Partition table generation failed\n"
404
+ error_msg += f"stderr: {result.stderr}\n"
405
+ error_msg += f"stdout: {result.stdout}"
406
+ raise BinaryGeneratorError(error_msg)
407
+
408
+ if not output_bin.exists():
409
+ raise BinaryGeneratorError(f"partitions.bin was not created: {output_bin}")
410
+
411
+ if self.show_progress:
412
+ size = output_bin.stat().st_size
413
+ print(f"✓ Created partitions.bin: {size:,} bytes")
414
+
415
+ return output_bin
416
+
417
+ except subprocess.TimeoutExpired as e:
418
+ raise BinaryGeneratorError("Partition table generation timeout") from e
419
+ except KeyboardInterrupt as ke:
420
+ from fbuild.interrupt_utils import handle_keyboard_interrupt_properly
421
+ handle_keyboard_interrupt_properly(ke)
422
+ raise # Never reached, but satisfies type checker
423
+ except Exception as e:
424
+ raise BinaryGeneratorError(f"Failed to generate partition table: {e}") from e
425
+
426
+ @staticmethod
427
+ def _normalize_flash_freq(flash_freq: Any) -> str:
428
+ """Normalize flash frequency to esptool format.
429
+
430
+ Args:
431
+ flash_freq: Flash frequency (int/float in Hz, or string like "80m" or "80000000L")
432
+
433
+ Returns:
434
+ Normalized frequency string (e.g., "80m")
435
+ """
436
+ if isinstance(flash_freq, (int, float)):
437
+ # Convert Hz to MHz format like "80m"
438
+ return f"{int(flash_freq // 1000000)}m"
439
+ elif isinstance(flash_freq, str) and flash_freq.endswith('L'):
440
+ # Handle string representation of long integers like "80000000L"
441
+ freq_value = int(flash_freq.rstrip('L'))
442
+ return f"{freq_value // 1000000}m"
443
+ else:
444
+ return str(flash_freq)
@@ -0,0 +1,131 @@
1
+ """
2
+ Build component factory for Fbuild build system.
3
+
4
+ This module provides factory methods for creating build components
5
+ (Compiler, Linker) with appropriate configurations. It centralizes
6
+ the logic for setting up these components with correct parameters.
7
+ """
8
+
9
+ from pathlib import Path
10
+ from typing import List, Optional, TYPE_CHECKING
11
+
12
+ from ..config.board_config import BoardConfig
13
+ from ..config.mcu_specs import get_max_flash, get_max_ram
14
+ from ..packages.package import IToolchain
15
+ from .compiler_avr import CompilerAVR
16
+ from .linker import LinkerAVR
17
+
18
+ if TYPE_CHECKING:
19
+ from ..daemon.compilation_queue import CompilationJobQueue
20
+
21
+
22
+ class BuildComponentFactory:
23
+ """
24
+ Factory for creating build components with proper configurations.
25
+
26
+ This class centralizes the creation of build system components (Compiler, Linker)
27
+ with appropriate settings derived from board configuration and toolchain.
28
+
29
+ Example usage:
30
+ factory = BuildComponentFactory()
31
+ compiler = factory.create_compiler(
32
+ toolchain=toolchain,
33
+ board_config=board_config,
34
+ core_path=core_path,
35
+ lib_include_paths=[Path("lib1/include"), Path("lib2/include")]
36
+ )
37
+ linker = factory.create_linker(
38
+ toolchain=toolchain,
39
+ board_config=board_config
40
+ )
41
+ """
42
+
43
+ @staticmethod
44
+ def create_compiler(
45
+ toolchain: IToolchain,
46
+ board_config: BoardConfig,
47
+ core_path: Path,
48
+ lib_include_paths: Optional[List[Path]] = None,
49
+ compilation_queue: Optional['CompilationJobQueue'] = None
50
+ ) -> CompilerAVR:
51
+ """
52
+ Create compiler instance with appropriate settings.
53
+
54
+ Configures the compiler with:
55
+ - Toolchain binaries (avr-gcc, avr-g++)
56
+ - MCU and F_CPU from board configuration
57
+ - Include paths (core + variant + libraries)
58
+ - Defines (Arduino version, board-specific defines)
59
+ - Optional compilation queue for async/parallel compilation
60
+
61
+ Args:
62
+ toolchain: Toolchain instance
63
+ board_config: Board configuration
64
+ core_path: Arduino core path
65
+ lib_include_paths: Optional library include paths
66
+ compilation_queue: Optional compilation queue for async compilation
67
+
68
+ Returns:
69
+ Configured Compiler instance
70
+ """
71
+ # Get toolchain binaries
72
+ tools = toolchain.get_all_tools()
73
+
74
+ # Get include paths from board config
75
+ include_paths = board_config.get_include_paths(core_path)
76
+
77
+ # Add library include paths
78
+ if lib_include_paths:
79
+ include_paths = list(include_paths) + list(lib_include_paths)
80
+
81
+ # Get defines from board config
82
+ defines = board_config.get_defines()
83
+
84
+ # Create and return compiler
85
+ return CompilerAVR(
86
+ avr_gcc=tools['avr-gcc'],
87
+ avr_gpp=tools['avr-g++'],
88
+ mcu=board_config.mcu,
89
+ f_cpu=board_config.f_cpu,
90
+ includes=include_paths,
91
+ defines=defines,
92
+ compilation_queue=compilation_queue
93
+ )
94
+
95
+ @staticmethod
96
+ def create_linker(
97
+ toolchain: IToolchain,
98
+ board_config: BoardConfig
99
+ ) -> LinkerAVR:
100
+ """
101
+ Create linker instance with appropriate settings.
102
+
103
+ Configures the linker with:
104
+ - Toolchain binaries (avr-gcc, avr-ar, avr-objcopy, avr-size)
105
+ - MCU from board configuration
106
+ - Flash and RAM limits from MCU specifications
107
+
108
+ Args:
109
+ toolchain: Toolchain instance
110
+ board_config: Board configuration
111
+
112
+ Returns:
113
+ Configured Linker instance
114
+ """
115
+ # Get toolchain binaries
116
+ tools = toolchain.get_all_tools()
117
+
118
+ # Get MCU specifications from centralized module
119
+ max_flash = get_max_flash(board_config.mcu)
120
+ max_ram = get_max_ram(board_config.mcu)
121
+
122
+ # Create and return linker
123
+ return LinkerAVR(
124
+ avr_gcc=tools['avr-gcc'],
125
+ avr_ar=tools['avr-ar'],
126
+ avr_objcopy=tools['avr-objcopy'],
127
+ avr_size=tools['avr-size'],
128
+ mcu=board_config.mcu,
129
+ max_flash=max_flash,
130
+ max_ram=max_ram
131
+ )