From 8c9c583f7c8669141e01f25dbd61ffdaefc88398 Mon Sep 17 00:00:00 2001 From: Brian McKenna Date: Fri, 8 Nov 2024 01:06:15 +0000 Subject: [PATCH 01/13] cygwin: init as a target toolchain --- lib/systems/examples.nix | 5 +++++ lib/systems/parse.nix | 9 ++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/lib/systems/examples.nix b/lib/systems/examples.nix index 20f96f0849d16..b6c90ee113909 100644 --- a/lib/systems/examples.nix +++ b/lib/systems/examples.nix @@ -332,6 +332,11 @@ rec { useLLVM = true; }; + x86_64-cygwin = { + config = "x86_64-pc-cygwin"; + libc = "cygwin"; # cygwin (posix) toolchain + }; + # BSDs x86_64-freebsd = { diff --git a/lib/systems/parse.nix b/lib/systems/parse.nix index a2ee288f2c1f8..88e49288d5fd7 100644 --- a/lib/systems/parse.nix +++ b/lib/systems/parse.nix @@ -444,7 +444,7 @@ rec { else throw "Target specification with 1 components is ambiguous"; "2" = # We only do 2-part hacks for things Nix already supports if elemAt l 1 == "cygwin" - then { cpu = elemAt l 0; kernel = "windows"; abi = "cygnus"; } + then mkSkeletonFromList [ (elemAt l 0) "pc" "cygwin" ] # MSVC ought to be the default ABI so this case isn't needed. But then it # becomes difficult to handle the gnu* variants for Aarch32 correctly for # minGW. So it's easier to make gnu* the default for the MinGW, but @@ -479,6 +479,13 @@ rec { then "windows" # autotools breaks on -gnu for window else elemAt l 2; } + # lots of tools expect a triplet for Cygwin, even though the vendor is just "pc" + else if elemAt l 2 == "cygwin" + then { + cpu = elemAt l 0; + kernel = "windows"; + abi = "cygnus"; + } else throw "Target specification with 3 components is ambiguous"; "4" = { cpu = elemAt l 0; vendor = elemAt l 1; kernel = elemAt l 2; abi = elemAt l 3; }; }.${toString (length l)} From 12c6e6224f25799c4f3ae1340498dd41a498285e Mon Sep 17 00:00:00 2001 From: Brian McKenna Date: Fri, 8 Nov 2024 01:10:40 +0000 Subject: [PATCH 02/13] cygwin: add pre-libc headers --- .../compilers/gcc/common/configure-flags.nix | 4 ++ pkgs/os-specific/windows/cygwin/headers.nix | 40 +++++++++++++++++++ pkgs/os-specific/windows/default.nix | 1 + .../os-specific/windows/mingw-w64/headers.nix | 2 + pkgs/top-level/all-packages.nix | 1 + 5 files changed, 48 insertions(+) create mode 100644 pkgs/os-specific/windows/cygwin/headers.nix diff --git a/pkgs/development/compilers/gcc/common/configure-flags.nix b/pkgs/development/compilers/gcc/common/configure-flags.nix index 25d4f1f53bae9..9d33891d661db 100644 --- a/pkgs/development/compilers/gcc/common/configure-flags.nix +++ b/pkgs/development/compilers/gcc/common/configure-flags.nix @@ -242,6 +242,10 @@ let # cc1: error: fp software completion requires '-mtrap-precision=i' [-Werror] "--disable-werror" ] + ++ lib.optionals targetPlatform.isCygwin [ + # doesn't cross-compile under Cygwin + "--disable-libvtv" + ] ; in configureFlags diff --git a/pkgs/os-specific/windows/cygwin/headers.nix b/pkgs/os-specific/windows/cygwin/headers.nix new file mode 100644 index 0000000000000..ecceb372b0805 --- /dev/null +++ b/pkgs/os-specific/windows/cygwin/headers.nix @@ -0,0 +1,40 @@ +{ + lib, + stdenvNoCC, + fetchFromGitHub, + fetchpatch, + mingw_w64_headers, +}: + +stdenvNoCC.mkDerivation (finalAttrs: { + pname = "cygwin-headers"; + version = "3.5.4"; + + src = fetchFromGitHub { + owner = "mirror"; + repo = "newlib-cygwin"; + rev = "cygwin-${finalAttrs.version}"; + hash = "sha256-ZfT6JhOXLCJOY0vSVz6aKShmtuTN9/0NZ1k1RMSZX4Q="; + }; + + patches = [ + (fetchpatch { + url = "https://raw.githubusercontent.com/Windows-on-ARM-Experiments/mingw-woarm64-build/371102dfa23b3e56b6759e1a44026d0640d55223/patches/cygwin/0001-before-autogen.patch"; + sha256 = "sha256-1JsbfYAPpsQSjknZcKfJOHA0RcdmgzkzAI4RcHG1kpA="; + }) + ]; + + dontConfigure = true; + dontBuild = true; + + installPhase = '' + mkdir -p $out/include/ + ln -s ${mingw_w64_headers}/include/w32api $out/include/ + cp -r newlib/libc/include/* $out/include/ + cp -r winsup/cygwin/include/* $out/include/ + ''; + + meta = { + platforms = lib.platforms.windows; + }; +}) diff --git a/pkgs/os-specific/windows/default.nix b/pkgs/os-specific/windows/default.nix index 59806318a23ec..3e7fd4912060e 100644 --- a/pkgs/os-specific/windows/default.nix +++ b/pkgs/os-specific/windows/default.nix @@ -16,6 +16,7 @@ lib.makeScope newScope ( dlfcn = callPackage ./dlfcn { }; w32api = callPackage ./w32api { }; + cygwin_headers = callPackage ./cygwin/headers.nix { }; mingwrt = callPackage ./mingwrt { }; mingw_runtime = mingwrt; diff --git a/pkgs/os-specific/windows/mingw-w64/headers.nix b/pkgs/os-specific/windows/mingw-w64/headers.nix index daae7ee0aa42a..78bee797ac0fa 100644 --- a/pkgs/os-specific/windows/mingw-w64/headers.nix +++ b/pkgs/os-specific/windows/mingw-w64/headers.nix @@ -17,6 +17,8 @@ stdenvNoCC.mkDerivation (finalAttrs: { cd mingw-w64-headers ''; + configureFlags = lib.optionals stdenvNoCC.targetPlatform.isCygwin [ "--enable-w32api" ]; + meta = { platforms = lib.platforms.windows; }; diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index 2963ef53755a0..2b51ec2f307ee 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -19546,6 +19546,7 @@ with pkgs; preLibcCrossHeaders = let inherit (stdenv.targetPlatform) libc; in if stdenv.targetPlatform.isMinGW then targetPackages.windows.mingw_w64_headers or windows.mingw_w64_headers + else if stdenv.targetPlatform.isCygwin then targetPackages.windows.cygwin_headers or windows.cygwin_headers else if libc == "nblibc" then targetPackages.netbsd.headers or netbsd.headers else null; From e670bc62dda26d65b9a476f28c061721b61e8bb0 Mon Sep 17 00:00:00 2001 From: Brian McKenna Date: Fri, 8 Nov 2024 01:13:55 +0000 Subject: [PATCH 03/13] cygwin: remove old w32api, it's in mingw-w64 --- pkgs/os-specific/windows/default.nix | 1 - .../os-specific/windows/mingw-w64/default.nix | 5 +++-- pkgs/os-specific/windows/w32api/default.nix | 21 ------------------- 3 files changed, 3 insertions(+), 24 deletions(-) delete mode 100644 pkgs/os-specific/windows/w32api/default.nix diff --git a/pkgs/os-specific/windows/default.nix b/pkgs/os-specific/windows/default.nix index 3e7fd4912060e..e886ce2c6b6fe 100644 --- a/pkgs/os-specific/windows/default.nix +++ b/pkgs/os-specific/windows/default.nix @@ -15,7 +15,6 @@ lib.makeScope newScope ( dlfcn = callPackage ./dlfcn { }; - w32api = callPackage ./w32api { }; cygwin_headers = callPackage ./cygwin/headers.nix { }; mingwrt = callPackage ./mingwrt { }; diff --git a/pkgs/os-specific/windows/mingw-w64/default.nix b/pkgs/os-specific/windows/mingw-w64/default.nix index d8103d7b8d37d..1f2b04d7a89fd 100644 --- a/pkgs/os-specific/windows/mingw-w64/default.nix +++ b/pkgs/os-specific/windows/mingw-w64/default.nix @@ -22,8 +22,9 @@ stdenv.mkDerivation { ]; configureFlags = [ - (lib.enableFeature true "idl") - (lib.enableFeature true "secure-api") + (lib.enableFeature stdenv.targetPlatform.isMinGW "idl") + (lib.enableFeature stdenv.targetPlatform.isMinGW "secure-api") + (lib.enableFeature stdenv.targetPlatform.isCygwin "w32api") (lib.withFeatureAs true "default-msvcrt" crt) # Including other architectures causes errors with invalid asm diff --git a/pkgs/os-specific/windows/w32api/default.nix b/pkgs/os-specific/windows/w32api/default.nix deleted file mode 100644 index e368338525664..0000000000000 --- a/pkgs/os-specific/windows/w32api/default.nix +++ /dev/null @@ -1,21 +0,0 @@ -{ - stdenv, - fetchurl, - lib, -}: - -stdenv.mkDerivation rec { - pname = "w32api"; - version = "3.17-2"; - - src = fetchurl { - url = "mirror://sourceforge/mingw/MinGW/Base/w32api/w32api-${lib.versions.majorMinor version}/w32api-${version}-mingw32-src.tar.lzma"; - sha256 = "09rhnl6zikmdyb960im55jck0rdy5z9nlg3akx68ixn7khf3j8wb"; - }; - - meta = { - platforms = lib.platforms.windows; - }; - - dontStrip = true; -} From b6262e05e9cc883dd94345d13e24d7d53af7b6cb Mon Sep 17 00:00:00 2001 From: Brian McKenna Date: Fri, 8 Nov 2024 01:15:52 +0000 Subject: [PATCH 04/13] cocom-tool-set: init at 0.996 --- pkgs/by-name/co/cocom-tool-set/package.nix | 28 +++++++++++++ .../co/cocom-tool-set/remove-lto.patch | 42 +++++++++++++++++++ 2 files changed, 70 insertions(+) create mode 100644 pkgs/by-name/co/cocom-tool-set/package.nix create mode 100644 pkgs/by-name/co/cocom-tool-set/remove-lto.patch diff --git a/pkgs/by-name/co/cocom-tool-set/package.nix b/pkgs/by-name/co/cocom-tool-set/package.nix new file mode 100644 index 0000000000000..c0a3409c04a03 --- /dev/null +++ b/pkgs/by-name/co/cocom-tool-set/package.nix @@ -0,0 +1,28 @@ +{ + lib, + stdenv, + fetchgit, + bison, +}: +stdenv.mkDerivation { + pname = "cocom"; + version = "0.996"; + + src = fetchgit { + url = "https://git.code.sf.net/p/cocom/git"; + sha256 = "sha256-utLafkznMC4LrZgF6vKehtIGMwNMwLP9M9Nwu/RyWio="; + rev = "64ee80224aa13f9944d439f3f90862ca76158705"; + }; + + nativeBuildInputs = [ bison ]; + + patches = [ ./remove-lto.patch ]; + + meta = { + description = "Tool set oriented towards the creation of compilers"; + homepage = "https://cocom.sourceforge.net/"; + license = lib.licenses.gpl2Plus; + maintainers = with lib.maintainers; [ puffnfresh ]; + platforms = lib.platforms.linux; + }; +} diff --git a/pkgs/by-name/co/cocom-tool-set/remove-lto.patch b/pkgs/by-name/co/cocom-tool-set/remove-lto.patch new file mode 100644 index 0000000000000..0726a1b8b0162 --- /dev/null +++ b/pkgs/by-name/co/cocom-tool-set/remove-lto.patch @@ -0,0 +1,42 @@ +diff --git a/configure b/configure +index 574cbe9..0dc2aa0 100755 +--- a/configure ++++ b/configure +@@ -5858,37 +5858,6 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + CXXFLAGS="`echo $CXXFLAGS|sed s/-O2//` -O3" + fi + +- my_save_cflags="$CFLAGS" +- CFLAGS=-flto +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether CC supports -flto" >&5 +-$as_echo_n "checking whether CC supports -flto... " >&6; } +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +-int +-main () +-{ +- +- ; +- return 0; +-} +-_ACEOF +-if ac_fn_c_try_compile "$LINENO"; then : +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +-$as_echo "yes" >&6; } +- lto=yes +-else +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +-$as_echo "no" >&6; } +- +-fi +-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +- CFLAGS="$my_save_cflags" +- if test "$lto" = yes; then +- CFLAGS="`echo $CFLAGS` -flto" +- CXXFLAGS="`echo $CXXFLAGS` -flto" +- fi +- + system=`uname -m` + case $system in + i386*|i486*|i586*|i686*) From 4ecdadfa9ae80270a0ff4946d257a75e920b26db Mon Sep 17 00:00:00 2001 From: Brian McKenna Date: Fri, 8 Nov 2024 01:17:26 +0000 Subject: [PATCH 05/13] cygwin: package newlib-cygwin as the libc --- pkgs/development/compilers/gcc/default.nix | 7 +- .../windows/cygwin/after-autogen.patch | 158 ++++++++++++++++++ pkgs/os-specific/windows/cygwin/default.nix | 65 +++++++ pkgs/os-specific/windows/default.nix | 3 + .../os-specific/windows/mingw-w64/default.nix | 16 ++ pkgs/top-level/all-packages.nix | 3 +- 6 files changed, 250 insertions(+), 2 deletions(-) create mode 100644 pkgs/os-specific/windows/cygwin/after-autogen.patch create mode 100644 pkgs/os-specific/windows/cygwin/default.nix diff --git a/pkgs/development/compilers/gcc/default.nix b/pkgs/development/compilers/gcc/default.nix index d5d59adabb74c..8e682b419f0d2 100644 --- a/pkgs/development/compilers/gcc/default.nix +++ b/pkgs/development/compilers/gcc/default.nix @@ -245,7 +245,12 @@ pipe ((callFile ./common/builder.nix {}) ({ '-s' # workaround for hitting hydra log limit 'LIMITS_H_TEST=false' ) - ''); + '') + + optionalString targetPlatform.isCygwin ('' + substituteInPlace gcc/config/i386/cygwin.h \ + --replace '../../include/w32api' "${libcCross}/include/w32api" \ + --replace '../include/w32api' "${libcCross}/include/w32api" + ''); inherit noSysDirs staticCompiler withoutTargetLibc libcCross crossMingw; diff --git a/pkgs/os-specific/windows/cygwin/after-autogen.patch b/pkgs/os-specific/windows/cygwin/after-autogen.patch new file mode 100644 index 0000000000000..fa4748093e332 --- /dev/null +++ b/pkgs/os-specific/windows/cygwin/after-autogen.patch @@ -0,0 +1,158 @@ +--- winsup/configure.old 2024-11-01 22:38:21.005768397 +1100 ++++ winsup/configure 2024-11-01 22:39:33.247435255 +1100 +@@ -3970,155 +3970,6 @@ + _ACEOF + ac_clean_files_save=$ac_clean_files + ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" +-# Try to create an executable without -o first, disregard a.out. +-# It will help us diagnose broken compilers, and finding out an intuition +-# of exeext. +-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 +-printf %s "checking whether the C compiler works... " >&6; } +-ac_link_default=`printf "%s\n" "$ac_link" | sed 's/ -o *conftest[^ ]*//'` +- +-# The possible output files: +-ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" +- +-ac_rmfiles= +-for ac_file in $ac_files +-do +- case $ac_file in +- *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; +- * ) ac_rmfiles="$ac_rmfiles $ac_file";; +- esac +-done +-rm -f $ac_rmfiles +- +-if { { ac_try="$ac_link_default" +-case "(($ac_try" in +- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; +- *) ac_try_echo=$ac_try;; +-esac +-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +-printf "%s\n" "$ac_try_echo"; } >&5 +- (eval "$ac_link_default") 2>&5 +- ac_status=$? +- printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 +- test $ac_status = 0; } +-then : +- # Autoconf-2.13 could set the ac_cv_exeext variable to 'no'. +-# So ignore a value of 'no', otherwise this would lead to 'EXEEXT = no' +-# in a Makefile. We should not override ac_cv_exeext if it was cached, +-# so that the user can short-circuit this test for compilers unknown to +-# Autoconf. +-for ac_file in $ac_files '' +-do +- test -f "$ac_file" || continue +- case $ac_file in +- *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) +- ;; +- [ab].out ) +- # We found the default executable, but exeext='' is most +- # certainly right. +- break;; +- *.* ) +- if test ${ac_cv_exeext+y} && test "$ac_cv_exeext" != no; +- then :; else +- ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` +- fi +- # We set ac_cv_exeext here because the later test for it is not +- # safe: cross compilers may not add the suffix if given an '-o' +- # argument, so we may need to know it at that point already. +- # Even if this section looks crufty: it has the advantage of +- # actually working. +- break;; +- * ) +- break;; +- esac +-done +-test "$ac_cv_exeext" = no && ac_cv_exeext= +- +-else case e in #( +- e) ac_file='' ;; +-esac +-fi +-if test -z "$ac_file" +-then : +- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +-printf "%s\n" "no" >&6; } +-printf "%s\n" "$as_me: failed program was:" >&5 +-sed 's/^/| /' conftest.$ac_ext >&5 +- +-{ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 +-printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} +-as_fn_error 77 "C compiler cannot create executables +-See 'config.log' for more details" "$LINENO" 5; } +-else case e in #( +- e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +-printf "%s\n" "yes" >&6; } ;; +-esac +-fi +-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 +-printf %s "checking for C compiler default output file name... " >&6; } +-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 +-printf "%s\n" "$ac_file" >&6; } +-ac_exeext=$ac_cv_exeext +- +-rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out +-ac_clean_files=$ac_clean_files_save +-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 +-printf %s "checking for suffix of executables... " >&6; } +-if { { ac_try="$ac_link" +-case "(($ac_try" in +- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; +- *) ac_try_echo=$ac_try;; +-esac +-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +-printf "%s\n" "$ac_try_echo"; } >&5 +- (eval "$ac_link") 2>&5 +- ac_status=$? +- printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 +- test $ac_status = 0; } +-then : +- # If both 'conftest.exe' and 'conftest' are 'present' (well, observable) +-# catch 'conftest.exe'. For instance with Cygwin, 'ls conftest' will +-# work properly (i.e., refer to 'conftest.exe'), while it won't with +-# 'rm'. +-for ac_file in conftest.exe conftest conftest.*; do +- test -f "$ac_file" || continue +- case $ac_file in +- *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; +- *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` +- break;; +- * ) break;; +- esac +-done +-else case e in #( +- e) { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 +-printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} +-as_fn_error $? "cannot compute suffix of executables: cannot compile and link +-See 'config.log' for more details" "$LINENO" 5; } ;; +-esac +-fi +-rm -f conftest conftest$ac_cv_exeext +-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 +-printf "%s\n" "$ac_cv_exeext" >&6; } +- +-rm -f conftest.$ac_ext +-EXEEXT=$ac_cv_exeext +-ac_exeext=$EXEEXT +-cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +-#include +-int +-main (void) +-{ +-FILE *f = fopen ("conftest.out", "w"); +- if (!f) +- return 1; +- return ferror (f) || fclose (f) != 0; +- +- ; +- return 0; +-} +-_ACEOF +-ac_clean_files="$ac_clean_files conftest.out" + # Check that the compiler produces executables we can run. If not, either + # the compiler is broken, or we cross compile. + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 diff --git a/pkgs/os-specific/windows/cygwin/default.nix b/pkgs/os-specific/windows/cygwin/default.nix new file mode 100644 index 0000000000000..a5b95f2b5b902 --- /dev/null +++ b/pkgs/os-specific/windows/cygwin/default.nix @@ -0,0 +1,65 @@ +{ + lib, + stdenv, + cygwin_headers, + buildPackages, + automake, + autoconf, + bison, + cocom-tool-set, + flex, + perl, + mingw_w64, +}: + +stdenv.mkDerivation { + pname = "cygwin"; + + inherit (cygwin_headers) + version + src + meta + patches + ; + + preConfigure = '' + pushd winsup + aclocal --force + autoconf -f + automake -ac + rm -rf autom4te.cache + popd + patch -p0 -i ${./after-autogen.patch} + ''; + + postPatch = '' + patchShebangs --build winsup/cygwin/scripts + ''; + + env.CXXFLAGS_FOR_TARGET = "-Wno-error"; + + depsBuildBuild = [ buildPackages.stdenv.cc ]; + nativeBuildInputs = [ + autoconf + automake + bison + cocom-tool-set + flex + perl + ]; + buildInputs = [ mingw_w64 ]; + + hardeningDisable = [ "fortify" ]; + configurePlatforms = [ + "build" + "target" + ]; + configureFlags = [ + "--disable-shared" + "--disable-doc" + "--enable-static" + "--disable-dumper" + "--with-cross-bootstrap" + "ac_cv_prog_CC=gcc" + ]; +} diff --git a/pkgs/os-specific/windows/default.nix b/pkgs/os-specific/windows/default.nix index e886ce2c6b6fe..00e88760d86d6 100644 --- a/pkgs/os-specific/windows/default.nix +++ b/pkgs/os-specific/windows/default.nix @@ -15,6 +15,9 @@ lib.makeScope newScope ( dlfcn = callPackage ./dlfcn { }; + cygwin = callPackage ./cygwin { + stdenv = stdenvNoLibc; + }; cygwin_headers = callPackage ./cygwin/headers.nix { }; mingwrt = callPackage ./mingwrt { }; diff --git a/pkgs/os-specific/windows/mingw-w64/default.nix b/pkgs/os-specific/windows/mingw-w64/default.nix index 1f2b04d7a89fd..d490debcebb0f 100644 --- a/pkgs/os-specific/windows/mingw-w64/default.nix +++ b/pkgs/os-specific/windows/mingw-w64/default.nix @@ -33,6 +33,22 @@ stdenv.mkDerivation { (lib.enableFeature stdenv.hostPlatform.isAarch64 "libarm64") ]; + postInstall = lib.optionalString stdenv.targetPlatform.isCygwin '' + cd $out/lib + ln -fs w32api/libkernel32.a . + ln -fs w32api/libuser32.a . + ln -fs w32api/libadvapi32.a . + ln -fs w32api/libshell32.a . + ln -fs w32api/libgdi32.a . + ln -fs w32api/libcomdlg32.a . + ln -fs w32api/libntdll.a . + ln -fs w32api/libnetapi32.a . + ln -fs w32api/libpsapi.a . + ln -fs w32api/libuserenv.a . + ln -fs w32api/libnetapi32.a . + ln -fs w32api/libdbghelp.a . + ''; + enableParallelBuilding = true; nativeBuildInputs = [ autoreconfHook ]; diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index 2b51ec2f307ee..fef945edbb7aa 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -14462,7 +14462,7 @@ with pkgs; isl = if !stdenv.hostPlatform.isDarwin then isl_0_20 else null; withoutTargetLibc = true; - langCC = false; + langCC = stdenv.targetPlatform.isCygwin; # can't compile libcygwin1.a without C++ libcCross = libcCross1; targetPackages.stdenv.cc.bintools = binutilsNoLibc; enableShared = @@ -19567,6 +19567,7 @@ with pkgs; else if name == "musl" then targetPackages.muslCross or muslCross else if name == "msvcrt" then targetPackages.windows.mingw_w64 or windows.mingw_w64 else if name == "ucrt" then targetPackages.windows.mingw_w64 or windows.mingw_w64 + else if name == "cygwin" then targetPackages.windows.cygwin or windows.cygwin else if name == "libSystem" then if stdenv.targetPlatform.useiOSPrebuilt then targetPackages.darwin.iosSdkPkgs.libraries or darwin.iosSdkPkgs.libraries From 85dd4c2a0385b73ddee90b382f6d998a41d25adf Mon Sep 17 00:00:00 2001 From: Brian McKenna Date: Fri, 8 Nov 2024 01:25:26 +0000 Subject: [PATCH 06/13] cygwin: create libc from joined newlib-cygwin and mingw_w64 --- pkgs/os-specific/windows/cygwin/default.nix | 107 ++++++++++++-------- 1 file changed, 64 insertions(+), 43 deletions(-) diff --git a/pkgs/os-specific/windows/cygwin/default.nix b/pkgs/os-specific/windows/cygwin/default.nix index a5b95f2b5b902..6f2ed2cf3729f 100644 --- a/pkgs/os-specific/windows/cygwin/default.nix +++ b/pkgs/os-specific/windows/cygwin/default.nix @@ -10,56 +10,77 @@ flex, perl, mingw_w64, + symlinkJoin, }: -stdenv.mkDerivation { - pname = "cygwin"; +let + newlib-cygwin = stdenv.mkDerivation { + pname = "cygwin"; - inherit (cygwin_headers) - version - src - meta - patches - ; + inherit (cygwin_headers) + version + src + meta + patches + ; - preConfigure = '' - pushd winsup - aclocal --force - autoconf -f - automake -ac - rm -rf autom4te.cache - popd - patch -p0 -i ${./after-autogen.patch} - ''; + preConfigure = '' + pushd winsup + aclocal --force + autoconf -f + automake -ac + rm -rf autom4te.cache + popd + patch -p0 -i ${./after-autogen.patch} + ''; - postPatch = '' - patchShebangs --build winsup/cygwin/scripts - ''; + postPatch = '' + patchShebangs --build winsup/cygwin/scripts + ''; - env.CXXFLAGS_FOR_TARGET = "-Wno-error"; + env.CXXFLAGS_FOR_TARGET = "-Wno-error"; - depsBuildBuild = [ buildPackages.stdenv.cc ]; - nativeBuildInputs = [ - autoconf - automake - bison - cocom-tool-set - flex - perl - ]; - buildInputs = [ mingw_w64 ]; + depsBuildBuild = [ buildPackages.stdenv.cc ]; + nativeBuildInputs = [ + autoconf + automake + bison + cocom-tool-set + flex + perl + ]; + buildInputs = [ mingw_w64 ]; - hardeningDisable = [ "fortify" ]; - configurePlatforms = [ - "build" - "target" - ]; - configureFlags = [ - "--disable-shared" - "--disable-doc" - "--enable-static" - "--disable-dumper" - "--with-cross-bootstrap" - "ac_cv_prog_CC=gcc" + postInstall = '' + mv $out/x86_64-pc-cygwin/* $out/ + rmdir $out/x86_64-pc-cygwin + ''; + + hardeningDisable = [ + "fortify" + "stackprotector" + ]; + configurePlatforms = [ + "build" + "target" + ]; + configureFlags = [ + "--disable-shared" + "--disable-doc" + "--enable-static" + "--disable-dumper" + "--with-cross-bootstrap" + "ac_cv_prog_CC=gcc" + ]; + }; +in +# TODO: Is there something like nix-support which would achieve this better? +symlinkJoin { + pname = "cygwin-and-mingw_w64"; + inherit (newlib-cygwin) version; + paths = [ + newlib-cygwin + mingw_w64 + mingw_w64.dev ]; } From 8692585ef3fdff570e56747fe75f34e8e08da0dc Mon Sep 17 00:00:00 2001 From: Brian McKenna Date: Fri, 8 Nov 2024 01:26:47 +0000 Subject: [PATCH 07/13] readline: fix compilation under Cygwin --- pkgs/development/libraries/readline/8.2.nix | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/pkgs/development/libraries/readline/8.2.nix b/pkgs/development/libraries/readline/8.2.nix index 7bf5caf4060f1..40833dec2533d 100644 --- a/pkgs/development/libraries/readline/8.2.nix +++ b/pkgs/development/libraries/readline/8.2.nix @@ -3,7 +3,7 @@ , updateAutotoolsGnuConfigScriptsHook , ncurses, termcap , curses-library ? - if stdenv.hostPlatform.isWindows + if stdenv.hostPlatform.isWindows && !stdenv.hostPlatform.isUnix then termcap else ncurses }: @@ -35,13 +35,15 @@ stdenv.mkDerivation rec { in import ./readline-8.2-patches.nix patch); + hardeningDisable = lib.optionals stdenv.hostPlatform.isCygwin [ "fortify" ]; + patches = lib.optionals (curses-library.pname == "ncurses") [ ./link-against-ncurses.patch ] ++ [ ./no-arch_only-8.2.patch ] ++ upstreamPatches - ++ lib.optionals stdenv.hostPlatform.isWindows [ + ++ lib.optionals (stdenv.hostPlatform.isWindows && !stdenv.hostPlatform.isUnix) [ (fetchpatch { name = "0001-sigwinch.patch"; url = "https://github.com/msys2/MINGW-packages/raw/90e7536e3b9c3af55c336d929cfcc32468b2f135/mingw-w64-readline/0001-sigwinch.patch"; From 8b47da26c80999a4ac32cb47427cc5cf2ffd8b02 Mon Sep 17 00:00:00 2001 From: Brian McKenna Date: Fri, 8 Nov 2024 01:27:10 +0000 Subject: [PATCH 08/13] ncurses: disable fortify under Cygwin --- pkgs/development/libraries/ncurses/default.nix | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pkgs/development/libraries/ncurses/default.nix b/pkgs/development/libraries/ncurses/default.nix index 0ee09d2416cd8..8dc98c70bdb83 100644 --- a/pkgs/development/libraries/ncurses/default.nix +++ b/pkgs/development/libraries/ncurses/default.nix @@ -99,6 +99,11 @@ stdenv.mkDerivation (finalAttrs: { CFLAGS=-D_XOPEN_SOURCE_EXTENDED ''; + # Fortify currently breaks under the nixpkgs' Cygwin with errors such as: + # two or more data types in declaration specifiers + # conflicting types for 'read' + hardeningDisable = lib.optionals stdenv.hostPlatform.isCygwin [ "fortify" ]; + enableParallelBuilding = true; doCheck = false; From 74bc0449269a80c546899d859e39089e9468bff2 Mon Sep 17 00:00:00 2001 From: Brian McKenna Date: Fri, 8 Nov 2024 01:27:29 +0000 Subject: [PATCH 09/13] bash: fix compilation under Cygwin --- pkgs/shells/bash/5.nix | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/pkgs/shells/bash/5.nix b/pkgs/shells/bash/5.nix index 1e1fe340dcda1..ae2c7742abc62 100644 --- a/pkgs/shells/bash/5.nix +++ b/pkgs/shells/bash/5.nix @@ -14,6 +14,7 @@ , forFHSEnv ? false , pkgsStatic +, ncurses }: let @@ -36,7 +37,7 @@ stdenv.mkDerivation rec { # bionic libc is super weird and has issues with fortify outside of its own libc, check this comment: # https://github.com/NixOS/nixpkgs/pull/192630#discussion_r978985593 # or you can check libc/include/sys/cdefs.h in bionic source code - ++ lib.optional (stdenv.hostPlatform.libc == "bionic") "fortify"; + ++ lib.optional (stdenv.hostPlatform.libc == "bionic" || stdenv.hostPlatform.isCygwin) "fortify"; outputs = [ "out" "dev" "man" "doc" "info" ]; @@ -84,10 +85,9 @@ stdenv.mkDerivation rec { ] ++ lib.optionals stdenv.hostPlatform.isCygwin [ "--without-libintl-prefix" "--without-libiconv-prefix" - "--with-installed-readline" + "--with-curses" "bash_cv_dev_stdin=present" "bash_cv_dev_fd=standard" - "bash_cv_termcap_lib=libncurses" ] ++ lib.optionals (stdenv.hostPlatform.libc == "musl") [ "--disable-nls" ] ++ lib.optionals stdenv.hostPlatform.isFreeBSD [ @@ -103,15 +103,10 @@ stdenv.mkDerivation rec { ++ lib.optional withDocs texinfo ++ lib.optional stdenv.hostPlatform.isDarwin stdenv.cc.bintools; - buildInputs = lib.optional interactive readline; + buildInputs = lib.optional interactive readline ++ lib.optionals stdenv.hostPlatform.isCygwin [ ncurses ]; enableParallelBuilding = true; - makeFlags = lib.optionals stdenv.hostPlatform.isCygwin [ - "LOCAL_LDFLAGS=-Wl,--export-all,--out-implib,libbash.dll.a" - "SHOBJ_LIBS=-lbash" - ]; - nativeCheckInputs = [ util-linux ]; doCheck = false; # dependency cycle, needs to be interactive From 3495b2eeff4953b68c05294f6a7a1a5a1c50b24c Mon Sep 17 00:00:00 2001 From: Brian McKenna Date: Fri, 8 Nov 2024 01:27:47 +0000 Subject: [PATCH 10/13] cygwin: include libcygwin1.dll in DLL search path --- pkgs/build-support/cc-wrapper/default.nix | 1 + 1 file changed, 1 insertion(+) diff --git a/pkgs/build-support/cc-wrapper/default.nix b/pkgs/build-support/cc-wrapper/default.nix index 085f64d37dd4b..8a0c9ab0787b9 100644 --- a/pkgs/build-support/cc-wrapper/default.nix +++ b/pkgs/build-support/cc-wrapper/default.nix @@ -474,6 +474,7 @@ stdenvNoCC.mkDerivation { echo addToSearchPath "LINK_DLL_FOLDERS" "${cc_solib}/lib" > $out echo addToSearchPath "LINK_DLL_FOLDERS" "${cc_solib}/lib64" >> $out echo addToSearchPath "LINK_DLL_FOLDERS" "${cc_solib}/lib32" >> $out + echo addToSearchPath "LINK_DLL_FOLDERS" "${libc_bin}/bin" > $out ''; }); From c0b60f38d17897cfc626e58215f1a4c0a85ef8fc Mon Sep 17 00:00:00 2001 From: Brian McKenna Date: Sat, 9 Nov 2024 09:19:30 +1100 Subject: [PATCH 11/13] bintools-wrapper: don't set fortify on Cygwin The size of various things don't line up when enabling fortification. This might be able to be fixed by looking at the Cywin builds, because I think they don't generally disable fortify. --- pkgs/build-support/bintools-wrapper/default.nix | 2 ++ pkgs/development/libraries/ncurses/default.nix | 5 ----- pkgs/development/libraries/readline/8.2.nix | 2 -- pkgs/shells/bash/5.nix | 2 +- 4 files changed, 3 insertions(+), 8 deletions(-) diff --git a/pkgs/build-support/bintools-wrapper/default.nix b/pkgs/build-support/bintools-wrapper/default.nix index a2a0736c2221b..5f9904162a0bf 100644 --- a/pkgs/build-support/bintools-wrapper/default.nix +++ b/pkgs/build-support/bintools-wrapper/default.nix @@ -39,8 +39,10 @@ , defaultHardeningFlags ? [ "bindnow" "format" + ] ++ lib.optionals (!stdenvNoCC.targetPlatform.isCygwin) [ "fortify" "fortify3" + ] ++ [ "pic" "relro" "stackprotector" diff --git a/pkgs/development/libraries/ncurses/default.nix b/pkgs/development/libraries/ncurses/default.nix index 8dc98c70bdb83..0ee09d2416cd8 100644 --- a/pkgs/development/libraries/ncurses/default.nix +++ b/pkgs/development/libraries/ncurses/default.nix @@ -99,11 +99,6 @@ stdenv.mkDerivation (finalAttrs: { CFLAGS=-D_XOPEN_SOURCE_EXTENDED ''; - # Fortify currently breaks under the nixpkgs' Cygwin with errors such as: - # two or more data types in declaration specifiers - # conflicting types for 'read' - hardeningDisable = lib.optionals stdenv.hostPlatform.isCygwin [ "fortify" ]; - enableParallelBuilding = true; doCheck = false; diff --git a/pkgs/development/libraries/readline/8.2.nix b/pkgs/development/libraries/readline/8.2.nix index 40833dec2533d..4f85d75ad3256 100644 --- a/pkgs/development/libraries/readline/8.2.nix +++ b/pkgs/development/libraries/readline/8.2.nix @@ -35,8 +35,6 @@ stdenv.mkDerivation rec { in import ./readline-8.2-patches.nix patch); - hardeningDisable = lib.optionals stdenv.hostPlatform.isCygwin [ "fortify" ]; - patches = lib.optionals (curses-library.pname == "ncurses") [ ./link-against-ncurses.patch ] ++ [ diff --git a/pkgs/shells/bash/5.nix b/pkgs/shells/bash/5.nix index ae2c7742abc62..ecc0813551389 100644 --- a/pkgs/shells/bash/5.nix +++ b/pkgs/shells/bash/5.nix @@ -37,7 +37,7 @@ stdenv.mkDerivation rec { # bionic libc is super weird and has issues with fortify outside of its own libc, check this comment: # https://github.com/NixOS/nixpkgs/pull/192630#discussion_r978985593 # or you can check libc/include/sys/cdefs.h in bionic source code - ++ lib.optional (stdenv.hostPlatform.libc == "bionic" || stdenv.hostPlatform.isCygwin) "fortify"; + ++ lib.optional (stdenv.hostPlatform.libc == "bionic") "fortify"; outputs = [ "out" "dev" "man" "doc" "info" ]; From 20d2d5b9931bc9a6e73120abebeda6076b569246 Mon Sep 17 00:00:00 2001 From: Brian McKenna Date: Sat, 9 Nov 2024 09:21:17 +1100 Subject: [PATCH 12/13] bash: set empty makeFlags to avoid mass rebuild --- pkgs/shells/bash/5.nix | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pkgs/shells/bash/5.nix b/pkgs/shells/bash/5.nix index ecc0813551389..860dd64362595 100644 --- a/pkgs/shells/bash/5.nix +++ b/pkgs/shells/bash/5.nix @@ -107,6 +107,8 @@ stdenv.mkDerivation rec { enableParallelBuilding = true; + makeFlags = [ ]; + nativeCheckInputs = [ util-linux ]; doCheck = false; # dependency cycle, needs to be interactive From 573c420de7c44b44e49981edf2b80aafae17756e Mon Sep 17 00:00:00 2001 From: Brian McKenna Date: Sat, 9 Nov 2024 09:21:38 +1100 Subject: [PATCH 13/13] mingw-w64: allow Cygwin as a crt --- pkgs/os-specific/windows/mingw-w64/default.nix | 1 + 1 file changed, 1 insertion(+) diff --git a/pkgs/os-specific/windows/mingw-w64/default.nix b/pkgs/os-specific/windows/mingw-w64/default.nix index d490debcebb0f..684d4bd3efeeb 100644 --- a/pkgs/os-specific/windows/mingw-w64/default.nix +++ b/pkgs/os-specific/windows/mingw-w64/default.nix @@ -10,6 +10,7 @@ assert lib.assertOneOf "crt" crt [ "msvcrt" "ucrt" + "cygwin" ]; stdenv.mkDerivation {