avr-oxide 0.4.0

An extremely simple Rusty operating system for AVR microcontrollers
/* build.rs
 *
 * Developed by Tim Walls <tim.walls@snowgoons.com>
 * Copyright (c) All Rights Reserved, Tim Walls
 */
//! Build script to shoehorn our assembly files into the build library
use std::env;

fn main() {
  let out_dir = env::var("OUT_DIR").unwrap();

  println!("cargo:rustc-link-search=native={}", out_dir);

  match env::var("CARGO_CFG_TARGET_ARCH").unwrap().as_str() {
    "avr" => {
      if env::var("CARGO_FEATURE_ATMEGA4809").is_ok() {
        build_device_boot(&out_dir, "atmega4809", "avrxmega3");
      }
      if env::var("CARGO_FEATURE_ATMEGA328P").is_ok() {
        build_device_boot(&out_dir, "atmega328p", "atmega328p");
      }
    },
    _ => {
      // If we're not building for AVR, don't try to build the native library
    }
  }

  println!("cargo:rerun-if-changed=build.rs");
}


fn build_device_boot(out_dir: &str, device: &str, arch: &str) {
  use std::path::Path;
  use std::process::Command;

  let srcfile = format!("src/hal/{}/boot.S", device);

  let _result = Command::new("cpp")
    .args(&[&srcfile])
    .arg(&format!("{}/boot.cpp.S", out_dir))
    .output().expect("Boot Preprocessor failed");

  let _result = Command::new("avr-as")
    .args(&[&format!("{}/boot.cpp.S", out_dir),
      &format!("-mmcu={}", arch), "-a",
      "-o"])
    .arg(&format!("{}/oxide-boot-{}.o", out_dir, device))
    .output().expect("Boot Assembly failed");

  let _result = Command::new("avr-ar")
    .args(&["crus",
      &format!("liboxide-boot-{}.a", device),
      &format!("oxide-boot-{}.o", device)])
    .current_dir(&Path::new(out_dir))
    .output().expect("Packaging boot library failed");

  println!("cargo:rustc-link-lib=static=oxide-boot-{}", device);
  println!("cargo:rerun-if-changed=src/hal/{}/boot.S", device);
  println!("cargo:rerun-if-changed=src/hal/{}/context.S", device);
  println!("cargo:rerun-if-changed=src/hal/generic/context.S");
}