Skip to content

Add configuration UI #158

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 59 commits into from
Apr 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
b739904
Initial project template
lucasssvaz Feb 21, 2024
352e85a
Fix EOF
lucasssvaz Feb 21, 2024
e2c0516
Simplify
lucasssvaz Feb 21, 2024
ed73ad9
Test
lucasssvaz Feb 28, 2024
bc48e6b
Fix
lucasssvaz Feb 29, 2024
ca29343
Improve Screens
lucasssvaz Feb 29, 2024
4cf89ba
Add placeholder Readme
lucasssvaz Feb 29, 2024
dc1539a
Remove unused imports
lucasssvaz Feb 29, 2024
c142e5b
Fix CWD
lucasssvaz Mar 1, 2024
6921aee
Fix target selection
lucasssvaz Mar 1, 2024
21092e4
Misc improvements
lucasssvaz Mar 1, 2024
1e986a7
WIP compile screen
lucasssvaz Mar 1, 2024
b21e885
Update
lucasssvaz Mar 1, 2024
f4701bb
Fix command
lucasssvaz Mar 1, 2024
430bb18
Finish compile screen
lucasssvaz Mar 1, 2024
2416cdf
Added comments and improvements
lucasssvaz Mar 1, 2024
6e9dd8f
Run on task
lucasssvaz Mar 2, 2024
88da64d
Make style a bit more Arduino-esque
me-no-dev Mar 2, 2024
bfd8159
Merge branch 'master' into feature/config_ui
lucasssvaz Mar 4, 2024
c53b7eb
Add CLI arguments
lucasssvaz Mar 6, 2024
18ce802
Merge branch 'master' into feature/config_ui
lucasssvaz Mar 6, 2024
683e548
Small improvements
lucasssvaz Mar 6, 2024
e9fbf63
Rename
lucasssvaz Mar 6, 2024
0d6d21a
Add custom widgets
lucasssvaz Mar 8, 2024
bb13cc0
Fix widgets
lucasssvaz Mar 8, 2024
b118528
Add remaining settings
lucasssvaz Mar 8, 2024
9f4becd
Improve style
lucasssvaz Mar 8, 2024
6a5319a
Improve compilation screen
lucasssvaz Mar 8, 2024
54f1082
Handle exception
lucasssvaz Mar 8, 2024
2d8e462
Add no copy argument
lucasssvaz Mar 9, 2024
f649a80
Replace "arch" with "uname -m"
lucasssvaz Mar 9, 2024
31dbd36
Merge branch 'bugfix/arch_cmd' into feature/config_ui
lucasssvaz Mar 9, 2024
4581265
Fix copy argument
lucasssvaz Mar 9, 2024
e735844
Fix arg message
lucasssvaz Mar 9, 2024
e2de23a
Fix chdir
lucasssvaz Mar 9, 2024
b1e3681
Improve header
lucasssvaz Mar 9, 2024
fd5c2fc
Properly kill subprocess
lucasssvaz Mar 9, 2024
cdd170d
Fix compilation issues
lucasssvaz Mar 9, 2024
8662df0
Hide setting depending on switch state
lucasssvaz Mar 12, 2024
9d32f26
QoL improvements
lucasssvaz Mar 12, 2024
8caa77e
Improve style
lucasssvaz Mar 12, 2024
8364e75
Add python version check
lucasssvaz Mar 12, 2024
d2a0f10
Separate main menu screen
lucasssvaz Mar 18, 2024
e90707e
Fix quit and improve logs
lucasssvaz Mar 18, 2024
7eef90c
Propagate exit code
lucasssvaz Mar 18, 2024
febe5fa
Rename quit to exit for consistency
lucasssvaz Mar 18, 2024
9fbb3f8
Add readme
lucasssvaz Mar 18, 2024
8358f57
Improve Readme
lucasssvaz Mar 18, 2024
7ae42f4
Add keybindings
lucasssvaz Mar 18, 2024
d58881f
Improve readme
lucasssvaz Mar 18, 2024
c184c89
Revert "Merge branch 'bugfix/arch_cmd' into feature/config_ui"
lucasssvaz Mar 19, 2024
11c3298
Merge branch 'master' into feature/config_ui
lucasssvaz Apr 3, 2024
303bad3
Merge branch 'master' into feature/config_ui
me-no-dev Apr 5, 2024
6bdcb04
Target list based on JSON and support for any combination of targets
lucasssvaz Apr 5, 2024
f0702ef
Improve documentation
lucasssvaz Apr 5, 2024
6e5ea45
Add note to the documentation
lucasssvaz Apr 5, 2024
b252b7c
Fix copy after compilation
lucasssvaz Apr 5, 2024
967d887
Fix bugs
lucasssvaz Apr 5, 2024
d82696b
Improve documentation
lucasssvaz Apr 5, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,32 @@ git clone https://github.com/espressif/esp32-arduino-lib-builder
cd esp32-arduino-lib-builder
./build.sh
```

### Using the User Interface

You can more easily build the libraries using the user interface found in the `tools/config_editor/` folder.
It is a Python script that allows you to select and edit the options for the libraries you want to build.
The script has mouse support and can also be pre-configured using the same command line arguments as the `build.sh` script.
For more information and troubleshooting, please refer to the [UI README](tools/config_editor/README.md).

To use it, follow these steps:

1. Make sure you have the required dependencies installed:
- Python 3.9 or later
- The [Textual](https://github.com/textualize/textual/) library
- All the dependencies listed in the previous section

2. Execute the script `tools/config_editor/app.py` from any folder. It will automatically detect the path to the root of the repository.

3. Configure the compilation and ESP-IDF options as desired.

4. Click on the "Compile Static Libraries" button to start the compilation process.

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.

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.
- 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.

### Documentation

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)
2 changes: 2 additions & 0 deletions tools/config_editor/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.venv/
__pycache__/
38 changes: 38 additions & 0 deletions tools/config_editor/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Arduino Static Libraries Configuration Editor

This is a simple application to configure the static libraries for the ESP32 Arduino core.
It allows the user to select the targets to compile, change the configuration options and compile the libraries.
It has mouse support and can be pre-configured using command line arguments.

## Requirements
- Python 3.9 or later
- The "textual" library (install it using `pip install textual`)
- The requirements from esp32-arduino-lib-builder

## Troubleshooting

In some cases, the UI might not look as expected. This can happen due to the terminal emulator not supporting the required features.

### WSL

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.
The Windows Terminal can be installed from the Microsoft Store.

### MacOS

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.

## Usage

These command line arguments can be used to pre-configure the application:

Command line arguments:
-t, --target <target> Comma-separated list of targets to be compiled.
Choose from: all, esp32, esp32s2, esp32s3, esp32c2, esp32c3, esp32c6, esp32h2. Default: all except esp32c2
--copy, --no-copy Enable/disable copying the compiled libraries to arduino-esp32. Enabled by default
-c, --arduino-path <path> Path to arduino-esp32 directory. Default: OS dependent
-A, --arduino-branch <branch> Branch of the arduino-esp32 repository to be used. Default: set by the build script
-I, --idf-branch <branch> Branch of the ESP-IDF repository to be used. Default: set by the build script
-i, --idf-commit <commit> Commit of the ESP-IDF repository to be used. Default: set by the build script
-D, --debug-level <level> Debug level to be set to ESP-IDF.
Choose from: default, none, error, warning, info, debug, verbose. Default: default
278 changes: 278 additions & 0 deletions tools/config_editor/app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,278 @@
#!/usr/bin/env python

"""
Arduino Static Libraries Configuration Editor

This is a simple application to configure the static libraries for the ESP32 Arduino core.
It allows the user to select the targets to compile, change the configuration options and compile the libraries.

Requires Python 3.9 or later.

The application is built using the "textual" library, which is a Python library for building text-based user interfaces.

Note that this application still needs the requirements from esp32-arduino-lib-builder to be installed.

Command line arguments:
-t, --target <target> Comma-separated list of targets to be compiled.
Choose from: all, esp32, esp32s2, esp32s3, esp32c2, esp32c3, esp32c6, esp32h2. Default: all except esp32c2
--copy, --no-copy Enable/disable copying the compiled libraries to arduino-esp32. Enabled by default
-c, --arduino-path <path> Path to arduino-esp32 directory. Default: OS dependent
-A, --arduino-branch <branch> Branch of the arduino-esp32 repository to be used. Default: set by the build script
-I, --idf-branch <branch> Branch of the ESP-IDF repository to be used. Default: set by the build script
-i, --idf-commit <commit> Commit of the ESP-IDF repository to be used. Default: set by the build script
-D, --debug-level <level> Debug level to be set to ESP-IDF.
Choose from: default, none, error, warning, info, debug, verbose. Default: default

"""

import argparse
import json
import os
import platform
import sys

from pathlib import Path

try:
from textual.app import App, ComposeResult
from textual.binding import Binding
from textual.containers import VerticalScroll
from textual.screen import Screen
from textual.widgets import Button, Header, Label, Footer
except ImportError:
print("Please install the \"textual\" package before running this script.")
exit(1)

from settings import SettingsScreen
from editor import EditorScreen
from compile import CompileScreen

class MainScreen(Screen):
# Main screen class

# Set the key bindings
BINDINGS = [
Binding("c", "app.push_screen('compile')", "Compile"),
Binding("e", "app.push_screen('editor')", "Editor"),
Binding("s", "app.push_screen('settings')", "Settings"),
Binding("q", "app.quit", "Quit"),
]

def on_button_pressed(self, event: Button.Pressed) -> None:
# Event handler called when a button is pressed
if event.button.id == "compile-button":
print("Compile button pressed")
self.app.push_screen("compile")
elif event.button.id == "settings-button":
print("Settings button pressed")
self.app.push_screen("settings")
elif event.button.id == "editor-button":
print("Editor button pressed")
self.app.push_screen("editor")
elif event.button.id == "quit-button":
print("Quit button pressed")
self.app.exit()

def compose(self) -> ComposeResult:
# Compose main menu
yield Header()
with VerticalScroll(id="main-menu-container"):
yield Label("ESP32 Arduino Static Libraries Configuration Editor", id="main-menu-title")
yield Button("Compile Static Libraries", id="compile-button", classes="main-menu-button")
yield Button("Sdkconfig Editor", id="editor-button", classes="main-menu-button")
yield Button("Settings", id="settings-button", classes="main-menu-button")
yield Button("Quit", id="quit-button", classes="main-menu-button")
yield Footer()

def on_mount(self) -> None:
# Event handler called when the app is mounted for the first time
self.title = "Configurator"
self.sub_title = "Main Menu"
print("Main screen mounted.")

class ConfigEditorApp(App):
# Main application class

# Set the root and script paths
SCRIPT_PATH = os.path.abspath(os.path.dirname(__file__))
ROOT_PATH = os.path.abspath(os.path.join(SCRIPT_PATH, "..", ".."))

# Set the application options
supported_targets = []
setting_enable_copy = True

# Options to be set by the command line arguments
setting_target = ""
setting_arduino_path = ""
setting_arduino_branch = ""
setting_idf_branch = ""
setting_idf_commit = ""
setting_debug_level = ""

ENABLE_COMMAND_PALETTE = False
CSS_PATH = "style.tcss"
SCREENS = {
"main": MainScreen(),
"settings": SettingsScreen(),
"compile": CompileScreen(),
"editor": EditorScreen(),
}

def on_mount(self) -> None:
print("Application mounted. Initial options:")
print("Python version: " + sys.version)
print("Root path: " + self.ROOT_PATH)
print("Script path: " + self.SCRIPT_PATH)
print("Supported Targets: " + ", ".join(self.supported_targets))
print("Default targets: " + self.setting_target)
print("Enable Copy: " + str(self.setting_enable_copy))
print("Arduino Path: " + str(self.setting_arduino_path))
print("Arduino Branch: " + str(self.setting_arduino_branch))
print("IDF Branch: " + str(self.setting_idf_branch))
print("IDF Commit: " + str(self.setting_idf_commit))
print("IDF Debug Level: " + str(self.setting_debug_level))
self.push_screen("main")

def arduino_default_path():
sys_name = platform.system()
home = str(Path.home())
if sys_name == "Linux":
return os.path.join(home, "Arduino", "hardware", "espressif", "esp32")
else: # Windows and MacOS
return os.path.join(home, "Documents", "Arduino", "hardware", "espressif", "esp32")

def check_arduino_path(path):
return os.path.isdir(path)

def main() -> None:
# Set the PYTHONUNBUFFERED environment variable to "1" to disable the output buffering
os.environ['PYTHONUNBUFFERED'] = "1"

# Check Python version
if sys.version_info < (3, 9):
print("This script requires Python 3.9 or later")
exit(1)

app = ConfigEditorApp()

# List of tuples for the target choices containing the target name and if it is enabled by default
target_choices = []

# Parse build JSON file
build_json_path = os.path.join(app.ROOT_PATH, "configs", "builds.json")
if os.path.isfile(build_json_path):
with open(build_json_path, "r") as build_json_file:
build_json = json.load(build_json_file)
for target in build_json["targets"]:
try:
default = False if target["skip"] else True
except:
default = True
target_choices.append((target["target"], default))
else:
print("Error: configs/builds.json file not found.")
exit(1)

target_choices.sort(key=lambda x: x[0])

parser = argparse.ArgumentParser(description="Configure and compile the ESP32 Arduino static libraries")

parser.add_argument("-t", "--target",
metavar="<target>",
type=str,
default="default",
required=False,
help="Comma-separated list of targets to be compiled. Choose from: " + ", ".join([x[0] for x in target_choices])
+ ". Default: All except " + ", ".join([x[0] for x in target_choices if not x[1]]))

parser.add_argument("--copy",
type=bool,
action=argparse.BooleanOptionalAction,
default=True,
required=False,
help="Enable/disable copying the compiled libraries to arduino-esp32. Enabled by default")

parser.add_argument("-c", "--arduino-path",
metavar="<arduino path>",
type=str,
default=arduino_default_path(),
required=False,
help="Path to arduino-esp32 directory. Default: " + arduino_default_path())

parser.add_argument("-A", "--arduino-branch",
metavar="<arduino branch>",
type=str,
default="",
required=False,
help="Branch of the arduino-esp32 repository to be used")

parser.add_argument("-I", "--idf-branch",
metavar="<IDF branch>",
type=str,
default="",
required=False,
help="Branch of the ESP-IDF repository to be used")

parser.add_argument("-i", "--idf-commit",
metavar="<IDF commit>",
type=str,
default="",
required=False,
help="Commit of the ESP-IDF repository to be used")

debug_level_choices = ("default", "none", "error", "warning", "info", "debug", "verbose")
parser.add_argument("-D", "--debug-level",
metavar="<level>",
type=str,
default="default",
choices=debug_level_choices,
required=False,
help="Debug level to be set to ESP-IDF. Choose from: " + ", ".join(debug_level_choices))

args = parser.parse_args()

# Set the options in the app
if args.target.strip() == "default":
args.target = ",".join([x[0] for x in target_choices if x[1]])
elif args.target.strip() == "all":
args.target = ",".join([x[0] for x in target_choices])

app.supported_targets = [x[0] for x in target_choices]

for target in args.target.split(","):
if target not in app.supported_targets:
print("Invalid target: " + target)
exit(1)

app.setting_target = args.target

if args.copy:
if check_arduino_path(args.arduino_path):
app.setting_enable_copy = True
elif args.arduino_path == arduino_default_path():
print("Warning: Default Arduino path not found. Disabling copy to Arduino.")
app.setting_enable_copy = False
else:
print("Invalid path to Arduino core: " + os.path.abspath(args.arduino_path))
exit(1)
else:
app.setting_enable_copy = False

app.setting_arduino_path = os.path.abspath(args.arduino_path)
app.setting_arduino_branch = args.arduino_branch
app.setting_idf_branch = args.idf_branch
app.setting_idf_commit = args.idf_commit
app.setting_debug_level = args.debug_level

# Change to the root directory of the app to the root of the project
os.chdir(app.ROOT_PATH)

# Main function to run the app
app.run()

# Propagate the exit code from the app
exit(app.return_code or 0)

if __name__ == "__main__":
# If this script is run directly, start the app
main()
Loading