Skip to content

Commit 943b116

Browse files
committed
Add generic_ctypes Cargo feature
NB: SGX and Switch can just use the generics
1 parent 599bafe commit 943b116

File tree

11 files changed

+205
-40
lines changed

11 files changed

+205
-40
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ use_std = []
2828
align = []
2929
rustc-dep-of-std = ['align', 'rustc-std-workspace-core']
3030
extra_traits = ["align"]
31+
generic_ctypes = []
3132

3233
[workspace]
3334
members = ["libc-test"]

README.md

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ libc = { version = "0.2", features = ["align"] }
4545
```
4646

4747
All structs implemented by the libc crate have the `Copy` and `Clone` traits
48-
implemented for them. The additional traits of `Debug, `Eq`, `Hash`, and
48+
implemented for them. The additional traits of `Debug`, `Eq`, `Hash`, and
4949
`PartialEq` can be enabled with the *extra_traits* feature (requires Rust 1.25
5050
or newer):
5151

@@ -54,6 +54,22 @@ or newer):
5454
libc = { version = "0.2", features = ["extra_traits"] }
5555
```
5656

57+
A large number of targets are supported by libc; however, some unsupported or
58+
custom targets just need libc's basic types (`c_int`, `size_t`, etc...) for
59+
linking to C code. These types can be enabled for _any_ target with the
60+
*generic_ctypes* feature:
61+
62+
```toml
63+
[dependencies.libc]
64+
version = "0.2"
65+
default-features = false
66+
features = ["generic_ctypes"]
67+
```
68+
69+
Note that if you target has strange definitions for C types, *generic_ctypes*
70+
will not necessarily generate the correct types, as the generation process is
71+
based only on your CPU architecture and pointer size.
72+
5773
## What is libc?
5874

5975
The primary purpose of this crate is to provide all of the definitions necessary

src/cloudabi/mod.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,18 @@
11
use dox::Option;
22

3+
pub type c_short = i16;
4+
pub type c_ushort = u16;
5+
pub type c_int = i32;
6+
pub type c_uint = u32;
7+
pub type c_longlong = i64;
8+
pub type c_ulonglong = u64;
9+
pub type intmax_t = i64;
10+
pub type uintmax_t = u64;
11+
12+
pub type size_t = usize;
13+
pub type ptrdiff_t = isize;
14+
pub type ssize_t = isize;
15+
316
pub type in_addr_t = u32;
417
pub type in_port_t = u16;
518
pub type pthread_key_t = usize;
@@ -58,6 +71,9 @@ s! {
5871
}
5972
}
6073

74+
pub const INT_MIN: c_int = -2147483648;
75+
pub const INT_MAX: c_int = 2147483647;
76+
6177
pub const _SC_NPROCESSORS_ONLN: ::c_int = 52;
6278
pub const _SC_PAGESIZE: ::c_int = 54;
6379

src/fuchsia/mod.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,19 @@ use dox::{mem, Option};
77

88
// PUB_TYPE
99

10+
pub type c_short = i16;
11+
pub type c_ushort = u16;
12+
pub type c_int = i32;
13+
pub type c_uint = u32;
14+
pub type c_longlong = i64;
15+
pub type c_ulonglong = u64;
16+
pub type intmax_t = i64;
17+
pub type uintmax_t = u64;
18+
19+
pub type size_t = usize;
20+
pub type ptrdiff_t = isize;
21+
pub type ssize_t = isize;
22+
1023
pub type pid_t = i32;
1124
pub type uid_t = u32;
1225
pub type gid_t = u32;
@@ -1069,6 +1082,9 @@ s! {
10691082

10701083
// PUB_CONST
10711084

1085+
pub const INT_MIN: c_int = -2147483648;
1086+
pub const INT_MAX: c_int = 2147483647;
1087+
10721088
pub const SIG_DFL: sighandler_t = 0 as sighandler_t;
10731089
pub const SIG_IGN: sighandler_t = 1 as sighandler_t;
10741090
pub const SIG_ERR: sighandler_t = !0 as sighandler_t;

src/generic.rs

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
//! This module attempts to attempts to give reasonable definitions for most
2+
//! basic C types. Note that these are essentially educated guesses and are NOT
3+
//! guaranteed to match the types produced by your C compiler.
4+
5+
// Per the C11 specification, these type definitions are not guaranteed to be
6+
// correct for all platforms. However, virtually all platforms use these
7+
// definitions, including all targets supported by rustc.
8+
pub type c_short = i16;
9+
pub type c_ushort = u16;
10+
pub type c_int = i32;
11+
pub type c_uint = u32;
12+
pub type c_longlong = i64;
13+
pub type c_ulonglong = u64;
14+
pub type intmax_t = i64;
15+
pub type uintmax_t = u64;
16+
pub type size_t = usize;
17+
pub type ptrdiff_t = isize;
18+
pub type ssize_t = isize;
19+
20+
pub const INT_MIN: c_int = -2147483648;
21+
pub const INT_MAX: c_int = 2147483647;
22+
23+
// There are two ways that platforms (in practice) differ in their C types:
24+
// - chars can either be signed or unsigned
25+
// - longs can either be 32-bit or 64-bit
26+
27+
// Whether chars default to signed or unsigned is primarily determined by
28+
// architecture (windows is the main exception here).
29+
pub use self::chars::*;
30+
#[cfg(any(
31+
target_arch = "aarch64",
32+
target_arch = "arm",
33+
target_arch = "armebv7r",
34+
target_arch = "armv5te",
35+
target_arch = "armv7",
36+
target_arch = "armv7r",
37+
target_arch = "armv7s",
38+
target_arch = "asmjs",
39+
target_arch = "wasm32",
40+
target_arch = "wasm64",
41+
target_arch = "powerpc",
42+
target_arch = "powerpc64",
43+
target_arch = "powerpc64le",
44+
target_arch = "s390x",
45+
target_arch = "thumbv6",
46+
target_arch = "thumbv6m",
47+
target_arch = "thummv7",
48+
target_arch = "thumbv7em",
49+
target_arch = "thumbv7m",
50+
target_arch = "thumbv7neon",
51+
target_arch = "tummbv8",
52+
target_arch = "thumbv8m",
53+
target_arch = "thumbv8m.main"
54+
))]
55+
mod chars {
56+
pub type c_char = u8;
57+
pub type wchar_t = u32;
58+
}
59+
60+
#[cfg(any(
61+
target_arch = "i386",
62+
target_arch = "i586",
63+
target_arch = "i686",
64+
target_arch = "x86",
65+
target_arch = "x86_64",
66+
target_arch = "mips",
67+
target_arch = "mips64",
68+
target_arch = "mips64el",
69+
target_arch = "mipsel",
70+
target_arch = "nvptx",
71+
target_arch = "nvptx64",
72+
target_arch = "sparc64",
73+
target_arch = "sparcv9",
74+
target_arch = "riscv64",
75+
target_arch = "riscv32",
76+
target_arch = "riscv32imac",
77+
target_arch = "riscv32imc"
78+
))]
79+
mod chars {
80+
pub type c_char = i8;
81+
pub type wchar_t = i32;
82+
}
83+
84+
// On all platforms but Windows, longs are the same size as a pointer.
85+
pub use self::long::*;
86+
#[cfg(target_pointer_width = "64")]
87+
mod long {
88+
pub type c_long = i64;
89+
pub type c_ulong = u64;
90+
}
91+
92+
#[cfg(any(target_pointer_width = "16", target_pointer_width = "32"))]
93+
mod long {
94+
pub type c_long = i32;
95+
pub type c_ulong = u32;
96+
}
97+
98+
// POSIX specifications make no guarantees that off_t == long int, but this is
99+
// what GNU and others always do.
100+
pub type off_t = ::c_long;

src/lib.rs

Lines changed: 8 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ mod macros;
135135

136136
mod dox;
137137

138-
// C types that are always the same Rust type
138+
// Per the Rust and C11 specs, these C types will always have these definitions.
139139
pub type int8_t = i8;
140140
pub type int16_t = i16;
141141
pub type int32_t = i32;
@@ -144,28 +144,12 @@ pub type uint8_t = u8;
144144
pub type uint16_t = u16;
145145
pub type uint32_t = u32;
146146
pub type uint64_t = u64;
147-
147+
pub type intptr_t = isize;
148+
pub type uintptr_t = usize;
148149
pub type c_schar = i8;
149150
pub type c_uchar = u8;
150-
pub type c_short = i16;
151-
pub type c_ushort = u16;
152-
pub type c_int = i32;
153-
pub type c_uint = u32;
154151
pub type c_float = f32;
155152
pub type c_double = f64;
156-
pub type c_longlong = i64;
157-
pub type c_ulonglong = u64;
158-
pub type intmax_t = i64;
159-
pub type uintmax_t = u64;
160-
161-
pub type size_t = usize;
162-
pub type ptrdiff_t = isize;
163-
pub type intptr_t = isize;
164-
pub type uintptr_t = usize;
165-
pub type ssize_t = isize;
166-
167-
pub const INT_MIN: c_int = -2147483648;
168-
pub const INT_MAX: c_int = 2147483647;
169153

170154
cfg_if! {
171155
if #[cfg(core_cvoid)] {
@@ -199,16 +183,13 @@ cfg_if! {
199183
} else if #[cfg(target_os = "fuchsia")] {
200184
mod fuchsia;
201185
pub use fuchsia::*;
202-
} else if #[cfg(target_os = "switch")] {
203-
mod switch;
204-
pub use switch::*;
205186
} else if #[cfg(unix)] {
206187
mod unix;
207188
pub use unix::*;
208-
} else if #[cfg(target_env = "sgx")] {
209-
mod sgx;
210-
pub use sgx::*;
211-
} else {
212-
// non-supported targets: empty...
189+
} else {
190+
// Some targets only need the generic C types (and don't need functions)
191+
#[cfg(any(feature = "generic_ctypes", target_env = "sgx", target_os = "switch"))]
192+
mod generic;
193+
pub use generic::*;
213194
}
214195
}

src/redox/mod.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,16 @@
1+
pub type c_short = i16;
2+
pub type c_ushort = u16;
3+
pub type c_int = i32;
4+
pub type c_uint = u32;
5+
pub type c_longlong = i64;
6+
pub type c_ulonglong = u64;
7+
pub type intmax_t = i64;
8+
pub type uintmax_t = u64;
9+
10+
pub type size_t = usize;
11+
pub type ptrdiff_t = isize;
12+
pub type ssize_t = isize;
13+
114
pub type c_char = i8;
215
pub type c_long = i64;
316
pub type c_ulong = u64;
@@ -73,6 +86,9 @@ s! {
7386
}
7487
}
7588

89+
pub const INT_MIN: ::c_int = -2147483648;
90+
pub const INT_MAX: ::c_int = 2147483647;
91+
7692
pub const STDIN_FILENO: ::c_int = 0;
7793
pub const STDOUT_FILENO: ::c_int = 1;
7894
pub const STDERR_FILENO: ::c_int = 2;

src/sgx.rs

Lines changed: 0 additions & 5 deletions
This file was deleted.

src/switch.rs

Lines changed: 0 additions & 7 deletions
This file was deleted.

src/unix/mod.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,19 @@
55
66
use dox::Option;
77

8+
pub type c_short = i16;
9+
pub type c_ushort = u16;
10+
pub type c_int = i32;
11+
pub type c_uint = u32;
12+
pub type c_longlong = i64;
13+
pub type c_ulonglong = u64;
14+
pub type intmax_t = i64;
15+
pub type uintmax_t = u64;
16+
17+
pub type size_t = usize;
18+
pub type ptrdiff_t = isize;
19+
pub type ssize_t = isize;
20+
821
pub type pid_t = i32;
922
pub type uid_t = u32;
1023
pub type gid_t = u32;
@@ -198,6 +211,9 @@ s! {
198211
}
199212
}
200213

214+
pub const INT_MIN: ::c_int = -2147483648;
215+
pub const INT_MAX: ::c_int = 2147483647;
216+
201217
pub const SIG_DFL: sighandler_t = 0 as sighandler_t;
202218
pub const SIG_IGN: sighandler_t = 1 as sighandler_t;
203219
pub const SIG_ERR: sighandler_t = !0 as sighandler_t;

src/windows/mod.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,17 @@
11
//! Windows CRT definitions
22
3+
pub type c_short = i16;
4+
pub type c_ushort = u16;
5+
pub type c_int = i32;
6+
pub type c_uint = u32;
7+
pub type c_longlong = i64;
8+
pub type c_ulonglong = u64;
9+
pub type intmax_t = i64;
10+
pub type uintmax_t = u64;
11+
12+
pub type size_t = usize;
13+
pub type ptrdiff_t = isize;
14+
pub type ssize_t = isize;
315
pub type sighandler_t = usize;
416

517
pub type c_char = i8;
@@ -80,6 +92,9 @@ s! {
8092
}
8193
}
8294

95+
pub const INT_MIN: ::c_int = -2147483648;
96+
pub const INT_MAX: ::c_int = 2147483647;
97+
8398
pub const EXIT_FAILURE: ::c_int = 1;
8499
pub const EXIT_SUCCESS: ::c_int = 0;
85100
pub const RAND_MAX: ::c_int = 32767;

0 commit comments

Comments
 (0)