Implement the next OSDK

This commit is contained in:
Zhang Junyang
2024-04-13 01:08:36 +08:00
committed by Tate, Hongliang Tian
parent 79bdbbe4f9
commit e4c2151566
41 changed files with 1819 additions and 1466 deletions

View File

@ -14,7 +14,6 @@ use crate::{
bin::{AsterBin, AsterBinType, AsterBzImageMeta, AsterElfMeta},
file::BundleFile,
},
config_manager::action::BootProtocol,
util::get_current_crate_info,
};
@ -22,13 +21,13 @@ pub fn make_install_bzimage(
install_dir: impl AsRef<Path>,
target_dir: impl AsRef<Path>,
aster_elf: &AsterBin,
protocol: &BootProtocol,
linux_x86_legacy_boot: bool,
) -> AsterBin {
let target_name = get_current_crate_info().name;
let image_type = match protocol {
BootProtocol::LinuxLegacy32 => BzImageType::Legacy32,
BootProtocol::LinuxEfiHandover64 => BzImageType::Efi64,
_ => unreachable!(),
let image_type = if linux_x86_legacy_boot {
BzImageType::Legacy32
} else {
BzImageType::Efi64
};
let setup_bin = {
let setup_install_dir = target_dir.as_ref();
@ -60,9 +59,9 @@ pub fn make_install_bzimage(
AsterBin::new(
&install_path,
AsterBinType::BzImage(AsterBzImageMeta {
support_legacy32_boot: matches!(protocol, BootProtocol::LinuxLegacy32),
support_legacy32_boot: linux_x86_legacy_boot,
support_efi_boot: false,
support_efi_handover: matches!(protocol, BootProtocol::LinuxEfiHandover64),
support_efi_handover: !linux_x86_legacy_boot,
}),
aster_elf.version().clone(),
aster_elf.stripped(),

View File

@ -12,7 +12,10 @@ use crate::{
file::BundleFile,
vm_image::{AsterGrubIsoImageMeta, AsterVmImage, AsterVmImageType},
},
config_manager::{action::BootProtocol, BuildConfig},
config::{
scheme::{ActionChoice, BootProtocol},
Config,
},
util::get_current_crate_info,
};
@ -20,11 +23,16 @@ pub fn create_bootdev_image(
target_dir: impl AsRef<Path>,
aster_bin: &AsterBin,
initramfs_path: Option<impl AsRef<Path>>,
config: &BuildConfig,
config: &Config,
action: ActionChoice,
) -> AsterVmImage {
let target_name = get_current_crate_info().name;
let iso_root = &target_dir.as_ref().join("iso_root");
let protocol = &config.settings.boot_protocol;
let action = match &action {
ActionChoice::Run => &config.run,
ActionChoice::Test => &config.test,
};
let protocol = &action.grub.boot_protocol;
// Clear or make the iso dir.
if iso_root.exists() {
@ -43,12 +51,12 @@ pub fn create_bootdev_image(
// Make the kernel image and place it in the boot directory.
match protocol {
Some(BootProtocol::LinuxLegacy32) | Some(BootProtocol::LinuxEfiHandover64) => {
BootProtocol::Linux => {
make_install_bzimage(
iso_root.join("boot"),
&target_dir,
aster_bin,
&protocol.clone().unwrap(),
action.build.linux_x86_legacy_boot,
);
}
_ => {
@ -65,22 +73,17 @@ pub fn create_bootdev_image(
None
};
let grub_cfg = generate_grub_cfg(
&config.settings.combined_kcmd_args().join(" "),
true,
&action.boot.kcmdline.join(" "),
!action.grub.display_grub_menu,
initramfs_in_image,
&protocol.clone().unwrap_or(BootProtocol::Multiboot2),
protocol,
);
let grub_cfg_path = iso_root.join("boot").join("grub").join("grub.cfg");
fs::write(grub_cfg_path, grub_cfg).unwrap();
// Make the boot device CDROM image using `grub-mkrescue`.
let iso_path = &target_dir.as_ref().join(target_name.to_string() + ".iso");
let grub_mkrescue_bin = &config
.settings
.grub_mkrescue
.clone()
.unwrap_or_else(|| PathBuf::from("grub-mkrescue"));
let mut grub_mkrescue_cmd = std::process::Command::new(grub_mkrescue_bin.as_os_str());
let mut grub_mkrescue_cmd = std::process::Command::new(action.grub.grub_mkrescue.as_os_str());
grub_mkrescue_cmd
.arg(iso_root.as_os_str())
.arg("-o")
@ -92,7 +95,7 @@ pub fn create_bootdev_image(
AsterVmImage::new(
iso_path,
AsterVmImageType::GrubIso(AsterGrubIsoImageMeta {
grub_version: get_grub_mkrescue_version(grub_mkrescue_bin),
grub_version: get_grub_mkrescue_version(&action.grub.grub_mkrescue),
}),
aster_bin.version().clone(),
)
@ -115,7 +118,7 @@ fn generate_grub_cfg(
"#GRUB_TIMEOUT_STYLE#",
if skip_grub_menu { "hidden" } else { "menu" },
)
.replace("#GRUB_TIMEOUT#", if skip_grub_menu { "0" } else { "1" });
.replace("#GRUB_TIMEOUT#", if skip_grub_menu { "0" } else { "5" });
// Replace all occurrences of "#KERNEL_COMMAND_LINE#" with the desired value.
let grub_cfg = grub_cfg.replace("#KERNEL_COMMAND_LINE#", kcmdline);
// Replace the grub commands according to the protocol selected.
@ -147,7 +150,7 @@ fn generate_grub_cfg(
"".to_owned()
},
),
BootProtocol::LinuxLegacy32 | BootProtocol::LinuxEfiHandover64 => grub_cfg
BootProtocol::Linux => grub_cfg
.replace("#GRUB_CMD_KERNEL#", "linux")
.replace("#KERNEL#", &aster_bin_path_on_device)
.replace(

View File

@ -3,7 +3,12 @@
mod bin;
mod grub;
use std::{ffi::OsString, path::Path, process};
use std::{
ffi::OsString,
path::{Path, PathBuf},
process,
time::{Duration, SystemTime},
};
use bin::strip_elf_for_qemu;
@ -15,39 +20,53 @@ use crate::{
bin::{AsterBin, AsterBinType, AsterElfMeta},
Bundle,
},
cli::CargoArgs,
config_manager::{action::Bootloader, BuildConfig},
cli::BuildArgs,
config::{
scheme::{ActionChoice, BootMethod},
Config,
},
error::Errno,
error_msg,
util::{get_current_crate_info, get_target_directory},
util::{get_cargo_metadata, get_current_crate_info, get_target_directory},
};
pub fn execute_build_command(config: &BuildConfig) {
let ws_target_directory = get_target_directory();
let osdk_target_directory = ws_target_directory.join(DEFAULT_TARGET_RELPATH);
if !osdk_target_directory.exists() {
std::fs::create_dir_all(&osdk_target_directory).unwrap();
pub fn execute_build_command(config: &Config, build_args: &BuildArgs) {
let cargo_target_directory = get_target_directory();
let osdk_output_directory = build_args
.output
.clone()
.unwrap_or(cargo_target_directory.join(DEFAULT_TARGET_RELPATH));
if !osdk_output_directory.exists() {
std::fs::create_dir_all(&osdk_output_directory).unwrap();
}
let target_info = get_current_crate_info();
let bundle_path = osdk_target_directory.join(target_info.name);
let bundle_path = osdk_output_directory.join(target_info.name);
let _bundle = create_base_and_build(
let action = if build_args.for_test {
ActionChoice::Test
} else {
ActionChoice::Run
};
let _bundle = create_base_and_cached_build(
bundle_path,
&osdk_target_directory,
&ws_target_directory,
&osdk_output_directory,
&cargo_target_directory,
config,
action,
&[],
);
}
pub fn create_base_and_build(
pub fn create_base_and_cached_build(
bundle_path: impl AsRef<Path>,
osdk_target_directory: impl AsRef<Path>,
osdk_output_directory: impl AsRef<Path>,
cargo_target_directory: impl AsRef<Path>,
config: &BuildConfig,
config: &Config,
action: ActionChoice,
rustflags: &[&str],
) -> Bundle {
let base_crate_path = osdk_target_directory.as_ref().join("base");
let base_crate_path = osdk_output_directory.as_ref().join("base");
new_base_crate(
&base_crate_path,
&get_current_crate_info().name,
@ -55,55 +74,108 @@ pub fn create_base_and_build(
);
let original_dir = std::env::current_dir().unwrap();
std::env::set_current_dir(&base_crate_path).unwrap();
let bundle = do_build(
let bundle = do_cached_build(
&bundle_path,
&osdk_target_directory,
&osdk_output_directory,
&cargo_target_directory,
config,
action,
rustflags,
);
std::env::set_current_dir(original_dir).unwrap();
bundle
}
/// If the source is not since modified and the last build is recent, we can reuse the existing bundle.
pub fn do_cached_build(
bundle_path: impl AsRef<Path>,
osdk_output_directory: impl AsRef<Path>,
cargo_target_directory: impl AsRef<Path>,
config: &Config,
action: ActionChoice,
rustflags: &[&str],
) -> Bundle {
let build_a_new_one = || {
do_build(
&bundle_path,
&osdk_output_directory,
&cargo_target_directory,
config,
action,
rustflags,
)
};
let existing_bundle = Bundle::load(&bundle_path);
let Some(existing_bundle) = existing_bundle else {
return build_a_new_one();
};
if existing_bundle.can_run_with_config(config, action).is_err() {
return build_a_new_one();
}
let Ok(built_since) = SystemTime::now().duration_since(existing_bundle.last_modified_time())
else {
return build_a_new_one();
};
if built_since > Duration::from_secs(600) {
return build_a_new_one();
}
let workspace_root = {
let meta = get_cargo_metadata(None::<&str>, None::<&[&str]>).unwrap();
PathBuf::from(meta.get("workspace_root").unwrap().as_str().unwrap())
};
if get_last_modified_time(workspace_root) < existing_bundle.last_modified_time() {
return existing_bundle;
}
build_a_new_one()
}
pub fn do_build(
bundle_path: impl AsRef<Path>,
osdk_target_directory: impl AsRef<Path>,
osdk_output_directory: impl AsRef<Path>,
cargo_target_directory: impl AsRef<Path>,
config: &BuildConfig,
config: &Config,
action: ActionChoice,
rustflags: &[&str],
) -> Bundle {
if bundle_path.as_ref().exists() {
std::fs::remove_dir_all(&bundle_path).unwrap();
}
let mut bundle = Bundle::new(
&bundle_path,
config.settings.clone(),
config.cargo_args.clone(),
);
let mut bundle = Bundle::new(&bundle_path, config, action);
info!("Building kernel ELF");
let aster_elf = build_kernel_elf(
&config.arch,
&config.cargo_args,
&config.target_arch,
&config.build.profile,
&config.build.features[..],
&cargo_target_directory,
rustflags,
);
if matches!(config.settings.bootloader, Some(Bootloader::Qemu)) {
let stripped_elf = strip_elf_for_qemu(&osdk_target_directory, &aster_elf);
bundle.consume_aster_bin(stripped_elf);
}
let boot = match action {
ActionChoice::Run => &config.run.boot,
ActionChoice::Test => &config.test.boot,
};
if matches!(config.settings.bootloader, Some(Bootloader::Grub)) {
info!("Building boot device image");
let bootdev_image = grub::create_bootdev_image(
&osdk_target_directory,
&aster_elf,
config.settings.initramfs.as_ref(),
config,
);
bundle.consume_vm_image(bootdev_image);
match boot.method {
BootMethod::GrubRescueIso => {
info!("Building boot device image");
let bootdev_image = grub::create_bootdev_image(
&osdk_output_directory,
&aster_elf,
boot.initramfs.as_ref(),
config,
action,
);
bundle.consume_vm_image(bootdev_image);
}
BootMethod::QemuDirect => {
let stripped_elf = strip_elf_for_qemu(&osdk_output_directory, &aster_elf);
bundle.consume_aster_bin(stripped_elf);
}
BootMethod::GrubQcow2 => {
todo!()
}
}
bundle
@ -111,7 +183,8 @@ pub fn do_build(
fn build_kernel_elf(
arch: &Arch,
cargo_args: &CargoArgs,
profile: &str,
features: &[String],
cargo_target_directory: impl AsRef<Path>,
rustflags: &[&str],
) -> AsterBin {
@ -135,12 +208,13 @@ fn build_kernel_elf(
command.env_remove("RUSTUP_TOOLCHAIN");
command.env("RUSTFLAGS", rustflags.join(" "));
command.arg("build");
command.arg("--features").arg(features.join(" "));
command.arg("--target").arg(&target_os_string);
command
.arg("--target-dir")
.arg(cargo_target_directory.as_ref());
command.args(COMMON_CARGO_ARGS);
command.arg("--profile=".to_string() + &cargo_args.profile);
command.arg("--profile=".to_string() + profile);
let status = command.status().unwrap();
if !status.success() {
error_msg!("Cargo build failed");
@ -148,10 +222,10 @@ fn build_kernel_elf(
}
let aster_bin_path = cargo_target_directory.as_ref().join(&target_os_string);
let aster_bin_path = if cargo_args.profile == "dev" {
let aster_bin_path = if profile == "dev" {
aster_bin_path.join("debug")
} else {
aster_bin_path.join(&cargo_args.profile)
aster_bin_path.join(profile)
}
.join(get_current_crate_info().name);
@ -167,3 +241,21 @@ fn build_kernel_elf(
false,
)
}
fn get_last_modified_time(path: impl AsRef<Path>) -> SystemTime {
let mut last_modified = SystemTime::UNIX_EPOCH;
for entry in std::fs::read_dir(path).unwrap() {
let entry = entry.unwrap();
if entry.file_name() == "target" {
continue;
}
let metadata = entry.metadata().unwrap();
if metadata.is_dir() {
last_modified = std::cmp::max(last_modified, get_last_modified_time(&entry.path()));
} else {
last_modified = std::cmp::max(last_modified, metadata.modified().unwrap());
}
}
last_modified
}

View File

@ -1,15 +1,13 @@
// SPDX-License-Identifier: MPL-2.0
use crate::commands::util::{bin_file_name, profile_adapter};
use crate::config_manager::DebugConfig;
use crate::commands::util::bin_file_name;
use crate::util::get_target_directory;
use crate::{cli::DebugArgs, util::get_target_directory};
use std::process::Command;
pub fn execute_debug_command(config: &DebugConfig) {
let DebugConfig { cargo_args, remote } = config;
pub fn execute_debug_command(profile: &String, args: &DebugArgs) {
let remote = &args.remote;
let profile = profile_adapter(&cargo_args.profile);
let file_path = get_target_directory()
.join("x86_64-unknown-none")
.join(profile)

View File

@ -19,12 +19,11 @@ use crate::arch::get_default_arch;
/// Execute the forwarded cargo command with args containing the subcommand and its arguments.
pub fn execute_forwarded_command(subcommand: &str, args: &Vec<String>) -> ! {
let mut cargo = util::cargo();
cargo
.arg(subcommand)
.args(util::COMMON_CARGO_ARGS)
.arg("--target")
.arg(get_default_arch().triple())
.args(args);
cargo.arg(subcommand).args(util::COMMON_CARGO_ARGS);
if !args.contains(&"--target".to_owned()) {
cargo.arg("--target").arg(get_default_arch().triple());
}
cargo.args(args);
let status = cargo.status().expect("Failed to execute cargo");
std::process::exit(status.code().unwrap_or(1));
}

View File

@ -1,18 +1,25 @@
[project]
type = "kernel"
project_type = "kernel"
[run]
bootloader = "grub"
ovmf = "/usr/share/OVMF"
qemu_args = [
"-machine q35,kernel-irqchip=split",
"-cpu Icelake-Server,+x2apic",
"--no-reboot",
"-m 2G",
"-nographic",
"-serial chardev:mux",
"-monitor chardev:mux",
"-chardev stdio,id=mux,mux=on,signal=off",
"-display none",
"-device isa-debug-exit,iobase=0xf4,iosize=0x04",
vars = [
["OVMF_PATH", "/usr/share/OVMF"],
]
[boot]
method = "grub-rescue-iso"
[qemu]
args = """\
-machine q35,kernel-irqchip=split \
-cpu Icelake-Server,+x2apic \
--no-reboot \
-m 2G \
-smp 1 \
-nographic \
-serial chardev:mux \
-monitor chardev:mux \
-chardev stdio,id=mux,mux=on,signal=off \
-display none \
-device isa-debug-exit,iobase=0xf4,iosize=0x04 \
-drive if=pflash,format=raw,unit=0,readonly=on,file=$OVMF_PATH/OVMF_CODE.fd \
-drive if=pflash,format=raw,unit=1,file=$OVMF_PATH/OVMF_VARS.fd \
"""

View File

@ -1,17 +1,19 @@
[project]
type = "library"
project_type = "lib"
[test]
bootloader = "qemu"
qemu_args = [
"-machine q35,kernel-irqchip=split",
"-cpu Icelake-Server,+x2apic",
"--no-reboot",
"-m 2G",
"-nographic",
"-serial chardev:mux",
"-monitor chardev:mux",
"-chardev stdio,id=mux,mux=on,signal=off",
"-display none",
"-device isa-debug-exit,iobase=0xf4,iosize=0x04",
]
[boot]
method = "qemu-direct"
[qemu]
args = """\
-machine q35,kernel-irqchip=split \
-cpu Icelake-Server,+x2apic \
--no-reboot \
-m 2G \
-smp 1 \
-nographic \
-serial chardev:mux \
-monitor chardev:mux \
-chardev stdio,id=mux,mux=on,signal=off \
-display none \
-device isa-debug-exit,iobase=0xf4,iosize=0x04 \
"""

View File

@ -4,7 +4,7 @@ use std::{fs, path::PathBuf, process, str::FromStr};
use crate::{
cli::NewArgs,
config_manager::manifest::ProjectType,
config::manifest::ProjectType,
error::Errno,
error_msg,
util::{aster_crate_dep, cargo_new_lib, get_cargo_metadata},

View File

@ -1,19 +1,14 @@
// SPDX-License-Identifier: MPL-2.0
use std::{
path::{Path, PathBuf},
time::{Duration, SystemTime},
};
use super::{build::create_base_and_build, util::DEFAULT_TARGET_RELPATH};
use super::{build::create_base_and_cached_build, util::DEFAULT_TARGET_RELPATH};
use crate::{
bundle::Bundle,
config_manager::{BuildConfig, RunConfig},
util::{get_cargo_metadata, get_current_crate_info, get_target_directory},
cli::GdbServerArgs,
config::{scheme::ActionChoice, Config},
util::{get_current_crate_info, get_target_directory},
};
pub fn execute_run_command(config: &RunConfig) {
if config.gdb_server_args.is_gdb_enabled {
pub fn execute_run_command(config: &Config, gdb_server_args: &GdbServerArgs) {
if gdb_server_args.is_gdb_enabled {
use std::env;
env::set_var(
"RUSTFLAGS",
@ -21,111 +16,48 @@ pub fn execute_run_command(config: &RunConfig) {
);
}
let ws_target_directory = get_target_directory();
let osdk_target_directory = ws_target_directory.join(DEFAULT_TARGET_RELPATH);
let cargo_target_directory = get_target_directory();
let osdk_output_directory = cargo_target_directory.join(DEFAULT_TARGET_RELPATH);
let target_name = get_current_crate_info().name;
let default_bundle_directory = osdk_target_directory.join(target_name);
let existing_bundle = Bundle::load(&default_bundle_directory);
let config = RunConfig {
settings: {
if config.gdb_server_args.is_gdb_enabled {
let qemu_gdb_args: Vec<_> = {
let gdb_stub_addr = config.gdb_server_args.gdb_server_addr.as_str();
match gdb::stub_type_of(gdb_stub_addr) {
gdb::StubAddrType::Unix => {
let chardev = format!(
"-chardev socket,path={},server=on,wait=off,id=gdb0",
gdb_stub_addr
);
let stub = "-gdb chardev:gdb0".to_owned();
vec![chardev, stub, "-S".into()]
}
gdb::StubAddrType::Tcp => {
vec![
format!(
"-gdb tcp:{}",
gdb::tcp_addr_util::format_tcp_addr(gdb_stub_addr)
),
"-S".into(),
]
}
}
};
let qemu_gdb_args: Vec<_> = qemu_gdb_args
.into_iter()
.filter(|arg| !config.settings.qemu_args.iter().any(|x| x == arg))
.map(|x| x.to_string())
.collect();
let mut settings = config.settings.clone();
settings.qemu_args.extend(qemu_gdb_args);
settings
} else {
config.settings.clone()
}
},
..config.clone()
};
let _vsc_launch_file = config.gdb_server_args.vsc_launch_file.then(|| {
vsc::check_gdb_config(&config.gdb_server_args);
let profile = super::util::profile_adapter(&config.cargo_args.profile);
vsc::VscLaunchConfig::new(profile, &config.gdb_server_args.gdb_server_addr)
});
// If the source is not since modified and the last build is recent, we can reuse the existing bundle.
if let Some(existing_bundle) = existing_bundle {
if existing_bundle.can_run_with_config(&config) {
if let Ok(built_since) =
SystemTime::now().duration_since(existing_bundle.last_modified_time())
{
if built_since < Duration::from_secs(600) {
let workspace_root = {
let meta = get_cargo_metadata(None::<&str>, None::<&[&str]>).unwrap();
PathBuf::from(meta.get("workspace_root").unwrap().as_str().unwrap())
};
if get_last_modified_time(workspace_root) < existing_bundle.last_modified_time()
{
existing_bundle.run(&config);
return;
}
let mut config = config.clone();
if gdb_server_args.is_gdb_enabled {
let qemu_gdb_args = {
let gdb_stub_addr = gdb_server_args.gdb_server_addr.as_str();
match gdb::stub_type_of(gdb_stub_addr) {
gdb::StubAddrType::Unix => {
format!(
" -chardev socket,path={},server=on,wait=off,id=gdb0 -gdb chardev:gdb0 -S",
gdb_stub_addr
)
}
gdb::StubAddrType::Tcp => {
format!(
" -gdb tcp:{} -S",
gdb::tcp_addr_util::format_tcp_addr(gdb_stub_addr)
)
}
}
}
};
config.run.qemu.args += &qemu_gdb_args;
}
let _vsc_launch_file = gdb_server_args.vsc_launch_file.then(|| {
vsc::check_gdb_config(gdb_server_args);
let profile = super::util::profile_adapter(&config.build.profile);
vsc::VscLaunchConfig::new(profile, &gdb_server_args.gdb_server_addr)
});
let required_build_config = BuildConfig {
arch: config.arch,
settings: config.settings.clone(),
cargo_args: config.cargo_args.clone(),
};
let bundle = create_base_and_build(
let default_bundle_directory = osdk_output_directory.join(target_name);
let bundle = create_base_and_cached_build(
default_bundle_directory,
&osdk_target_directory,
&ws_target_directory,
&required_build_config,
&osdk_output_directory,
&cargo_target_directory,
&config,
ActionChoice::Run,
&[],
);
bundle.run(&config);
}
fn get_last_modified_time(path: impl AsRef<Path>) -> SystemTime {
let mut last_modified = SystemTime::UNIX_EPOCH;
for entry in std::fs::read_dir(path).unwrap() {
let entry = entry.unwrap();
if entry.file_name() == "target" {
continue;
}
let metadata = entry.metadata().unwrap();
if metadata.is_dir() {
last_modified = std::cmp::max(last_modified, get_last_modified_time(&entry.path()));
} else {
last_modified = std::cmp::max(last_modified, metadata.modified().unwrap());
}
}
last_modified
bundle.run(&config, ActionChoice::Run);
}
mod gdb {

View File

@ -2,38 +2,38 @@
use std::fs;
use super::{build::do_build, util::DEFAULT_TARGET_RELPATH};
use super::{build::do_cached_build, util::DEFAULT_TARGET_RELPATH};
use crate::{
base_crate::new_base_crate,
cli::GdbServerArgs,
config_manager::{BuildConfig, RunConfig, TestConfig},
cli::TestArgs,
config::{scheme::ActionChoice, Config},
util::{get_cargo_metadata, get_current_crate_info, get_target_directory},
};
pub fn execute_test_command(config: &TestConfig) {
pub fn execute_test_command(config: &Config, args: &TestArgs) {
let crates = get_workspace_default_members();
for crate_path in crates {
std::env::set_current_dir(crate_path).unwrap();
test_current_crate(config);
test_current_crate(config, args);
}
}
pub fn test_current_crate(config: &TestConfig) {
pub fn test_current_crate(config: &Config, args: &TestArgs) {
let current_crate = get_current_crate_info();
let ws_target_directory = get_target_directory();
let osdk_target_directory = ws_target_directory.join(DEFAULT_TARGET_RELPATH);
let target_crate_dir = osdk_target_directory.join("base");
let cargo_target_directory = get_target_directory();
let osdk_output_directory = cargo_target_directory.join(DEFAULT_TARGET_RELPATH);
let target_crate_dir = osdk_output_directory.join("base");
new_base_crate(&target_crate_dir, &current_crate.name, &current_crate.path);
let main_rs_path = target_crate_dir.join("src").join("main.rs");
let ktest_test_whitelist = match &config.test_name {
let ktest_test_whitelist = match &args.test_name {
Some(name) => format!(r#"Some(&["{}"])"#, name),
None => r#"None"#.to_string(),
};
let mut ktest_crate_whitelist = vec![current_crate.name];
if let Some(name) = &config.test_name {
if let Some(name) = &args.test_name {
ktest_crate_whitelist.push(name.clone());
}
@ -54,32 +54,21 @@ pub static KTEST_CRATE_WHITELIST: Option<&[&str]> = Some(&{:#?});
// Build the kernel with the given base crate
let target_name = get_current_crate_info().name;
let default_bundle_directory = osdk_target_directory.join(target_name);
let required_build_config = BuildConfig {
arch: config.arch,
settings: config.settings.clone(),
cargo_args: config.cargo_args.clone(),
};
let default_bundle_directory = osdk_output_directory.join(target_name);
let original_dir = std::env::current_dir().unwrap();
std::env::set_current_dir(&target_crate_dir).unwrap();
let bundle = do_build(
let bundle = do_cached_build(
default_bundle_directory,
&osdk_target_directory,
&ws_target_directory,
&required_build_config,
&osdk_output_directory,
&cargo_target_directory,
config,
ActionChoice::Test,
&["--cfg ktest"],
);
std::env::remove_var("RUSTFLAGS");
std::env::set_current_dir(original_dir).unwrap();
let required_run_config = RunConfig {
arch: config.arch,
settings: required_build_config.settings.clone(),
cargo_args: required_build_config.cargo_args.clone(),
gdb_server_args: GdbServerArgs::default(),
};
bundle.run(&required_run_config);
bundle.run(config, ActionChoice::Test);
}
fn get_workspace_default_members() -> Vec<String> {