Commit d278fd78 authored by Adam Joseph's avatar Adam Joseph
Browse files

lib.systems.extensions.sharedLibrary: do not `throw`

Because downstream code expects to use `==` on platform attrsets, we
are unfortunately not able to throw a useful error message when the
`sharedLibrary` attribute is accessed.

When users do a comparison like:

  stdenv.hostPlatform == pkgsStatic.stdenv.hostPlatform

... in a situation where `stdenv.hostPlatform.hasSharedLibraries`,
they expect this to return `false`.  Unfortunately Nix does a deep
equality comparison here, and ends up forcing the
`pkgsStatic.stdenv.hostPlatform.extensions.sharedLibrary` attribute,
which throws the error.

Rather than returning `null`, this commit instead simply omits the
`extensions.sharedLibrary` attribute.  This provides the user with a
more-useful error message: instead of waiting until the `null` is
used (and hoping that produces an error), the user will get an error
about the `extensions.sharedLibrary` attribute being missing, at the
position where it was referenced.

Big thanks to @trofi for his PR to add
`NIX_VALIDATE_EVAL_NONDETERMINISM` to Nix, which I am now using.  It
made tracking this down really easy!

Fixes #244045
parent 083a9cb4
Loading
Loading
Loading
Loading
+6 −5
Original line number Diff line number Diff line
@@ -85,17 +85,18 @@ rec {
        # is why we use the more obscure "bfd" and not "binutils" for this
        # choice.
        else                                     "bfd";
      extensions = rec {
        sharedLibrary = assert final.hasSharedLibraries;
          /**/ if final.isDarwin  then ".dylib"
      extensions = lib.optionalAttrs final.hasSharedLibraries {
        sharedLibrary =
          if      final.isDarwin  then ".dylib"
          else if final.isWindows then ".dll"
          else                         ".so";
      } // {
        staticLibrary =
          /**/ if final.isWindows then ".lib"
          else                         ".a";
        library =
          /**/ if final.isStatic then staticLibrary
          else                        sharedLibrary;
          /**/ if final.isStatic then final.extensions.staticLibrary
          else                        final.extensions.sharedLibrary;
        executable =
          /**/ if final.isWindows then ".exe"
          else                         "";