Skip to content

Commit

Permalink
Merge pull request #879 from mkroening/xtask-ci
Browse files Browse the repository at this point in the history
feat(xtask): add ci subcommand
mkroening authored Sep 11, 2023
2 parents 9a66a9c + f91f321 commit a2656ce
Showing 17 changed files with 1,436 additions and 538 deletions.
239 changes: 48 additions & 191 deletions .github/workflows/ci.yml

Large diffs are not rendered by default.

561 changes: 544 additions & 17 deletions Cargo.lock

Large diffs are not rendered by default.

13 changes: 0 additions & 13 deletions fc-config.json

This file was deleted.

5 changes: 4 additions & 1 deletion xtask/Cargo.toml
Original file line number Diff line number Diff line change
@@ -5,7 +5,10 @@ edition = "2021"

[dependencies]
anyhow = "1.0"
clap = { version = "4", features = ["derive"] }
goblin = { version = "0.7", default-features = false, features = ["archive", "elf32", "elf64", "std"] }
llvm-tools = "0.1"
xflags = "0.3"
sysinfo = "0.29"
ureq = "2"
wait-timeout = "0.2"
xshell = "0.2"
47 changes: 25 additions & 22 deletions xtask/src/arch.rs
Original file line number Diff line number Diff line change
@@ -1,32 +1,34 @@
use std::str::FromStr;
use clap::ValueEnum;

use anyhow::anyhow;

#[derive(Clone, Copy, PartialEq, Eq, Debug)]
/// Target architecture.
#[derive(ValueEnum, Clone, Copy, PartialEq, Eq, Debug)]
#[value(rename_all = "snake_case")]
pub enum Arch {
/// x86-64
X86_64,
AArch64,
/// AArch64
Aarch64,
}

impl Arch {
pub fn name(&self) -> &'static str {
match self {
Self::X86_64 => "x86_64",
Self::AArch64 => "aarch64",
Self::Aarch64 => "aarch64",
}
}

pub fn triple(&self) -> &'static str {
match self {
Self::X86_64 => "x86_64-unknown-none",
Self::AArch64 => "aarch64-unknown-none-softfloat",
Self::Aarch64 => "aarch64-unknown-none-softfloat",
}
}

pub fn hermit_triple(&self) -> &'static str {
match self {
Arch::X86_64 => "x86_64-unknown-hermit",
Arch::AArch64 => "aarch64-unknown-hermit",
Arch::Aarch64 => "aarch64-unknown-hermit",
}
}

@@ -37,7 +39,7 @@ impl Arch {
"-Zbuild-std=core",
"-Zbuild-std-features=compiler-builtins-mem",
],
Arch::AArch64 => &[
Arch::Aarch64 => &[
"--target=aarch64-unknown-hermit",
"-Zbuild-std=core",
"-Zbuild-std-features=compiler-builtins-mem",
@@ -48,7 +50,7 @@ impl Arch {
pub fn cargo_args(&self) -> &'static [&'static str] {
match self {
Self::X86_64 => &["--target=x86_64-unknown-none"],
Self::AArch64 => &[
Self::Aarch64 => &[
"--target=aarch64-unknown-none-softfloat",
// We can't use prebuilt std for aarch64 because it is built with
// relocation-model=static and we need relocation-model=pic
@@ -58,22 +60,23 @@ impl Arch {
}
}

pub fn rustflags(&self) -> &'static [&'static str] {
pub fn ci_cargo_args(&self) -> &'static [&'static str] {
match self {
Self::X86_64 => &[],
Self::AArch64 => &["-Crelocation-model=pic"],
Arch::X86_64 => &[
"--target=x86_64-unknown-hermit",
"-Zbuild-std=std,panic_abort",
],
Arch::Aarch64 => &[
"--target=aarch64-unknown-hermit",
"-Zbuild-std=std,panic_abort",
],
}
}
}

impl FromStr for Arch {
type Err = anyhow::Error;

fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"x86_64" => Ok(Self::X86_64),
"aarch64" => Ok(Self::AArch64),
s => Err(anyhow!("Unsupported arch: {s}")),
pub fn rustflags(&self) -> &'static [&'static str] {
match self {
Self::X86_64 => &[],
Self::Aarch64 => &["-Crelocation-model=pic"],
}
}
}
95 changes: 95 additions & 0 deletions xtask/src/artifact.rs
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()
}
}
123 changes: 123 additions & 0 deletions xtask/src/build.rs
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(())
}
}
Loading

0 comments on commit a2656ce

Please sign in to comment.