2024-04-01 17:23:12 +03:00
|
|
|
use std::{
|
|
|
|
collections::HashMap,
|
|
|
|
ffi::OsStr,
|
|
|
|
path::{Path, PathBuf},
|
|
|
|
process::Command,
|
|
|
|
};
|
|
|
|
|
|
|
|
use serde::Deserialize;
|
2024-03-12 18:17:47 +02:00
|
|
|
|
|
|
|
use crate::{
|
2024-11-18 19:34:24 +02:00
|
|
|
env::{Arch, BuildEnv, Profile},
|
2024-03-12 18:17:47 +02:00
|
|
|
error::Error,
|
|
|
|
};
|
|
|
|
|
2024-04-01 17:23:12 +03:00
|
|
|
#[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,
|
|
|
|
}
|
|
|
|
|
2024-03-12 18:17:47 +02:00
|
|
|
pub enum CargoBuilder<'e> {
|
2024-03-20 21:21:39 +02:00
|
|
|
Host(bool),
|
2024-03-12 18:17:47 +02:00
|
|
|
Userspace(&'e BuildEnv),
|
2024-11-11 15:19:36 +02:00
|
|
|
Ygglibc(&'e BuildEnv),
|
2024-03-12 18:17:47 +02:00
|
|
|
Kernel(&'e BuildEnv),
|
2024-04-01 17:23:12 +03:00
|
|
|
Module(&'e BuildEnv, &'e ModuleInfo),
|
2024-03-12 18:17:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
impl<'e> CargoBuilder<'e> {
|
|
|
|
pub fn run<P: AsRef<Path>, S: AsRef<OsStr>>(self, dir: P, arg: S) -> Result<(), Error> {
|
|
|
|
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()));
|
|
|
|
|
2024-03-20 21:21:39 +02:00
|
|
|
if env.verbose {
|
|
|
|
command.arg("-v");
|
|
|
|
}
|
|
|
|
|
2024-03-12 18:17:47 +02:00
|
|
|
if env.profile == Profile::Release {
|
|
|
|
command.arg("--release");
|
|
|
|
}
|
|
|
|
}
|
2024-11-11 15:19:36 +02:00
|
|
|
Self::Ygglibc(env) => {
|
2024-11-12 17:07:06 +02:00
|
|
|
let target = format!(
|
|
|
|
"{}/{:?}-unknown-none.json",
|
|
|
|
env.workspace_root
|
|
|
|
.join("userspace/lib/ygglibc/etc")
|
|
|
|
.display(),
|
|
|
|
env.arch
|
|
|
|
);
|
2024-11-18 19:34:24 +02:00
|
|
|
let mut build_std_features =
|
|
|
|
"compiler-builtins-mangled-names,compiler-builtins-mem".to_owned();
|
|
|
|
if env.arch == Arch::i686 {
|
|
|
|
build_std_features += ",compiler-builtins-no-f16-f128";
|
|
|
|
}
|
2024-11-11 15:19:36 +02:00
|
|
|
|
|
|
|
command
|
|
|
|
.arg(arg)
|
2024-11-13 15:58:29 +02:00
|
|
|
.arg("-Zbuild-std=core,alloc")
|
2024-11-18 19:34:24 +02:00
|
|
|
.arg(&format!("-Zbuild-std-features={build_std_features}"))
|
2024-11-11 15:19:36 +02:00
|
|
|
.arg(&format!("--target={target}"));
|
|
|
|
|
|
|
|
if env.verbose {
|
|
|
|
command.arg("-v");
|
|
|
|
}
|
|
|
|
|
|
|
|
if env.profile == Profile::Release {
|
|
|
|
command.arg("--release");
|
|
|
|
}
|
|
|
|
}
|
2024-03-20 21:21:39 +02:00
|
|
|
Self::Host(verbose) => {
|
2024-03-12 18:17:47 +02:00
|
|
|
command.arg("+nightly").arg(arg);
|
2024-03-20 21:21:39 +02:00
|
|
|
|
|
|
|
if verbose {
|
|
|
|
command.arg("-v");
|
|
|
|
}
|
2024-03-12 18:17:47 +02:00
|
|
|
}
|
|
|
|
Self::Kernel(env) => {
|
2024-04-01 17:23:12 +03:00
|
|
|
command.env(
|
|
|
|
"RUSTFLAGS",
|
|
|
|
format!(
|
|
|
|
"-C link-arg=-T{}/etc/{}.ld",
|
|
|
|
env.workspace_root.display(),
|
|
|
|
env.arch.kernel_triple()
|
|
|
|
),
|
|
|
|
);
|
2024-03-12 18:17:47 +02:00
|
|
|
command.arg("+nightly").arg(arg);
|
|
|
|
|
2024-03-20 21:21:39 +02:00
|
|
|
if env.verbose {
|
|
|
|
command.arg("-v");
|
|
|
|
}
|
|
|
|
|
2024-03-12 18:17:47 +02:00
|
|
|
let target_spec_arg = format!(
|
|
|
|
"--target={}/etc/{}.json",
|
|
|
|
env.workspace_root.display(),
|
|
|
|
env.arch.kernel_triple()
|
|
|
|
);
|
|
|
|
|
|
|
|
command.arg(target_spec_arg);
|
|
|
|
command.args(["-Z", "build-std=core,alloc,compiler_builtins"]);
|
|
|
|
|
2024-04-01 17:23:12 +03:00
|
|
|
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.arch.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.arch.kernel_triple()
|
|
|
|
);
|
|
|
|
|
|
|
|
command.arg(target_spec_arg);
|
|
|
|
|
2024-03-12 18:17:47 +02:00
|
|
|
if env.profile == Profile::Release {
|
|
|
|
command.arg("--release");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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")
|
|
|
|
}
|
|
|
|
}
|