Skip to content
tezvyn:
Menu

Rust `cfg`: Compile Code for Specific Targets

Source: doc.rust-lang.orgEasyHow cards are made

Rust's cfg attribute acts like a compile-time switch, including or excluding code based on the target platform or features. It's used for cross-platform support (e.g., Windows vs. Unix) or enabling optional dependencies.

Why it exists

Programs often need to behave differently depending on the environment they're compiled for. A server running on Linux needs different system calls than a desktop app on Windows. Conditional compilation provides a clean, built-in way to manage this complexity without cluttering the code with runtime checks for things that are known before the program even runs.

The mental model

Think of cfg as a set of compile-time gates. Before the compiler builds the final binary, it checks these gates. If a gate's condition is true (e.g., the target is unix), the code it guards is included. If the condition is false, the code is completely ignored, as if it were commented out. This applies to functions, structs, modules, or even single expressions.

How it works

You apply the #[cfg(...)] attribute to a piece of code. Inside the parentheses is a configuration predicate. This can be a simple name like #[cfg(unix)], a key-value pair like #[cfg(target_arch = "aarch64")], or a combination using any(), all(), and not(). For example, #[cfg(all(unix, target_pointer_width = "64"))] means "only compile this for 64-bit Unix-like systems." These configuration options are set by the compiler based on the target triple (e.g., target_os) or passed manually with the --cfg flag, often managed by Cargo's features system.

When to use it

Use cfg for platform-specific code, like different implementations for file I/O on Windows versus Linux. It's also the standard way to handle optional features. For instance, you can provide serialization support via Serde but only compile it if a user enables the serde feature for your crate, avoiding an unnecessary dependency for users who don't need it.

When not to use it

Do not use cfg for logic that needs to be decided at runtime. If your program's behavior depends on user input, a configuration file, or a network response, use a standard if/else block. cfg is strictly for compile-time decisions. Using it for runtime logic is a fundamental misunderstanding of its purpose, as the excluded code doesn't even exist in the final binary.

One canonical example

A common pattern is providing different function implementations for different operating systems. For a function get_home_dir(), you could have two versions. One is decorated with #[cfg(unix)] and contains the logic for Linux and macOS. The other is decorated with #[cfg(windows)] and contains the logic for Windows. When you compile on Linux, only the unix version of get_home_dir is included in the binary. When you compile on Windows, only the windows version is included. The compiler ensures that exactly one version exists for any given target.

Interview question

Which scenario is NOT an appropriate use case for Rust's `cfg` attribute?

  • a.Deciding which configuration file to load based on a command-line argument provided by the user.Correct
  • b.Including a dependency like Serde only when a specific Cargo feature is enabled.
  • c.Providing different implementations for a function based on the target operating system.
  • d.Optimizing code for a specific CPU architecture, such as ARM or x86.
Why?

`cfg` is strictly for compile-time decisions, such as platform-specific code or optional features. Deciding which configuration file to load based on a command-line argument is a runtime decision, requiring standard conditional logic like an if/else statement.

Just read this? Test yourself on what you have been reading.

Read the original → doc.rust-lang.org

Put your scrolling time to good use

Learn one idea, try a quiz and save useful cards for revision. Tezvyn makes it easy to learn and stay current in your tech field, a few minutes at a time.

The iPhone app is on the way

We are building it. Until it lands, nothing here is held back from you: every interview card, your saved cards, streaks and the job board all work in Safari, plus hundreds of free practice quizzes of thirty questions each. Sign in and it all carries over to the app the day it arrives.

Want it as an icon? Tap Share at the bottom of Safari, then Add to Home Screen. It opens full screen and the cards you have read stay available offline.

Get it on Google PlayiPhone app coming soon

We are hiring for this. Open roles that interview on rust — each one lists the topics its interview covers.

See open roles