Repository navigation
Conversation
GNU Emacs 31.1 skips set_initial_environment while constructing a dump. Neomacs instead retained the entire builder environment through initial-environment, pinning build-only Nix dependencies in the output. Use the typed loadup dump mode to omit that snapshot, seed a portable shell before cus-start captures its standard value, and exclude exec-path only during serialization so loadup can still run Git. Keep construction state native and reset it when restoring or activating a runtime image. Keep Context offsets stable using trailing padding, an ABI guard, and a compile-time size assertion. Ordinary runtime redumps retain their existing environment policy. Exercise both image modes through public dump/load APIs in isolated processes, scan image bytes, preserve repository metadata, and verify runtime environment, subprocesses, and subsequent user redumps. Reject build-only references in the Nix package output. Fixes #578.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info
📝 Walkthrough
Merge Risk: ⚪ Minimal · up to
|
There was a problem hiding this comment.
🔵 Needs a closer look
The change touches ABI-pinned Context layout, dump serialization internals, and platform/packaging behavior for every produced image, which warrants final human review despite being well-tested.
1 open issue
What changed in this PR
This PR fixes issue #578, where the portable dump (neomacs.pdump) captured the builder's entire process environment (initial-environment/process-environment, plus the build-time SHELL and exec-path), turning build-only Nix store paths into runtime closure dependencies (and leaking CI env into .deb assets). The fix mirrors GNU Emacs 31.1's !will_dump_p() behavior: when loadup.el is evaluated to construct a dump, host environment state is not snapshotted into the image, while exec-path is deliberately retained until the moment of serialization (so loadup can still query Git) and then excluded only while writing the image. Runtime activation re-derives the environment, shell, and search path from the real process, and ordinary user redumps keep their existing behavior.
Changes:
- Thread a non-serialized
loadup_dump_modeflag throughContext(placed in trailingrepr(C)padding, with a size assertion) and set it only on theLoadupInvocation::Dumppath;dump-emacs-portableuses it to blankexec-patharound serialization. - Skip the host-environment snapshot during dump construction and seed a portable
shell-file-namedefault (install_dump_default) beforecus-startrecords its standard value. - Add a Nix
disallowedReferencesregression guard and a newdump_environmentintegration test covering production and bootstrap images, byte-level marker checks, runtime activation, and user redump.
| File | Description |
|---|---|
| nix/package.nix | Adds disallowedReferences guard to fail the build if build-only inputs leak into the output; reflows a lib.optionals call. |
| crates/neovm-core/tests/dump_environment.rs | New integration test verifying dumps exclude build env and runtime re-derives it. |
| crates/neovm-core/Cargo.toml | Registers the new explicit [[test]] target (required under autotests = false). |
| crates/neovm-core/src/emacs_core/lisp/load/mod.rs | Branches env/shell setup on PreloadOnly vs Dump; sets/resets loadup_dump_mode; retains exec-path until serialization. |
| crates/neovm-core/src/emacs_core/lisp/native/builtins/symbols.rs | Excludes exec-path from the image only for loadup dumps, saving/restoring it in native locals. |
| crates/neovm-core/src/emacs_core/system/shell_file_name/mod.rs | Adds install_dump_default for a portable, builder-independent shell. |
| crates/neovm-core/src/emacs_core/runtime/eval/mod.rs | Adds the loadup_dump_mode field plus a compile-time size assertion. |
| crates/neovm-core/src/emacs_core/runtime/eval/construct.rs, pdump_reconstruct.rs | Initialize the new field to None. |
| crates/neovm-core/src/emacs_core/system/environment/mod.rs | Doc-comment update noting the dump-time exception. |
Review effort: Balanced

Dump construction captured the builder's entire environment in
initial-environment, retaining build-only Nix store paths even though runtime startup replaced the environment. GNU Emacs 31.1 skips this snapshot while constructing a dump.This change uses the typed loadup mode to omit the construction-time snapshot and seed a portable shell before customization records its standard value. It preserves
exec-pathwhile loadup queries Git, then excludes it only during image serialization. Native construction state resets on restoration and runtime activation; ordinary runtime redumps retain their existing behavior. TheContextlayout remains unchanged, with compile-time size and existing offset checks.Public dump/load regressions cover production and bootstrap images, inspect image bytes for build markers, preserve repository metadata, and verify runtime environment lists, real subprocesses, and subsequent user redumps. The Nix package also rejects references to build-only inputs.
Fixes #578.
Verification
The branch is rebased onto
48ec663ed2(origin/main). The dump regression tests were rerun after rebasing. Before rebasing, the same fix passed:cargo nextest run -p neovm-core --lib --no-fail-fast: 14,769 passed, 67 skipped.cargo check --workspace --all-targets,cargo xtask fresh-build --release, andcargo fmt --all --check./nix/storepaths. This is a current-build measurement, not a controlled comparison with the reporter's older build.Verification was performed on Linux. Whole-flake Nix formatting still fails on the unchanged
nix/dependencies.nix; the changednix/package.nixpasses the pinned formatter.