Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cygwin: add as a cross-compilation target, and get bash.exe to compile #354137

Open
wants to merge 13 commits into
base: master
Choose a base branch
from
Open
7 changes: 6 additions & 1 deletion pkgs/development/compilers/gcc/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
158 changes: 158 additions & 0 deletions pkgs/os-specific/windows/cygwin/after-autogen.patch
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we instead patch configure.ac and regen with autoreconfHook?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe. This was copied from Microsoft's Windows-on-ARM-Experiments repository. Not sure why it was done that way.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh probably because they are lazy af lol

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why copied and not fetched? If you used fetchpatch you could even use extraPrefix to make it so you can just put it in patches.

Original file line number Diff line number Diff line change
@@ -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 <stdio.h>
-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
65 changes: 65 additions & 0 deletions pkgs/os-specific/windows/cygwin/default.nix
Original file line number Diff line number Diff line change
@@ -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"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why? This looks like it's hardcoding an assumption that the compiler is GCC.

];
}
3 changes: 3 additions & 0 deletions pkgs/os-specific/windows/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ lib.makeScope newScope (

dlfcn = callPackage ./dlfcn { };

cygwin = callPackage ./cygwin {
stdenv = stdenvNoLibc;
};
cygwin_headers = callPackage ./cygwin/headers.nix { };

mingwrt = callPackage ./mingwrt { };
Expand Down
16 changes: 16 additions & 0 deletions pkgs/os-specific/windows/mingw-w64/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -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 .
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would w32api/*.a be wrong?

Changing directory without changing back at the end also makes me worry about fixupPhase not working.

'';

enableParallelBuilding = true;

nativeBuildInputs = [ autoreconfHook ];
Expand Down
3 changes: 2 additions & 1 deletion pkgs/top-level/all-packages.nix
Original file line number Diff line number Diff line change
Expand Up @@ -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 =
Expand Down Expand Up @@ -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
Expand Down