Build natively on the development Orin
Two units with different jobs: one builds and runs CI, the other is the deployment target. Building on the target architecture makes the glibc constraint structural rather than configured. The remaining risk is version parity between the two units, not architecture. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013kj58Jugkic783b8ZrtTVZ
This commit is contained in:
+31
-20
@@ -145,35 +145,46 @@ libraries.
|
||||
|
||||
#### Building for the Orin
|
||||
|
||||
Services cross-compile from the workstation:
|
||||
Services build **natively on the development Orin**. The sysroot is then the
|
||||
target's own, so a binary cannot reference a symbol the car unit lacks — the
|
||||
guarantee is structural rather than configured.
|
||||
|
||||
```bash
|
||||
cargo build --release --target aarch64-unknown-linux-gnu
|
||||
```
|
||||
Two Orin Nanos, and they have different jobs:
|
||||
|
||||
Each service repo's `.cargo/config.toml` points at `aarch64-linux-gnu-gcc`, from
|
||||
the `gcc-aarch64-linux-gnu` package.
|
||||
| Unit | Role |
|
||||
|---|---|
|
||||
| Development Orin | Build, CI runner, bench testing. Always powered, on the LAN |
|
||||
| Car Orin | Deployment target only |
|
||||
|
||||
⚠ **The linker binds each symbol to the newest version present in the sysroot**,
|
||||
so the cross sysroot (glibc 2.43) sets the floor, not the toolchain. Rust std
|
||||
itself targets 2.17 — making the toolchain older changes nothing.
|
||||
⚠ **The guarantee is version parity, not architecture.** An aarch64 binary built
|
||||
on a newer userland still fails to load on an older one. A JetPack or Ubuntu
|
||||
upgrade applied to one unit and not the other reintroduces the problem, silently
|
||||
and only at runtime. **Upgrade both, or neither.**
|
||||
|
||||
Currently the highest referenced version is **2.34**, below the Orin's 2.35. Every
|
||||
symbol above 2.30 comes from one event: glibc 2.34 merged `libpthread` and
|
||||
`libdl` into `libc` and re-versioned the moved symbols (`__libc_start_main`, the
|
||||
`pthread_*` family). Re-versioning is rare, so this ceiling is stable — exceeding
|
||||
it would take a **dependency** calling a glibc function introduced after 2.35.
|
||||
|
||||
That failure lands at **runtime**, on the car, as a loader error; the build
|
||||
succeeds. Check before deploying:
|
||||
The check that catches drift between them:
|
||||
|
||||
```bash
|
||||
objdump -T <binary> | grep -o 'GLIBC_[0-9.]*' | sort -Vu | tail -1
|
||||
```
|
||||
|
||||
At or below `GLIBC_2.35` it will run. Above it, the control is the **sysroot**:
|
||||
build in a container supplying an older one — `cross` does this with the host's
|
||||
own toolchain — or build on the Orin.
|
||||
It detects, it does not fix — its job is to fail the build rather than let a bad
|
||||
binary reach the car, and to name the symbol that caused it.
|
||||
|
||||
##### Cross-compiling from the workstation
|
||||
|
||||
Available as a fallback. Each service repo's `.cargo/config.toml` points at
|
||||
`aarch64-linux-gnu-gcc`, from the `gcc-aarch64-linux-gnu` package:
|
||||
|
||||
```bash
|
||||
cargo build --release --target aarch64-unknown-linux-gnu
|
||||
```
|
||||
|
||||
⚠ **The linker binds each symbol to the newest version present in the sysroot**,
|
||||
so the workstation's glibc 2.43 sets the floor — not the toolchain, which targets
|
||||
2.17. Currently the highest referenced version is 2.34, below the Orin's 2.35,
|
||||
because everything above 2.30 comes from one event: glibc 2.34 merged
|
||||
`libpthread` and `libdl` into `libc` and re-versioned the moved symbols. Stable,
|
||||
but not guaranteed the way a native build is.
|
||||
|
||||
### Writing style
|
||||
|
||||
|
||||
Reference in New Issue
Block a user