Open bltavares opened 6 months ago
Comparing the emulation binfmt_misc
registration between a working host and NixOS, it seems there are a few missing flags.
Debian host
$ cat /proc/sys/fs/binfmt_misc/qemu-aarch64
enabled
interpreter /usr/libexec/qemu-binfmt/aarch64-binfmt-P
flags: POCF
offset 0
magic 7f454c460201010000000000000000000200b700
mask ffffffffffffff00fffffffffffffffffeffffff
NixOS host
$ cat /proc/sys/fs/binfmt_misc/aarch64-linux
enabled
interpreter /run/binfmt/aarch64-linux
flags: P
offset 0
magic 7f454c460201010000000000000000000200b700
mask ffffffffffffff00ffffffffffff00fffeffffff
It seems that these flags are possible to be set on NixOS, but they are disabled by default.
To match exactly the same configuration as the Debian host, I've applied the following overrides:
{
boot.binfmt.emulatedSystems = ["aarch64-linux"];
boot.binfmt.registrations.aarch64-linux = {
matchCredentials = true;
fixBinary = true;
mask = lib.mkForce ''\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff'';
};
}
This results in the same configuration options as the compared host:
$ cat /proc/sys/fs/binfmt_misc/aarch64-linux
enabled
interpreter /run/binfmt/aarch64-linux
flags: POCF
offset 0
magic 7f454c460201010000000000000000000200b700
mask ffffffffffffff00fffffffffffffffffeffffff
The interpreter points to a qemu-static-*-P
binary, just like the Debian host.
$ file /run/binfmt/aarch64-linux
/run/binfmt/aarch64-linux: symbolic link to /nix/store/mp17zkcxaqmjyjbhb3pvr0ni2z8jgnzh-qemu-aarch64-binfmt-P-x86_64-unknown-linux-musl/bin/qemu-aarch64-binfmt-P
I've attempted a few combinations of parameters, such as wrapInterpreterInShell
and preserveArgvZero
without much success yet.
Even after a huge detour attempting to enable qemu-user-static
, the results are still the same when running the emulated compilation tools under NixOS.
After applying the following patches:
And adjusting the /etc/nixos/configuration.nix
:
boot = {
binfmt = {
emulatedSystems = ["aarch64-linux"];
preferStaticEmulators = true;
registrations = {
aarch64-linux = {
matchCredentials = true;
mask = lib.mkForce ''\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff'';
};
};
};
};
I'm able to have a qemu-user-static running under binfmt_misc
with the same flags as the Ubuntu host.
$ cat /proc/sys/fs/binfmt_misc/aarch64-linux
enabled
interpreter /run/binfmt/aarch64-linux
flags: POCF
offset 0
magic 7f454c460201010000000000000000000200b700
mask ffffffffffffff00fffffffffffffffffeffffff
$ file /run/binfmt/aarch64-linux
/run/binfmt/aarch64-linux: symbolic link to /nix/store/gapqjg8p33gmgj4hvdb300hpiggslyjr-qemu-static-x86_64-unknown-linux-musl-8.2.2/bin/qemu-aarch64
$ file /nix/store/gapqjg8p33gmgj4hvdb300hpiggslyjr-qemu-static-x86_64-unknown-linux-musl-8.2.2/bin/qemu-aarch64
/nix/store/gapqjg8p33gmgj4hvdb300hpiggslyjr-qemu-static-x86_64-unknown-linux-musl-8.2.2/bin/qemu-aarch64: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, BuildID[sha1]=0f92fecf54c877035eee6b8c29ce285b7ed03336, not stripped
$ nix-build default.nix --argstr system aarch64-linux
With this change, I think it's clear this is unrelated to LDFLAGS
overrides by qemu
itself, but something different on how Nix changes environment variables when running on Ubuntu vs using Nix on NixOS.
I'm out of ideas after so many levels of ~yak shaving~ abstractions.
@bltavares Seems to be a regression introduced by QEMU 8.2. Most distros (and the setup-qemu-action
for Github Actions) are on 8.1, while nixos-unstable
updated to the 8.2 branch around 4 months ago (commit fc38d28b26904c294b33b64cdce0866e778b6bc8). If you pin nixpkgs to this branch of my fork (which partially reverts QEMU to 8.1.3) the build should succeed. I based that branch on your perl and qemu-user-static branches when I was trying to troubleshoot, but in theory this should work for dynamically linked QEMU as well. You can test this by pinning mainline nixpkgs to commit a45f095fced4dbafce7cc65c800b7c70302025ab (which should be the commit immediately preceding the update to 8.2), although I haven't tried that yet. Still unsure of the root cause, but based on the changelogs it appears to be either a /proc/cpuinfo
issue or a vDSO issue.
Update: bisection indicates that the first bad commit is e8967b61, problem remains as of nixpkgs commit 82cbb284d39164690797fdf721070c54b6719a28 (QEMU 9.0.2).
Describe the bug
Hello everyone,
I’ve been trying to configure a Rust project using Nix to produce binaries for Darwin (
arm64
,x86_64
) and Linux (arm64
,x86_64
) systems, so people can easily download them from GitHub releases. I’m trying to use Nix as the build process this time, to have a reproducible build locally as well as on GitHub Actions.Instead of going through the cross-compilation route, with logic to use either
${system}.packages
or${system}.pkgsCross.${targetSystem}
, I’m attempting to use an emulated cross-platform toolchain with qemu-user over binfmt_misc on the Kernel.So far, I've been able to use the following Nix expression to build a barebone Rust file using Nix in all platforms, as long as the
qemu-user-static
emulation happens on a Non-NixOS Host.As long as the cross-platform emulation happens on a non-NixOS layer, such as the LXD host, the Docker host or on a Non-NixOS VM, the generated
rust-std
compilation is valid.Build logs
``` error: aborting due to previous error error: builder for '/nix/store/7kz25f4zqfyrfixcc3fj804kbd9s6ap0-out.drv' failed with exit code 1; last 10 log lines: > Running phase: buildPhase > error: linking with `cc` failed: exit status: 1 > | > = note: LC_ALL="C" PATH="/nix/store/y3bpndhxdb1gfagnd2316x0833737n78-rustc-1.75.0/lib/rustlib/aarch64-unknown-linux-gnu/bin:/nix/store/adms7m11kx2skc7bhi0z48mjlyqk74sp-rustc-wrapper-1.75.0/bin:/nix/store/abrrb6s259fsi5szq5w92ni70x7sp9ih-patchelf-0.15.0/bin:/nix/store/z062sjm2ppd5jdcisdgaxvl8l08dq774-gcc-wrapper-13.2.0/bin:/nix/store/yk0nw4wb0y7hy187p6s5i1cayzj1nbya-gcc-13.2.0/bin:/nix/store/pabzgfm37yk00mpnkh4akmr0nzg97kqq-glibc-2.38-44-bin/bin:/nix/store/hbh2gmp1idyjzw2wdh50idi8q01xm6yb-coreutils-9.4/bin:/nix/store/v5252q77fafyra57c8rzq2svlhawd14f-binutils-wrapper-2.40/bin:/nix/store/d5zbc1vk664z7azivyv38fsg6ia5w35w-binutils-2.40/bin:/nix/store/hbh2gmp1idyjzw2wdh50idi8q01xm6yb-coreutils-9.4/bin:/nix/store/9pfnndp3l9aj4a905r4k1m6iwcbl6vpj-findutils-4.9.0/bin:/nix/store/mrycscd5wfpp11g9bjvlllf6bia9m4kq-diffutils-3.10/bin:/nix/store/f3dmzlahl1avdbcbanfyyq8l8aycrzbn-gnused-4.9/bin:/nix/store/5fn8gw10q5nq3wqz84q29j9zd9wxba6k-gnugrep-3.11/bin:/nix/store/lq5z0piqczqamgy5h9s6lixj7plvls2c-gawk-5.2.2/bin:/nix/store/d6p4xfwg72kvwr9xx0ai3wn5g4znz11p-gnutar-1.35/bin:/nix/store/k0g5khwhv60vzwh7n8w47mm6kachb2yj-gzip-1.13/bin:/nix/store/y0817cpgflxrl42jjgdbz8bpxlarncmc-bzip2-1.0.8-bin/bin:/nix/store/dq0vnn5gnllnibc52x2l8vfshz1k4zvr-gnumake-4.4.1/bin:/nix/store/2icvzb9pj2ryvsy1m9jf4kj2mbkgbczj-bash-5.2p26/bin:/nix/store/sf5mmdwxiv8navi5a5brj969sdrkhx7i-patch-2.7.6/bin:/nix/store/cxyn9ww64idkxgv02685c6qwvyisvzan-xz-5.4.6-bin/bin:/nix/store/j96xh64m4x03fi9b633d6n87qq4v7g1d-file-5.45/bin" VSLANG="1033" "cc" "/build/rustcsAWxVf/symbols.o" "main.main.6d5145388994a7b7-cgu.0.rcgu.o" "main.4k7vvgzx11b68cao.rcgu.o" "-Wl,--as-needed" "-L" "/nix/store/y3bpndhxdb1gfagnd2316x0833737n78-rustc-1.75.0/lib/rustlib/aarch64-unknown-linux-gnu/lib" "-Wl,-Bstatic" "/nix/store/y3bpndhxdb1gfagnd2316x0833737n78-rustc-1.75.0/lib/rustlib/aarch64-unknown-linux-gnu/lib/libstd-436329434b63751b.rlib" "/nix/store/y3bpndhxdb1gfagnd2316x0833737n78-rustc-1.75.0/lib/rustlib/aarch64-unknown-linux-gnu/lib/libpanic_unwind-645486d646ae78ee.rlib" "/nix/store/y3bpndhxdb1gfagnd2316x0833737n78-rustc-1.75.0/lib/rustlib/aarch64-unknown-linux-gnu/lib/libobject-05eb0ca8862e71d6.rlib" "/nix/store/y3bpndhxdb1gfagnd2316x0833737n78-rustc-1.75.0/lib/rustlib/aarch64-unknown-linux-gnu/lib/libmemchr-e29b4003c65f7892.rlib" "/nix/store/y3bpndhxdb1gfagnd2316x0833737n78-rustc-1.75.0/lib/rustlib/aarch64-unknown-linux-gnu/lib/libaddr2line-75516828d20fd799.rlib" "/nix/store/y3bpndhxdb1gfagnd2316x0833737n78-rustc-1.75.0/lib/rustlib/aarch64-unknown-linux-gnu/lib/libgimli-48e15cafb03bf5af.rlib" "/nix/store/y3bpndhxdb1gfagnd2316x0833737n78-rustc-1.75.0/lib/rustlib/aarch64-unknown-linux-gnu/lib/librustc_demangle-6e6e48662894ac3c.rlib" "/nix/store/y3bpndhxdb1gfagnd2316x0833737n78-rustc-1.75.0/lib/rustlib/aarch64-unknown-linux-gnu/lib/libstd_detect-27e76fbf8405ed1a.rlib" "/nix/store/y3bpndhxdb1gfagnd2316x0833737n78-rustc-1.75.0/lib/rustlib/aarch64-unknown-linux-gnu/lib/libhashbrown-fc59afcb036257bc.rlib" "/nix/store/y3bpndhxdb1gfagnd2316x0833737n78-rustc-1.75.0/lib/rustlib/aarch64-unknown-linux-gnu/lib/librustc_std_workspace_alloc-0ce5a40297c0b123.rlib" "/nix/store/y3bpndhxdb1gfagnd2316x0833737n78-rustc-1.75.0/lib/rustlib/aarch64-unknown-linux-gnu/lib/libminiz_oxide-44673f3a7f799a8a.rlib" "/nix/store/y3bpndhxdb1gfagnd2316x0833737n78-rustc-1.75.0/lib/rustlib/aarch64-unknown-linux-gnu/lib/libadler-cf9241d85da8aafa.rlib" "/nix/store/y3bpndhxdb1gfagnd2316x0833737n78-rustc-1.75.0/lib/rustlib/aarch64-unknown-linux-gnu/lib/libunwind-729ec6f67ecd9d0c.rlib" "/nix/store/y3bpndhxdb1gfagnd2316x0833737n78-rustc-1.75.0/lib/rustlib/aarch64-unknown-linux-gnu/lib/libcfg_if-14289be8725ff0e3.rlib" "/nix/store/y3bpndhxdb1gfagnd2316x0833737n78-rustc-1.75.0/lib/rustlib/aarch64-unknown-linux-gnu/lib/liblibc-1ba610f6ee9c1082.rlib" "/nix/store/y3bpndhxdb1gfagnd2316x0833737n78-rustc-1.75.0/lib/rustlib/aarch64-unknown-linux-gnu/lib/liballoc-7510187c76712943.rlib" "/nix/store/y3bpndhxdb1gfagnd2316x0833737n78-rustc-1.75.0/lib/rustlib/aarch64-unknown-linux-gnu/lib/librustc_std_workspace_core-197ec3f9e11b1939.rlib" "/nix/store/y3bpndhxdb1gfagnd2316x0833737n78-rustc-1.75.0/lib/rustlib/aarch64-unknown-linux-gnu/lib/libcore-3134799bb6fa5396.rlib" "/nix/store/y3bpndhxdb1gfagnd2316x0833737n78-rustc-1.75.0/lib/rustlib/aarch64-unknown-linux-gnu/lib/libcompiler_builtins-04c9643a755e1271.rlib" "-Wl,-Bdynamic" "-lgcc_s" "-lutil" "-lrt" "-lpthread" "-lm" "-ldl" "-lc" "-Wl,--eh-frame-hdr" "-Wl,-z,noexecstack" "-L" "/nix/store/y3bpndhxdb1gfagnd2316x0833737n78-rustc-1.75.0/lib/rustlib/aarch64-unknown-linux-gnu/lib" "-o" "main" "-Wl,--gc-sections" "-pie" "-Wl,-z,relro,-z,now" "-nodefaultlibs" > = note: /build/rustcsAWxVf/symbols.o: file not recognized: file format not recognized > collect2: error: ld returned 1 exit status > > > error: aborting due to previous error > For full logs, run 'nix log /nix/store/7kz25f4zqfyrfixcc3fj804kbd9s6ap0-out.drv'.``` ```Steps To Reproduce
nix-build
To reproduce the behaviour, you can use the following expression:
Ensure your NixOS has cross-platform emulation enabled
Ensure emulation is working as expected calling a cross-platform Nix package
nix-shell
It's also possible to use a
nix-shell
command to enter a troubleshooting environment, and inspect the resultingsymbols.o
. I'm not familiar enough with investigating why the.o
is considered malformed (yet) tho.Ensure your NixOS has cross-platform emulation enabled
Ensure emulation is working as expected calling a cross-platform Nix package
nix-shell
with rustc and attempt to compile, while keeping the temporary filesExpected behavior
The compilation of the barebone Rust program should produce a cross-platform binary on
result
as using Nix on Non-NixOS platforms.Additional context
I've created a repository with additional tests, including a flake-based build and a Github Actions task to showcase the expression works when running Nix on Ubuntu.
This is the minimal reproducible scenario I've been able to extract with just
nixpkgs
packages and non-experimental commands.Metadata
Please run
nix-shell -p nix-info --run "nix-info -m"
and paste the result.