From b322ac299a1645c379f671d64a369585b4d1ce62 Mon Sep 17 00:00:00 2001 From: Amanieu d'Antras Date: Thu, 3 Nov 2016 04:44:45 +0000 Subject: [PATCH 1/4] Create a separate libc_types crate for basic C types --- text/0000-libc-types.md | 83 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 text/0000-libc-types.md diff --git a/text/0000-libc-types.md b/text/0000-libc-types.md new file mode 100644 index 00000000000..7258c39d545 --- /dev/null +++ b/text/0000-libc-types.md @@ -0,0 +1,83 @@ +- Feature Name: libc_types +- Start Date: 2016-11-03 +- RFC PR: (leave this empty) +- Rust Issue: (leave this empty) + +# Summary +[summary]: #summary + +Move the basic type definitions of the `libc` crate (`c_int`, `c_ulong`, etc) into a separate `libc_types` crate which does not require linking to the platform C library. + +# Motivation +[motivation]: #motivation + +Sometimes it is desirable to call C code through FFI or use C data structures in an environment without a C library. This is specified in the C standard as a freestanding environment. From the [GCC documentataion](https://gcc.gnu.org/onlinedocs/gcc/Standards.html): + +> The ISO C standard defines (in clause 4) two classes of conforming implementation. A conforming hosted implementation supports the whole standard including all the library facilities; a conforming freestanding implementation is only required to provide certain library facilities: those in , , , and ; since AMD1, also those in ; since C99, also those in and ; and since C11, also those in and . In addition, complex types, added in C99, are not required for freestanding implementations. +> +> The standard also defines two environments for programs, a freestanding environment, required of all implementations and which may not have library facilities beyond those required of freestanding implementations, where the handling of program startup and termination are implementation-defined; and a hosted environment, which is not required, in which all the library facilities are provided and startup is through a function int main (void) or int main (int, char *[]). An OS kernel is an example of a program running in a freestanding environment; a program using the facilities of an operating system is an example of a program running in a hosted environment. + +The obvious use case for such a crate would be kernels and other bare-metal code which need to link to existing C libraries. Although such code can simply use raw Rust types (`i32` instead of `c_int` for example), this is unergonomic. + +A more interesting case is that of bindings for C libraries which can work in a freestanding environment. Bindings for such libraries are typically defined using types from the `libc` crate, which prevents them from being used in a freestanding environment without a C library. + +Finally, a separate `libc_types` crate would allow Rust on Windows to avoid linking to the MS CRT entirely. This would make Rust executables more portable since they would not require a user to install a Visual Studio redistributable package. + +Relevant discussions on [internals](https://internals.rust-lang.org/t/solve-std-os-raw-c-void/3268) and on [Github](https://github.com/rust-lang/rust/issues/31536). + +# Detailed design +[design]: #detailed-design + +The following types will be moved to a separate `libc_types` crate: + +```rust +pub enum c_void; + +pub type int8_t; +pub type int16_t; +pub type int32_t; +pub type int64_t; +pub type uint8_t; +pub type uint16_t; +pub type uint32_t; +pub type uint64_t; + +pub type c_schar; +pub type c_uchar; +pub type c_short; +pub type c_ushort; +pub type c_int; +pub type c_uint; +pub type c_float; +pub type c_double; +pub type c_longlong; +pub type c_ulonglong; +pub type intmax_t; +pub type uintmax_t; + +pub type size_t; +pub type ptrdiff_t; +pub type intptr_t; +pub type uintptr_t; +pub type ssize_t; + +pub type c_long; +pub type c_ulong; +``` + +To preserve backward compatibility, these types will be re-exported by the `libc` crate. This is not a breaking change since the `c_void` type still only comes from a single source, so there will not be conflicting definitions. Thus only a minor version bump is required, which avoids extensive breakage across the ecosystem similar to what happened when the `libc` version was bumped to 0.2. + +# Drawbacks +[drawbacks]: #drawbacks + +- Adds an additional crate to the standard library. + +# Alternatives +[alternatives]: #alternatives + +- Do nothing. Freestanding code will have to use standard rust types and write their own bindings for C libraries. + +# Unresolved questions +[unresolved]: #unresolved-questions + +- The exact crate name is subject to the usual bikeshedding. From ef4e3bc4b180c71d8ffbd89b2f6fd60b420e5cdf Mon Sep 17 00:00:00 2001 From: Amanieu d'Antras Date: Thu, 3 Nov 2016 09:08:42 +0000 Subject: [PATCH 2/4] Fix quote from GCC documentation --- text/0000-libc-types.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/text/0000-libc-types.md b/text/0000-libc-types.md index 7258c39d545..bb7c78040ef 100644 --- a/text/0000-libc-types.md +++ b/text/0000-libc-types.md @@ -13,9 +13,9 @@ Move the basic type definitions of the `libc` crate (`c_int`, `c_ulong`, etc) in Sometimes it is desirable to call C code through FFI or use C data structures in an environment without a C library. This is specified in the C standard as a freestanding environment. From the [GCC documentataion](https://gcc.gnu.org/onlinedocs/gcc/Standards.html): -> The ISO C standard defines (in clause 4) two classes of conforming implementation. A conforming hosted implementation supports the whole standard including all the library facilities; a conforming freestanding implementation is only required to provide certain library facilities: those in , , , and ; since AMD1, also those in ; since C99, also those in and ; and since C11, also those in and . In addition, complex types, added in C99, are not required for freestanding implementations. +> The ISO C standard defines (in clause 4) two classes of conforming implementation. A conforming hosted implementation supports the whole standard including all the library facilities; a conforming freestanding implementation is only required to provide certain library facilities: those in ``, ``, ``, and ``; since AMD1, also those in ``; since C99, also those in `` and ``; and since C11, also those in `` and ``. In addition, complex types, added in C99, are not required for freestanding implementations. > -> The standard also defines two environments for programs, a freestanding environment, required of all implementations and which may not have library facilities beyond those required of freestanding implementations, where the handling of program startup and termination are implementation-defined; and a hosted environment, which is not required, in which all the library facilities are provided and startup is through a function int main (void) or int main (int, char *[]). An OS kernel is an example of a program running in a freestanding environment; a program using the facilities of an operating system is an example of a program running in a hosted environment. +> The standard also defines two environments for programs, a freestanding environment, required of all implementations and which may not have library facilities beyond those required of freestanding implementations, where the handling of program startup and termination are implementation-defined; and a hosted environment, which is not required, in which all the library facilities are provided and startup is through a function `int main (void)` or `int main (int, char *[])`. An OS kernel is an example of a program running in a freestanding environment; a program using the facilities of an operating system is an example of a program running in a hosted environment. The obvious use case for such a crate would be kernels and other bare-metal code which need to link to existing C libraries. Although such code can simply use raw Rust types (`i32` instead of `c_int` for example), this is unergonomic. From 55ee1840d94d6283af7e4d6175f80f08dc961ebd Mon Sep 17 00:00:00 2001 From: Amanieu d'Antras Date: Thu, 3 Nov 2016 23:13:01 +0000 Subject: [PATCH 3/4] Update motivation and drawbacks --- text/0000-libc-types.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/text/0000-libc-types.md b/text/0000-libc-types.md index bb7c78040ef..7035fd429b7 100644 --- a/text/0000-libc-types.md +++ b/text/0000-libc-types.md @@ -23,6 +23,8 @@ A more interesting case is that of bindings for C libraries which can work in a Finally, a separate `libc_types` crate would allow Rust on Windows to avoid linking to the MS CRT entirely. This would make Rust executables more portable since they would not require a user to install a Visual Studio redistributable package. +The types in the `libc` cannot be used in these situations because the `libc` crate will cause the resulting binary to link to the platform C library, which is undesirable. + Relevant discussions on [internals](https://internals.rust-lang.org/t/solve-std-os-raw-c-void/3268) and on [Github](https://github.com/rust-lang/rust/issues/31536). # Detailed design @@ -70,11 +72,12 @@ To preserve backward compatibility, these types will be re-exported by the `libc # Drawbacks [drawbacks]: #drawbacks -- Adds an additional crate to the standard library. +- Adds an additional crate to the standard library. Although users will only import this crate from crates.io, it must still be distributed as part of the standard library since it is a dependency of the `libc` crate. The version distributed with the standard library will of course be unstable and hidden behind the same feature flag as `libc`. # Alternatives [alternatives]: #alternatives +- Put these types in `libcore` instead. This was proposed on the internals thread, but the consensus seems to be that C FFI types do not belong in `libcore. - Do nothing. Freestanding code will have to use standard rust types and write their own bindings for C libraries. # Unresolved questions From 85b7d3e990f3ad33b3f9dbd2b68080e712fab169 Mon Sep 17 00:00:00 2001 From: Amanieu d'Antras Date: Fri, 4 Nov 2016 05:59:07 +0000 Subject: [PATCH 4/4] Add c_char --- text/0000-libc-types.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/text/0000-libc-types.md b/text/0000-libc-types.md index 7035fd429b7..74d782196e5 100644 --- a/text/0000-libc-types.md +++ b/text/0000-libc-types.md @@ -65,6 +65,8 @@ pub type ssize_t; pub type c_long; pub type c_ulong; + +pub type c_char; ``` To preserve backward compatibility, these types will be re-exported by the `libc` crate. This is not a breaking change since the `c_void` type still only comes from a single source, so there will not be conflicting definitions. Thus only a minor version bump is required, which avoids extensive breakage across the ecosystem similar to what happened when the `libc` version was bumped to 0.2.