//! Implementation module //! //! **File:** `build.rs` //! **Author:** Kevin Thomas //! **Date:** 2025 //! //! MIT License //! //! Copyright (c) 2025 Kevin Thomas //! //! Permission is hereby granted, free of charge, to any person obtaining a copy //! of this software and associated documentation files (the "Software"), to deal //! in the Software without restriction, including without limitation the rights //! to use, copy, modify, merge, publish, distribute, sublicense, and/or sell //! copies of the Software, and to permit persons to whom the Software is //! furnished to do so, subject to the following conditions: //! //! The above copyright notice and this permission notice shall be included in //! all copies or substantial portions of the Software. //! //! THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR //! IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, //! FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE //! AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER //! LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, //! OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE //! SOFTWARE. // Import regex::Regex use regex::Regex; // Import dependencies from std::fs use std::fs::{File, read_to_string}; // Import std::io::Write use std::io::Write; // Import std::path::PathBuf use std::path::PathBuf; /// The main entry point. fn main() { let out = PathBuf::from(std::env::var_os("OUT_DIR").unwrap()); let contents = read_to_string(".pico-rs") .unwrap_or_default() .trim() .to_lowercase(); let target = setup_target(&contents, &out); update_cargo_config(&target); write_riscv(&out); print_cfgs(&out); } /// Executes the setup target operation. /// /// # Arguments /// /// * `c` - Command byte. /// * `out` - The `out` parameter. /// /// # Returns /// /// A value of type `String`. fn setup_target(c: &str, out: &PathBuf) -> String { if c == "rp2040" { write_rp2040(out); return "thumbv6m-none-eabi".to_string(); } write_rp2350(out); if c.contains("riscv") { "riscv32imac-unknown-none-elf".to_string() } else { "thumbv8m.main-none-eabihf".to_string() } } /// Executes the write rp2040 operation. /// /// # Arguments /// /// * `out` - The `out` parameter. fn write_rp2040(out: &PathBuf) { File::create(out.join("memory.x")) .unwrap() .write_all(include_bytes!("rp2040.x")) .unwrap(); println!("cargo::rustc-cfg=rp2040"); println!("cargo:rerun-if-changed=rp2040.x"); } /// Executes the write rp2350 operation. /// /// # Arguments /// /// * `out` - The `out` parameter. fn write_rp2350(out: &PathBuf) { File::create(out.join("memory.x")) .unwrap() .write_all(include_bytes!("rp2350.x")) .unwrap(); println!("cargo::rustc-cfg=rp2350"); println!("cargo:rerun-if-changed=rp2350.x"); } /// Executes the update cargo config operation. /// /// # Arguments /// /// * `target` - The `target` parameter. fn update_cargo_config(target: &str) { let re = Regex::new(r"target = .*").unwrap(); let result = re.replace( include_str!(".cargo/config.toml"), format!("target = \"{}\"", target), ); File::create(".cargo/config.toml") .unwrap() .write_all(result.as_bytes()) .unwrap(); } /// Executes the write riscv operation. /// /// # Arguments /// /// * `out` - The `out` parameter. fn write_riscv(out: &PathBuf) { File::create(out.join("rp2350_riscv.x")) .unwrap() .write_all(include_bytes!("rp2350_riscv.x")) .unwrap(); } /// Executes the print cfgs operation. /// /// # Arguments /// /// * `out` - The `out` parameter. fn print_cfgs(out: &PathBuf) { println!("cargo::rustc-check-cfg=cfg(rp2040)"); println!("cargo::rustc-check-cfg=cfg(rp2350)"); println!("cargo:rustc-link-search={}", out.display()); println!("cargo:rerun-if-changed=.pico-rs"); println!("cargo:rerun-if-changed=rp2350_riscv.x"); println!("cargo:rerun-if-changed=build.rs"); }