Skip to content

Add aarch64 support#32

Draft
ludfjig wants to merge 6 commits into
hyperlight-dev:mainfrom
ludfjig:aarch64
Draft

Add aarch64 support#32
ludfjig wants to merge 6 commits into
hyperlight-dev:mainfrom
ludfjig:aarch64

Conversation

@ludfjig
Copy link
Copy Markdown
Contributor

@ludfjig ludfjig commented Mar 10, 2026

Adds support for compiling aarch64, with some fixes for cross compiling from x86_64 as well

@ludfjig ludfjig force-pushed the aarch64 branch 3 times, most recently from 04c7534 to ddedf1c Compare March 10, 2026 18:39
ludfjig and others added 6 commits May 26, 2026 19:12
canonicalize() resolves the cargo -> rustup symlink, causing
commands like 'cargo rustc' to be invoked as 'rustup rustc'
which doesn't understand cargo-specific arguments.

Signed-off-by: Ludvig Liljenberg <4257730+ludfjig@users.noreply.github.com>
Signed-off-by: Lucy Menon <168595099+syntactically@users.noreply.github.com>
User CLI args like --target aarch64-unknown-none were passed
through to the final cargo build command, overriding the
resolved CARGO_BUILD_TARGET env var set by populate_from_args.
Filter these out since the resolved hyperlight target is set
via environment variable.

Signed-off-by: Ludvig Liljenberg <4257730+ludfjig@users.noreply.github.com>
Signed-off-by: Lucy Menon <168595099+syntactically@users.noreply.github.com>
- Add aarch64-hyperlight-none target spec derived from
  aarch64-unknown-none with hyperlight customizations
- Select correct musl arch headers (aarch64 vs x86_64)
- Use appropriate clang --target for aarch64
- Make -mno-red-zone x86_64-only (aarch64 has no red zone)
- Fix get_spec to pass --target as CLI arg instead of env var

Signed-off-by: Ludvig Liljenberg <4257730+ludfjig@users.noreply.github.com>
Signed-off-by: Lucy Menon <168595099+syntactically@users.noreply.github.com>
- Add concurrency group to cancel stale CI runs
- Gate KVM setup on X64 runners
- Gate run-guest on X64 (no host support on ARM yet)
- Update README to mention aarch64 target
- Use arch() in justfile for target-independent paths

Signed-off-by: Ludvig Liljenberg <4257730+ludfjig@users.noreply.github.com>
Signed-off-by: Lucy Menon <168595099+syntactically@users.noreply.github.com>
aarch64: improve rust target json:
- Set a relocation model that makes it easier for our loader
- Compile for Armv8.1-A, since we likely don't care about older
  machines, and this allows us to use FEAT_LSE.

Signed-off-by: Lucy Menon <168595099+syntactically@users.noreply.github.com>
Fix a Rust warning, hopefully fixing CI.

Signed-off-by: Lucy Menon <168595099+syntactically@users.noreply.github.com>
@syntactically
Copy link
Copy Markdown
Member

@ludfjig I rebased this PR and added some minor fixes used by the main hyperlight PR.

Looks like CI is passing, so hopefully we can merge that soon.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds support for building Hyperlight guest binaries targeting aarch64-hyperlight-none, and adjusts argument forwarding / toolchain behavior to improve cross-compilation correctness.

Changes:

  • Add a new aarch64-hyperlight-none Rust target spec derived from aarch64-unknown-none, and update target-spec generation to pass --target explicitly.
  • Adjust clang/cflags generation to use an aarch64 --target and make -mno-red-zone x86_64-only.
  • Improve cargo invocation behavior by avoiding canonicalize() on the cargo path and filtering --target / --target-dir from forwarded CLI args; update docs/CI/justfile for multi-arch support.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/toolchain.rs Adds aarch64-aware clang target selection and changes libc header preparation logic.
src/sysroot.rs Introduces aarch64-hyperlight-none target-spec customization and adjusts how base target specs are queried.
src/command.rs Filters --target / --target-dir from forwarded args to avoid overriding resolved env-based target settings.
src/cargo_cmd.rs Stops canonicalizing the cargo binary path to avoid resolving rustup symlinks.
README.md Documents default target selection on ARM and updates output path description.
justfile Uses arch() to make the guest path target-arch independent.
.github/workflows/ci.yml Adds concurrency cancellation and gates KVM / guest execution based on runner architecture.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/toolchain.rs
Comment on lines +77 to +104
if !args.target.starts_with("aarch64") {
// Detect which libc variant is present: picolibc or legacy musl
let include_dirs: &[&str] = &[
// directories for musl
"third_party/printf/",
"third_party/musl/include",
"third_party/musl/arch/generic",
"third_party/musl/arch/x86_64",
"third_party/musl/src/internal",
// directories for picolibc
"third_party/picolibc/libc/include",
"third_party/picolibc/libc/stdio",
"include",
];

for dir in include_dirs {
let include_src_dir = libc_dir.join(dir);
let files = glob::glob(&format!("{}/**/*.h", include_src_dir.display()))
.context("Failed to read include source directory")?;
for file in files {
let src = file.context("Failed to read include source file")?;
let dst = src.strip_prefix(&include_src_dir).unwrap();
let dst = include_dst_dir.join(dst);

std::fs::create_dir_all(dst.parent().unwrap())
.context("Failed to create include subdirectory")?;
std::fs::copy(&src, &dst).context("Failed to copy include file")?;
}
Comment thread src/command.rs
Comment on lines +535 to +544
let mut skip_next = false;
for arg in args.iter() {
if skip_next {
skip_next = false;
continue;
}
let arg_str = arg.to_string_lossy();
if arg_str == "--target" || arg_str == "--target-dir" {
skip_next = true; // skip the next arg (the value)
continue;
Comment thread src/cargo_cmd.rs
Comment on lines 49 to 53
pub fn find_cargo() -> Result<CargoBinary> {
let cargo = match env::var_os("CARGO") {
Some(cargo) => Path::new(&cargo).canonicalize()?,
None => which::which("cargo")?.canonicalize()?,
Some(cargo) => PathBuf::from(cargo),
None => which::which("cargo")?,
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants