Files
yggdrasil/xtask/src/build/cargo.rs
T

232 lines
7.8 KiB
Rust

use std::{ffi::OsStr, path::Path, process::Command};
use crate::{
env::{BuildEnv, Profile},
error::Error,
};
// #[derive(Debug, Clone, Deserialize)]
// pub struct ModuleDependency {
// pub version: Option<semver::VersionReq>,
// pub path: PathBuf,
// }
// #[derive(Debug, Deserialize)]
// pub struct ModuleManifest {
// pub name: String,
// pub version: semver::Version,
// #[serde(default)]
// pub dependencies: HashMap<String, ModuleDependency>,
// }
// #[derive(Debug)]
// pub struct ModuleInfo {
// pub dependencies: Vec<(String, String, ModuleDependency)>,
// pub module_dir_name: PathBuf,
// pub manifest_dir: PathBuf,
// pub manifest: ModuleManifest,
// }
pub enum CargoBuilder<'e> {
Host(bool),
Userspace(&'e BuildEnv),
Ygglibc(&'e BuildEnv),
Kernel(&'e BuildEnv),
// Module(&'e BuildEnv, &'e ModuleInfo),
}
impl<'e> CargoBuilder<'e> {
fn make_command<P: AsRef<Path>, S: AsRef<OsStr>>(
self,
dir: P,
arg: S,
) -> Result<Command, Error> {
let arg = arg.as_ref();
let mut command = Command::new("cargo");
command.current_dir(dir);
match self {
Self::Userspace(env) => {
// Add clippy dependency libraries to LD_LIBRARY_PATH
let toolchain_libs_path = env
.workspace_root
.join("toolchain/build")
.join(&env.host_triple)
.join("stage1/lib/rustlib")
.join(&env.host_triple)
.join("lib");
let ld_library_path = std::env::var("LD_LIBRARY_PATH");
let ld_library_path = match ld_library_path {
Ok(path) => format!("{}:{}", toolchain_libs_path.display(), path),
Err(_) => toolchain_libs_path.display().to_string(),
};
command.env("LD_LIBRARY_PATH", ld_library_path);
command
.arg("+ygg-stage1")
.arg(arg)
.arg(&format!("--target={}", env.arch.user_triple()));
if env.verbose {
command.arg("-v");
}
if env.profile == Profile::Release {
command.arg("--release");
}
}
Self::Ygglibc(env) => {
let target = format!(
"{}/{:?}-unknown-none.json",
env.workspace_root
.join("userspace/lib/ygglibc/etc")
.display(),
env.arch
);
let build_std_features = "compiler-builtins".to_owned();
// let build_std_features =
// "compiler-builtins-mangled-names,compiler-builtins-mem".to_owned();
command
.arg(arg)
.arg("-Zbuild-std=core,alloc")
.arg(&format!("-Zbuild-std-features={build_std_features}"))
.arg(&format!("--target={target}"));
if env.verbose {
command.arg("-v");
}
if env.profile == Profile::Release {
command.arg("--release");
}
}
Self::Host(verbose) => {
command.arg("+nightly").arg(arg);
if verbose {
command.arg("-v");
}
}
Self::Kernel(env) => {
command.env(
"RUSTFLAGS",
format!(
"-C link-arg=-T{}/etc/ld/{}.ld",
env.workspace_root.display(),
env.kernel_triple
),
);
command.arg("+nightly").arg(arg);
if env.verbose {
command.arg("-v");
}
command.arg(format!(
"--target={}/etc/{}.json",
env.workspace_root.display(),
env.kernel_triple
));
command.args([
"-Z",
"build-std=core,alloc,compiler_builtins",
"-Zjson-target-spec",
"-Zunstable-options",
]);
if env.profile == Profile::Release {
command.arg("--release");
}
} // Self::Module(env, module) => {
// let mut lib_paths = vec![];
// let mut extern_libs = vec![];
// let mut dependency_list = String::new();
// for (i, (name, dep)) in module.manifest.dependencies.iter().enumerate() {
// if i != 0 {
// dependency_list.push(':');
// }
// let dep_path = module.manifest_dir.join(&dep.path).canonicalize()?;
// let output_dir = dep_path.join(format!(
// "target/{}/{}",
// env.kernel_triple,
// env.profile.name()
// ));
// let dependency_so = output_dir.join(format!("lib{}.so", name));
// lib_paths.push(output_dir.join("deps"));
// lib_paths.push(output_dir.clone());
// lib_paths.push(dep_path.join(format!("target/{}/deps", env.profile.name())));
// dependency_list.push_str(&format!("{}={}", name, dependency_so.display()));
// extern_libs.push((name.clone(), dependency_so));
// }
// lib_paths.push(env.kernel_output_dir.join("deps"));
// lib_paths.push(env.kernel_output_dir.clone());
// lib_paths.push(
// env.workspace_root
// .join(format!("target/{}/deps", env.profile.name())),
// );
// extern_libs.push(("libk".into(), env.kernel_output_dir.join("liblibk.so")));
// let mut rust_flags = Vec::new();
// for lib_path in lib_paths {
// rust_flags.push(format!("-L{}", lib_path.display()));
// }
// for (lib, path) in extern_libs {
// rust_flags.push(format!("--extern {}={}", lib, path.display()));
// }
// rust_flags.push("-Cprefer-dynamic".into());
// command.env("RUSTFLAGS", rust_flags.join(" "));
// command.env("MOD_DEPENDENCIES", dependency_list);
// command.env("MOD_LIBK_SO", env.kernel_output_dir.join("liblibk.so"));
// command.arg("+nightly").arg(arg);
// if env.verbose {
// command.arg("-v");
// }
// let target_spec_arg = format!(
// "--target={}/etc/{}.json",
// env.workspace_root.display(),
// env.kernel_triple
// );
// command.arg(target_spec_arg);
// if env.profile == Profile::Release {
// command.arg("--release");
// }
// }
}
Ok(command)
}
pub fn run<P: AsRef<Path>, S: AsRef<OsStr>>(self, dir: P, arg: S) -> Result<(), Error> {
let mut command = self.make_command(dir, arg)?;
log::trace!("Run cargo: {:?}", command);
let status = command.status()?;
if status.success() {
Ok(())
} else {
Err(Error::CargoFailed)
}
}
pub fn build<P: AsRef<Path>>(self, dir: P) -> Result<(), Error> {
self.run(dir, "build")
}
}