1. Symptoms
When attempting to link an external library using the #[link] attribute without specifying the required name parameter, the Rust compiler emits error E0132. The error manifests during compilation with a message indicating that the name argument is mandatory for this attribute context.
The typical compiler output looks like this:
error[E0132]: `#[link]` attribute in this context requires a `name` argument
--> src/main.rs:5:1
|
5 | #[link(kind = "static", cfg(feature = "openssl"))]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: provide the argument: `name = "..."`
|
= note: `#[link]` accepts: `name`, `kind`, `cfg`, `modifiers`, `wasm_import_module`
In this example, the developer attempted to specify kind and cfg parameters but omitted the essential name argument that identifies which library to link. The compiler recognizes the attribute syntax but refuses compilation because the linkage target cannot be determined without a library name.
The error can also appear in a slightly different form when using #[link] with an empty attribute list:
error[E0132]: `#[link]` attribute in this context requires a `name` argument
--> src/lib.rs:3:1
|
3 | #[link]
| ^^^^^^^^ expected `name`
These error messages are deliberately descriptive, indicating exactly what information is missing and listing the acceptable parameters for the #[link] attribute.
2. Root Cause
The #[link] attribute in Rust serves as the primary mechanism for declaring dependencies on native libraries, particularly those written in C, C++, or assembly that will be linked into the final binary. This attribute is exclusively valid within an extern block, which defines the FFI (Foreign Function Interface) boundary between Rust code and external native code.
The fundamental design of this attribute requires specifying which library to link. Without a library name, the Rust compiler has no way to determine what native code to include in the linking phase. The name parameter is not optional but rather the core identifier that maps the attribute to an actual library on the system or provided by a crate.
When a crate uses #[link] with only the optional parameters like kind, cfg, or modifiers but omits name, the compiler cannot complete the linkage configuration. Each of these optional parameters modifies how the library should be linked, but none of them identifies which library should be linked. This is analogous to specifying the file format of a document without indicating which file to open.
The Rust compiler enforces this requirement at the attribute parsing stage, well before the actual linking phase occurs. This early detection prevents confusing linker errors that might arise if the compiler attempted to link an unspecified library.
3. Step-by-Step Fix
To resolve E0132, you must add the name parameter to your #[link] attribute. The name should be a string literal containing the library’s name as it would appear in the linking command or as the library file is named on the system.
Before:
use std::ffi::CString;
use std::ffi::CStr;
use std::ptr;
#[link(kind = "static")]
extern "C" {
fn some_external_function() -> i32;
}
After:
use std::ffi::CString;
use std::ffi::CStr;
use std::ptr;
#[link(name = "mylib", kind = "static")]
extern "C" {
fn some_external_function() -> i32;
}
The name value should match the actual library name without platform-specific prefixes or suffixes. For example, for the C standard math library, use "m" on Unix systems rather than "libm.a" or "libm.so".
Before:
#[link(cfg(feature = "ssl"), kind = "dylib")]
extern "C" {
fn init_ssl();
}
After:
#[link(name = "ssl", cfg(feature = "ssl"), kind = "dylib")]
extern "C" {
fn init_ssl();
}
When working with system libraries that have different names across platforms, you may need to use conditional compilation or platform-specific attributes:
#[cfg(target_os = "linux")]
#[link(name = "ssl", kind = "dylib")]
extern "C" {
fn init_ssl() -> i32;
}
#[cfg(target_os = "windows")]
#[link(name = "ssleay32", kind = "dylib")]
extern "C" {
fn init_ssl() -> i32;
}
Alternatively, use the pkg-config crate or bindgen to handle platform-specific library naming automatically. For most common system libraries, you can also leverage the libc crate or specialized binding crates that already handle the #[link] attribute correctly.
4. Verification
After adding the name parameter to your #[link] attribute, verify that the error has been resolved by recompiling your project:
cargo build
A successful compilation with no E0132 errors confirms the fix. The build output should proceed without the attribute-related error message.
You can also check that the linking actually occurs by examining the build artifacts or using verbose compilation:
RUSTFLAGS="-v" cargo build 2>&1 | grep -E "(Compiling|Linking|warning:|error:)"
For libraries that are part of a crate’s build process, ensure that the library exists and is discoverable by the linker. If the library cannot be found, you may encounter subsequent linker errors like cannot find -l<name> or library not found. These errors indicate that while the attribute syntax is now correct, the actual library file is missing or not in the expected location.
To verify the linkage is correctly configured, you can inspect the compiled binary’s linked libraries on Unix systems:
ldd target/debug/your_binary | grep library_name
Or on macOS:
otool -L target/debug/your_binary | grep library_name
On Windows, use a tool like dumpbin or Dependencies to inspect the linked DLLs.
5. Common Pitfalls
Several frequent mistakes lead to E0132 or similar linking errors. Understanding these pitfalls helps avoid repeated mistakes during FFI development.
Omitting the name entirely: The most obvious but common error is forgetting that name is mandatory. Always verify that every #[link] attribute contains a name parameter, even if you are only using optional parameters like kind or cfg.
Using the wrong library name: The library name specified in name must match the actual library file or crate name. On many Unix systems, the lib prefix is automatically handled by the linker, so specifying name = "m" links against libm.so or libm.a. On Windows, the .lib or .dll extension should not be included.
Placing the attribute outside an extern block: The #[link] attribute is only valid within extern blocks. Using it on regular function definitions or structs will produce a different error, but the confusion between attribute contexts can lead to misplaced #[link] declarations.
Mismatching kind parameter: When specifying kind, ensure it matches how the library is actually built. The four valid kinds are static, dylib, framework, and dynamic. Using kind = "static" for a dynamic library or vice versa can cause runtime loading failures even if compilation succeeds.
Conditional compilation with missing fallback: When using #[link] with cfg conditions, ensure that at least one configuration will always provide a valid library. If all #[link] attributes are conditionally excluded, you may get linker errors about undefined symbols.
6. Related Errors
E0131: This error occurs when the #[link] attribute is used in an invalid context, such as outside of an extern block. While E0132 deals with a missing argument, E0131 addresses the structural placement of the attribute itself.
E0458: The linker cannot find the specified library when the name in the #[link] attribute does not match any available library. This error occurs after compilation succeeds but during the linking phase, indicating that the attribute syntax is valid but the library is actually missing from the system.
E0583: This error happens when a link target (library) cannot be found because the specified library is not a direct dependency and is not available through the link search path. It often occurs when depending on optional features that require system libraries not present in the build environment.
Understanding the relationship between E0132 and these related errors helps diagnose complex linking issues. E0132 prevents compilation when the attribute is syntactically incomplete, while E0458 and E0583 surface when the attribute is valid but the referenced library cannot be located or accessed.