23 stable releases

1.43.0 Feb 9, 2022
1.41.0 Feb 14, 2021
1.40.0 Sep 27, 2020
1.38.1 Jul 14, 2020
1.35.3 Mar 19, 2020

#148 in Command-line interface

Download history 54/week @ 2022-03-10 96/week @ 2022-03-17 7/week @ 2022-03-24 13/week @ 2022-03-31 14/week @ 2022-04-07 6/week @ 2022-04-14 8/week @ 2022-04-21 168/week @ 2022-04-28 102/week @ 2022-05-05 373/week @ 2022-05-12 99/week @ 2022-05-19 100/week @ 2022-05-26 239/week @ 2022-06-02 9/week @ 2022-06-09 11/week @ 2022-06-16 19/week @ 2022-06-23

278 downloads per month
Used in libuv

Custom license

62K SLoC

C 61K SLoC // 0.1% comments Automake 489 SLoC // 0.0% comments Rust 324 SLoC // 0.1% comments Batch 238 SLoC // 0.0% comments Python 120 SLoC // 0.7% comments Shell 109 SLoC // 0.2% comments JavaScript 18 SLoC

Build Status Latest Release


libuv-sys2 provides ffi bindings to the libuv library.

Why libuv-sys2?

I am committed to maintaining libuv-sys2. In fact, releases are largely automated. When libuv releases a new version, you may see a corresponding release of libuv-sys2 within minutes. Sometimes the release cannot be completely automated, however. In these cases, where I need to manually make some changes, I aim to have a release within 24-hours.


libuv-sys2 uses semantic versioning, like libuv. Major and minor versions of libuv-sys2 are bound to specific major/minor versions of libuv, ie, libuv-sys2 v1.30.x corresponds to v1.30.x of libuv. The patch version of libuv-sys2 will change anytime libuv updates, or if libuv-sys2 updates.

Getting Started

Include libuv-sys2 as a dependency in your Cargo.toml. It is recommended to use the tilde operator when specifying your dependency on libuv-sys2 so that you'll automatically received the latest bug fixes without any breaking API changes. For example:

libuv-sys2 = "~1.34.1"

This would be the same as specifying the version as >= 1.34.1, < 1.35.0.

If you need a specific patch version of libuv, check the releases page to find the version of libuv-sys2 that corresponds to the patch of libuv that you need.

Under the hood, libuv-sys2 uses bindgen to generate the bindings to libuv. If you're having trouble compiling libuv-sys2, check out the bindgen documentation to make sure you have all the required software installed. For example, on Windows, you'll need to use the msvc toolchain to compile libuv-sys2.

libuv-sys2 will attempt to use pkg-config to find a matching local install of libuv. If that fails, it will build libuv from source. Starting with version 1.40.1, you can enable the skip-pkg-config feature to always build from source. In prior versions, you could skip pkg-config by setting an environment variable called LIBUV_NO_PKG_CONFIG. See the pkg-config documentation for more information.


Import the library in your project:

extern crate libuv_sys2;

As this library is a thin binding to libuv, the first thing you should do is familiarize yourself with libuv's documentation. Once you're familiar with the concepts, take a look at the examples.

Some general advice: any data (such as libuv handle types) that you are planning on passing into libuv should probably be allocated on the heap (using Box, for example). That way, they'll have a stable memory address. Keep in mind that rust's default is to allocate things on the stack, which means that their memory address changes if you pass it into a function or return it from a function, and it will get deallocated once it falls out of scope. It's very easy to write a progarm that will compile, but fail to run or cause all sorts of undefined behavior because you'll be passing around a lot of raw, unsafe pointers while interacting with the library. If something isn't working, but you're pretty sure you're doing the right thing as far as libuv is concerned, make sure your data has a stable memory address.

In addition to bindings for all of the libuv functionality, this library provides one convenience macro: uv_handle!. This macro can be used to convert any reference or raw pointer of one type, to a raw pointer of a different type. This is frequently useful when using libuv to cast a uv_SOMETHING_t to a uv_handle_t. For example:

let mut tty: uv_tty_t = unsafe { mem::zeroed() };

// without the macro, you'd need to cast the reference to a raw pointer of the
// same type, and then cast that as a raw pointer of the target type:
let handle: *mut uv_handle_t = &mut tty as *mut uv_tty_t as *mut uv_handle_t;

// the macro is much more wieldy:
let handle: *mut uv_handle_t = uv_handle!(&mut tty);

Cross-Platform Considerations

It appears the type of uv_buf_t.len is different on Windows. A simple solution is to use a usize (which appears to be the default elsewhere) and then any place that you read from or write to a uv_buf_t.len, simply add a as _ to the end and the compiler will do the right thing. For example:

let buf: uv_buf_t = { base: my_ptr, len: my_len as _ };
let buflen: usize = buf.len as _;

Speaking of Windows, because bindgen is used to generate the bindings, you'll need to use rust's msvc toolchain to compile libuv-sys2!