facebookexperimental / facebookexperimental/hermit

Link liblzma explicitly when building against Ubuntu libunwind

Open
#53 0 comments 0 reactions 0 assignees View on GitHub
bug
Dominant language
Rust
Stars
1.4k
Forks
50
PR merge metrics
No merged PRs in 30d

Description

## Problem

Hermit fails to link on Ubuntu GitHub runners and on affected Ubuntu developer machines even though the required libunwind package installs successfully.

A representative current failure is [GitHub Actions run 29623210906](https://github.com/facebookexperimental/hermit/actions/runs/29623210906). The linker reports:

```text
rust-lld: error: undefined reference: lzma_stream_buffer_decode
>>> referenced by /usr/lib/x86_64-linux-gnu/libunwind-ptrace.so
>>> disallowed by --no-allow-shlib-undefined
```

The same failure includes `lzma_index_uncompressed_size`, `lzma_index_end`, `lzma_index_buffer_decode`, `lzma_stream_footer_decode`, and `lzma_index_size`.

## Steps to reproduce

On an Ubuntu 24.04 environment matching `ubuntu-latest`:

```bash
sudo apt-get update
sudo apt-get install -y libunwind-dev
cargo build --workspace
```

The `libunwind-dev` installation automatically installs `liblzma-dev`, but the final Hermit link still fails.

## Root cause

The dependency chain is:

```text
hermit -> reverie-ptrace -> unwind -> unwind-sys
```

`unwind-sys 0.1.4` probes `libunwind-ptrace` with `pkg-config`. On the affected Ubuntu runner that contributes:

```text
-lunwind-ptrace -lunwind-generic -lunwind
```

It does not contribute `-llzma`. Ubuntu's `libunwind-ptrace.so` references LZMA symbols, and the nightly Rust toolchain invokes `rust-lld` with `--no-allow-shlib-undefined`, so those transitive references fail the final link.

Installing `liblzma-dev` is a prerequisite but is not sufficient by itself. The original workaround works because it adds the missing library at the final link step:

```bash
RUSTFLAGS="-C link-arg=-llzma" cargo build --workspace
RUSTFLAGS="-C link-arg=-llzma" cargo test --workspace
```

## Proposed fix

Prefer a durable native-link declaration over requiring every user to set `RUSTFLAGS` manually:

- Make the relevant build probe emit an explicit LZMA link dependency when Ubuntu libunwind requires it, ideally in `unwind-sys` or the owning upstream dependency.
- If an upstream fix is not practical, add a narrowly documented repository-level fallback that applies consistently to build, test, and Clippy invocations.
- Keep `liblzma-dev` for Debian/Ubuntu and `xz-devel` for Fedora/CentOS in the documented system prerequisites.
- Validate that an unconditional LZMA link does not regress supported non-Ubuntu Linux environments.

A CI-only environment variable would make Actions green but leave the documented local `cargo build` path broken, so it should be treated as a temporary workaround rather than the final fix.

## Acceptance criteria

- `cargo build --workspace` succeeds on a clean Ubuntu `ubuntu-latest` runner without user-supplied `RUSTFLAGS`.
- `cargo test --workspace` and `cargo clippy --all-targets -- -D warnings` use the same working link configuration.
- GitHub Actions reaches Rust tests instead of failing at the Hermit link step.
- Debian/Ubuntu and Fedora/CentOS prerequisites remain documented and verified.
- The issue is fixed at the narrowest maintainable dependency or repository layer, with a regression check for the generated linker arguments.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.