nix: resolve Windows crypt32 import library metadata

This commit is contained in:
Moritz Angermann committed 2026-10-17 19:40:35 +09:00
1 parent 8dfd5f932e
commit 6fdb6b54c5
4 files changed
+92 -1

No files matched your search

+3 -1
View File
@@ -166,7 +166,9 @@
}
)
] ++ darwinBitvec.modules ++ pkgs.lib.optional pkgs'.stdenv.hostPlatform.isWindows ({ lib, ... }: {
] ++ darwinBitvec.modules ++ [
(import ./scripts/nix/windows-crypt32.nix { hostPlatform = pkgs'.stdenv.hostPlatform; })
] ++ pkgs.lib.optional pkgs'.stdenv.hostPlatform.isWindows ({ lib, ... }: {
# The preplanned local source already applies the modern patch.
# Avoid applying it again after v2 source packaging.
packages.crypton-x509-system.patches = lib.mkForce [];
+10
View File
@@ -120,6 +120,16 @@ This keeps planning and packaged Cabal metadata aligned, including the metadata
used for native package unit IDs.
The source producer applies the existing haskell.nix patch once; its later
package patch list is empty to prevent a second application.
For this Windows GHC 9.14 package, the Nix dependency resolver also recognizes
lowercase `crypt32` as an implicit MinGW import library, matching the existing
`Crypt32` mapping. Cabal keeps the lowercase library declaration and linker flag;
all other package/library mappings stay intact. The focused resolver check uses
the real haskell.nix plan and package modules without building a compiler:
```sh
nix eval --impure --json --file scripts/nix/check-windows-crypt32.nix \
--apply 'test: let f = builtins.getFlake (toString ./.); in test { lib = f.inputs.haskellNix.inputs.nixpkgs.lib; haskellNix = f.inputs.haskellNix; }'
```
Linux-built Win64 `ghc914-sh` v2 projects patch only the RTS DLL search-path
caller, including normal and profiling interpreters. It resolves relative paths
+70
View File
@@ -0,0 +1,70 @@
# Exercise the actual HN plan/package/component argument fixed point.
# No source producer, toolchain, compiler, or Cabal planner is built.
{ lib, haskellNix, scenario ? "checks" }:
let
provider = builtins.toFile "crypt32-resolver-other-provider" "";
basePkgs = { inherit lib; Crypt32 = null; otherLibrary = provider; };
evaluate = mapping: windows: compiler: extra: lib.evalModules {
modules = [ (haskellNix + "/modules/plan.nix") (haskellNix + "/modules/error-handler.nix") {
options = {
compiler-nix-name = lib.mkOption { type = lib.types.str; default = compiler; };
hackage.configs = lib.mkOption { type = lib.types.unspecified; default = {}; };
hsPkgs = lib.mkOption { type = lib.types.unspecified; default = {}; };
cabal = {
system = lib.mkOption { type = lib.types.unspecified; default = { isWindows = windows; }; };
compiler = lib.mkOption { type = lib.types.unspecified; default = {}; };
};
};
config = {
_module.args = {
pkgs = basePkgs;
pkgconfPkgs = {};
haskellLib.types = import (haskellNix + "/lib/types.nix") { inherit lib; };
};
use-package-keys = false;
plan.pkg-def = _: let
revision = { pkgs, system, errorHandler, ... }: {
# Exact expression emitted for the failed crypton-x509-system plan.
components.library.libs = pkgs.lib.optional (system.isWindows)
(pkgs."crypt32" or (errorHandler.sysDepError "crypt32"))
++ lib.optional (extra == "provided") pkgs.otherLibrary
++ lib.optional (extra == "missing")
(pkgs.unrelated or (errorHandler.sysDepError "unrelated"));
};
in {
compiler = { nix-name = compiler; version = "9.14.0"; packages = {}; };
packages = { crypton-x509-system = { inherit revision; }; another-package = { inherit revision; }; };
};
};
} ] ++ lib.optional mapping (import ./windows-crypt32.nix { hostPlatform.isWindows = windows; });
};
libs = mapping: windows: compiler: extra:
(evaluate mapping windows compiler extra).config.packages.crypton-x509-system.components.library.libs;
succeeds = value: (builtins.tryEval (builtins.deepSeq value true)).success;
disabled = windows: compiler: (lib.evalModules {
modules = [ (import ./windows-crypt32.nix { hostPlatform.isWindows = windows; }) {
options = {
compiler-nix-name = lib.mkOption { type = lib.types.str; default = compiler; };
packages = lib.mkOption { type = lib.types.unspecified; default = {}; };
};
config._module.args.pkgs = throw "Disabled resolver forced its package set";
} ];
}).config.packages;
checks = {
oldCaseOnlyMappingRejected = !succeeds (libs false true "ghc914-sh" "none");
lowercaseImportLibraryResolved = libs true true "ghc914-sh" "none" == [];
otherLibrariesPreserved = libs true true "ghc914-sh" "provided" == [ provider ];
unrelatedMissingLibraryRejected = !succeeds (libs true true "ghc914-sh" "missing");
otherPackageMappingUnchanged = !succeeds
(evaluate true true "ghc914-sh" "none").config.packages.another-package.components.library.libs;
nonWindowsUnchanged = libs true false "ghc914-sh" "provided" == [ provider ];
otherCompilerUnchanged = !succeeds (libs true true "ghc912" "none");
nonWindowsPackageSetLazy = disabled false "ghc914-sh" == {};
otherCompilerPackageSetLazy = disabled true "ghc912" == {};
};
in
if scenario == "baseline" then libs false true "ghc914-sh" "none"
else if scenario == "unrelated" then libs true true "ghc914-sh" "missing"
else assert scenario == "checks";
assert builtins.all (value: value) (builtins.attrValues checks);
checks
+9
View File
@@ -0,0 +1,9 @@
# The patched x509 Cabal file uses the import library's lowercase name.
# MinGW supplies crypt32 implicitly, just like HN's legacy Crypt32 alias.
{ hostPlatform }:
{ lib, pkgs, config, ... }:
lib.mkIf (hostPlatform.isWindows && config.compiler-nix-name == "ghc914-sh") {
packages.crypton-x509-system._module.args.pkgs = lib.mkForce (pkgs // {
crypt32 = null;
});
}