Fix Studuino setup reproducibility

This commit is contained in:
2026-09-25 21:02:44 +10:00
parent feddce04c3
commit 75d2099655
7 changed files with 178 additions and 838 deletions
+7
View File
@@ -0,0 +1,7 @@
# Generated editor and Arduino CLI files
/compile_commands.json
/.arduino/
*.bin
*.eep
*.elf
*.hex
+9 -3
View File
@@ -1,9 +1,15 @@
#include <Arduino.h> #include <Studuino.h>
#include <Clock.h> // Keep the complete smoke-test dependency set in clangd's database.
Studuino board;
void setup() { void setup() {
// Add Studuino initialization here. board.InitSensorPort(PORT_A0, PIDLED);
} }
void loop() { void loop() {
// Add Studuino code here. board.LED(PORT_A0, ON);
board.Timer(1);
board.LED(PORT_A0, OFF);
board.Timer(1);
} }
+34 -32
View File
@@ -1,16 +1,18 @@
# Studuino on Linux with Neovim # Studuino on Linux with Neovim
A development template for using the Artec Studuino (ATmega168/328, 3.3 V, 8 MHz) on Arch Linux with `arduino-cli`, `clangd`, and Neovim. A development template for using the Artec Studuino (ATmega168/328, 3.3 V, 8 MHz) on Arch Linux with `arduino-cli` and optional `clangd`/Neovim tooling.
This repository contains the Studuino hardware definition, the legacy Studuino libraries, an Arduino CLI setup script, and optional Neovim integration resources. This repository contains the Studuino hardware definition, the legacy Studuino libraries, an Arduino CLI setup script, and optional Neovim integration resources.
## Features ## Features
- Manual installation of the legacy Studuino hardware platform. - Manual installation of the checked-in legacy Studuino hardware platform.
- Arduino CLI project defaults for `studuino:avr:studuino`. - Arduino CLI project defaults for `studuino:avr:studuino`.
- Installation of the required `Servo` library. - Installation of the checked-in Studuino libraries, including `Servo`.
- Optional cleanup of unrelated user libraries. - Optional cleanup of unrelated user libraries.
- A generated `compile_commands.json` for `clangd` and Neovim. - A generated, git-ignored `compile_commands.json` for `clangd` and Neovim.
- A real Studuino Blink smoke-test build during setup.
- Optional Neovim/Arduino language-server tooling.
- Optional `picocom` serial-monitor support. - Optional `picocom` serial-monitor support.
- A LazyVim/Arduino-Nvim configuration template. - A LazyVim/Arduino-Nvim configuration template.
@@ -21,16 +23,13 @@ This repository contains the Studuino hardware definition, the legacy Studuino l
- A user account with permission to use serial devices. - A user account with permission to use serial devices.
- Internet access for the initial Arduino CLI core/library installation. - Internet access for the initial Arduino CLI core/library installation.
The setup script installs these Arch packages by default: The setup script installs `arduino-cli` by default. On Arch Linux, it can also install editor tooling with `--with-editor`:
- `arduino-cli` - `clang` (provides `clangd`)
- `clangd`
- `make`
- `neovim` - `neovim`
- `python` - `arduino-language-server`
- `unzip`
It can optionally install `picocom` with `--with-monitor`. It can optionally install `picocom` with `--with-monitor`. On other distributions, use `--skip-packages` and install the required commands through the distribution's package manager.
## Quick start ## Quick start
@@ -38,21 +37,21 @@ From the repository root:
```bash ```bash
cd /path/to/this/repository cd /path/to/this/repository
./setup.sh ./setup.sh --with-editor
``` ```
The script performs the following tasks: The script performs the following tasks:
1. Installs required Arch packages. 1. Installs the required packages for the selected options.
2. Adds the current user to `uucp` and `dialout`. 2. Adds the current user to `uucp` and `dialout`.
3. Initializes the Arduino CLI configuration if necessary. 3. Initializes the Arduino CLI configuration if necessary.
4. Installs the AVR core when it is missing. 4. Installs or upgrades the Arduino AVR core to a supported version.
5. Installs the Studuino hardware definition. 5. Installs the checked-in Studuino hardware definition.
6. Installs the libraries from `Resources/studuino_v1_lib.zip`. 6. Installs the checked-in Studuino libraries, including `Servo`.
7. Installs `Servo`, which is required by `Studuino.h`. 7. Ensures the sketch and default FQBN are configured.
8. Ensures the sketch and default FQBN are configured. 8. Generates `compile_commands.json` for `clangd`.
9. Generates `compile_commands.json` for `clangd`. 9. Compiles the bundled Studuino Blink smoke test.
10. Verifies board discovery and compilation. 10. Compiles the project and verifies board/library discovery.
Log out and back in after the first run if the script adds you to a new serial-port group. Group changes do not affect the current login session immediately. Log out and back in after the first run if the script adds you to a new serial-port group. Group changes do not affect the current login session immediately.
@@ -70,22 +69,25 @@ Useful options:
# Do not install Arch packages or modify group membership # Do not install Arch packages or modify group membership
./setup.sh --skip-packages --skip-permissions ./setup.sh --skip-packages --skip-permissions
# Install Neovim, clangd, and Arduino language-server tooling
./setup.sh --with-editor
# Install picocom for a serial monitor # Install picocom for a serial monitor
./setup.sh --with-monitor ./setup.sh --with-monitor
# Remove user libraries not supplied by the Studuino bundle # Remove user libraries not present in this repository
./setup.sh --clean ./setup.sh --clean
# Replace existing Studuino library and hardware files # Replace existing hardware/libraries with the checked-in versions
./setup.sh --force ./setup.sh --force
# Skip regeneration of compile_commands.json # Skip regeneration of compile_commands.json
./setup.sh --skip-compile-db ./setup.sh --skip-compile-db
``` ```
`--clean` is destructive. It preserves the libraries supplied in the Studuino ZIP and `Servo`, but removes other directories under the configured Arduino `libraries` directory. Back up any libraries you want to keep. `--clean` is destructive. It preserves the libraries checked into this repository, including `Servo`, but removes other directories under the configured Arduino `libraries` directory. Back up any libraries you want to keep.
`--force` overwrites existing Studuino library and hardware files. Use it only when intentionally refreshing the Studuino installation. `--force` overwrites existing Studuino hardware and library files with the checked-in versions. Use it after updating this repository or when intentionally refreshing the Studuino installation.
## Project layout ## Project layout
@@ -95,7 +97,7 @@ Useful options:
├── sketch.yaml # arduino-cli project defaults ├── sketch.yaml # arduino-cli project defaults
├── .arduino_config.lua # Arduino-Nvim board/port configuration ├── .arduino_config.lua # Arduino-Nvim board/port configuration
├── setup.sh # Idempotent setup script ├── setup.sh # Idempotent setup script
├── compile_commands.json # clangd compilation database ├── compile_commands.json # Generated locally; not tracked
├── hardware/ ├── hardware/
│ └── studuino/ │ └── studuino/
│ └── avr/ │ └── avr/
@@ -109,7 +111,7 @@ Useful options:
└── nvim/ └── nvim/
``` ```
The Studuino platform is manually installed because it predates the modern Boards Manager package format. The Studuino platform is manually installed because it predates the modern Boards Manager package format. The checked-in `hardware/` and `libraries/` trees are the canonical installation sources; the ZIP files under `Resources/` are retained as upstream source material and provenance.
## Board and port configuration ## Board and port configuration
@@ -181,7 +183,7 @@ arduino-cli upload \
--port /dev/ttyUSB0 --port /dev/ttyUSB0
``` ```
The setup script verifies the project with a clean build. The Studuino target is an ATmega168 target, so the available program storage is smaller than a default Arduino Uno/ATmega328 build. The setup script verifies the project with a clean build and also compiles `libraries/Studuino/example/Blink` as a smoke test. The Studuino target is an ATmega168 target, so the available program storage is 14,336 bytes and static data is limited to 1,024 bytes.
### Compile the bundled Blink example ### Compile the bundled Blink example
@@ -195,9 +197,9 @@ arduino-cli compile \
## Neovim and clangd ## Neovim and clangd
The setup script installs `clangd` and generates `compile_commands.json` in the project root. `clangd` automatically searches the project directory for this file. With `--with-editor`, the setup script installs the `clang` package (which provides `clangd`), Neovim, and `arduino-language-server`. It generates `compile_commands.json` in the project root; the file is ignored by Git because its paths are specific to the local Arduino CLI installation.
The initial database is generated from the minimal sketch, so it may not contain the Studuino library include paths. If clangd reports `Studuino.h file not found` after adding `#include <Studuino.h>`, refresh the database with the setup script after changing the sketch. The initial database is generated from `Arduino.ino`, which includes `<Studuino.h>` and `<Clock.h>`, so the complete bundled smoke-test dependency set is available to `clangd`. If you add a new library or change the FQBN, refresh the database with the setup script.
If you add a new library or change the FQBN, refresh the database with: If you add a new library or change the FQBN, refresh the database with:
@@ -344,7 +346,7 @@ The supported path is:
### `Servo.h` not found ### `Servo.h` not found
`Studuino.h` includes the Servo library, but Servo is distributed separately from the Studuino ZIP. Install it with: `Studuino.h` includes the Servo library. It is checked into this repository and is installed by the setup script. If it is missing, install it with:
```bash ```bash
arduino-cli lib install Servo arduino-cli lib install Servo
@@ -400,7 +402,7 @@ The key must be `default_fqbn`; a top-level `fqbn` key is not used as the defaul
## Re-running setup ## Re-running setup
The setup script is designed to be rerun. It skips existing packages, libraries, and core installations unless `--force` is supplied. It always verifies the final board, libraries, and project compilation. The setup script is designed to be rerun. It preserves existing user installations unless `--force` is supplied, verifies that the Arduino AVR core is at least version 1.8.8, and always verifies the board, libraries, Studuino smoke test, and project compilation.
To inspect all available options: To inspect all available options:
@@ -410,4 +412,4 @@ To inspect all available options:
## License and source materials ## License and source materials
The Studuino hardware archive and Studuino library archive are kept in `Resources/` because they use a legacy/manual Arduino hardware layout. Keep the archives with the project so the setup can be recreated on another Linux machine. The hardware and library ZIP files are retained in `Resources/` as upstream source archives. The active, maintained definitions are the checked-in `hardware/studuino/avr/` and `libraries/` directories; the setup script installs from those directories.
+9 -3
View File
@@ -35,7 +35,13 @@ return {
## Requirements ## Requirements
- [arduino-cli](https://arduino.github.io/arduino-cli/latest/installation/) The repository setup script can install the command-line prerequisites with:
- [arduino-language-server](https://github.com/arduino/arduino-language-server)
```bash
./setup.sh --with-editor
```
This installs `arduino-cli`, the `clang` package that provides `clangd`, `neovim`, and `arduino-language-server` on Arch Linux. The Neovim plugin dependencies are:
- [Telescope.nvim](https://github.com/nvim-telescope/telescope.nvim) - [Telescope.nvim](https://github.com/nvim-telescope/telescope.nvim)
- [nvim-lspconfig](https://github.com/neovim/nvim-lspconfig) - [nvim-lspconfig](https://github.com/neovim/nvim-lspconfig) for Neovim versions older than 0.11
-684
View File
@@ -1,684 +0,0 @@
[
{
"directory": "/home/alvin/Arduino",
"arguments": [
"/home/alvin/.arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7/bin/avr-g++",
"-c",
"-g",
"-Os",
"-w",
"-std=gnu++11",
"-fno-exceptions",
"-ffunction-sections",
"-fdata-sections",
"-fno-threadsafe-statics",
"-MMD",
"-mmcu=atmega168",
"-DF_CPU=8000000L",
"-DARDUINO=10607",
"-DARDUINO_AVR_PRO",
"-DARDUINO_ARCH_AVR",
"-I/home/alvin/.arduino15/packages/arduino/hardware/avr/1.8.8/cores/arduino",
"-I/home/alvin/.arduino15/packages/arduino/hardware/avr/1.8.8/variants/standard",
"/home/alvin/.cache/arduino/studuino-compile-db/sketch/Arduino.ino.cpp",
"-o",
"/home/alvin/.cache/arduino/studuino-compile-db/sketch/Arduino.ino.cpp.o"
],
"file": "/home/alvin/.cache/arduino/studuino-compile-db/sketch/Arduino.ino.cpp"
},
{
"directory": "/home/alvin/Arduino",
"arguments": [
"/home/alvin/.arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7/bin/avr-g++",
"-c",
"-g",
"-Os",
"-w",
"-std=gnu++11",
"-fno-exceptions",
"-ffunction-sections",
"-fdata-sections",
"-fno-threadsafe-statics",
"-MMD",
"-mmcu=atmega168",
"-DF_CPU=8000000L",
"-DARDUINO=10607",
"-DARDUINO_AVR_PRO",
"-DARDUINO_ARCH_AVR",
"-I/home/alvin/.arduino15/packages/arduino/hardware/avr/1.8.8/cores/arduino",
"-I/home/alvin/.arduino15/packages/arduino/hardware/avr/1.8.8/variants/standard",
"/home/alvin/.arduino15/packages/arduino/hardware/avr/1.8.8/cores/arduino/CDC.cpp",
"-o",
"/home/alvin/.cache/arduino/studuino-compile-db/core/CDC.cpp.o"
],
"file": "/home/alvin/.arduino15/packages/arduino/hardware/avr/1.8.8/cores/arduino/CDC.cpp"
},
{
"directory": "/home/alvin/Arduino",
"arguments": [
"/home/alvin/.arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7/bin/avr-g++",
"-c",
"-g",
"-Os",
"-w",
"-std=gnu++11",
"-fno-exceptions",
"-ffunction-sections",
"-fdata-sections",
"-fno-threadsafe-statics",
"-MMD",
"-mmcu=atmega168",
"-DF_CPU=8000000L",
"-DARDUINO=10607",
"-DARDUINO_AVR_PRO",
"-DARDUINO_ARCH_AVR",
"-I/home/alvin/.arduino15/packages/arduino/hardware/avr/1.8.8/cores/arduino",
"-I/home/alvin/.arduino15/packages/arduino/hardware/avr/1.8.8/variants/standard",
"/home/alvin/.arduino15/packages/arduino/hardware/avr/1.8.8/cores/arduino/HardwareSerial1.cpp",
"-o",
"/home/alvin/.cache/arduino/studuino-compile-db/core/HardwareSerial1.cpp.o"
],
"file": "/home/alvin/.arduino15/packages/arduino/hardware/avr/1.8.8/cores/arduino/HardwareSerial1.cpp"
},
{
"directory": "/home/alvin/Arduino",
"arguments": [
"/home/alvin/.arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7/bin/avr-g++",
"-c",
"-g",
"-Os",
"-w",
"-std=gnu++11",
"-fno-exceptions",
"-ffunction-sections",
"-fdata-sections",
"-fno-threadsafe-statics",
"-MMD",
"-mmcu=atmega168",
"-DF_CPU=8000000L",
"-DARDUINO=10607",
"-DARDUINO_AVR_PRO",
"-DARDUINO_ARCH_AVR",
"-I/home/alvin/.arduino15/packages/arduino/hardware/avr/1.8.8/cores/arduino",
"-I/home/alvin/.arduino15/packages/arduino/hardware/avr/1.8.8/variants/standard",
"/home/alvin/.arduino15/packages/arduino/hardware/avr/1.8.8/cores/arduino/HardwareSerial.cpp",
"-o",
"/home/alvin/.cache/arduino/studuino-compile-db/core/HardwareSerial.cpp.o"
],
"file": "/home/alvin/.arduino15/packages/arduino/hardware/avr/1.8.8/cores/arduino/HardwareSerial.cpp"
},
{
"directory": "/home/alvin/Arduino",
"arguments": [
"/home/alvin/.arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7/bin/avr-g++",
"-c",
"-g",
"-Os",
"-w",
"-std=gnu++11",
"-fno-exceptions",
"-ffunction-sections",
"-fdata-sections",
"-fno-threadsafe-statics",
"-MMD",
"-mmcu=atmega168",
"-DF_CPU=8000000L",
"-DARDUINO=10607",
"-DARDUINO_AVR_PRO",
"-DARDUINO_ARCH_AVR",
"-I/home/alvin/.arduino15/packages/arduino/hardware/avr/1.8.8/cores/arduino",
"-I/home/alvin/.arduino15/packages/arduino/hardware/avr/1.8.8/variants/standard",
"/home/alvin/.arduino15/packages/arduino/hardware/avr/1.8.8/cores/arduino/HardwareSerial3.cpp",
"-o",
"/home/alvin/.cache/arduino/studuino-compile-db/core/HardwareSerial3.cpp.o"
],
"file": "/home/alvin/.arduino15/packages/arduino/hardware/avr/1.8.8/cores/arduino/HardwareSerial3.cpp"
},
{
"directory": "/home/alvin/Arduino",
"arguments": [
"/home/alvin/.arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7/bin/avr-g++",
"-c",
"-g",
"-Os",
"-w",
"-std=gnu++11",
"-fno-exceptions",
"-ffunction-sections",
"-fdata-sections",
"-fno-threadsafe-statics",
"-MMD",
"-mmcu=atmega168",
"-DF_CPU=8000000L",
"-DARDUINO=10607",
"-DARDUINO_AVR_PRO",
"-DARDUINO_ARCH_AVR",
"-I/home/alvin/.arduino15/packages/arduino/hardware/avr/1.8.8/cores/arduino",
"-I/home/alvin/.arduino15/packages/arduino/hardware/avr/1.8.8/variants/standard",
"/home/alvin/.arduino15/packages/arduino/hardware/avr/1.8.8/cores/arduino/Print.cpp",
"-o",
"/home/alvin/.cache/arduino/studuino-compile-db/core/Print.cpp.o"
],
"file": "/home/alvin/.arduino15/packages/arduino/hardware/avr/1.8.8/cores/arduino/Print.cpp"
},
{
"directory": "/home/alvin/Arduino",
"arguments": [
"/home/alvin/.arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7/bin/avr-g++",
"-c",
"-g",
"-Os",
"-w",
"-std=gnu++11",
"-fno-exceptions",
"-ffunction-sections",
"-fdata-sections",
"-fno-threadsafe-statics",
"-MMD",
"-mmcu=atmega168",
"-DF_CPU=8000000L",
"-DARDUINO=10607",
"-DARDUINO_AVR_PRO",
"-DARDUINO_ARCH_AVR",
"-I/home/alvin/.arduino15/packages/arduino/hardware/avr/1.8.8/cores/arduino",
"-I/home/alvin/.arduino15/packages/arduino/hardware/avr/1.8.8/variants/standard",
"/home/alvin/.arduino15/packages/arduino/hardware/avr/1.8.8/cores/arduino/HardwareSerial2.cpp",
"-o",
"/home/alvin/.cache/arduino/studuino-compile-db/core/HardwareSerial2.cpp.o"
],
"file": "/home/alvin/.arduino15/packages/arduino/hardware/avr/1.8.8/cores/arduino/HardwareSerial2.cpp"
},
{
"directory": "/home/alvin/Arduino",
"arguments": [
"/home/alvin/.arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7/bin/avr-g++",
"-c",
"-g",
"-Os",
"-w",
"-std=gnu++11",
"-fno-exceptions",
"-ffunction-sections",
"-fdata-sections",
"-fno-threadsafe-statics",
"-MMD",
"-mmcu=atmega168",
"-DF_CPU=8000000L",
"-DARDUINO=10607",
"-DARDUINO_AVR_PRO",
"-DARDUINO_ARCH_AVR",
"-I/home/alvin/.arduino15/packages/arduino/hardware/avr/1.8.8/cores/arduino",
"-I/home/alvin/.arduino15/packages/arduino/hardware/avr/1.8.8/variants/standard",
"/home/alvin/.arduino15/packages/arduino/hardware/avr/1.8.8/cores/arduino/IPAddress.cpp",
"-o",
"/home/alvin/.cache/arduino/studuino-compile-db/core/IPAddress.cpp.o"
],
"file": "/home/alvin/.arduino15/packages/arduino/hardware/avr/1.8.8/cores/arduino/IPAddress.cpp"
},
{
"directory": "/home/alvin/Arduino",
"arguments": [
"/home/alvin/.arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7/bin/avr-g++",
"-c",
"-g",
"-Os",
"-w",
"-std=gnu++11",
"-fno-exceptions",
"-ffunction-sections",
"-fdata-sections",
"-fno-threadsafe-statics",
"-MMD",
"-mmcu=atmega168",
"-DF_CPU=8000000L",
"-DARDUINO=10607",
"-DARDUINO_AVR_PRO",
"-DARDUINO_ARCH_AVR",
"-I/home/alvin/.arduino15/packages/arduino/hardware/avr/1.8.8/cores/arduino",
"-I/home/alvin/.arduino15/packages/arduino/hardware/avr/1.8.8/variants/standard",
"/home/alvin/.arduino15/packages/arduino/hardware/avr/1.8.8/cores/arduino/Tone.cpp",
"-o",
"/home/alvin/.cache/arduino/studuino-compile-db/core/Tone.cpp.o"
],
"file": "/home/alvin/.arduino15/packages/arduino/hardware/avr/1.8.8/cores/arduino/Tone.cpp"
},
{
"directory": "/home/alvin/Arduino",
"arguments": [
"/home/alvin/.arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7/bin/avr-g++",
"-c",
"-g",
"-Os",
"-w",
"-std=gnu++11",
"-fno-exceptions",
"-ffunction-sections",
"-fdata-sections",
"-fno-threadsafe-statics",
"-MMD",
"-mmcu=atmega168",
"-DF_CPU=8000000L",
"-DARDUINO=10607",
"-DARDUINO_AVR_PRO",
"-DARDUINO_ARCH_AVR",
"-I/home/alvin/.arduino15/packages/arduino/hardware/avr/1.8.8/cores/arduino",
"-I/home/alvin/.arduino15/packages/arduino/hardware/avr/1.8.8/variants/standard",
"/home/alvin/.arduino15/packages/arduino/hardware/avr/1.8.8/cores/arduino/HardwareSerial0.cpp",
"-o",
"/home/alvin/.cache/arduino/studuino-compile-db/core/HardwareSerial0.cpp.o"
],
"file": "/home/alvin/.arduino15/packages/arduino/hardware/avr/1.8.8/cores/arduino/HardwareSerial0.cpp"
},
{
"directory": "/home/alvin/Arduino",
"arguments": [
"/home/alvin/.arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7/bin/avr-gcc",
"-c",
"-g",
"-Os",
"-w",
"-std=gnu11",
"-ffunction-sections",
"-fdata-sections",
"-MMD",
"-mmcu=atmega168",
"-DF_CPU=8000000L",
"-DARDUINO=10607",
"-DARDUINO_AVR_PRO",
"-DARDUINO_ARCH_AVR",
"-I/home/alvin/.arduino15/packages/arduino/hardware/avr/1.8.8/cores/arduino",
"-I/home/alvin/.arduino15/packages/arduino/hardware/avr/1.8.8/variants/standard",
"/home/alvin/.arduino15/packages/arduino/hardware/avr/1.8.8/cores/arduino/WInterrupts.c",
"-o",
"/home/alvin/.cache/arduino/studuino-compile-db/core/WInterrupts.c.o"
],
"file": "/home/alvin/.arduino15/packages/arduino/hardware/avr/1.8.8/cores/arduino/WInterrupts.c"
},
{
"directory": "/home/alvin/Arduino",
"arguments": [
"/home/alvin/.arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7/bin/avr-g++",
"-c",
"-g",
"-Os",
"-w",
"-std=gnu++11",
"-fno-exceptions",
"-ffunction-sections",
"-fdata-sections",
"-fno-threadsafe-statics",
"-MMD",
"-mmcu=atmega168",
"-DF_CPU=8000000L",
"-DARDUINO=10607",
"-DARDUINO_AVR_PRO",
"-DARDUINO_ARCH_AVR",
"-I/home/alvin/.arduino15/packages/arduino/hardware/avr/1.8.8/cores/arduino",
"-I/home/alvin/.arduino15/packages/arduino/hardware/avr/1.8.8/variants/standard",
"/home/alvin/.arduino15/packages/arduino/hardware/avr/1.8.8/cores/arduino/WMath.cpp",
"-o",
"/home/alvin/.cache/arduino/studuino-compile-db/core/WMath.cpp.o"
],
"file": "/home/alvin/.arduino15/packages/arduino/hardware/avr/1.8.8/cores/arduino/WMath.cpp"
},
{
"directory": "/home/alvin/Arduino",
"arguments": [
"/home/alvin/.arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7/bin/avr-g++",
"-c",
"-g",
"-Os",
"-w",
"-std=gnu++11",
"-fno-exceptions",
"-ffunction-sections",
"-fdata-sections",
"-fno-threadsafe-statics",
"-MMD",
"-mmcu=atmega168",
"-DF_CPU=8000000L",
"-DARDUINO=10607",
"-DARDUINO_AVR_PRO",
"-DARDUINO_ARCH_AVR",
"-I/home/alvin/.arduino15/packages/arduino/hardware/avr/1.8.8/cores/arduino",
"-I/home/alvin/.arduino15/packages/arduino/hardware/avr/1.8.8/variants/standard",
"/home/alvin/.arduino15/packages/arduino/hardware/avr/1.8.8/cores/arduino/Stream.cpp",
"-o",
"/home/alvin/.cache/arduino/studuino-compile-db/core/Stream.cpp.o"
],
"file": "/home/alvin/.arduino15/packages/arduino/hardware/avr/1.8.8/cores/arduino/Stream.cpp"
},
{
"directory": "/home/alvin/Arduino",
"arguments": [
"/home/alvin/.arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7/bin/avr-g++",
"-c",
"-g",
"-Os",
"-w",
"-std=gnu++11",
"-fno-exceptions",
"-ffunction-sections",
"-fdata-sections",
"-fno-threadsafe-statics",
"-MMD",
"-mmcu=atmega168",
"-DF_CPU=8000000L",
"-DARDUINO=10607",
"-DARDUINO_AVR_PRO",
"-DARDUINO_ARCH_AVR",
"-I/home/alvin/.arduino15/packages/arduino/hardware/avr/1.8.8/cores/arduino",
"-I/home/alvin/.arduino15/packages/arduino/hardware/avr/1.8.8/variants/standard",
"/home/alvin/.arduino15/packages/arduino/hardware/avr/1.8.8/cores/arduino/PluggableUSB.cpp",
"-o",
"/home/alvin/.cache/arduino/studuino-compile-db/core/PluggableUSB.cpp.o"
],
"file": "/home/alvin/.arduino15/packages/arduino/hardware/avr/1.8.8/cores/arduino/PluggableUSB.cpp"
},
{
"directory": "/home/alvin/Arduino",
"arguments": [
"/home/alvin/.arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7/bin/avr-g++",
"-c",
"-g",
"-Os",
"-w",
"-std=gnu++11",
"-fno-exceptions",
"-ffunction-sections",
"-fdata-sections",
"-fno-threadsafe-statics",
"-MMD",
"-mmcu=atmega168",
"-DF_CPU=8000000L",
"-DARDUINO=10607",
"-DARDUINO_AVR_PRO",
"-DARDUINO_ARCH_AVR",
"-I/home/alvin/.arduino15/packages/arduino/hardware/avr/1.8.8/cores/arduino",
"-I/home/alvin/.arduino15/packages/arduino/hardware/avr/1.8.8/variants/standard",
"/home/alvin/.arduino15/packages/arduino/hardware/avr/1.8.8/cores/arduino/USBCore.cpp",
"-o",
"/home/alvin/.cache/arduino/studuino-compile-db/core/USBCore.cpp.o"
],
"file": "/home/alvin/.arduino15/packages/arduino/hardware/avr/1.8.8/cores/arduino/USBCore.cpp"
},
{
"directory": "/home/alvin/Arduino",
"arguments": [
"/home/alvin/.arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7/bin/avr-g++",
"-c",
"-g",
"-Os",
"-w",
"-std=gnu++11",
"-fno-exceptions",
"-ffunction-sections",
"-fdata-sections",
"-fno-threadsafe-statics",
"-MMD",
"-mmcu=atmega168",
"-DF_CPU=8000000L",
"-DARDUINO=10607",
"-DARDUINO_AVR_PRO",
"-DARDUINO_ARCH_AVR",
"-I/home/alvin/.arduino15/packages/arduino/hardware/avr/1.8.8/cores/arduino",
"-I/home/alvin/.arduino15/packages/arduino/hardware/avr/1.8.8/variants/standard",
"/home/alvin/.arduino15/packages/arduino/hardware/avr/1.8.8/cores/arduino/new.cpp",
"-o",
"/home/alvin/.cache/arduino/studuino-compile-db/core/new.cpp.o"
],
"file": "/home/alvin/.arduino15/packages/arduino/hardware/avr/1.8.8/cores/arduino/new.cpp"
},
{
"directory": "/home/alvin/Arduino",
"arguments": [
"/home/alvin/.arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7/bin/avr-gcc",
"-c",
"-g",
"-Os",
"-w",
"-std=gnu11",
"-ffunction-sections",
"-fdata-sections",
"-MMD",
"-mmcu=atmega168",
"-DF_CPU=8000000L",
"-DARDUINO=10607",
"-DARDUINO_AVR_PRO",
"-DARDUINO_ARCH_AVR",
"-I/home/alvin/.arduino15/packages/arduino/hardware/avr/1.8.8/cores/arduino",
"-I/home/alvin/.arduino15/packages/arduino/hardware/avr/1.8.8/variants/standard",
"/home/alvin/.arduino15/packages/arduino/hardware/avr/1.8.8/cores/arduino/wiring.c",
"-o",
"/home/alvin/.cache/arduino/studuino-compile-db/core/wiring.c.o"
],
"file": "/home/alvin/.arduino15/packages/arduino/hardware/avr/1.8.8/cores/arduino/wiring.c"
},
{
"directory": "/home/alvin/Arduino",
"arguments": [
"/home/alvin/.arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7/bin/avr-g++",
"-c",
"-g",
"-Os",
"-w",
"-std=gnu++11",
"-fno-exceptions",
"-ffunction-sections",
"-fdata-sections",
"-fno-threadsafe-statics",
"-MMD",
"-mmcu=atmega168",
"-DF_CPU=8000000L",
"-DARDUINO=10607",
"-DARDUINO_AVR_PRO",
"-DARDUINO_ARCH_AVR",
"-I/home/alvin/.arduino15/packages/arduino/hardware/avr/1.8.8/cores/arduino",
"-I/home/alvin/.arduino15/packages/arduino/hardware/avr/1.8.8/variants/standard",
"/home/alvin/.arduino15/packages/arduino/hardware/avr/1.8.8/cores/arduino/abi.cpp",
"-o",
"/home/alvin/.cache/arduino/studuino-compile-db/core/abi.cpp.o"
],
"file": "/home/alvin/.arduino15/packages/arduino/hardware/avr/1.8.8/cores/arduino/abi.cpp"
},
{
"directory": "/home/alvin/Arduino",
"arguments": [
"/home/alvin/.arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7/bin/avr-g++",
"-c",
"-g",
"-Os",
"-w",
"-std=gnu++11",
"-fno-exceptions",
"-ffunction-sections",
"-fdata-sections",
"-fno-threadsafe-statics",
"-MMD",
"-mmcu=atmega168",
"-DF_CPU=8000000L",
"-DARDUINO=10607",
"-DARDUINO_AVR_PRO",
"-DARDUINO_ARCH_AVR",
"-I/home/alvin/.arduino15/packages/arduino/hardware/avr/1.8.8/cores/arduino",
"-I/home/alvin/.arduino15/packages/arduino/hardware/avr/1.8.8/variants/standard",
"/home/alvin/.arduino15/packages/arduino/hardware/avr/1.8.8/cores/arduino/WString.cpp",
"-o",
"/home/alvin/.cache/arduino/studuino-compile-db/core/WString.cpp.o"
],
"file": "/home/alvin/.arduino15/packages/arduino/hardware/avr/1.8.8/cores/arduino/WString.cpp"
},
{
"directory": "/home/alvin/Arduino",
"arguments": [
"/home/alvin/.arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7/bin/avr-gcc",
"-c",
"-g",
"-Os",
"-w",
"-std=gnu11",
"-ffunction-sections",
"-fdata-sections",
"-MMD",
"-mmcu=atmega168",
"-DF_CPU=8000000L",
"-DARDUINO=10607",
"-DARDUINO_AVR_PRO",
"-DARDUINO_ARCH_AVR",
"-I/home/alvin/.arduino15/packages/arduino/hardware/avr/1.8.8/cores/arduino",
"-I/home/alvin/.arduino15/packages/arduino/hardware/avr/1.8.8/variants/standard",
"/home/alvin/.arduino15/packages/arduino/hardware/avr/1.8.8/cores/arduino/wiring_pulse.c",
"-o",
"/home/alvin/.cache/arduino/studuino-compile-db/core/wiring_pulse.c.o"
],
"file": "/home/alvin/.arduino15/packages/arduino/hardware/avr/1.8.8/cores/arduino/wiring_pulse.c"
},
{
"directory": "/home/alvin/Arduino",
"arguments": [
"/home/alvin/.arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7/bin/avr-gcc",
"-c",
"-g",
"-Os",
"-w",
"-std=gnu11",
"-ffunction-sections",
"-fdata-sections",
"-MMD",
"-mmcu=atmega168",
"-DF_CPU=8000000L",
"-DARDUINO=10607",
"-DARDUINO_AVR_PRO",
"-DARDUINO_ARCH_AVR",
"-I/home/alvin/.arduino15/packages/arduino/hardware/avr/1.8.8/cores/arduino",
"-I/home/alvin/.arduino15/packages/arduino/hardware/avr/1.8.8/variants/standard",
"/home/alvin/.arduino15/packages/arduino/hardware/avr/1.8.8/cores/arduino/hooks.c",
"-o",
"/home/alvin/.cache/arduino/studuino-compile-db/core/hooks.c.o"
],
"file": "/home/alvin/.arduino15/packages/arduino/hardware/avr/1.8.8/cores/arduino/hooks.c"
},
{
"directory": "/home/alvin/Arduino",
"arguments": [
"/home/alvin/.arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7/bin/avr-gcc",
"-c",
"-g",
"-x",
"assembler-with-cpp",
"-mmcu=atmega168",
"-DF_CPU=8000000L",
"-DARDUINO=10607",
"-DARDUINO_AVR_PRO",
"-DARDUINO_ARCH_AVR",
"-I/home/alvin/.arduino15/packages/arduino/hardware/avr/1.8.8/cores/arduino",
"-I/home/alvin/.arduino15/packages/arduino/hardware/avr/1.8.8/variants/standard",
"/home/alvin/.arduino15/packages/arduino/hardware/avr/1.8.8/cores/arduino/wiring_pulse.S",
"-o",
"/home/alvin/.cache/arduino/studuino-compile-db/core/wiring_pulse.S.o"
],
"file": "/home/alvin/.arduino15/packages/arduino/hardware/avr/1.8.8/cores/arduino/wiring_pulse.S"
},
{
"directory": "/home/alvin/Arduino",
"arguments": [
"/home/alvin/.arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7/bin/avr-gcc",
"-c",
"-g",
"-Os",
"-w",
"-std=gnu11",
"-ffunction-sections",
"-fdata-sections",
"-MMD",
"-mmcu=atmega168",
"-DF_CPU=8000000L",
"-DARDUINO=10607",
"-DARDUINO_AVR_PRO",
"-DARDUINO_ARCH_AVR",
"-I/home/alvin/.arduino15/packages/arduino/hardware/avr/1.8.8/cores/arduino",
"-I/home/alvin/.arduino15/packages/arduino/hardware/avr/1.8.8/variants/standard",
"/home/alvin/.arduino15/packages/arduino/hardware/avr/1.8.8/cores/arduino/wiring_digital.c",
"-o",
"/home/alvin/.cache/arduino/studuino-compile-db/core/wiring_digital.c.o"
],
"file": "/home/alvin/.arduino15/packages/arduino/hardware/avr/1.8.8/cores/arduino/wiring_digital.c"
},
{
"directory": "/home/alvin/Arduino",
"arguments": [
"/home/alvin/.arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7/bin/avr-gcc",
"-c",
"-g",
"-Os",
"-w",
"-std=gnu11",
"-ffunction-sections",
"-fdata-sections",
"-MMD",
"-mmcu=atmega168",
"-DF_CPU=8000000L",
"-DARDUINO=10607",
"-DARDUINO_AVR_PRO",
"-DARDUINO_ARCH_AVR",
"-I/home/alvin/.arduino15/packages/arduino/hardware/avr/1.8.8/cores/arduino",
"-I/home/alvin/.arduino15/packages/arduino/hardware/avr/1.8.8/variants/standard",
"/home/alvin/.arduino15/packages/arduino/hardware/avr/1.8.8/cores/arduino/wiring_shift.c",
"-o",
"/home/alvin/.cache/arduino/studuino-compile-db/core/wiring_shift.c.o"
],
"file": "/home/alvin/.arduino15/packages/arduino/hardware/avr/1.8.8/cores/arduino/wiring_shift.c"
},
{
"directory": "/home/alvin/Arduino",
"arguments": [
"/home/alvin/.arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7/bin/avr-gcc",
"-c",
"-g",
"-Os",
"-w",
"-std=gnu11",
"-ffunction-sections",
"-fdata-sections",
"-MMD",
"-mmcu=atmega168",
"-DF_CPU=8000000L",
"-DARDUINO=10607",
"-DARDUINO_AVR_PRO",
"-DARDUINO_ARCH_AVR",
"-I/home/alvin/.arduino15/packages/arduino/hardware/avr/1.8.8/cores/arduino",
"-I/home/alvin/.arduino15/packages/arduino/hardware/avr/1.8.8/variants/standard",
"/home/alvin/.arduino15/packages/arduino/hardware/avr/1.8.8/cores/arduino/wiring_analog.c",
"-o",
"/home/alvin/.cache/arduino/studuino-compile-db/core/wiring_analog.c.o"
],
"file": "/home/alvin/.arduino15/packages/arduino/hardware/avr/1.8.8/cores/arduino/wiring_analog.c"
},
{
"directory": "/home/alvin/Arduino",
"arguments": [
"/home/alvin/.arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7/bin/avr-g++",
"-c",
"-g",
"-Os",
"-w",
"-std=gnu++11",
"-fno-exceptions",
"-ffunction-sections",
"-fdata-sections",
"-fno-threadsafe-statics",
"-MMD",
"-mmcu=atmega168",
"-DF_CPU=8000000L",
"-DARDUINO=10607",
"-DARDUINO_AVR_PRO",
"-DARDUINO_ARCH_AVR",
"-I/home/alvin/.arduino15/packages/arduino/hardware/avr/1.8.8/cores/arduino",
"-I/home/alvin/.arduino15/packages/arduino/hardware/avr/1.8.8/variants/standard",
"/home/alvin/.arduino15/packages/arduino/hardware/avr/1.8.8/cores/arduino/main.cpp",
"-o",
"/home/alvin/.cache/arduino/studuino-compile-db/core/main.cpp.o"
],
"file": "/home/alvin/.arduino15/packages/arduino/hardware/avr/1.8.8/cores/arduino/main.cpp"
}
]
+2 -3
View File
@@ -7,7 +7,8 @@ menu.cpu=Processor
studuino.name=Studuino (3.3V, 8 MHz) w/ ATmega168 studuino.name=Studuino (3.3V, 8 MHz) w/ ATmega168
studuino.upload.tool=avrdude studuino.upload.tool=avrdude
studuino.upload.protocol=arduino studuino.upload.protocol=arduino
studuino.upload.maximum_size=15872 studuino.upload.maximum_size=14336
studuino.upload.maximum_data_size=1024
studuino.upload.speed=115200 studuino.upload.speed=115200
studuino.bootloader.tool=avrdude studuino.bootloader.tool=avrdude
@@ -22,7 +23,5 @@ studuino.bootloader.lock_bits=0x0F
studuino.build.mcu=atmega168 studuino.build.mcu=atmega168
studuino.build.f_cpu=8000000L studuino.build.f_cpu=8000000L
studuino.build.board=AVR_PRO studuino.build.board=AVR_PRO
studuino.build.core=arduino
studuino.build.variant=standard
studuino.build.core=arduino:arduino studuino.build.core=arduino:arduino
studuino.build.variant=arduino:standard studuino.build.variant=arduino:standard
+116 -112
View File
@@ -6,40 +6,35 @@ set -Eeuo pipefail
SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)" SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
ARDUINO_USER_OVERRIDE="${ARDUINO_USER:-}" ARDUINO_USER_OVERRIDE="${ARDUINO_USER:-}"
ARDUINO_USER="${ARDUINO_USER:-$HOME/Arduino}" ARDUINO_USER="${ARDUINO_USER:-$HOME/Arduino}"
RESOURCE_DIR="$SCRIPT_DIR/Resources" HARDWARE_SOURCE_DIR="$SCRIPT_DIR/hardware/studuino/avr"
LIBRARY_ARCHIVE="$RESOURCE_DIR/studuino_v1_lib.zip" LIBRARY_SOURCE_DIR="$SCRIPT_DIR/libraries"
HARDWARE_ARCHIVE="$RESOURCE_DIR/arduino_IDE_hardware_settings_ver17x.zip"
FQBN="studuino:avr:studuino" FQBN="studuino:avr:studuino"
MIN_AVR_CORE_VERSION="1.8.8"
BUILD_DIR="${XDG_CACHE_HOME:-$HOME/.cache}/arduino/studuino-compile-db" BUILD_DIR="${XDG_CACHE_HOME:-$HOME/.cache}/arduino/studuino-compile-db"
VERIFY_BUILD_DIR="$BUILD_DIR/verify" VERIFY_BUILD_DIR="$BUILD_DIR/verify"
SMOKE_VERIFY_BUILD_DIR="$BUILD_DIR/verify-studuino-blink"
SMOKE_SKETCH_DIR="$LIBRARY_SOURCE_DIR/Studuino/example/Blink"
FORCE=0 FORCE=0
CLEAN_LIBRARIES=0 CLEAN_LIBRARIES=0
SKIP_PACKAGES=0 SKIP_PACKAGES=0
SKIP_PERMISSIONS=0 SKIP_PERMISSIONS=0
SKIP_COMPILE_DB=0 SKIP_COMPILE_DB=0
WITH_EDITOR=0
WITH_MONITOR=0 WITH_MONITOR=0
CONFIG_FILE="${ARDUINO_CONFIG_FILE:-}" CONFIG_FILE="${ARDUINO_CONFIG_FILE:-}"
TEMP_DIRS=()
cleanup() {
local temporary
for temporary in "${TEMP_DIRS[@]}"; do
[[ -d "$temporary" ]] && rm -rf -- "$temporary"
done
}
trap cleanup EXIT
usage() { usage() {
cat <<'EOF' cat <<'EOF'
Usage: ./setup.sh [options] Usage: ./setup.sh [options]
Options: Options:
--force Replace existing Studuino library/hardware files. --force Replace hardware/libraries with checked-in versions.
--clean Remove user libraries not supplied by the Studuino bundle. --clean Remove user libraries absent from this repository.
--skip-packages Do not install Arch packages. --skip-packages Do not install Arch packages.
--skip-permissions Do not modify serial-port group membership. --skip-permissions Do not modify serial-port group membership.
--skip-compile-db Do not generate compile_commands.json. --skip-compile-db Do not generate compile_commands.json.
--with-editor Install Neovim, clang, and Arduino language-server tools.
--with-monitor Also install picocom for a serial monitor. --with-monitor Also install picocom for a serial monitor.
-h, --help Show this help. -h, --help Show this help.
@@ -66,6 +61,9 @@ while (($# > 0)); do
--skip-compile-db) --skip-compile-db)
SKIP_COMPILE_DB=1 SKIP_COMPILE_DB=1
;; ;;
--with-editor)
WITH_EDITOR=1
;;
--with-monitor) --with-monitor)
WITH_MONITOR=1 WITH_MONITOR=1
;; ;;
@@ -129,24 +127,28 @@ install_packages() {
info "Skipping Arch package installation." info "Skipping Arch package installation."
else else
require_command pacman require_command pacman
local -a packages=( local -a packages=(arduino-cli)
arduino-cli
clangd if ((WITH_EDITOR)); then
make packages+=(clang neovim arduino-language-server)
neovim fi
python
unzip
)
if ((WITH_MONITOR)); then if ((WITH_MONITOR)); then
packages+=(picocom) packages+=(picocom)
fi fi
info "Installing required Arch packages." info "Installing required Arch packages."
as_root pacman -S --needed "${packages[@]}" as_root pacman -S --needed "${packages[@]}"
fi fi
require_command arduino-cli require_command arduino-cli
require_command python3 if ((WITH_EDITOR)); then
require_command unzip require_command clangd
require_command nvim
require_command arduino-language-server
fi
if ((WITH_MONITOR)); then
require_command picocom
fi
} }
ensure_serial_permissions() { ensure_serial_permissions() {
@@ -207,7 +209,29 @@ resolve_arduino_user() {
fi fi
} }
validate_hardware_files() {
local directory="$1"
[[ -f "$directory/boards.txt" ]] || die "Missing Studuino board definition: $directory/boards.txt"
[[ -f "$directory/platform.txt" ]] || die "Missing Studuino platform definition: $directory/platform.txt"
[[ -f "$directory/platform.local.txt" ]] || die "Missing Studuino CLI overrides: $directory/platform.local.txt"
grep -q '^studuino.name=' "$directory/boards.txt" \
|| die "The Studuino board definition is missing its board entry."
grep -q '^name=' "$directory/platform.txt" \
|| die "The Studuino platform definition is missing its platform name."
}
hardware_matches_source() {
local file
for file in boards.txt platform.txt platform.local.txt; do
cmp -s -- "$HARDWARE_SOURCE_DIR/$file" "$ARDUINO_USER/hardware/studuino/avr/$file" || return 1
done
}
ensure_hardware_layout() { ensure_hardware_layout() {
[[ -d "$HARDWARE_SOURCE_DIR" ]] || die "Checked-in hardware directory not found: $HARDWARE_SOURCE_DIR"
validate_hardware_files "$HARDWARE_SOURCE_DIR"
local vendor_dir="$ARDUINO_USER/hardware/studuino" local vendor_dir="$ARDUINO_USER/hardware/studuino"
local hardware_dir="$vendor_dir/avr" local hardware_dir="$vendor_dir/avr"
local nested_dir="$vendor_dir/studuino/avr" local nested_dir="$vendor_dir/studuino/avr"
@@ -227,120 +251,88 @@ ensure_hardware_layout() {
fi fi
fi fi
if [[ -f "$hardware_dir/boards.txt" && -f "$hardware_dir/platform.txt" ]] && (( FORCE == 0 )); then if [[ "$HARDWARE_SOURCE_DIR" -ef "$hardware_dir" ]]; then
info "Using the checked-in Studuino hardware definition."
elif [[ -L "$hardware_dir" ]]; then
die "Refusing to replace symlinked hardware directory: $hardware_dir"
elif [[ -e "$hardware_dir" ]] && ((FORCE == 0)); then
if hardware_matches_source; then
info "Studuino hardware files are already installed; keeping them." info "Studuino hardware files are already installed; keeping them."
else else
[[ -f "$HARDWARE_ARCHIVE" ]] || die "Hardware archive not found: $HARDWARE_ARCHIVE" warn "Installed Studuino hardware differs from this repository; keeping it. Re-run with --force to replace it."
mkdir -p -- "$hardware_dir"
# The official archive was created on Windows and uses backslashes in ZIP
# entry names. Extract only the Linux/other Studuino platform files.
python3 - "$HARDWARE_ARCHIVE" "$hardware_dir" "$FORCE" <<'PY'
from pathlib import Path
import sys
from zipfile import ZipFile
archive = Path(sys.argv[1])
destination = Path(sys.argv[2])
force = sys.argv[3] == "1"
wanted = {
"arduino_ide_settings_ver17x/other/hardware/studuino/avr/boards.txt": "boards.txt",
"arduino_ide_settings_ver17x/other/hardware/studuino/avr/platform.txt": "platform.txt",
}
found = set()
with ZipFile(archive) as zipped:
for info in zipped.infolist():
normalized = info.filename.replace("\\", "/")
target_name = wanted.get(normalized)
if target_name is None:
continue
target = destination / target_name
if target.exists() and not force:
print(f"[studuino] Keeping existing {target}")
else:
target.write_bytes(zipped.read(info))
print(f"[studuino] Installed {target}")
found.add(target_name)
missing = set(wanted.values()) - found
if missing:
raise SystemExit("Missing hardware files in archive: " + ", ".join(sorted(missing)))
PY
fi fi
else
mkdir -p -- "$hardware_dir"
if ((FORCE)) && [[ -e "$hardware_dir" ]]; then
rm -rf -- "$hardware_dir"
mkdir -p -- "$hardware_dir"
fi
cp -a -- "$HARDWARE_SOURCE_DIR/." "$hardware_dir/"
info "Installed checked-in Studuino hardware files: $hardware_dir"
fi
}
# The archive targets the legacy IDE's tool paths. These overrides make it version_at_least() {
# work with the AVR tools installed by arduino-cli. local current="$1"
local local_properties="$hardware_dir/platform.local.txt" local minimum="$2"
cat >"$local_properties" <<'EOF'
# Generated by setup.sh for modern arduino-cli AVR tool paths.
compiler.path={runtime.tools.avr-gcc.path}/bin/
archive_file_path={build.path}/{archive_file}
recipe.ar.pattern="{compiler.path}{compiler.ar.cmd}" {compiler.ar.flags} {compiler.ar.extra_flags} "{archive_file_path}" "{object_file}"
tools.avrdude.path={runtime.tools.avrdude.path}
tools.avrdude.cmd.path={path}/bin/avrdude
tools.avrdude.config.path={path}/etc/avrdude.conf
EOF
info "Wrote modern CLI compatibility overrides: $local_properties"
grep -q '^studuino.name=' "$hardware_dir/boards.txt" \ [[ "$current" == "$minimum" ]] && return 0
|| die "The installed Studuino boards.txt is missing its board definition." [[ "$(printf '%s\n%s\n' "$minimum" "$current" | sort -V | head -n 1)" == "$minimum" ]]
grep -q '^name=' "$hardware_dir/platform.txt" \
|| die "The installed Studuino platform.txt is missing its platform name."
} }
ensure_avr_core() { ensure_avr_core() {
if run_cli core list | awk '$1 == "arduino:avr" { found = 1 } END { exit !found }'; then local installed
info "AVR core is already installed." installed="$(run_cli core list | awk '$1 == "arduino:avr" { print $2; exit }')"
if [[ -z "$installed" ]]; then
info "Installing Arduino AVR core $MIN_AVR_CORE_VERSION."
run_cli core update-index
run_cli core install "arduino:avr@$MIN_AVR_CORE_VERSION"
return return
fi fi
info "Installing the Arduino AVR core." if version_at_least "$installed" "$MIN_AVR_CORE_VERSION"; then
info "Arduino AVR core $installed is installed."
return
fi
warn "Arduino AVR core $installed is older than $MIN_AVR_CORE_VERSION; upgrading."
run_cli core update-index run_cli core update-index
run_cli core install arduino:avr run_cli core install "arduino:avr@$MIN_AVR_CORE_VERSION"
} }
install_studuino_libraries() { install_studuino_libraries() {
[[ -f "$LIBRARY_ARCHIVE" ]] || die "Library archive not found: $LIBRARY_ARCHIVE" [[ -d "$LIBRARY_SOURCE_DIR/Studuino" ]] \
|| die "Checked-in Studuino library not found: $LIBRARY_SOURCE_DIR/Studuino"
local temporary
temporary="$(mktemp -d)"
TEMP_DIRS+=("$temporary")
unzip -q "$LIBRARY_ARCHIVE" -d "$temporary"
local bundle_dir="$temporary/studuino_v1_lib"
[[ -d "$bundle_dir/Studuino" ]] || die "Unexpected Studuino library archive layout."
mkdir -p -- "$ARDUINO_USER/libraries" mkdir -p -- "$ARDUINO_USER/libraries"
local source_dir destination name local source_dir destination name
for source_dir in "$bundle_dir"/*; do for source_dir in "$LIBRARY_SOURCE_DIR"/*; do
[[ -d "$source_dir" ]] || continue [[ -d "$source_dir" && ! -L "$source_dir" ]] || continue
name="${source_dir##*/}" name="${source_dir##*/}"
destination="$ARDUINO_USER/libraries/$name" destination="$ARDUINO_USER/libraries/$name"
if [[ -L "$destination" ]]; then if [[ "$source_dir" -ef "$destination" ]]; then
info "Using checked-in library: $name"
elif [[ -L "$destination" ]]; then
die "Refusing to replace symlinked library: $destination" die "Refusing to replace symlinked library: $destination"
fi elif [[ -e "$destination" ]] && ((FORCE == 0)); then
if [[ -e "$destination" ]] && ((FORCE == 0)); then
info "Keeping existing Studuino library: $destination" info "Keeping existing Studuino library: $destination"
else else
if [[ -e "$destination" ]]; then if [[ -e "$destination" ]]; then
rm -rf -- "$destination" rm -rf -- "$destination"
fi fi
cp -a -- "$source_dir" "$destination" cp -a -- "$source_dir" "$destination"
info "Installed Studuino library: $destination" info "Installed checked-in Studuino library: $destination"
fi fi
done done
if ((CLEAN_LIBRARIES)); then if ((CLEAN_LIBRARIES)); then
local -A keep=() local -A keep=()
for source_dir in "$bundle_dir"/*; do for source_dir in "$LIBRARY_SOURCE_DIR"/*; do
[[ -d "$source_dir" ]] || continue [[ -d "$source_dir" && ! -L "$source_dir" ]] || continue
keep["${source_dir##*/}"]=1 keep["${source_dir##*/}"]=1
done done
# Servo is required by Studuino even though it is not in the ZIP.
keep[Servo]=1
local installed_dir installed_name local installed_dir installed_name
for installed_dir in "$ARDUINO_USER/libraries"/*; do for installed_dir in "$ARDUINO_USER/libraries"/*; do
@@ -348,7 +340,7 @@ install_studuino_libraries() {
installed_name="${installed_dir##*/}" installed_name="${installed_dir##*/}"
if [[ -z "${keep[$installed_name]+present}" ]]; then if [[ -z "${keep[$installed_name]+present}" ]]; then
rm -rf -- "$installed_dir" rm -rf -- "$installed_dir"
info "Removed non-Studuino library: $installed_dir" info "Removed library not supplied by this repository: $installed_dir"
fi fi
done done
fi fi
@@ -391,17 +383,23 @@ EOF
mv -- "$SCRIPT_DIR/sketch.ino" "$sketch" mv -- "$SCRIPT_DIR/sketch.ino" "$sketch"
else else
cat >"$sketch" <<'EOF' cat >"$sketch" <<'EOF'
#include <Arduino.h> #include <Studuino.h>
#include <Clock.h> // Keep the complete smoke-test dependency set in clangd's database.
Studuino board;
void setup() { void setup() {
// Add Studuino initialization here. board.InitSensorPort(PORT_A0, PIDLED);
} }
void loop() { void loop() {
// Add Studuino code here. board.LED(PORT_A0, ON);
board.Timer(1);
board.LED(PORT_A0, OFF);
board.Timer(1);
} }
EOF EOF
info "Created a minimal sketch at $sketch" info "Created a Studuino smoke-test sketch at $sketch"
fi fi
elif [[ -f "$SCRIPT_DIR/sketch.ino" ]]; then elif [[ -f "$SCRIPT_DIR/sketch.ino" ]]; then
warn "Both Arduino.ino and sketch.ino exist; leaving sketch.ino untouched." warn "Both Arduino.ino and sketch.ino exist; leaving sketch.ino untouched."
@@ -416,13 +414,13 @@ generate_compile_database() {
mkdir -p -- "$BUILD_DIR" mkdir -p -- "$BUILD_DIR"
info "Generating the Neovim/clangd compilation database." info "Generating the Neovim/clangd compilation database."
if run_cli compile --clean --fqbn "$FQBN" --only-compilation-database \ if ! run_cli compile --clean --fqbn "$FQBN" --only-compilation-database \
--build-path "$BUILD_DIR" "$SCRIPT_DIR"; then --build-path "$BUILD_DIR" "$SCRIPT_DIR"; then
die "Could not generate compile_commands.json."
fi
cp -- "$BUILD_DIR/compile_commands.json" "$SCRIPT_DIR/compile_commands.json" cp -- "$BUILD_DIR/compile_commands.json" "$SCRIPT_DIR/compile_commands.json"
info "Wrote $SCRIPT_DIR/compile_commands.json" info "Wrote $SCRIPT_DIR/compile_commands.json"
else
warn "Could not generate compile_commands.json; the Studuino setup is otherwise complete."
fi
} }
verify_setup() { verify_setup() {
@@ -436,6 +434,12 @@ verify_setup() {
run_cli lib list | grep -E '^Servo[[:space:]]' >/dev/null \ run_cli lib list | grep -E '^Servo[[:space:]]' >/dev/null \
|| die "The Servo library is not visible to arduino-cli." || die "The Servo library is not visible to arduino-cli."
[[ -f "$SMOKE_SKETCH_DIR/Blink.ino" ]] \
|| die "Studuino smoke-test sketch not found: $SMOKE_SKETCH_DIR/Blink.ino"
info "Compiling the Studuino Blink smoke test for $FQBN..."
run_cli compile --clean --fqbn "$FQBN" \
--build-path "$SMOKE_VERIFY_BUILD_DIR" "$SMOKE_SKETCH_DIR"
info "Compiling the project for $FQBN..." info "Compiling the project for $FQBN..."
run_cli compile --clean --fqbn "$FQBN" \ run_cli compile --clean --fqbn "$FQBN" \
--build-path "$VERIFY_BUILD_DIR" "$SCRIPT_DIR" --build-path "$VERIFY_BUILD_DIR" "$SCRIPT_DIR"