freerdp-sys 0.1.0

Low-level Rust FFI bindings to FreeRDP 3.x (Remote Desktop Protocol). Supports vendored CMake builds from source or linking against system-installed FreeRDP. Bindings generated via bindgen. General-purpose — usable by any Rust project needing RDP client/server functionality.
docs.rs failed to build freerdp-sys-0.1.0
Please check the build logs for more information.
See Builds for ideas on how to fix a failed build, or Metadata for how to configure docs.rs builds.
If you believe this is docs.rs' fault, open an issue.

freerdp-sys

CI Crates.io Docs.rs License: MIT OR Apache-2.0 MSRV

Low-level Rust FFI bindings to FreeRDP 3.x — a free, open-source implementation of the Remote Desktop Protocol (RDP).

Overview

freerdp-sys is a general-purpose, standalone -sys crate that exposes the FreeRDP 3.x C API to Rust. It is not tied to any specific application or framework — any Rust project that needs RDP client or server functionality can build on top of it.

Key characteristics:

  • Bindings generated via bindgen from FreeRDP 3.x headers
  • Vendored CMake build compiles FreeRDP from source (zero system dependencies at link time)
  • Optional system linking via pkg-config for distro-packaged FreeRDP
  • Pre-generated bindings included so downstream users don't need libclang
  • Dual-licensed (MIT / Apache-2.0) for maximum compatibility

Installation

Vendored build (default, recommended)

Compiles FreeRDP 3.x from source during cargo build. No system FreeRDP installation required.

[dependencies]
freerdp-sys = "0.1"

System linking

Links against a system-installed FreeRDP 3.x discovered via pkg-config.

[dependencies]
freerdp-sys = { version = "0.1", default-features = false, features = ["system"] }

With runtime binding generation

Generates fresh bindings at build time using bindgen (requires libclang).

[dependencies]
freerdp-sys = { version = "0.1", features = ["generate-bindings"] }

Feature Flags

Feature Default Description
vendored Compile FreeRDP 3.x from vendored source via CMake. Produces static libraries.
system Link against a system-installed FreeRDP 3.x discovered via pkg-config.
generate-bindings Run bindgen at build time to regenerate FFI bindings (requires libclang). When disabled, pre-generated src/bindings.rs is used.

Note: vendored and system are mutually exclusive. Enable exactly one.

Requirements

Vendored build

Dependency Minimum Version Purpose
CMake 3.13 Build system for FreeRDP
C compiler C11 gcc, clang, or MSVC
OpenSSL 1.1.1+ TLS/crypto support
zlib 1.2+ Compression
Rust 1.77+ Crate MSRV

Platform-specific:

  • Linux: libssl-dev, zlib1g-dev, cmake, build-essential
  • macOS: brew install cmake openssl zlib
  • Windows: Visual Studio Build Tools, vcpkg OpenSSL + zlib

System linking

  • FreeRDP 3.x development packages (libfreerdp3-dev or equivalent)
  • pkg-config
  • WinPR 3.x development packages

Binding generation (optional)

  • libclang (used by the bindgen crate)
    • Linux: libclang-dev
    • macOS: brew install llvm (set LIBCLANG_PATH if needed)

Usage

use freerdp_sys::*;

fn main() {
    unsafe {
        // Create a FreeRDP instance
        let instance = freerdp_new();
        assert!(!instance.is_null());

        // Access settings
        let settings = freerdp_get_settings(instance);
        // ... configure hostname, port, credentials, etc. ...

        // Connect
        let result = freerdp_connect(instance);
        if result != 0 {
            println!("Connected!");
            // ... RDP session ...
            freerdp_disconnect(instance);
        }

        // Cleanup
        freerdp_free(instance);
    }
}

Safety: All functions in this crate are unsafe FFI calls. Refer to the FreeRDP API documentation for correct usage, memory ownership, and threading constraints.

Build Configuration

Environment Variables

Variable Description Example
FREERDP_CMAKE_DEFS Extra CMake definitions (semicolon-separated) WITH_CAIRO=ON;WITH_FFMPEG=ON
FREERDP_BINDGEN_CLANG_ARGS Extra clang arguments passed to bindgen -DWITH_SMARTCARD=1
LIBCLANG_PATH Path to libclang (if not in default search path) /usr/lib/llvm-18/lib
CMAKE Path to cmake binary /usr/local/bin/cmake

CMake Build Options

The vendored build configures FreeRDP with these defaults (optimized for a minimal static library):

BUILD_SHARED_LIBS=OFF    WITH_SERVER=OFF
WITH_CLIENT=OFF          WITH_CHANNELS=OFF
WITH_WINPR_TOOLS=OFF     WITH_MANPAGES=OFF
BUILD_TESTING=OFF        WITH_SAMPLE=OFF
WITH_PROXY=OFF           WITH_SHADOW=OFF
CMAKE_BUILD_TYPE=Release

Override any of these via FREERDP_CMAKE_DEFS:

FREERDP_CMAKE_DEFS="WITH_SERVER=ON;WITH_CHANNELS=ON" cargo build

Development

Getting Started

# Clone with submodule
git clone --recurse-submodules https://github.com/GOODBOY008/freerdp-sys.git
cd freerdp-sys

# Or initialize submodule after clone
git submodule update --init --recursive

Building

# Default vendored build (pre-generated bindings)
cargo build

# Vendored + regenerate bindings from headers
cargo build --features vendored,generate-bindings

# System linking
cargo build --no-default-features --features system

# Check without linking (uses pre-generated bindings)
cargo check --no-default-features

Testing

cargo test --features vendored,generate-bindings

Regenerating Pre-built Bindings

# Using the helper script
./scripts/regenerate-bindings.sh

# Or manually
cargo build --features vendored,generate-bindings
cp target/debug/build/freerdp-sys-*/out/bindings.rs src/bindings.rs
rustfmt src/bindings.rs

Project Structure

freerdp-sys/
├── Cargo.toml              # Crate manifest with feature flags & crates.io metadata
├── build.rs                # Build script: cmake vendored build + bindgen orchestration
├── src/
│   ├── lib.rs              # Crate root: conditional binding inclusion, docs
│   ├── bindings.rs         # Pre-generated bindings (no libclang needed by consumers)
│   └── wrapper.h           # C header input for bindgen (FreeRDP 3.x + WinPR)
├── vendor/
│   └── FreeRDP/            # Git submodule → FreeRDP 3.x source (stable-3.0)
├── cmake/
│   └── CMakeLists.txt      # Optional CMake wrapper for standalone/test builds
├── scripts/
│   └── regenerate-bindings.sh  # Helper to regenerate src/bindings.rs
├── .github/workflows/
│   └── ci.yml              # CI: check, clippy, test, fmt, publish
├── .gitmodules             # Submodule config (FreeRDP stable-3.0)
├── rustfmt.toml            # Formatting configuration
├── LICENSE-MIT             # MIT license
├── LICENSE-APACHE          # Apache 2.0 license
└── README.md               # This file

Troubleshooting

"vendored FreeRDP source not found"

freerdp-sys: vendored FreeRDP source not found at `vendor/FreeRDP`.

Fix: Initialize the git submodule:

git submodule update --init --recursive

"could not find FreeRDP 3.x via pkg-config"

freerdp-sys: could not find FreeRDP 3.x via pkg-config.

Fix: Install FreeRDP 3.x development packages:

# Debian/Ubuntu
sudo apt install libfreerdp3-dev libwinpr3-dev

# Fedora
sudo dnf install freerdp-devel

# Or switch to vendored build

bindgen / libclang errors

thread 'main' panicked: Unable to find libclang

Fix: Install libclang and set the path:

# Linux
sudo apt install libclang-dev

# macOS
brew install llvm
export LIBCLANG_PATH="$(brew --prefix llvm)/lib"

CMake not found

Failed to run cmake: No such file or directory

Fix: Install CMake ≥ 3.13:

# Linux
sudo apt install cmake

# macOS
brew install cmake

# Or set CMAKE env var
export CMAKE=/path/to/cmake

Linker errors (missing symbols)

If you see undefined symbol errors at link time, ensure all platform dependencies are installed:

# Linux
sudo apt install libssl-dev zlib1g-dev

# macOS (if using Homebrew OpenSSL)
export OPENSSL_ROOT_DIR="$(brew --prefix openssl)"

Publishing to crates.io

This crate is configured for automated publishing via GitHub Actions on tag push:

# Tag a release
git tag v0.1.0
git push origin v0.1.0
# CI will run checks, then publish to crates.io

Manual publishing:

cargo package --no-verify   # Verify the package
cargo publish               # Publish to crates.io

Contributing

Contributions are welcome! Please follow these guidelines:

  1. Fork the repository and create a feature branch
  2. Initialize submodules: git submodule update --init --recursive
  3. Make your changes following the existing code style
  4. Format: cargo fmt --all
  5. Check: cargo clippy --features vendored,generate-bindings
  6. Test: cargo test --features vendored,generate-bindings
  7. Commit with a descriptive message
  8. Open a Pull Request against main

Code Style

  • Follow rustfmt defaults (configured in rustfmt.toml)
  • All public items must have doc comments
  • Unsafe code must have safety comments explaining invariants
  • Keep bindings generation reproducible — commit updated src/bindings.rs when headers change

Reporting Issues

When reporting bugs, please include:

  • OS and architecture
  • Rust version (rustc --version)
  • Feature flags used
  • Full error output
  • CMake version (for vendored builds)

License

Licensed under either of:

at your option.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in this crate shall be dual licensed as above, without any additional terms or conditions.

Acknowledgments

  • FreeRDP — The FreeRDP project and its contributors
  • bindgen — Automatic Rust FFI binding generation
  • cmake-rs — CMake build integration for Cargo