Conditional Compilation with Rust's cfg Attribute

RustRustBeginner
Practice Now

This tutorial is from open-source community. Access the source code

Introduction

In this lab, you will learn about the cfg attribute and cfg! macro in Rust, which allow for conditional checks in configuration and evaluation, respectively. The cfg attribute enables conditional compilation, while the cfg! macro evaluates to true or false at run-time. Code blocks using cfg! must be valid regardless of the evaluation result, unlike #[cfg] which can remove code.

Note: If the lab does not specify a file name, you can use any file name you want. For example, you can use main.rs, compile and run it with rustc main.rs && ./main.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL rust(("`Rust`")) -.-> rust/DataTypesGroup(["`Data Types`"]) rust(("`Rust`")) -.-> rust/FunctionsandClosuresGroup(["`Functions and Closures`"]) rust(("`Rust`")) -.-> rust/MemorySafetyandManagementGroup(["`Memory Safety and Management`"]) rust/DataTypesGroup -.-> rust/string_type("`String Type`") rust/FunctionsandClosuresGroup -.-> rust/function_syntax("`Function Syntax`") rust/FunctionsandClosuresGroup -.-> rust/expressions_statements("`Expressions and Statements`") rust/MemorySafetyandManagementGroup -.-> rust/lifetime_specifiers("`Lifetime Specifiers`") subgraph Lab Skills rust/string_type -.-> lab-99342{{"`Conditional Compilation with Rust's cfg Attribute`"}} rust/function_syntax -.-> lab-99342{{"`Conditional Compilation with Rust's cfg Attribute`"}} rust/expressions_statements -.-> lab-99342{{"`Conditional Compilation with Rust's cfg Attribute`"}} rust/lifetime_specifiers -.-> lab-99342{{"`Conditional Compilation with Rust's cfg Attribute`"}} end

cfg

Configuration conditional checks are possible through two different operators:

  • the cfg attribute: #[cfg(...)] in attribute position
  • the cfg! macro: cfg!(...) in boolean expressions

While the former enables conditional compilation, the latter conditionally evaluates to true or false literals allowing for checks at run-time. Both utilize identical argument syntax.

cfg!, unlike #[cfg], does not remove any code and only evaluates to true or false. For example, all blocks in an if/else expression need to be valid when cfg! is used for the condition, regardless of what cfg! is evaluating.

// This function only gets compiled if the target OS is linux
#[cfg(target_os = "linux")]
fn are_you_on_linux() {
    println!("You are running linux!");
}

// And this function only gets compiled if the target OS is *not* linux
#[cfg(not(target_os = "linux"))]
fn are_you_on_linux() {
    println!("You are *not* running linux!");
}

fn main() {
    are_you_on_linux();

    println!("Are you sure?");
    if cfg!(target_os = "linux") {
        println!("Yes. It's definitely linux!");
    } else {
        println!("Yes. It's definitely *not* linux!");
    }
}

Summary

Congratulations! You have completed the Cfg lab. You can practice more labs in LabEx to improve your skills.

Other Rust Tutorials you may like