Preserve current core, source, REST, desktop, recovery, documentation and validation work, including AGENTS.md and the development summary. This is a work-in-progress checkpoint: the new compact palette has outstanding compilation errors and native acceptance; earlier passing gates retain their documented scope.
12 KiB
Windows-hosted Linux cross-build feasibility and bounded probe — 2026-09-06
Result and scope
Compilation and ELF inspection PASS; Linux execution NOT RUN. An explicitly selected Windows-hosted Rust 1.90.0 compiler produced an x86-64 Linux PIE executable containing the exact locked ring 0.17.14 native implementation. This is a successful toolchain feasibility probe, not an ARCADIA GUI build, Linux runtime acceptance, or complete workspace MSRV claim.
The authorized setup/probe began 2026-09-07 06:44:39 UTC. The successful third build ended 06:52:06 UTC: 35.05 seconds reported by Cargo, 40.02 seconds including command overhead. Earlier attempts and their compiler work remain in the cache; this is not a cold-build timing. Heavy Cargo ownership was returned to root immediately after completion. No VM was launched, no default toolchain or global PATH was changed, and production sources/lockfile were not changed.
Exact prepared tools and artifact
All downloaded tools, cache, build output, sources and logs are ignored under .local/cross-linux-qa. Rustup uses the already established .local/toolchain homes.
| Input | Pinned value / verification |
|---|---|
| Rust host | 1.90.0-x86_64-pc-windows-gnu, rustc 1159e78c4 (2025-09-14), Cargo 1.90.0 |
| Target standard library | x86_64-unknown-linux-gnu, added to this explicit toolchain using Rustup |
| Zig | 0.16.0 Windows x86-64 archive, 97,217,739 bytes; SHA256 68659eb5f1e4eb1437a722f1dd889c5a322c9954607f5edcf337bc3684a75a7e |
| cargo-zigbuild | 0.23.3 Windows MSVC portable executable archive, 1,730,059 bytes; SHA256 7c1edab4815fa6542f1899c0fd8921c3995b2b109f65dd96e81247036f3a5970 |
| Host linker | Existing LLVM-MinGW Clang/LLD 23.1.0, with a task-local GNU-runtime wrapper |
| Target baseline | x86_64-unknown-linux-gnu.2.28 |
| Native dependency | ring = "=0.17.14"; local probe lock seeded from the workspace lock, subsequent builds --offline --locked |
The Zig archive was checked against the official download index. cargo-zigbuild was checked against both the official release asset digest and its separately downloaded checksum file from release 0.23.3. Captured provenance: downloads/zig-index.json, downloads/cargo-zigbuild-release-v0.23.3.json, checksum file, and verified-tools.json.
Output: .local/cross-linux-qa/target/x86_64-unknown-linux-gnu/debug/arcadia-linux-cross-probe, 530,064 bytes, SHA256 53DD54F85EEFD31006B76999D756753A8EDE94AA10D5CD1259237C776A583CC3.
llvm-readelf -h -l -d -V confirms ELF64 little-endian AMD x86-64, PIE, interpreter /lib64/ld-linux-x86-64.so.2, and dynamic requirements libc.so.6, ld-linux-x86-64.so.2, libpthread.so.0, libdl.so.2. Highest recorded required GLIBC version is 2.28. Complete metadata is retained in probe-elf.txt; machine-readable result is probe-result.json.
What the probe actually establishes
probe/build.rs asserts the Windows GNU host and Linux GNU target separately, and emitted its success warning while executing on Windows. The target program asserts Linux/x86-64, computes the known SHA256 of abc through ring on a Rust thread, writes and reads a UTF-8 temporary file, removes only its own file/directory, and prints a fixed JSON success record. These runtime assertions are compiled but have not executed.
The link includes ring's compiled native archive. Thus the result crosses the material native C/assembly dependency, rather than testing only Rust std. Rust build scripts run on the host and must configure their target work correctly; that distinction is described in the Cargo build-script documentation.
Reproduction from the repository root, after the pinned preparation:
. .local/cross-linux-qa/env.ps1
cargo +1.90.0-x86_64-pc-windows-gnu zigbuild `
--manifest-path .local/cross-linux-qa/probe/Cargo.toml `
--target x86_64-unknown-linux-gnu.2.28 --offline --locked -v
The environment confines Cargo target output, Zig caches and wrapper files to the new directory; jobs=1 and incremental=0. A separate root-approved Linux runtime gate should copy the hash-checked executable, execute it under a short timeout, and require exit 0 plus the JSON digest ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad. An ELF header inspection alone cannot supply that result.
Failures retained and why the final host link works
- Portable Python lacked zlib, so ZIP extraction failed. The verified preparation then validated archive paths/types and used existing
tar.exeinto a fresh destination. The partial directory was preserved and is unused. - First Cargo attempt failed host build-script linkage: LLVM-MinGW did not supply
-lgcc_eh/-lgccrequired by Rust's GNU host std. - Adding Rust's matching self-contained library directory exposed a second mismatch: Clang still supplied UCRT startup objects while the host Rust libraries expected the GNU/MSVCRT startup contract.
- The successful task-local
host-link.cmddisables Clang's default config/startfiles, explicitly supplies the Rust toolchain's matchingcrt2.oand self-contained libraries, and selects LLD. Host build scripts then linked and ran.
Logs/status JSON for all three attempts are preserved as probe-build{1,2,3}.log and probe-build{1,2,3}-status.json. Rust 1.90 has no downloadable Windows gnullvm host compiler; switching to that spelling would not solve the problem. The explicit GNU host was retained without changing the user's default.
Important next prerequisite: this wrapper is proven for executable build scripts only. It unconditionally selects crt2.o; a full GUI graph includes host proc-macro DLLs, which require correct DLL startup/link behavior. Before committing to an Iced build, add a tiny proc-macro dependency probe and make any wrapper DLL handling explicit. Do not infer that the present wrapper supports arbitrary host artifact kinds.
Exact GUI feasibility and remaining boundaries
The inspected locked GUI graph uses Iced 0.14 with wgpu, X11 and Wayland; rfd 0.15.4 uses the portal backend rather than GTK3. Inspected X11/Wayland/XKB and graphics paths use runtime dynamic loading; the inspected font path uses Rust parsing. Ring is the principal identified native C/assembly compilation dependency. This source inspection reduces the expected sysroot burden, but does not prove the entire resolved Linux feature graph links without further native packages.
Zig is the lower-setup-risk choice here: cargo-zigbuild supplies the target linker integration and glibc-version targeting, and this exact Windows/Rust combination now reaches a real Linux ELF. Clang plus a guest sysroot remains viable but would additionally require a complete, correctly preserved glibc CRT/library/header tree, target runtime libraries, symlink handling and explicit suppression of the Windows driver's defaults. These are precisely the target/sysroot/toolchain distinctions in Clang's cross-compilation guidance.
A Windows cross-build could avoid much of QEMU TCG's measured compiler cost. Prior native Linux core/server compilation was measured in tens of minutes; no cold full Linux GUI build timing exists, so a numerical GUI speedup would be speculative. The remaining minimally useful sequence is: proc-macro host probe; bounded exact locked GUI cross-build; ELF dependency inventory; then actual guest launch and engineer workflow execution with the packaged teaching folder.
Actual GUI execution additionally needs a usable display server, graphics software stack, XKB/fonts and portal/session services. The retained QEMU launch's -vga none cannot be fixed merely by changing its host display flag. Packaged examples must be placed relative to the executable as expected by Home. None of these runtime prerequisites was changed in this probe.
Preserve native Linux core/server test gates: some integration tests embed CARGO_MANIFEST_DIR into runtime paths, so cross-built test binaries may refer to Windows paths. This work does not justify rewriting those tests or treating a cross-built GUI as evidence that they executed under Linux. Likewise, Rust 1.90 compiling this probe is prerequisite evidence only; the entire locked ARCADIA graph must still compile at that version before claiming full MSRV compliance.
Authorized proc-macro follow-up — 2026-09-07 00:01 PDT
Host executable + host proc-macro DLL + target Linux link PASS. The follow-up stayed within its separate ten-minute lease; the successful run completed at 07:01:06 UTC and the lease was released immediately. No full GUI build or VM execution followed.
A new local arcadia-host-macro-probe dependency has proc-macro = true. Its invoked macro asserts Windows/x86-64 at expansion time, emits an execution marker, and returns a string literal that the Linux program checks. This directly proves that the host compiler loaded and executed the newly linked DLL; a successful DLL file link alone would not prove this. The same successful run deliberately rebuilt and executed the ordinary build.rs executable, preserving both artifact-kind paths.
The first run failed as predicted with DllMainCRTStartup and WinMain unresolved: the old wrapper forced executable crt2.o. The bounded task-local correction selects matching Rust GNU dllcrt2.o when rustc passes -shared, and otherwise keeps crt2.o. The original executable-only wrapper is preserved as host-link-exe-only.cmd. Final wrapper SHA256: 9B2C18E6B5B963B93868610C17C74061CAE620D146229BF3732B7307ABF65030. This covers the observed explicit rustc linker arguments; an eventual unusually long response-file-only invocation remains untested and must not silently choose the wrong startup kind.
proc-macro-build2.log records both execution markers and a successful Linux link: 1.42 seconds Cargo, 1.99 seconds wall, with ring and target dependencies warm. proc-macro-build1.log retains the negative result. The command remains the earlier zigbuild --offline --locked command after the local path dependency was added to the probe lockfile.
| Artifact | Bytes | SHA256 |
|---|---|---|
| New Linux probe at the normal target path | 530,168 | 1D7029F9B6EBEA28B35765760C56631EBD4829E3C33DBDCC225D992F558EA023 |
Host arcadia_host_macro_probe-6ddfc14bcc6b9433.dll |
1,503,232 | 86B6321CE14606BD9E51CE3430331F787C1C3471858D8861DFC3EAA150362710 |
The previous 530,064-byte Linux result was preserved as .local/cross-linux-qa/hello-ring-before-macro.elf before rebuilding. The new output remains ELF64 x86-64 PIE with the same Linux interpreter and glibc baseline. Host inspection confirms COFF x86-64 and imports the matching msvcrt.dll, along with Windows system libraries; the macro actually executed successfully. Metadata and hashes are retained in proc-macro-elf.txt, proc-macro-dll.txt, and proc-macro-result.json. Free host RAM after the probe was about 3.88 GiB.
This closes the identified proc-macro startup prerequisite. The remaining next engineering gate is an explicitly authorized bounded build of the actual locked GUI graph, followed separately by real Linux execution; neither is claimed here.
Separately authorized real Linux execution — 2026-09-07 00:07 PDT
The proc-macro/ring probe now also passes actual Linux execution. Root booted the retained Ubuntu 24.04.4 guest separately at 07:02:43 UTC. After SSH became healthy, the new ELF was transferred to a fresh task directory. Guest sha256sum -c confirmed 1D7029F9B6EBEA28B35765760C56631EBD4829E3C33DBDCC225D992F558EA023, then timeout 30s ./arcadia-linux-cross-probe exited 0 and emitted:
{"probe":"hello-ring-thread-file","os":"linux","arch":"x86_64","sha256":"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad","passed":true}
The host independently parsed and checked every expected JSON field. Guest kernel is 6.8.0-139-generic, x86-64. Evidence: .local/linux-qa/runtime/source7-probe-and-unpack.log. This supersedes the earlier probe runtime-pending statement, while full GUI compilation/execution remains unperformed. The subsequent native Linux source7 server/core gate is separate and cannot be inferred from this small executable's success.