-
Notifications
You must be signed in to change notification settings - Fork 87
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #879 from mkroening/xtask-ci
feat(xtask): add ci subcommand
Showing
17 changed files
with
1,436 additions
and
538 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
use std::path::{Path, PathBuf}; | ||
|
||
use clap::Args; | ||
|
||
use crate::arch::Arch; | ||
use crate::archive::Archive; | ||
|
||
#[derive(Args)] | ||
pub struct Artifact { | ||
/// Target architecture. | ||
#[arg(value_enum, long)] | ||
pub arch: Arch, | ||
|
||
/// Directory for all generated artifacts. | ||
#[arg(long, id = "DIRECTORY")] | ||
pub target_dir: Option<PathBuf>, | ||
|
||
/// Build artifacts in release mode, with optimizations. | ||
#[arg(short, long)] | ||
pub release: bool, | ||
|
||
/// Build artifacts with the specified profile. | ||
#[arg(long, id = "PROFILE-NAME")] | ||
pub profile: Option<String>, | ||
} | ||
|
||
impl Artifact { | ||
pub fn profile(&self) -> &str { | ||
self.profile | ||
.as_deref() | ||
.unwrap_or(if self.release { "release" } else { "dev" }) | ||
} | ||
|
||
pub fn profile_path_component(&self) -> &str { | ||
match self.profile() { | ||
"dev" => "debug", | ||
profile => profile, | ||
} | ||
} | ||
|
||
pub fn target_dir(&self) -> &Path { | ||
self.target_dir | ||
.as_deref() | ||
.unwrap_or_else(|| Path::new("target")) | ||
} | ||
|
||
pub fn builtins_archive(&self) -> Archive { | ||
[ | ||
"hermit-builtins".as_ref(), | ||
self.target_dir(), | ||
self.arch.hermit_triple().as_ref(), | ||
"release".as_ref(), | ||
"libhermit_builtins.a".as_ref(), | ||
] | ||
.iter() | ||
.collect::<PathBuf>() | ||
.into() | ||
} | ||
|
||
pub fn build_archive(&self) -> Archive { | ||
[ | ||
self.target_dir(), | ||
self.arch.triple().as_ref(), | ||
self.profile_path_component().as_ref(), | ||
"libhermit.a".as_ref(), | ||
] | ||
.iter() | ||
.collect::<PathBuf>() | ||
.into() | ||
} | ||
|
||
pub fn dist_archive(&self) -> Archive { | ||
[ | ||
self.target_dir(), | ||
self.arch.name().as_ref(), | ||
self.profile_path_component().as_ref(), | ||
"libhermit.a".as_ref(), | ||
] | ||
.iter() | ||
.collect::<PathBuf>() | ||
.into() | ||
} | ||
|
||
pub fn ci_image(&self, package: &str) -> PathBuf { | ||
[ | ||
"..".as_ref(), | ||
self.target_dir(), | ||
self.arch.hermit_triple().as_ref(), | ||
self.profile_path_component().as_ref(), | ||
package.as_ref(), | ||
] | ||
.iter() | ||
.collect() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
use std::env::{self, VarError}; | ||
|
||
use anyhow::Result; | ||
use clap::Args; | ||
use xshell::cmd; | ||
|
||
use crate::cargo_build::{CargoBuild, CmdExt}; | ||
|
||
/// Build the kernel. | ||
#[derive(Args)] | ||
pub struct Build { | ||
#[command(flatten)] | ||
cargo_build: CargoBuild, | ||
|
||
/// Enable the `-Z instrument-mcount` flag. | ||
#[arg(long)] | ||
pub instrument_mcount: bool, | ||
|
||
/// Enable the `-Z randomize-layout` flag. | ||
#[arg(long)] | ||
pub randomize_layout: bool, | ||
} | ||
|
||
impl Build { | ||
pub fn run(self) -> Result<()> { | ||
let sh = crate::sh()?; | ||
|
||
eprintln!("Building kernel"); | ||
cmd!(sh, "cargo build") | ||
.env("CARGO_ENCODED_RUSTFLAGS", self.cargo_encoded_rustflags()?) | ||
.args(self.cargo_build.artifact.arch.cargo_args()) | ||
.cargo_build_args(&self.cargo_build) | ||
.run()?; | ||
|
||
let build_archive = self.cargo_build.artifact.build_archive(); | ||
let dist_archive = self.cargo_build.artifact.dist_archive(); | ||
eprintln!( | ||
"Copying {} to {}", | ||
build_archive.as_ref().display(), | ||
dist_archive.as_ref().display() | ||
); | ||
sh.create_dir(dist_archive.as_ref().parent().unwrap())?; | ||
sh.copy_file(&build_archive, &dist_archive)?; | ||
|
||
eprintln!("Exporting symbols"); | ||
self.export_syms()?; | ||
|
||
eprintln!("Building hermit-builtins"); | ||
cmd!(sh, "cargo build --release") | ||
.arg("--manifest-path=hermit-builtins/Cargo.toml") | ||
.args(self.cargo_build.artifact.arch.builtins_cargo_args()) | ||
.target_dir_args(&self.cargo_build) | ||
.run()?; | ||
|
||
eprintln!("Exporting hermit-builtins symbols"); | ||
let builtins = self.cargo_build.artifact.builtins_archive(); | ||
let builtin_symbols = sh.read_file("hermit-builtins/exports")?; | ||
builtins.retain_symbols(builtin_symbols.lines())?; | ||
|
||
dist_archive.append(&builtins)?; | ||
|
||
eprintln!("Setting OSABI"); | ||
dist_archive.set_osabi()?; | ||
|
||
eprintln!("Kernel available at {}", dist_archive.as_ref().display()); | ||
Ok(()) | ||
} | ||
|
||
fn cargo_encoded_rustflags(&self) -> Result<String> { | ||
let outer_rustflags = match env::var("CARGO_ENCODED_RUSTFLAGS") { | ||
Ok(s) => Some(s), | ||
Err(VarError::NotPresent) => None, | ||
Err(err) => return Err(err.into()), | ||
}; | ||
let mut rustflags = outer_rustflags | ||
.as_deref() | ||
.map(|s| vec![s]) | ||
.unwrap_or_default(); | ||
|
||
// TODO: Re-enable mutable-noalias | ||
// https://github.com/hermitcore/kernel/issues/200 | ||
rustflags.push("-Zmutable-noalias=no"); | ||
|
||
if self.instrument_mcount { | ||
rustflags.push("-Zinstrument-mcount"); | ||
} | ||
|
||
if self.randomize_layout { | ||
rustflags.push("-Zrandomize-layout") | ||
} | ||
|
||
rustflags.extend(self.cargo_build.artifact.arch.rustflags()); | ||
|
||
Ok(rustflags.join("\x1f")) | ||
} | ||
|
||
fn export_syms(&self) -> Result<()> { | ||
let archive = self.cargo_build.artifact.dist_archive(); | ||
|
||
let syscall_symbols = archive.syscall_symbols()?; | ||
let explicit_exports = [ | ||
"_start", | ||
"__bss_start", | ||
"runtime_entry", | ||
// lwIP functions (C runtime) | ||
"init_lwip", | ||
"lwip_read", | ||
"lwip_write", | ||
// lwIP rtl8139 driver | ||
"init_rtl8139_netif", | ||
"irq_install_handler", | ||
"virt_to_phys", | ||
"eoi", | ||
] | ||
.into_iter(); | ||
|
||
let symbols = explicit_exports.chain(syscall_symbols.iter().map(String::as_str)); | ||
|
||
archive.retain_symbols(symbols)?; | ||
|
||
Ok(()) | ||
} | ||
} |
Oops, something went wrong.