Skip to content

Add GitHub workflow for cross-compilation and fix build issues for macOS and FreeBSD#636

Open
nohajc wants to merge 3 commits intocontainers:mainfrom
nohajc:main
Open

Add GitHub workflow for cross-compilation and fix build issues for macOS and FreeBSD#636
nohajc wants to merge 3 commits intocontainers:mainfrom
nohajc:main

Conversation

@nohajc
Copy link
Copy Markdown
Contributor

@nohajc nohajc commented Apr 14, 2026

I figured it would be a good idea to run automated builds for our cross-compilation scenarios. So the new pull request workflow tests the following combinations:

  1. macOS host, Linux init
  2. macOS host, FreeBSD init
  3. Linux host, FreeBSD init

Of course I immediately found out my newly merged FreeBSD init port didn't compile, so the fix is included (it was just a broken Makefile rule).

I also tried to fix various issues with building unit tests on macOS which popped up in my VS Code. Most of the changes were suggested by AI with the following explanation:

test_get_supported_cpuid — x86_64-specific, removed entirely
Vm::supported_cpuid() is a KVM concept (fetching the CPUID leaf table the hypervisor supports). HVF on ARM has no such thing. The method doesn't exist on the macOS Vm struct.

test_setup_irqchip — KVM concept, removed entirely
The KVM Vmm had an explicit setup_irqchip() call to configure the in-kernel interrupt controller before vCPUs could be created. HVF doesn't have this: the GIC is set up differently and is not part of Vm. The method simply doesn't exist here.

test_kvm_context — KVM concept, removed entirely
KvmContext is a wrapper around the /dev/kvm file descriptor. HVF has no equivalent — Vm::new(nested_enabled) talks to Hypervisor.framework directly via dlopen. There's nothing to test here.

test_vcpu_kick + test_vcpu_rtsig_offset — signal-based mechanism, removed entirely
On Linux/KVM, to interrupt a vCPU that's running inside KVM_RUN, a real-time signal (SIGRTMIN + offset) is sent to the vCPU thread, and the KVM signal handler sets kvm_run.immediate_exit = 1. The test verified this entire signal delivery path by:

Spawning a thread, starting it in a KVM inner loop
Sending the RTSIG from the outer thread
Checking that kvm_run.immediate_exit was set
On macOS/HVF the entire mechanism is stubbed out — register_kick_signal_handler() is an empty function, KvmRunWrapper doesn't exist on HVF, and vcpu.fd doesn't exist. Interrupting an HVF vCPU is done through hvf::vcpu_request_exit() instead.

test_vm_save_restore_state / test_vcpu_save_restore_state — x86_64 only, gated already
These were already #[cfg(target_arch = "x86_64")] and test KVM save/restore state (PIT, IOAPIC, MSRs, CPUID). None of that exists on the ARM64/HVF path so they just couldn't compile.

What changed inside test_vcpu_tls
The original test had three extra assertions using a run_on_thread_local() method that doesn't exist in this codebase's Vcpu:

    assert!(Vcpu::run_on_thread_local(|_| ()).is_err());
run_on_thread_local was a KVM-era helper that accepted a closure and ran it against the TLS-stored Vcpu pointer. It was never ported to the HVF Vcpu. The simplified version keeps the meaningful assertions — that you can't double-init TLS, that you can reset it, and that you can't reset it twice — while using the methods that actually exist (init_thread_local_data / reset_thread_local_data).

Signed-off-by: Jan Noha <nohajc@gmail.com>
Signed-off-by: Jan Noha <nohajc@gmail.com>
Copy link
Copy Markdown
Contributor Author

@nohajc nohajc Apr 14, 2026

Choose a reason for hiding this comment

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

The runner configuration lets me run unit tests from VS Code editor.

Signed-off-by: Jan Noha <nohajc@gmail.com>
name: Cross-compilation (macOS)
runs-on: macos-latest
env:
DYLD_LIBRARY_PATH: /Library/Developer/CommandLineTools/usr/lib/
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

@slp I had issues building the macOS version which looked like this:
slp/homebrew-krun#14

Setting DYLD_LIBRARY_PATH fixed it for the GitHub action. Maybe the krun_display patch for homebrew is not needed.

</plist>
EOF

codesign --entitlements "$ENTITLEMENTS" --force -s - "$BINARY"
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

You don't need the temp file, you can just do:

Suggested change
codesign --entitlements "$ENTITLEMENTS" --force -s - "$BINARY"
codesign --entitlements /dev/stdin --force -s - "$BINARY" << 'EOF'
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.hypervisor</key>
<true/>
</dict>
</plist>
EOF

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.

2 participants