Skip to content

Commit b29fa71

Browse files
authored
Merge pull request #4279 from Berrysoft/dev/cygwin-main
Add cygwin support
2 parents 3e3f29c + f5569b1 commit b29fa71

File tree

7 files changed

+2665
-6
lines changed

7 files changed

+2665
-6
lines changed

Diff for: build.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ const CHECK_CFG_EXTRA: &'static [(&'static str, &'static [&'static str])] = &[
2626
(
2727
"target_os",
2828
&[
29-
"switch", "aix", "ohos", "hurd", "rtems", "visionos", "nuttx",
29+
"switch", "aix", "ohos", "hurd", "rtems", "visionos", "nuttx", "cygwin",
3030
],
3131
),
3232
("target_env", &["illumos", "wasi", "aix", "ohos"]),

Diff for: libc-test/build.rs

+170
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ fn do_cc() {
3131
|| target.contains("emscripten")
3232
|| target.contains("fuchsia")
3333
|| target.contains("bsd")
34+
|| target.contains("cygwin")
3435
{
3536
cc::Build::new().file("src/makedev.c").compile("makedev");
3637
}
@@ -60,6 +61,7 @@ fn do_ctest() {
6061
t if t.contains("linux") => return test_linux(t),
6162
t if t.contains("netbsd") => return test_netbsd(t),
6263
t if t.contains("openbsd") => return test_openbsd(t),
64+
t if t.contains("cygwin") => return test_cygwin(t),
6365
t if t.contains("redox") => return test_redox(t),
6466
t if t.contains("solaris") => return test_solarish(t),
6567
t if t.contains("illumos") => return test_solarish(t),
@@ -642,6 +644,174 @@ fn test_openbsd(target: &str) {
642644
cfg.generate(src_hotfix_dir().join("lib.rs"), "main.rs");
643645
}
644646

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+
// For consistency with other platforms. Actually a function ptr.
744+
"sighandler_t" => true,
745+
746+
_ => false,
747+
});
748+
749+
cfg.skip_struct(move |ty| {
750+
if ty.starts_with("__c_anonymous_") {
751+
return true;
752+
}
753+
754+
false
755+
});
756+
757+
cfg.field_name(move |struct_, field| {
758+
match field {
759+
// Our stat *_nsec fields normally don't actually exist but are part
760+
// of a timeval struct
761+
s if s.ends_with("_nsec") && struct_.starts_with("stat") => {
762+
s.replace("e_nsec", ".tv_nsec")
763+
}
764+
765+
// FIXME(cygwin): sigaction actually contains a union with two variants:
766+
// a sa_sigaction with type: (*)(int, struct __siginfo *, void *)
767+
// a sa_handler with type sig_t
768+
"sa_sigaction" if struct_ == "sigaction" => "sa_handler".to_string(),
769+
770+
s => s.to_string(),
771+
}
772+
});
773+
774+
cfg.skip_field(|struct_, field| {
775+
match (struct_, field) {
776+
// this is actually a union on linux, so we can't represent it well and
777+
// just insert some padding.
778+
("ifreq", "ifr_ifru") => true,
779+
("ifconf", "ifc_ifcu") => true,
780+
781+
_ => false,
782+
}
783+
});
784+
785+
cfg.skip_fn(move |name| {
786+
// skip those that are manually verified
787+
match name {
788+
// There are two versions of the sterror_r function, see
789+
//
790+
// https://linux.die.net/man/3/strerror_r
791+
//
792+
// An XSI-compliant version provided if:
793+
//
794+
// (_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) && ! _GNU_SOURCE
795+
//
796+
// and a GNU specific version provided if _GNU_SOURCE is defined.
797+
//
798+
// libc provides bindings for the XSI-compliant version, which is
799+
// preferred for portable applications.
800+
//
801+
// We skip the test here since here _GNU_SOURCE is defined, and
802+
// test the XSI version below.
803+
"strerror_r" => true,
804+
805+
// FIXME(cygwin): does not exist on Cygwin
806+
"mlockall" | "munlockall" => true,
807+
808+
_ => false,
809+
}
810+
});
811+
812+
cfg.generate("../src/lib.rs", "main.rs");
813+
}
814+
645815
fn test_windows(target: &str) {
646816
assert!(target.contains("windows"));
647817
let gnu = target.contains("gnu");

Diff for: libc-test/semver/cygwin.txt

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
FORK_NO_RELOAD
2+
FORK_RELOAD
3+
MOUNT_AUTOMATIC
4+
MOUNT_BIND
5+
MOUNT_CYGDRIVE
6+
MOUNT_CYGWIN_EXEC
7+
MOUNT_DEVFS
8+
MOUNT_DONT_USE
9+
MOUNT_DOS
10+
MOUNT_EXEC
11+
MOUNT_IHASH
12+
MOUNT_IMMUTABLE
13+
MOUNT_NOACL
14+
MOUNT_NOPOSIX
15+
MOUNT_NOTEXEC
16+
MOUNT_OVERRIDE
17+
MOUNT_PROC
18+
MOUNT_RO
19+
MOUNT_SPARSE
20+
MOUNT_SYSTEM
21+
MOUNT_TEXT
22+
MOUNT_USER_TEMP
23+
WINDOWS_HWND
24+
WINDOWS_POST
25+
WINDOWS_SEND
26+
cygwin_umount
27+
dlfork

Diff for: libc-test/src/makedev.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#include <sys/types.h>
2-
#if defined(__linux__) || defined(__EMSCRIPTEN__)
2+
#if defined(__linux__) || defined(__EMSCRIPTEN__) || defined(__CYGWIN__)
33
#include <sys/sysmacros.h>
44
#endif
55

Diff for: libc-test/test/makedev.rs

+2
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ mod ret {
5454
target_os = "linux",
5555
target_os = "netbsd",
5656
target_os = "openbsd",
57+
target_os = "cygwin",
5758
))]
5859
mod t {
5960
use libc::{self, c_uint, dev_t};
@@ -133,6 +134,7 @@ mod t {
133134
target_os = "freebsd",
134135
target_os = "fuchsia",
135136
target_os = "linux",
137+
target_os = "cygwin",
136138
))]
137139
#[test]
138140
fn test_fbsd12_like() {

0 commit comments

Comments
 (0)