| Crates.io | nng-sys |
| lib.rs | nng-sys |
| version | 0.3.0+1.11.0 |
| created_at | 2018-06-16 13:36:48.435598+00 |
| updated_at | 2025-10-22 09:09:27.282324+00 |
| description | Bindings to NNG (Nanomsg-Next-Generation) aka Nanomsg2 |
| homepage | |
| repository | https://github.com/nanomsg/nng-rs |
| max_upload_size | |
| id | 70346 |
| size | 3,745,670 |
Rust FFI bindings to NNG:
NNG, like its predecessors nanomsg (and to some extent ZeroMQ), is a lightweight, broker-less library, offering a simple API to solve common recurring messaging problems, such as publish/subscribe, RPC-style request/reply, or service discovery. The API frees the programmer from worrying about details like connection management, retries, and other common considerations, so that they can focus on the application instead of the plumbing.
To use the latest version of this crate, add the following to your Cargo.toml:
[dependencies]
nng-sys = "0.3.0"
If you need TLS support:
[dependencies]
nng-sys = { version = "0.3.0", features = ["tls"] }
This will bundle mbedTLS. See the NNG TLS documentation for details.
nng-sys comes with a vendored version of NNG, whose version is visible from the build metadata in the crate version (the part after +).
Vendoring is enabled through the vendored feature and is on by default.
This is mainly because NNG isn't generally going to be installed on users' systems,
unlike more widely used libraries like openssl or zlib.
For most users, the default set of features (so a vendored build) is what you'll want.
Just ensure you have cmake and a C compiler installed, and you're good to go.
If you do not want to use a vendored build, disable the vendored feature (or set NNG_NO_VENDOR).
This will make NNG instead search for a system-provided NNG install to link with.
Note that when using a system-provided NNG instead,
bindings are always re-generated with bindgen at build time since there is no guarantee that the system library is the same version
(or built with the same features)
as the pre-generated bindings.
The build script implements a preference hierarchy to discover system-provided NNG installations:
Explicit env vars (highest priority):
NNG_DIR: Root installation directory (containing lib/ and include/ subdirs)NNG_LIB_DIR + NNG_INCLUDE_DIR: Separate library and header directoriespkg-config / vcpkg. NNG does not yet ship nng.pc NNG, but it may be provided by certain distros.
Platform-specific fallback paths:
/opt/homebrew) and MacPorts (/opt/local)If no system-provided NNG is found, the build errors. There is no fallback to a vendored version.
Default (vendored build):
PATH
CMAKE_GENERATOR environment variableOptional (for bindgen feature):
This crate uses the format <crate version>+<nng version> following Semantic Versioning 2.0.0.
Example: 0.3.0+1.11.0
0.3.0 - The crate's own semantic version, indicating API compatibility+1.11.0 - Build metadata showing the wrapped NNG library version| Scenario | Example Version | Explanation |
|---|---|---|
| Patch fix in crate bindings | 0.3.1+1.11.0 |
Bug fixes, no API changes |
| Update to newer NNG version | 0.3.2+1.12.0 |
Compatible update to the NNG library |
| Breaking change in bindings | 0.4.0+1.12.0 |
Breaking API changes introduced by e.g. a bindgen upgrade (pre-1.0, minor acts as major) |
| NNG major version update | 0.5.0+2.0.0 |
A backwards-incompatible NNG release also results in a major version bump |
Note: Cargo ignores the +<nng version> build metadata suffix when resolving dependencies,
so version 0.3.0+1.11.0 and 0.3.0+1.12.0 are considered equivalent by Cargo and cannot coexist.
Note: Versions of this crate prior to 0.3.0 used a different scheme (<NNG_version>-rc.<crate_version>).
This legacy format has been replaced to allow for proper semantic versioning of the crate's API.
| Feature | Default | Description |
|---|---|---|
vendored |
✓ | Build NNG from bundled sources using CMake |
vendored-stats |
✓ | Enable NNG stats (NNG_ENABLE_STATS) when building vendored NNG |
std |
✓ | Enable standard library support |
static |
Force static linking (default: static for vendored, dynamic for system) | |
bindgen |
Generate bindings at build time (uses pre-generated by default) | |
tls |
Enable TLS support (NNG_ENABLE_TLS, requires mbedTLS) |
|
compat |
Bindings for nanomsg-compatible API (implies bindgen) |
|
supplemental |
Bindings for supplemental utilities (implies bindgen) |
Note: Features that control NNG build options (vendored-stats, tls) only affect vendored builds.
When using a system-provided NNG library, ensure it was built with the features you need.
| Variable | Purpose | Example |
|---|---|---|
NNG_DIR |
Root NNG installation directory | /usr/local |
NNG_LIB_DIR + NNG_INCLUDE_DIR |
Separate library and header paths | /opt/nng/lib, /opt/nng/include |
NNG_STATIC |
Force static (1) or dynamic (0) linking |
1 |
NNG_NO_VENDOR |
Prohibit vendored builds (error if system lib not found) | 1 |
{TARGET}_NNG_* |
Target-specific override (cross-compilation) | AARCH64_UNKNOWN_LINUX_GNU_NNG_DIR |
NNG_STATIC: Set to 1 to force static linking, 0 for dynamic
1 (static) for vendored builds, 0 (dynamic) for system-provided librariesNNG_NO_VENDOR: Set to 1 to force the use of a system-provided NNG install (errors if none is found)
vendored feature is enabledOPENSSL_NO_VENDOR) and libgit2-sys (LIBGIT2_NO_VENDOR)For cross-compilation, use target-prefixed variants which take precedence:
export AARCH64_UNKNOWN_LINUX_GNU_NNG_DIR=/path/to/nng-arm64
cargo build --target aarch64-unknown-linux-gnu
Target prefix format: {TARGET}_{VAR_NAME} where target uses _ instead of - and is uppercased.
use nng_sys::*;
use std::{ffi::CString, os::raw::c_char, ptr::null_mut};
fn example() {
unsafe {
let url = CString::new("inproc://nng_sys/tests/example").unwrap();
let url = url.as_bytes_with_nul().as_ptr() as *const c_char;
// Reply socket
let mut rep_socket = nng_socket::default();
nng_rep0_open(&mut rep_socket);
nng_listen(rep_socket, url, null_mut(), 0);
// Request socket
let mut req_socket = nng_socket::default();
nng_req0_open(&mut req_socket);
nng_dial(req_socket, url, null_mut(), 0);
// Send message
let mut req_msg: *mut nng_msg = null_mut();
nng_msg_alloc(&mut req_msg, 0);
// Add a value to the body of the message
let val = 0x12345678;
nng_msg_append_u32(req_msg, val);
nng_sendmsg(req_socket, req_msg, 0);
// Receive it
let mut recv_msg: *mut nng_msg = null_mut();
nng_recvmsg(rep_socket, &mut recv_msg, 0);
// Remove our value from the body of the received message
let mut recv_val: u32 = 0;
nng_msg_trim_u32(recv_msg, &mut recv_val);
assert_eq!(val, recv_val);
// Can't do this because nng uses network order (big-endian)
//assert_eq!(val, *(nng_msg_body(recv_msg) as *const u32));
nng_close(req_socket);
nng_close(rep_socket);
}
}