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,186 @@
1
+ """Compilation Flag Builder.
2
+
3
+ This module handles parsing and building compilation flags from platform
4
+ configuration files.
5
+
6
+ Design:
7
+ - Parses flag strings with proper handling of quoted values
8
+ - Builds flags from configuration dictionaries
9
+ - Adds platform-specific defines (Arduino, ESP32, etc.)
10
+ - Merges user build flags from platformio.ini
11
+ """
12
+
13
+ import shlex
14
+ from typing import List, Dict, Any, Optional
15
+
16
+
17
+ class FlagBuilderError(Exception):
18
+ """Raised when flag building operations fail."""
19
+ pass
20
+
21
+
22
+ class FlagBuilder:
23
+ """Builds compilation flags from configuration.
24
+
25
+ This class handles:
26
+ - Parsing flag strings with quoted values
27
+ - Building flags from platform config
28
+ - Adding platform-specific defines
29
+ - Merging user build flags
30
+ """
31
+
32
+ def __init__(
33
+ self,
34
+ config: Dict[str, Any],
35
+ board_config: Dict[str, Any],
36
+ board_id: str,
37
+ variant: str,
38
+ user_build_flags: Optional[List[str]] = None
39
+ ):
40
+ """Initialize flag builder.
41
+
42
+ Args:
43
+ config: Platform configuration dictionary
44
+ board_config: Board-specific configuration
45
+ board_id: Board identifier (e.g., "esp32-c6-devkitm-1")
46
+ variant: Board variant name
47
+ user_build_flags: Build flags from platformio.ini
48
+ """
49
+ self.config = config
50
+ self.board_config = board_config
51
+ self.board_id = board_id
52
+ self.variant = variant
53
+ self.user_build_flags = user_build_flags or []
54
+
55
+ @staticmethod
56
+ def parse_flag_string(flag_string: str) -> List[str]:
57
+ """Parse a flag string that may contain quoted values.
58
+
59
+ Args:
60
+ flag_string: String containing compiler flags
61
+
62
+ Returns:
63
+ List of individual flags with quotes preserved
64
+
65
+ Example:
66
+ >>> FlagBuilder.parse_flag_string('-DFOO="bar baz" -DTEST')
67
+ ['-DFOO="bar baz"', '-DTEST']
68
+ """
69
+ try:
70
+ return shlex.split(flag_string)
71
+ except KeyboardInterrupt as ke:
72
+ from fbuild.interrupt_utils import handle_keyboard_interrupt_properly
73
+ handle_keyboard_interrupt_properly(ke)
74
+ raise # Never reached, but satisfies type checker
75
+ except Exception:
76
+ return flag_string.split()
77
+
78
+ def build_flags(self) -> Dict[str, List[str]]:
79
+ """Build compilation flags from configuration.
80
+
81
+ Returns:
82
+ Dictionary with 'cflags', 'cxxflags', and 'common' keys
83
+ """
84
+ flags = {
85
+ 'common': [], # Common flags for both C and C++
86
+ 'cflags': [], # C-specific flags
87
+ 'cxxflags': [] # C++-specific flags
88
+ }
89
+
90
+ # Get flags from config
91
+ config_flags = self.config.get('compiler_flags', {})
92
+
93
+ # Common flags (CCFLAGS in PlatformIO)
94
+ if 'common' in config_flags:
95
+ flags['common'] = config_flags['common'].copy()
96
+
97
+ # C-specific flags (CFLAGS in PlatformIO)
98
+ if 'c' in config_flags:
99
+ flags['cflags'] = config_flags['c'].copy()
100
+
101
+ # C++-specific flags (CXXFLAGS in PlatformIO)
102
+ if 'cxx' in config_flags:
103
+ flags['cxxflags'] = config_flags['cxx'].copy()
104
+
105
+ # Add defines from config (CPPDEFINES in PlatformIO)
106
+ defines = self.config.get('defines', [])
107
+ for define in defines:
108
+ if isinstance(define, str):
109
+ flags['common'].append(f'-D{define}')
110
+ elif isinstance(define, list) and len(define) == 2:
111
+ flags['common'].append(f'-D{define[0]}={define[1]}')
112
+
113
+ # Add Arduino-specific defines
114
+ self._add_arduino_defines(flags)
115
+
116
+ # Add board-specific extra flags if present
117
+ self._add_board_extra_flags(flags)
118
+
119
+ # Add user build flags from platformio.ini
120
+ self._add_user_flags(flags)
121
+
122
+ return flags
123
+
124
+ def _add_arduino_defines(self, flags: Dict[str, List[str]]) -> None:
125
+ """Add Arduino-specific defines to flags.
126
+
127
+ Args:
128
+ flags: Flags dictionary to update
129
+ """
130
+ build_config = self.board_config.get("build", {})
131
+ f_cpu = build_config.get("f_cpu", "160000000L")
132
+ board = build_config.get("board", self.board_id.upper().replace("-", "_"))
133
+
134
+ flags['common'].extend([
135
+ f'-DF_CPU={f_cpu}',
136
+ '-DARDUINO=10812', # Arduino version
137
+ '-DESP32', # ESP32 platform define
138
+ f'-DARDUINO_{board}',
139
+ '-DARDUINO_ARCH_ESP32',
140
+ f'-DARDUINO_BOARD="{board}"',
141
+ f'-DARDUINO_VARIANT="{self.variant}"',
142
+ ])
143
+
144
+ def _add_board_extra_flags(self, flags: Dict[str, List[str]]) -> None:
145
+ """Add board-specific extra flags.
146
+
147
+ Args:
148
+ flags: Flags dictionary to update
149
+ """
150
+ build_config = self.board_config.get("build", {})
151
+ extra_flags = build_config.get("extra_flags", "")
152
+
153
+ if extra_flags:
154
+ if isinstance(extra_flags, str):
155
+ flag_list = extra_flags.split()
156
+ else:
157
+ flag_list = extra_flags
158
+
159
+ for flag in flag_list:
160
+ if flag.startswith('-D'):
161
+ flags['common'].append(flag)
162
+
163
+ def _add_user_flags(self, flags: Dict[str, List[str]]) -> None:
164
+ """Add user build flags from platformio.ini.
165
+
166
+ These override/extend board defaults.
167
+
168
+ Args:
169
+ flags: Flags dictionary to update
170
+ """
171
+ for flag in self.user_build_flags:
172
+ if flag.startswith('-D'):
173
+ # Add defines to common flags
174
+ flags['common'].append(flag)
175
+ # Could extend to handle other flag types if needed
176
+
177
+ def get_base_flags_for_library(self) -> List[str]:
178
+ """Get base compiler flags for library compilation.
179
+
180
+ Returns:
181
+ List of compiler flags suitable for library compilation
182
+ """
183
+ flags = self.build_flags()
184
+ base_flags = flags['common'].copy()
185
+ base_flags.extend(flags['cxxflags'])
186
+ return base_flags
@@ -0,0 +1,185 @@
1
+ """
2
+ Library dependency processing for Fbuild build system.
3
+
4
+ This module handles downloading, compiling, and managing library dependencies
5
+ from platformio.ini lib_deps configuration. It coordinates between the
6
+ library manager and the build system to ensure all dependencies are ready.
7
+ """
8
+
9
+ from pathlib import Path
10
+ from typing import List, Optional
11
+
12
+ from ..config.board_config import BoardConfig
13
+ from ..packages.library_manager import LibraryManager
14
+ from ..packages.toolchain import ToolchainAVR
15
+
16
+
17
+ class LibraryDependencyProcessor:
18
+ """
19
+ Processes library dependencies for the build system.
20
+
21
+ This class handles:
22
+ - Downloading library dependencies from GitHub URLs
23
+ - Compiling libraries with appropriate flags
24
+ - Managing library include paths and object files
25
+ - Coordinating between LibraryManager and build components
26
+
27
+ Example usage:
28
+ processor = LibraryDependencyProcessor(
29
+ build_dir=Path(".fbuild/build/uno"),
30
+ mode="release",
31
+ verbose=True
32
+ )
33
+ result = processor.process_dependencies(
34
+ lib_deps=["https://github.com/user/library"],
35
+ toolchain=toolchain,
36
+ board_config=board_config,
37
+ core_path=Path("~/.fbuild/packages/arduino-avr-1.8.6")
38
+ )
39
+ include_paths = result.include_paths
40
+ object_files = result.object_files
41
+ """
42
+
43
+ def __init__(
44
+ self,
45
+ build_dir: Path,
46
+ mode: str = "release",
47
+ verbose: bool = False
48
+ ):
49
+ """
50
+ Initialize library dependency processor.
51
+
52
+ Args:
53
+ build_dir: Build directory for storing library artifacts
54
+ mode: Build mode ('release' or 'debug')
55
+ verbose: Enable verbose output
56
+ """
57
+ self.build_dir = build_dir
58
+ self.mode = mode
59
+ self.verbose = verbose
60
+ self.library_manager: Optional[LibraryManager] = None
61
+
62
+ def process_dependencies(
63
+ self,
64
+ lib_deps: List[str],
65
+ toolchain: ToolchainAVR,
66
+ board_config: BoardConfig,
67
+ core_path: Path
68
+ ) -> 'LibraryProcessingResult':
69
+ """
70
+ Process all library dependencies.
71
+
72
+ Downloads, compiles, and prepares all library dependencies for linking.
73
+
74
+ Args:
75
+ lib_deps: List of library dependency URLs (e.g., GitHub URLs)
76
+ toolchain: Toolchain instance for compilation
77
+ board_config: Board configuration for compiler flags
78
+ core_path: Arduino core installation path
79
+
80
+ Returns:
81
+ LibraryProcessingResult with include paths and object files
82
+
83
+ Raises:
84
+ LibraryError: If library processing fails
85
+ """
86
+ if not lib_deps:
87
+ if self.verbose:
88
+ print(" No library dependencies")
89
+ return LibraryProcessingResult(
90
+ libraries=[],
91
+ include_paths=[],
92
+ object_files=[]
93
+ )
94
+
95
+ if self.verbose:
96
+ print(f" Found {len(lib_deps)} library dependencies")
97
+
98
+ # Initialize library manager
99
+ self.library_manager = LibraryManager(self.build_dir, mode=self.mode)
100
+
101
+ # Get compiler tools
102
+ tools = toolchain.get_all_tools()
103
+
104
+ # Prepare compilation parameters
105
+ lib_defines = self._prepare_defines(board_config)
106
+ lib_includes = board_config.get_include_paths(core_path)
107
+
108
+ # Ensure all libraries are downloaded and compiled
109
+ libraries = self.library_manager.ensure_libraries(
110
+ lib_deps=lib_deps,
111
+ compiler_path=tools['avr-gcc'],
112
+ mcu=board_config.mcu,
113
+ f_cpu=board_config.f_cpu,
114
+ defines=lib_defines,
115
+ include_paths=lib_includes,
116
+ extra_flags=[],
117
+ show_progress=self.verbose
118
+ )
119
+
120
+ # Get library artifacts
121
+ lib_include_paths = self.library_manager.get_library_include_paths()
122
+ lib_objects = self.library_manager.get_library_objects()
123
+
124
+ if self.verbose:
125
+ print(f" Compiled {len(libraries)} libraries")
126
+ print(f" Library objects: {len(lib_objects)}")
127
+
128
+ # Extract library directory paths from Library objects
129
+ library_paths = [lib.lib_dir for lib in libraries]
130
+
131
+ return LibraryProcessingResult(
132
+ libraries=library_paths,
133
+ include_paths=lib_include_paths,
134
+ object_files=lib_objects
135
+ )
136
+
137
+ def _prepare_defines(self, board_config: BoardConfig) -> List[str]:
138
+ """
139
+ Prepare defines for library compilation.
140
+
141
+ Converts board configuration defines dictionary to list format
142
+ suitable for library compilation.
143
+
144
+ Args:
145
+ board_config: Board configuration
146
+
147
+ Returns:
148
+ List of define strings (e.g., ["F_CPU=16000000L", "ARDUINO=10819"])
149
+ """
150
+ lib_defines_dict = board_config.get_defines()
151
+ lib_defines = []
152
+
153
+ for key, value in lib_defines_dict.items():
154
+ if value:
155
+ lib_defines.append(f"{key}={value}")
156
+ else:
157
+ lib_defines.append(key)
158
+
159
+ return lib_defines
160
+
161
+
162
+ class LibraryProcessingResult:
163
+ """
164
+ Result of library dependency processing.
165
+
166
+ Contains all information needed by the build system about processed libraries.
167
+ """
168
+
169
+ def __init__(
170
+ self,
171
+ libraries: List[Path],
172
+ include_paths: List[Path],
173
+ object_files: List[Path]
174
+ ):
175
+ """
176
+ Initialize library processing result.
177
+
178
+ Args:
179
+ libraries: List of library root directories
180
+ include_paths: List of include directories to add to compiler
181
+ object_files: List of compiled object files to link
182
+ """
183
+ self.libraries = libraries
184
+ self.include_paths = include_paths
185
+ self.object_files = object_files