Skip to content

Windows: nix-store-tests cannot be cross-compiled — unity build exceeds the COFF section limit #16366

Description

@awsmadi

nix-store-tests cannot be cross-compiled for x86_64-w64-mingw32 at all. The unity build
concatenates the suite into a single translation unit whose object file exceeds the section count
the COFF assembler will accept.

$ nix build .#nix-store-tests-x86_64-w64-mingw32
...
[1/2] Compiling C++ object nix-store-tests.exe.p/meson-generated_nix-store-tests-unity0.cpp.obj
FAILED: [code=1] nix-store-tests.exe.p/meson-generated_nix-store-tests-unity0.cpp.obj
x86_64-w64-mingw32-as: nix-store-tests.exe.p/meson-generated_nix-store-tests-unity0.cpp.obj: too many sections (32814)
.../cchryRsB.s: Fatal error: can't write 16 bytes to section .text of nix-store-tests.exe.p/meson-generated_nix-store-tests-unity0.cpp.obj: 'file too big'
ninja: build stopped: subcommand failed.

Reproduced on master 3aef07e8f, and identically on an unrelated branch, so it is not
branch-specific.

Why

The meson summary for that build reports:

unity       : on
unity_size  : 8192

so every source file in src/libstore-tests lands in one unity0.cpp. In C++ each template
instantiation and inline function gets its own COMDAT section, so one object covering the whole
suite reaches 32814 sections, and as refuses. The object-file name in the error
(meson-generated_nix-store-tests-unity0.cpp.obj) is the unity TU rather than any individual source,
which is what points at the unity build rather than at any one file.

nix-store-tests appears to be the only suite large enough to hit this. In the same configuration
nix-util-tests, nix-expr-tests, nix-fetchers-tests and nix-flake-tests all cross-compile
without complaint.

Consequence

This is not only a build annoyance. It means nix-store-tests can never be part of Windows CI
regardless of what else is fixed, because the artifact does not exist. That is one of the five
suites in #16360, and it is the one that fails for a reason unrelated to the other four.

Possible fixes

Either disable unity for this target when cross-compiling to mingw, or lower unity_size so meson
emits several smaller unity TUs instead of one. The second keeps most of the unity build's benefit
and is the smaller change, but I have not measured how low it needs to go, and I would rather not
guess at a number that happens to work today and breaks again as the suite grows. Turning unity off
for this one target on this one platform is the option that cannot silently regress.

Found while measuring which of the five cross-built suites can run under Wine, in connection with
#16360, #16363 and #16364.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions