The libc crate is now at v0.2.0


I’ve just pushed 0.2.0 of the libc crate to, which contains an implementation of RFC 1291 which is targeted at stabilizing libc and moving it to 1.0.

As libc can often be found at the core of many applications it may, and because some breaking changes have been made, it may be the case that some code with loose restrictions (e.g. a * dependency) may have compile errors soon. To help mitigate breakage, I’d recommend updating to 0.2.* if you see any problems, because it should be quite easy! To recap, the breaking changes made to libc were:

  • The module structure of the library has gone away, all items are now only available at the top level via libc::foo
  • Some types like size_t are now defined in terms of usize and isize on major platforms, helping to reduce the number of as casts needed.
  • Bindings to Windows functions not found in the CRT (e.g. those found in kernel32) were all removed. Many Windows types (like DWORD) were also removed. These are currently best found in the winapi crate for type definitions and the various *-sys crates for function bindings (e.g. kernel32-sys).

Most transitions should be quite smooth (I only had to change one of my own crates so far), but if you have any problems please feel free to open an issue in the libc repo!

My API is missing!

That’s ok, libc is ripe for expansion and has quite a bit of room to grow. If you’d like to add an API just follow the instructions in the README and it should land in no time!


I recommend bumping the first non-zero number on the package to avoid breaking existing code downstream. What happens is that Cargo tries to link two different versions of libc and this leads to compiler error. Bumping the first non-zero number prevents existing code from breaking.

To fix “*” dependencies you can publish an update that increments the patch number *.*.x using libc 0.1. Then you can bump the first non-zero number with libc 0.2.

Remember to update lower level libraries before the higher level ones, or else you might introduce breaking changes downstream.


I think the situation is more subtle than this: having multiple versions of libc works fine for me. If a dependency is purely used internally by a lib, then bumping the major version of the dep normally doesn’t require a major version bump in that library.

There’s some additional “fun” with native libraries, because these can only be linked once in general, and I think this is at the core of the problems around these upgrades.


libc is fine because stdlib already links to the actual libc C library. This is why the libc crate doesn’t need a build script.


Is the libc crate update behind these issues?


Hmm, the old libc had c_char = u8 for linux-aarch64 only, i8 for everything else. The new libc has u8 for linux-aarch64/arm and android (probably assuming arm). Benefit of the doubt presumes the new libc is more accurate, hopefully so.

But it’s a tricky issue that you may have different c_char in CStr depending on the compiler version, while the c_char you get from libc depends on which external crate you grab. You can use std::os::raw::c_char to match the builtin libc and CStr, but you need the crate’s c_char to call its functions. Hmm…