@@ -31,6 +31,7 @@ fn do_cc() {
31
31
|| target. contains ( "emscripten" )
32
32
|| target. contains ( "fuchsia" )
33
33
|| target. contains ( "bsd" )
34
+ || target. contains ( "cygwin" )
34
35
{
35
36
cc:: Build :: new ( ) . file ( "src/makedev.c" ) . compile ( "makedev" ) ;
36
37
}
@@ -60,6 +61,7 @@ fn do_ctest() {
60
61
t if t. contains ( "linux" ) => return test_linux ( t) ,
61
62
t if t. contains ( "netbsd" ) => return test_netbsd ( t) ,
62
63
t if t. contains ( "openbsd" ) => return test_openbsd ( t) ,
64
+ t if t. contains ( "cygwin" ) => return test_cygwin ( t) ,
63
65
t if t. contains ( "redox" ) => return test_redox ( t) ,
64
66
t if t. contains ( "solaris" ) => return test_solarish ( t) ,
65
67
t if t. contains ( "illumos" ) => return test_solarish ( t) ,
@@ -642,6 +644,173 @@ fn test_openbsd(target: &str) {
642
644
cfg. generate ( src_hotfix_dir ( ) . join ( "lib.rs" ) , "main.rs" ) ;
643
645
}
644
646
647
+ fn test_cygwin ( target : & str ) {
648
+ assert ! ( target. contains( "cygwin" ) ) ;
649
+
650
+ let mut cfg = ctest_cfg ( ) ;
651
+ cfg. define ( "_GNU_SOURCE" , None ) ;
652
+
653
+ headers ! { cfg:
654
+ "ctype.h" ,
655
+ "dirent.h" ,
656
+ "dlfcn.h" ,
657
+ "errno.h" ,
658
+ "fcntl.h" ,
659
+ "grp.h" ,
660
+ "iconv.h" ,
661
+ "langinfo.h" ,
662
+ "limits.h" ,
663
+ "locale.h" ,
664
+ "net/if.h" ,
665
+ "netdb.h" ,
666
+ "netinet/tcp.h" ,
667
+ "poll.h" ,
668
+ "pthread.h" ,
669
+ "pwd.h" ,
670
+ "resolv.h" ,
671
+ "sched.h" ,
672
+ "semaphore.h" ,
673
+ "signal.h" ,
674
+ "stddef.h" ,
675
+ "stdlib.h" ,
676
+ "string.h" ,
677
+ "sys/cpuset.h" ,
678
+ "sys/ioctl.h" ,
679
+ "sys/mman.h" ,
680
+ "sys/mount.h" ,
681
+ "sys/param.h" ,
682
+ "sys/quota.h" ,
683
+ "sys/random.h" ,
684
+ "sys/resource.h" ,
685
+ "sys/select.h" ,
686
+ "sys/socket.h" ,
687
+ "sys/statvfs.h" ,
688
+ "sys/times.h" ,
689
+ "sys/types.h" ,
690
+ "sys/uio.h" ,
691
+ "sys/un.h" ,
692
+ "sys/utsname.h" ,
693
+ "syslog.h" ,
694
+ "termios.h" ,
695
+ "unistd.h" ,
696
+ "utime.h" ,
697
+ "wait.h" ,
698
+ "wchar.h" ,
699
+ }
700
+
701
+ cfg. type_name ( move |ty, is_struct, is_union| {
702
+ match ty {
703
+ // Just pass all these through, no need for a "struct" prefix
704
+ "FILE" | "DIR" | "Dl_info" | "fd_set" => ty. to_string ( ) ,
705
+
706
+ "Ioctl" => "int" . to_string ( ) ,
707
+
708
+ t if is_union => format ! ( "union {}" , t) ,
709
+
710
+ t if t. ends_with ( "_t" ) => t. to_string ( ) ,
711
+
712
+ // sigval is a struct in Rust, but a union in C:
713
+ "sigval" => format ! ( "union sigval" ) ,
714
+
715
+ // put `struct` in front of all structs:.
716
+ t if is_struct => format ! ( "struct {}" , t) ,
717
+
718
+ t => t. to_string ( ) ,
719
+ }
720
+ } ) ;
721
+
722
+ cfg. skip_const ( move |name| {
723
+ match name {
724
+ // FIXME(cygwin): these constants do not exist on Cygwin
725
+ "ARPOP_REQUEST" | "ARPOP_REPLY" | "ATF_COM" | "ATF_PERM" | "ATF_PUBL"
726
+ | "ATF_USETRAILERS" => true ,
727
+
728
+ // not defined on Cygwin, but [get|set]priority is, so they are
729
+ // useful
730
+ "PRIO_MIN" | "PRIO_MAX" => true ,
731
+
732
+ // The following does not exist on Cygwin but is required by
733
+ // several crates
734
+ "FIOCLEX" | "SA_NOCLDWAIT" => true ,
735
+
736
+ _ => false ,
737
+ }
738
+ } ) ;
739
+
740
+ cfg. skip_signededness ( move |c| match c {
741
+ n if n. starts_with ( "pthread" ) => true ,
742
+
743
+ "sighandler_t" => true ,
744
+
745
+ _ => false ,
746
+ } ) ;
747
+
748
+ cfg. skip_struct ( move |ty| {
749
+ if ty. starts_with ( "__c_anonymous_" ) {
750
+ return true ;
751
+ }
752
+
753
+ false
754
+ } ) ;
755
+
756
+ cfg. field_name ( move |struct_, field| {
757
+ match field {
758
+ // Our stat *_nsec fields normally don't actually exist but are part
759
+ // of a timeval struct
760
+ s if s. ends_with ( "_nsec" ) && struct_. starts_with ( "stat" ) => {
761
+ s. replace ( "e_nsec" , ".tv_nsec" )
762
+ }
763
+
764
+ // FIXME(cygwin): sigaction actually contains a union with two variants:
765
+ // a sa_sigaction with type: (*)(int, struct __siginfo *, void *)
766
+ // a sa_handler with type sig_t
767
+ "sa_sigaction" if struct_ == "sigaction" => "sa_handler" . to_string ( ) ,
768
+
769
+ s => s. to_string ( ) ,
770
+ }
771
+ } ) ;
772
+
773
+ cfg. skip_field ( |struct_, field| {
774
+ match ( struct_, field) {
775
+ // this is actually a union on linux, so we can't represent it well and
776
+ // just insert some padding.
777
+ ( "ifreq" , "ifr_ifru" ) => true ,
778
+ ( "ifconf" , "ifc_ifcu" ) => true ,
779
+
780
+ _ => false ,
781
+ }
782
+ } ) ;
783
+
784
+ cfg. skip_fn ( move |name| {
785
+ // skip those that are manually verified
786
+ match name {
787
+ // There are two versions of the sterror_r function, see
788
+ //
789
+ // https://linux.die.net/man/3/strerror_r
790
+ //
791
+ // An XSI-compliant version provided if:
792
+ //
793
+ // (_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) && ! _GNU_SOURCE
794
+ //
795
+ // and a GNU specific version provided if _GNU_SOURCE is defined.
796
+ //
797
+ // libc provides bindings for the XSI-compliant version, which is
798
+ // preferred for portable applications.
799
+ //
800
+ // We skip the test here since here _GNU_SOURCE is defined, and
801
+ // test the XSI version below.
802
+ "strerror_r" => true ,
803
+
804
+ // FIXME(cygwin): does not exist on Cygwin
805
+ "mlockall" | "munlockall" => true ,
806
+
807
+ _ => false ,
808
+ }
809
+ } ) ;
810
+
811
+ cfg. generate ( "../src/lib.rs" , "main.rs" ) ;
812
+ }
813
+
645
814
fn test_windows ( target : & str ) {
646
815
assert ! ( target. contains( "windows" ) ) ;
647
816
let gnu = target. contains ( "gnu" ) ;
0 commit comments