66, capnprotoSanitizers ? null # Optional sanitizers to build cap'n proto with
77, cmakeVersion ? null
88, libcxxSanitizers ? null # Optional LLVM_USE_SANITIZER value to use for libc++, see https://llvm.org/docs/CMake.html
9+ , enableWine ? false # Whether to add wine64 for running cross-compiled Windows binaries
910} :
1011
1112let
4243 } // ( lib . optionalAttrs ( lib . versionOlder capnprotoVersion "0.10" ) {
4344 env = { } ; # Drop -std=c++20 flag forced by nixpkgs
4445 } ) ) ;
45- capnproto = ( capnprotoBase . overrideAttrs ( old : lib . optionalAttrs ( capnprotoSanitizers != null ) {
46+ # capnproto v1.1.0 puts cidr.c++ in libkj, but it calls inet_pton/inet_ntop
47+ # which require ws2_32 on Windows -- only kj-async links ws2_32. Apply the
48+ # upstream fix that moves cidr.c++ into kj-async (capnproto@a2deb05).
49+ # mingw with mcf thread model also requires _WIN32_WINNT to be defined
50+ # before any libstdc++ thread headers are included.
51+ capnprotoPatched = capnprotoBase . overrideAttrs ( old : lib . optionalAttrs crossPkgs . stdenv . hostPlatform . isMinGW {
52+ patches = ( old . patches or [ ] ) ++ [
53+ ./ci/patches/capnproto-cidr-kj-async.patch
54+ ./ci/patches/capnproto-wine-invalid-function.patch
55+ ] ;
56+ env = ( old . env or { } ) // {
57+ NIX_CFLAGS_COMPILE = lib . concatStringsSep " " [
58+ ( old . env . NIX_CFLAGS_COMPILE or "" )
59+ "-D_WIN32_WINNT=0x0601"
60+ ] ;
61+ } ;
62+ } ) ;
63+ capnproto = ( capnprotoPatched . overrideAttrs ( old : lib . optionalAttrs ( capnprotoSanitizers != null ) {
4664 env = ( old . env or { } ) // {
4765 CXXFLAGS =
4866 lib . concatStringsSep " " [
5270 "-g"
5371 ] ;
5472 } ;
55- } ) ) . override ( lib . optionalAttrs enableLibcxx { clangStdenv = llvm . libcxxStdenv ; } ) ;
73+ } ) ) . override (
74+ if enableLibcxx then { clangStdenv = llvm . libcxxStdenv ; }
75+ # nixpkgs forces capnproto to be built with clangStdenv, but the mingw
76+ # clang wrapper auto-adds `-lgcc_s` to the link line, which doesn't exist
77+ # in the mingw GCC runtime layout (see nixpkgs#177129). Fall back to the
78+ # GCC cross stdenv when cross-compiling to mingw.
79+ else if crossPkgs . stdenv . hostPlatform . isMinGW then { clangStdenv = crossPkgs . stdenv ; }
80+ else { } ) ;
5681 clang = if enableLibcxx then llvm . libcxxClang else llvm . clang ;
5782 clang-tools = llvm . clang-tools . override { inherit enableLibcxx ; } ;
5883 cmakeHashes = {
6691 } ;
6792 patches = [ ] ;
6893 } ) ) . override { isMinimalBuild = true ; } ;
69- in crossPkgs . mkShell {
94+ in crossPkgs . mkShell ( {
7095 buildInputs = [
7196 capnproto
7297 ] ;
@@ -77,8 +102,29 @@ in crossPkgs.mkShell {
77102 ] ++ lib . optionals ( ! minimal ) [
78103 clang
79104 clang-tools
80- ] ;
105+ ] ++ lib . optional enableWine pkgs . wineWowPackages . stable
106+ # When cross-compiling, also expose a native capnp/capnpc-c++ on PATH so
107+ # build-time code generators (capnp_generate_cpp) can run on the build host
108+ # instead of trying to execute target-arch binaries directly.
109+ ++ lib . optional ( crossPkgs . stdenv . hostPlatform != crossPkgs . stdenv . buildPlatform ) pkgs . capnproto ;
81110
82111 # Tell IWYU where its libc++ mapping lives
83112 IWYU_MAPPING_FILE = if enableLibcxx then "${ llvm . libcxx . dev } /include/c++/v1/libcxx.imp" else null ;
84- }
113+ } // lib . optionalAttrs ( enableWine && crossPkgs . stdenv . hostPlatform . isMinGW ) {
114+ # Cross-compiled .exe files run under wine64 need the capnproto and mingw
115+ # thread runtime DLLs at startup. Wine searches the .exe directory and the
116+ # Windows system directory for PE imports, so symlink the required DLLs
117+ # into $WINEPREFIX/drive_c/windows/system32 when entering the shell.
118+ shellHook = ''
119+ if [ -n "'' ${WINEPREFIX-}" ]; then
120+ _mp_sys32="$WINEPREFIX/drive_c/windows/system32"
121+ mkdir -p "$_mp_sys32"
122+ for _d in ${ capnproto } /bin ${ crossPkgs . windows . mcfgthreads } /bin; do
123+ for _dll in "$_d"/*.dll; do
124+ [ -e "$_dll" ] && ln -sf "$_dll" "$_mp_sys32/"
125+ done
126+ done
127+ unset _mp_sys32 _d _dll
128+ fi
129+ '' ;
130+ } )
0 commit comments