Course contentsShow
← Rust
Lesson 1472 of 1,91012. Unsafe Rust and Low-Level AccessFree lesson

Linking External Libraries

You will manage build-time dependencies on external shared and static C libraries.

In this lesson, you will learn how to orchestrate the build-time discovery and integration of external C shared and static libraries using the build.rs script.

The Role of build.rs

When you consume a C library that isn't provided by the system package manager in a predictable location, you must instruct rustc on how to find and link it. This is handled by a build.rs file—a script executed by Cargo before your crate is compiled.

To link an external library, your build.rs must output specific instructions to Cargo via stdout. These instructions take the form of cargo:rustc-link-search (to specify where the library lives) and cargo:rustc-link-lib (to specify the library name).

Practical Implementation

Suppose you have a static library named libmath_core.a located in a vendor/ folder within your project. Your build.rs would look like this:

fn main() {
    // Tell Cargo to look for libraries in the 'vendor' directory
    println!("cargo:rustc-link-search=native=vendor");

    // Tell Cargo to link the library 'math_core'
    // Rust automatically prefixes 'lib' and adds the extension
    println!("cargo:rustc-link-lib=static=math_core");
}

By specifying static=, you ensure the library is embedded directly into your final binary. If you were using a dynamic shared library (e.g., libmath_core.so or .dylib), you would use println!("cargo:rustc-link-lib=dylib=math_core"); instead.

Managing System Dependencies

In professional environments, you rarely hardcode paths. Instead, you often use the pkg-config crate within your build.rs to query the host system for library locations. If pkg-config finds the library, it automatically emits the necessary rustc-link-search and rustc-link-lib instructions for you, abstracting away the platform-specific complexities of file extensions and path searching.

Always remember: if you are linking against a C++ library, you may also need to explicitly link the C++ standard library (e.g., stdc++ or c++) using cargo:rustc-link-lib=dylib=stdc++ to satisfy internal symbol dependencies.

Key Takeaway: Linking external libraries requires communicating with Cargo via build.rs output commands to specify search paths and link types, ensuring the linker resolves your FFI symbols correctly at compile time.