Skip to content

Commit 72be81c

Browse files
committed
add graphic tool
1 parent 0f02ba0 commit 72be81c

File tree

9 files changed

+1020
-0
lines changed

9 files changed

+1020
-0
lines changed

README.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,36 @@ git clone https://github.com/Jason2866/esp32-arduino-lib-builder
1111
cd esp32-arduino-lib-builder
1212
./build.sh
1313
```
14+
15+
16+
### Using the User Interface
17+
18+
You can more easily build the libraries using the user interface found in the `tools/config_editor/` folder.
19+
It is a Python script that allows you to select and edit the options for the libraries you want to build.
20+
The script has mouse support and can also be pre-configured using the same command line arguments as the `build.sh` script.
21+
For more information and troubleshooting, please refer to the [UI README](tools/config_editor/README.md).
22+
23+
To use it, follow these steps:
24+
25+
1. Make sure you have the required dependencies installed:
26+
- Python 3.9 or later
27+
- The [Textual](https://github.com/textualize/textual/) library
28+
- All the dependencies listed in the previous section
29+
30+
2. Execute the script `tools/config_editor/app.py` from any folder. It will automatically detect the path to the root of the repository.
31+
32+
3. Configure the compilation and ESP-IDF options as desired.
33+
34+
4. Click on the "Compile Static Libraries" button to start the compilation process.
35+
36+
5. The script will show the compilation output in a new screen. Note that the compilation process can take many hours, depending on the number of libraries selected and the options chosen.
37+
38+
6. If the compilation is successful and the option to copy the libraries to the Arduino Core folder is enabled, it will already be available for use in the Arduino IDE. Otherwise, you can find the compiled libraries in the `esp32-arduino-libs` folder alongside this repository.
39+
- Note that the copy operation doesn't currently support the core downloaded from the Arduino IDE Boards Manager, only the manual installation from the [`arduino-esp32`](https://github.com/espressif/arduino-esp32) repository.
40+
41+
### Documentation
42+
43+
For more information about how to use the Library builder, please refer to this [Documentation page](https://docs.espressif.com/projects/arduino-esp32/en/latest/lib_builder.html?highlight=lib%20builder)
44+
1445
### Development builds
1546
Look in release and download a version. There is the Info of the used commits of IDF / Arduino.

tools/config_editor/.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
.venv/
2+
__pycache__/

tools/config_editor/README.md

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# Arduino Static Libraries Configuration Editor
2+
3+
This is a simple application to configure the static libraries for the ESP32 Arduino core.
4+
It allows the user to select the targets to compile, change the configuration options and compile the libraries.
5+
It has mouse support and can be pre-configured using command line arguments.
6+
7+
## Requirements
8+
- Python 3.9 or later
9+
- The "textual" library (install it using `pip install textual`)
10+
- The requirements from esp32-arduino-lib-builder
11+
12+
## Troubleshooting
13+
14+
In some cases, the UI might not look as expected. This can happen due to the terminal emulator not supporting the required features.
15+
16+
### WSL
17+
18+
If you are using WSL, it is recommended to use the Windows Terminal to visualize the application. Otherwise, the application layout and colors might not be displayed correctly.
19+
The Windows Terminal can be installed from the Microsoft Store.
20+
21+
### MacOS
22+
23+
If you are using MacOS and the application looks weird, check [this guide from Textual](https://textual.textualize.io/FAQ/#why-doesnt-textual-look-good-on-macos) to fix it.
24+
25+
## Usage
26+
27+
These command line arguments can be used to pre-configure the application:
28+
29+
```
30+
Command line arguments:
31+
-t, --target <target> Comma-separated list of targets to be compiled.
32+
Choose from: all, esp32, esp32s2, esp32s3, esp32c2, esp32c3, esp32c6, esp32h2. Default: all except esp32c2
33+
--copy, --no-copy Enable/disable copying the compiled libraries to arduino-esp32. Enabled by default
34+
-c, --arduino-path <path> Path to arduino-esp32 directory. Default: OS dependent
35+
-A, --arduino-branch <branch> Branch of the arduino-esp32 repository to be used. Default: set by the build script
36+
-I, --idf-branch <branch> Branch of the ESP-IDF repository to be used. Default: set by the build script
37+
-i, --idf-commit <commit> Commit of the ESP-IDF repository to be used. Default: set by the build script
38+
```

tools/config_editor/app.py

Lines changed: 270 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,270 @@
1+
#!/usr/bin/env python
2+
3+
"""
4+
Arduino Static Libraries Configuration Editor
5+
6+
This is a simple application to configure the static libraries for the ESP32 Arduino core.
7+
It allows the user to select the targets to compile, change the configuration options and compile the libraries.
8+
9+
Requires Python 3.9 or later.
10+
11+
The application is built using the "textual" library, which is a Python library for building text-based user interfaces.
12+
13+
Note that this application still needs the requirements from esp32-arduino-lib-builder to be installed.
14+
15+
Command line arguments:
16+
-t, --target <target> Comma-separated list of targets to be compiled.
17+
Choose from: all, esp32, esp32s2, esp32s3, esp32c2, esp32c3, esp32c6, esp32h2. Default: all except esp32c2
18+
--copy, --no-copy Enable/disable copying the compiled libraries to arduino-esp32. Enabled by default
19+
-c, --arduino-path <path> Path to arduino-esp32 directory. Default: OS dependent
20+
-A, --arduino-branch <branch> Branch of the arduino-esp32 repository to be used. Default: set by the build script
21+
-I, --idf-branch <branch> Branch of the ESP-IDF repository to be used. Default: set by the build script
22+
-i, --idf-commit <commit> Commit of the ESP-IDF repository to be used. Default: set by the build script
23+
24+
"""
25+
26+
import argparse
27+
import json
28+
import os
29+
import platform
30+
import sys
31+
32+
from pathlib import Path
33+
34+
try:
35+
from textual.app import App, ComposeResult
36+
from textual.binding import Binding
37+
from textual.containers import VerticalScroll
38+
from textual.screen import Screen
39+
from textual.widgets import Button, Header, Label, Footer
40+
except ImportError:
41+
print("Please install the \"textual\" package before running this script.")
42+
exit(1)
43+
44+
from settings import SettingsScreen
45+
from editor import EditorScreen
46+
from compile import CompileScreen
47+
48+
class MainScreen(Screen):
49+
# Main screen class
50+
51+
# Set the key bindings
52+
BINDINGS = [
53+
Binding("c", "app.push_screen('compile')", "Compile"),
54+
Binding("e", "app.push_screen('editor')", "Editor"),
55+
Binding("s", "app.push_screen('settings')", "Settings"),
56+
Binding("q", "app.quit", "Quit"),
57+
]
58+
59+
def on_button_pressed(self, event: Button.Pressed) -> None:
60+
# Event handler called when a button is pressed
61+
if event.button.id == "compile-button":
62+
print("Compile button pressed")
63+
self.app.push_screen("compile")
64+
elif event.button.id == "settings-button":
65+
print("Settings button pressed")
66+
self.app.push_screen("settings")
67+
elif event.button.id == "editor-button":
68+
print("Editor button pressed")
69+
self.app.push_screen("editor")
70+
elif event.button.id == "quit-button":
71+
print("Quit button pressed")
72+
self.app.exit()
73+
74+
def compose(self) -> ComposeResult:
75+
# Compose main menu
76+
yield Header()
77+
with VerticalScroll(id="main-menu-container"):
78+
yield Label("ESP32 Arduino Static Libraries Configuration Editor", id="main-menu-title")
79+
yield Button("Compile Static Libraries", id="compile-button", classes="main-menu-button")
80+
yield Button("Sdkconfig Editor", id="editor-button", classes="main-menu-button")
81+
yield Button("Settings", id="settings-button", classes="main-menu-button")
82+
yield Button("Quit", id="quit-button", classes="main-menu-button")
83+
yield Footer()
84+
85+
def on_mount(self) -> None:
86+
# Event handler called when the app is mounted for the first time
87+
self.title = "Configurator"
88+
self.sub_title = "Main Menu"
89+
print("Main screen mounted.")
90+
91+
class ConfigEditorApp(App):
92+
# Main application class
93+
94+
# Set the root and script paths
95+
SCRIPT_PATH = os.path.abspath(os.path.dirname(__file__))
96+
ROOT_PATH = os.path.abspath(os.path.join(SCRIPT_PATH, "..", ".."))
97+
98+
# Set the application options
99+
supported_targets = []
100+
setting_enable_copy = True
101+
102+
# Options to be set by the command line arguments
103+
setting_target = ""
104+
setting_arduino_path = ""
105+
setting_arduino_branch = ""
106+
setting_idf_branch = ""
107+
setting_idf_commit = ""
108+
109+
ENABLE_COMMAND_PALETTE = False
110+
CSS_PATH = "style.tcss"
111+
SCREENS = {
112+
"main": MainScreen(),
113+
"settings": SettingsScreen(),
114+
"compile": CompileScreen(),
115+
"editor": EditorScreen(),
116+
}
117+
118+
def on_mount(self) -> None:
119+
print("Application mounted. Initial options:")
120+
print("Python version: " + sys.version)
121+
print("Root path: " + self.ROOT_PATH)
122+
print("Script path: " + self.SCRIPT_PATH)
123+
print("Supported Targets: " + ", ".join(self.supported_targets))
124+
print("Default targets: " + self.setting_target)
125+
print("Enable Copy: " + str(self.setting_enable_copy))
126+
print("Arduino Path: " + str(self.setting_arduino_path))
127+
print("Arduino Branch: " + str(self.setting_arduino_branch))
128+
print("IDF Branch: " + str(self.setting_idf_branch))
129+
print("IDF Commit: " + str(self.setting_idf_commit))
130+
self.push_screen("main")
131+
132+
def arduino_default_path():
133+
sys_name = platform.system()
134+
home = str(Path.home())
135+
if sys_name == "Linux":
136+
return os.path.join(home, "Arduino", "hardware", "espressif", "esp32")
137+
else: # Windows and MacOS
138+
return os.path.join(home, "Documents", "Arduino", "hardware", "espressif", "esp32")
139+
140+
def check_arduino_path(path):
141+
return os.path.isdir(path)
142+
143+
def main() -> None:
144+
# Set the PYTHONUNBUFFERED environment variable to "1" to disable the output buffering
145+
os.environ['PYTHONUNBUFFERED'] = "1"
146+
147+
# Check Python version
148+
if sys.version_info < (3, 9):
149+
print("This script requires Python 3.9 or later")
150+
exit(1)
151+
152+
app = ConfigEditorApp()
153+
154+
# List of tuples for the target choices containing the target name and if it is enabled by default
155+
target_choices = []
156+
157+
# Parse build JSON file
158+
build_json_path = os.path.join(app.ROOT_PATH, "configs", "builds.json")
159+
if os.path.isfile(build_json_path):
160+
with open(build_json_path, "r") as build_json_file:
161+
build_json = json.load(build_json_file)
162+
for target in build_json["targets"]:
163+
try:
164+
default = False if target["skip"] else True
165+
except:
166+
default = True
167+
target_choices.append((target["target"], default))
168+
else:
169+
print("Error: configs/builds.json file not found.")
170+
exit(1)
171+
172+
target_choices.sort(key=lambda x: x[0])
173+
174+
parser = argparse.ArgumentParser(description="Configure and compile the ESP32 Arduino static libraries")
175+
176+
parser.add_argument("-t", "--target",
177+
metavar="<target>",
178+
type=str,
179+
default="default",
180+
required=False,
181+
help="Comma-separated list of targets to be compiled. Choose from: " + ", ".join([x[0] for x in target_choices])
182+
+ ". Default: All except " + ", ".join([x[0] for x in target_choices if not x[1]]))
183+
184+
parser.add_argument("--copy",
185+
type=bool,
186+
action=argparse.BooleanOptionalAction,
187+
default=True,
188+
required=False,
189+
help="Enable/disable copying the compiled libraries to arduino-esp32. Enabled by default")
190+
191+
parser.add_argument("-c", "--arduino-path",
192+
metavar="<arduino path>",
193+
type=str,
194+
default=arduino_default_path(),
195+
required=False,
196+
help="Path to arduino-esp32 directory. Default: " + arduino_default_path())
197+
198+
parser.add_argument("-A", "--arduino-branch",
199+
metavar="<arduino branch>",
200+
type=str,
201+
default="",
202+
required=False,
203+
help="Branch of the arduino-esp32 repository to be used")
204+
205+
parser.add_argument("-I", "--idf-branch",
206+
metavar="<IDF branch>",
207+
type=str,
208+
default="",
209+
required=False,
210+
help="Branch of the ESP-IDF repository to be used")
211+
212+
parser.add_argument("-i", "--idf-commit",
213+
metavar="<IDF commit>",
214+
type=str,
215+
default="",
216+
required=False,
217+
help="Commit of the ESP-IDF repository to be used")
218+
219+
220+
args = parser.parse_args()
221+
222+
# Force targets to be lower case
223+
args.target = args.target.lower()
224+
225+
# Check if the target is valid
226+
if args.target == "default":
227+
args.target = ",".join([x[0] for x in target_choices if x[1]])
228+
elif args.target == "all":
229+
args.target = ",".join([x[0] for x in target_choices])
230+
231+
app.supported_targets = [x[0] for x in target_choices]
232+
233+
for target in args.target.split(","):
234+
if target not in app.supported_targets:
235+
print("Invalid target: " + target)
236+
exit(1)
237+
238+
app.setting_target = args.target
239+
240+
# Check if the Arduino path is valid
241+
if args.copy:
242+
if check_arduino_path(args.arduino_path):
243+
app.setting_enable_copy = True
244+
elif args.arduino_path == arduino_default_path():
245+
print("Warning: Default Arduino path not found. Disabling copy to Arduino.")
246+
app.setting_enable_copy = False
247+
else:
248+
print("Invalid path to Arduino core: " + os.path.abspath(args.arduino_path))
249+
exit(1)
250+
else:
251+
app.setting_enable_copy = False
252+
253+
# Set the other options
254+
app.setting_arduino_path = os.path.abspath(args.arduino_path)
255+
app.setting_arduino_branch = args.arduino_branch
256+
app.setting_idf_branch = args.idf_branch
257+
app.setting_idf_commit = args.idf_commit
258+
259+
# Change to the root directory of the app to the root of the project
260+
os.chdir(app.ROOT_PATH)
261+
262+
# Main function to run the app
263+
app.run()
264+
265+
# Propagate the exit code from the app
266+
exit(app.return_code or 0)
267+
268+
if __name__ == "__main__":
269+
# If this script is run directly, start the app
270+
main()

0 commit comments

Comments
 (0)