Skip to content

Commit a73699c

Browse files
Berrysofttgross35
authored andcommitted
cygwin: add support
Co-authored-by: Ookiineko <[email protected]> (backport <rust-lang#4279>) (cherry picked from commit f5569b1)
1 parent e8b64cc commit a73699c

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
@@ -27,7 +27,7 @@ const CHECK_CFG_EXTRA: &'static [(&'static str, &'static [&'static str])] = &[
2727
(
2828
"target_os",
2929
&[
30-
"switch", "aix", "ohos", "hurd", "rtems", "visionos", "nuttx",
30+
"switch", "aix", "ohos", "hurd", "rtems", "visionos", "nuttx", "cygwin",
3131
],
3232
),
3333
("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),
@@ -686,6 +688,174 @@ fn test_openbsd(target: &str) {
686688
cfg.generate(src_hotfix_dir().join("lib.rs"), "main.rs");
687689
}
688690

691+
fn test_cygwin(target: &str) {
692+
assert!(target.contains("cygwin"));
693+
694+
let mut cfg = ctest_cfg();
695+
cfg.define("_GNU_SOURCE", None);
696+
697+
headers! { cfg:
698+
"ctype.h",
699+
"dirent.h",
700+
"dlfcn.h",
701+
"errno.h",
702+
"fcntl.h",
703+
"grp.h",
704+
"iconv.h",
705+
"langinfo.h",
706+
"limits.h",
707+
"locale.h",
708+
"net/if.h",
709+
"netdb.h",
710+
"netinet/tcp.h",
711+
"poll.h",
712+
"pthread.h",
713+
"pwd.h",
714+
"resolv.h",
715+
"sched.h",
716+
"semaphore.h",
717+
"signal.h",
718+
"stddef.h",
719+
"stdlib.h",
720+
"string.h",
721+
"sys/cpuset.h",
722+
"sys/ioctl.h",
723+
"sys/mman.h",
724+
"sys/mount.h",
725+
"sys/param.h",
726+
"sys/quota.h",
727+
"sys/random.h",
728+
"sys/resource.h",
729+
"sys/select.h",
730+
"sys/socket.h",
731+
"sys/statvfs.h",
732+
"sys/times.h",
733+
"sys/types.h",
734+
"sys/uio.h",
735+
"sys/un.h",
736+
"sys/utsname.h",
737+
"syslog.h",
738+
"termios.h",
739+
"unistd.h",
740+
"utime.h",
741+
"wait.h",
742+
"wchar.h",
743+
}
744+
745+
cfg.type_name(move |ty, is_struct, is_union| {
746+
match ty {
747+
// Just pass all these through, no need for a "struct" prefix
748+
"FILE" | "DIR" | "Dl_info" | "fd_set" => ty.to_string(),
749+
750+
"Ioctl" => "int".to_string(),
751+
752+
t if is_union => format!("union {}", t),
753+
754+
t if t.ends_with("_t") => t.to_string(),
755+
756+
// sigval is a struct in Rust, but a union in C:
757+
"sigval" => format!("union sigval"),
758+
759+
// put `struct` in front of all structs:.
760+
t if is_struct => format!("struct {}", t),
761+
762+
t => t.to_string(),
763+
}
764+
});
765+
766+
cfg.skip_const(move |name| {
767+
match name {
768+
// FIXME(cygwin): these constants do not exist on Cygwin
769+
"ARPOP_REQUEST" | "ARPOP_REPLY" | "ATF_COM" | "ATF_PERM" | "ATF_PUBL"
770+
| "ATF_USETRAILERS" => true,
771+
772+
// not defined on Cygwin, but [get|set]priority is, so they are
773+
// useful
774+
"PRIO_MIN" | "PRIO_MAX" => true,
775+
776+
// The following does not exist on Cygwin but is required by
777+
// several crates
778+
"FIOCLEX" | "SA_NOCLDWAIT" => true,
779+
780+
_ => false,
781+
}
782+
});
783+
784+
cfg.skip_signededness(move |c| match c {
785+
n if n.starts_with("pthread") => true,
786+
787+
// For consistency with other platforms. Actually a function ptr.
788+
"sighandler_t" => true,
789+
790+
_ => false,
791+
});
792+
793+
cfg.skip_struct(move |ty| {
794+
if ty.starts_with("__c_anonymous_") {
795+
return true;
796+
}
797+
798+
false
799+
});
800+
801+
cfg.field_name(move |struct_, field| {
802+
match field {
803+
// Our stat *_nsec fields normally don't actually exist but are part
804+
// of a timeval struct
805+
s if s.ends_with("_nsec") && struct_.starts_with("stat") => {
806+
s.replace("e_nsec", ".tv_nsec")
807+
}
808+
809+
// FIXME(cygwin): sigaction actually contains a union with two variants:
810+
// a sa_sigaction with type: (*)(int, struct __siginfo *, void *)
811+
// a sa_handler with type sig_t
812+
"sa_sigaction" if struct_ == "sigaction" => "sa_handler".to_string(),
813+
814+
s => s.to_string(),
815+
}
816+
});
817+
818+
cfg.skip_field(|struct_, field| {
819+
match (struct_, field) {
820+
// this is actually a union on linux, so we can't represent it well and
821+
// just insert some padding.
822+
("ifreq", "ifr_ifru") => true,
823+
("ifconf", "ifc_ifcu") => true,
824+
825+
_ => false,
826+
}
827+
});
828+
829+
cfg.skip_fn(move |name| {
830+
// skip those that are manually verified
831+
match name {
832+
// There are two versions of the sterror_r function, see
833+
//
834+
// https://linux.die.net/man/3/strerror_r
835+
//
836+
// An XSI-compliant version provided if:
837+
//
838+
// (_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) && ! _GNU_SOURCE
839+
//
840+
// and a GNU specific version provided if _GNU_SOURCE is defined.
841+
//
842+
// libc provides bindings for the XSI-compliant version, which is
843+
// preferred for portable applications.
844+
//
845+
// We skip the test here since here _GNU_SOURCE is defined, and
846+
// test the XSI version below.
847+
"strerror_r" => true,
848+
849+
// FIXME(cygwin): does not exist on Cygwin
850+
"mlockall" | "munlockall" => true,
851+
852+
_ => false,
853+
}
854+
});
855+
856+
cfg.generate("../src/lib.rs", "main.rs");
857+
}
858+
689859
fn test_windows(target: &str) {
690860
assert!(target.contains("windows"));
691861
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)