diff --git a/Software/MainBoard/rust/.cargo/config.toml b/Software/MainBoard/rust/.cargo/config.toml index 2ef7d6e..55152e5 100644 --- a/Software/MainBoard/rust/.cargo/config.toml +++ b/Software/MainBoard/rust/.cargo/config.toml @@ -23,6 +23,7 @@ target = "riscv32imac-unknown-none-elf" CHRONO_TZ_TIMEZONE_FILTER = "UTC|America/New_York|America/Chicago|America/Los_Angeles|Europe/London|Europe/Berlin|Europe/Paris|Asia/Tokyo|Asia/Shanghai|Asia/Kolkata|Australia/Sydney|America/Sao_Paulo|Africa/Johannesburg|Asia/Dubai|Pacific/Auckland" CARGO_WORKSPACE_DIR = { value = "", relative = true } ESP_LOG = "info" +PATH = { value = "../../../bin:/usr/bin:/usr/local/bin", force = true, relative = true } diff --git a/Software/MainBoard/rust/all.sh b/Software/MainBoard/rust/all.sh index 7f046eb..5a80cfb 100755 --- a/Software/MainBoard/rust/all.sh +++ b/Software/MainBoard/rust/all.sh @@ -1,11 +1,15 @@ +#!/usr/bin/env bash + rm ./src/webserver/index.html.gz rm ./src/webserver/bundle.js.gz set -e -cd ./src_webpack/ + +pushd ./src_webpack/ +npm install npx webpack build cp index.html.gz ../src/webserver/index.html.gz cp bundle.js.gz ../src/webserver/bundle.js.gz -cd ../ +popd cargo build --release espflash save-image --bootloader bootloader.bin --partition-table partitions.csv --chip esp32c6 target/riscv32imac-unknown-none-elf/release/plant-ctrl2 image.bin diff --git a/Software/MainBoard/rust/flash.sh b/Software/MainBoard/rust/flash.sh index 07ff4fb..8dff1d5 100755 --- a/Software/MainBoard/rust/flash.sh +++ b/Software/MainBoard/rust/flash.sh @@ -1,11 +1,15 @@ +#!/usr/bin/env bash + rm ./src/webserver/index.html.gz rm ./src/webserver/bundle.js.gz set -e -cd ./src_webpack/ + +pushd ./src_webpack/ +npm install npx webpack build cp index.html.gz ../src/webserver/index.html.gz cp bundle.js.gz ../src/webserver/bundle.js.gz -cd ../ +popd cargo build --release espflash flash --monitor --bootloader bootloader.bin --chip esp32c6 --baud 921600 --partition-table partitions.csv target/riscv32imac-unknown-none-elf/release/plant-ctrl2 diff --git a/Software/MainBoard/rust/image_build.sh b/Software/MainBoard/rust/image_build.sh index 4dc9a11..5685130 100755 --- a/Software/MainBoard/rust/image_build.sh +++ b/Software/MainBoard/rust/image_build.sh @@ -1,12 +1,16 @@ +#!/usr/bin/env bash + rm image.bin rm ./src/webserver/index.html.gz rm ./src/webserver/bundle.js.gz set -e -cd ./src_webpack/ + +pushd ./src_webpack/ +npm install npx webpack build cp index.html.gz ../src/webserver/index.html.gz cp bundle.js.gz ../src/webserver/bundle.js.gz -cd ../ +popd set -e cargo build --release diff --git a/Software/MainBoard/rust/src_webpack/package-lock.json b/Software/MainBoard/rust/src_webpack/package-lock.json index 5e1bd46..26340b5 100644 --- a/Software/MainBoard/rust/src_webpack/package-lock.json +++ b/Software/MainBoard/rust/src_webpack/package-lock.json @@ -707,7 +707,6 @@ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "license": "MIT", - "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -732,7 +731,6 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "license": "MIT", - "peer": true, "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", @@ -959,7 +957,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "baseline-browser-mapping": "^2.8.3", "caniuse-lite": "^1.0.30001741", @@ -2277,7 +2274,6 @@ "integrity": "sha512-V/PZeWsqhfpE27nKeX9EO2sbR+D17A+tLf6qU+ht66jdUsN0QLKJN27Z+1+gHrVMKgndBahes0PU6rRihDgHTw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@types/html-minifier-terser": "^6.0.0", "html-minifier-terser": "^6.0.2", @@ -3384,7 +3380,6 @@ "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -4343,8 +4338,7 @@ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", "dev": true, - "license": "0BSD", - "peer": true + "license": "0BSD" }, "node_modules/type-is": { "version": "1.6.18", @@ -4366,7 +4360,6 @@ "integrity": "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==", "dev": true, "license": "Apache-2.0", - "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -4515,7 +4508,6 @@ "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.101.3.tgz", "integrity": "sha512-7b0dTKR3Ed//AD/6kkx/o7duS8H3f1a4w3BYpIriX4BzIhjkn4teo05cptsxvLesHFKK5KObnadmCHBwGc+51A==", "license": "MIT", - "peer": true, "dependencies": { "@types/eslint-scope": "^3.7.7", "@types/estree": "^1.0.8", diff --git a/bin/build-esp-plant-dev-tools.sh b/bin/build-esp-plant-dev-tools.sh new file mode 100755 index 0000000..35b0a2e --- /dev/null +++ b/bin/build-esp-plant-dev-tools.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env bash + +set -euo pipefail + +CONTAINER_NAME="localhost/esp-plant-dev-tools:latest" +CONTAINER_TOOLS_BASEDIR="$(dirname "$(readlink -f "$0")")" + +pushd "$CONTAINER_TOOLS_BASEDIR" +podman build -t "$CONTAINER_NAME" -f "esp-plant-dev-tools.Containerfile" . +popd diff --git a/bin/esp-plant-dev-tools.Containerfile b/bin/esp-plant-dev-tools.Containerfile new file mode 100644 index 0000000..53a0507 --- /dev/null +++ b/bin/esp-plant-dev-tools.Containerfile @@ -0,0 +1,16 @@ +FROM debian:latest + +RUN apt update -y && apt upgrade -y && apt install unzip curl xz-utils nodejs -y + +RUN cd /root && \ + curl -L -o xpack-riscv-toolchain.tar.gz "https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack/releases/download/v14.2.0-3/xpack-riscv-none-elf-gcc-14.2.0-3-linux-x64.tar.gz" && \ + mkdir xpack-toolchain && \ + tar -xvf xpack-riscv-toolchain.tar.gz -C xpack-toolchain --strip-components=1 && \ + mv xpack-toolchain/bin/* /usr/local/bin && \ + mv xpack-toolchain/lib/ /usr/local && \ + mv xpack-toolchain/lib64/ /usr/local && \ + mv xpack-toolchain/libexec /usr/local && \ + mv xpack-toolchain/riscv-none-elf /usr/local && \ + rm -rf xpack-toolchain xpack-riscv-toolchain.tar.gz + +RUN apt install npm -y diff --git a/bin/npm b/bin/npm new file mode 100755 index 0000000..1b136c8 --- /dev/null +++ b/bin/npm @@ -0,0 +1,29 @@ +#!/usr/bin/env bash + +set -euo pipefail + +CONTAINER_IMAGE="localhost/esp-plant-dev-tools:latest" +CONTAINER_TOOLS_BASEDIR="$(dirname "$(readlink -f "$0")")" +PLANTCTL_PROJECT_DIR="$(readlink -f "$CONTAINER_TOOLS_BASEDIR/..")" + +function _fatal { + echo -e "\e[31mERROR\e[0m $(&2 + exit 1 +} + +declare -a PODMAN_ARGS=( + "--rm" "-i" "--log-driver=none" + "-v" "$PLANTCTL_PROJECT_DIR:$PLANTCTL_PROJECT_DIR:rw" + "-v" "$PWD:$PWD:rw" + "-w" "$PWD" +) + +[[ -t 1 ]] && PODMAN_ARGS+=("-t") + +if ! podman image exists "$CONTAINER_IMAGE"; then + #attempt to build container + "$CONTAINER_TOOLS_BASEDIR/build-esp-plant-dev-tools.sh" 1>&2 || + _fatal "faild to build local image, cannot continue! … please ensure you have an internet connection" +fi + +podman run "${PODMAN_ARGS[@]}" --entrypoint npm "$CONTAINER_IMAGE" "$@" diff --git a/bin/npx b/bin/npx new file mode 100755 index 0000000..70b2ded --- /dev/null +++ b/bin/npx @@ -0,0 +1,29 @@ +#!/usr/bin/env bash + +set -euo pipefail + +CONTAINER_IMAGE="localhost/esp-plant-dev-tools:latest" +CONTAINER_TOOLS_BASEDIR="$(dirname "$(readlink -f "$0")")" +PLANTCTL_PROJECT_DIR="$(readlink -f "$CONTAINER_TOOLS_BASEDIR/..")" + +function _fatal { + echo -e "\e[31mERROR\e[0m $(&2 + exit 1 +} + +declare -a PODMAN_ARGS=( + "--rm" "-i" "--log-driver=none" + "-v" "$PLANTCTL_PROJECT_DIR:$PLANTCTL_PROJECT_DIR:rw" + "-v" "$PWD:$PWD:rw" + "-w" "$PWD" +) + +[[ -t 1 ]] && PODMAN_ARGS+=("-t") + +if ! podman image exists "$CONTAINER_IMAGE"; then + #attempt to build container + "$CONTAINER_TOOLS_BASEDIR/build-esp-plant-dev-tools.sh" 1>&2 || + _fatal "faild to build local image, cannot continue! … please ensure you have an internet connection" +fi + +podman run "${PODMAN_ARGS[@]}" --entrypoint npx "$CONTAINER_IMAGE" "$@" diff --git a/bin/riscv32-unknown-elf-gcc b/bin/riscv32-unknown-elf-gcc new file mode 100755 index 0000000..8998516 --- /dev/null +++ b/bin/riscv32-unknown-elf-gcc @@ -0,0 +1,29 @@ +#!/usr/bin/env bash + +set -euo pipefail + +CONTAINER_IMAGE="localhost/esp-plant-dev-tools:latest" +CONTAINER_TOOLS_BASEDIR="$(dirname "$(readlink -f "$0")")" +PLANTCTL_PROJECT_DIR="$(readlink -f "$CONTAINER_TOOLS_BASEDIR/..")" + +function _fatal { + echo -e "\e[31mERROR\e[0m $(&2 + exit 1 +} + +declare -a PODMAN_ARGS=( + "--rm" "-i" "--log-driver=none" + "-v" "$PLANTCTL_PROJECT_DIR:$PLANTCTL_PROJECT_DIR:rw" + "-v" "$PWD:$PWD:rw" + "-w" "$PWD" +) + +[[ -t 1 ]] && PODMAN_ARGS+=("-t") + +if ! podman image exists "$CONTAINER_IMAGE"; then + #attempt to build container + "$CONTAINER_TOOLS_BASEDIR/build-esp-plant-dev-tools.sh" 1>&2 || + _fatal "faild to build local image, cannot continue! … please ensure you have an internet connection" +fi + +podman run "${PODMAN_ARGS[@]}" --entrypoint riscv-none-elf-gcc "$CONTAINER_IMAGE" "$@" diff --git a/rust/build.rs b/rust/build.rs new file mode 100644 index 0000000..735bf51 --- /dev/null +++ b/rust/build.rs @@ -0,0 +1,124 @@ +use std::{collections::VecDeque, env, process::Command}; + +use vergen::EmitBuilder; + +fn linker_be_nice() { + let args: Vec = std::env::args().collect(); + if args.len() > 1 { + let kind = &args[1]; + let what = &args[2]; + + match kind.as_str() { + "undefined-symbol" => match what.as_str() { + "_defmt_timestamp" => { + eprintln!(); + eprintln!("💡 `defmt` not found - make sure `defmt.x` is added as a linker script and you have included `use defmt_rtt as _;`"); + eprintln!(); + } + "_stack_start" => { + eprintln!(); + eprintln!("💡 Is the linker script `linkall.x` missing?"); + eprintln!(); + } + "esp_wifi_preempt_enable" + | "esp_wifi_preempt_yield_task" + | "esp_wifi_preempt_task_create" => { + eprintln!(); + eprintln!("💡 `esp-wifi` has no scheduler enabled. Make sure you have the `builtin-scheduler` feature enabled, or that you provide an external scheduler."); + eprintln!(); + } + "embedded_test_linker_file_not_added_to_rustflags" => { + eprintln!(); + eprintln!("💡 `embedded-test` not found - make sure `embedded-test.x` is added as a linker script for tests"); + eprintln!(); + } + _ => (), + }, + // we don't have anything helpful for "missing-lib" yet + _ => { + std::process::exit(1); + } + } + + std::process::exit(0); + } + + println!( + "cargo:rustc-link-arg=--error-handling-script={}", + std::env::current_exe().unwrap().display() + ); +} + +fn main() { + if Command::new("podman").arg("--version").output().is_err() { + println!("Could not find `podman` installation, assuming the developer has setup all required tool for build manually! … ") + } + webpack(); + linker_be_nice(); + let _ = EmitBuilder::builder().all_git().all_build().emit(); +} + +fn webpack() { + //println!("cargo:rerun-if-changed=./src/src_webpack"); + Command::new("rm") + .arg("./src/webserver/bundle.js.gz") + .output() + .unwrap(); + + match Command::new("cmd").spawn() { + Ok(_) => { + println!("Assuming build on windows"); + let output = Command::new("cmd") + .arg("/K") + .arg("npx") + .arg("webpack") + .current_dir("./src_webpack") + .output() + .unwrap(); + println!("status: {}", output.status); + println!("stdout: {}", String::from_utf8_lossy(&output.stdout)); + println!("stderr: {}", String::from_utf8_lossy(&output.stderr)); + assert!(output.status.success()); + + // move webpack results to rust webserver src + let _ = Command::new("cmd") + .arg("/K") + .arg("move") + .arg("./src_webpack/bundle.js.gz") + .arg("./src/webserver") + .output() + .unwrap(); + let _ = Command::new("cmd") + .arg("/K") + .arg("move") + .arg("./src_webpack/index.html.gz") + .arg("./src/webserver") + .output() + .unwrap(); + } + Err(_) => { + println!("Assuming build on linux"); + let output = Command::new("npx") + .arg("webpack") + .current_dir("./src_webpack") + .output() + .unwrap(); + println!("status: {}", output.status); + println!("stdout: {}", String::from_utf8_lossy(&output.stdout)); + println!("stderr: {}", String::from_utf8_lossy(&output.stderr)); + assert!(output.status.success()); + + // move webpack results to rust webserver src + let _ = Command::new("mv") + .arg("./src_webpack/bundle.js.gz") + .arg("./src/webserver") + .output() + .unwrap(); + let _ = Command::new("mv") + .arg("./src_webpack/index.html.gz") + .arg("./src/webserver") + .output() + .unwrap(); + } + } +}