🎓 A1Learner
🔍

Rust Target Cfg Values

Target cfg values are the compiler's facts about the machine a program is built for. The facts cover the system family, the chip, the byte order, and the C library.

Ask about the chip: target_arch

target_arch names the processor family the program is built for. This machine answers x86_64:

println!("x86_64 = {}", cfg!(target_arch = "x86_64"));

Families group systems together

target_family sorts systems into clans. The plain names unix and windows are shortcuts for the two big clans:

println!("unix = {}", cfg!(unix));
println!("windows = {}", cfg!(windows));

Byte order: target_endian

Endian names the order a machine stores the bytes of a number. Almost every machine you will meet is little:

println!("little = {}", cfg!(target_endian = "little"));

The C library world: target_env

target_env names the C library family the program links into. This machine says gnu. Windows builds usually say msvc, small static builds say musl, and some targets — WebAssembly among them — say nothing at all:

println!("gnu = {}", cfg!(target_env = "gnu"));

Read the answers as values: env::consts

cfg! gives yes-or-no answers. When you need the words themselves, std::env::consts holds them as text:

use std::env::consts;
println!("{} on {}", consts::OS, consts::ARCH);

Example

use std::env::consts;

fn main() {
    println!("os = {}", consts::OS);
    println!("arch = {}", consts::ARCH);
    println!("family = {}", consts::FAMILY);
    println!("pointers are {} bits", usize::BITS);
    if cfg!(target_endian = "little") {
        println!("endian = little");
    } else {
        println!("endian = big");
    }
    println!("unix family = {}", cfg!(unix));
}

Key points

  • Use rustc --print cfg to list every value your target sets, with the exact spellings
  • A target can carry two family values at once: some WebAssembly targets answer to both wasm and unix
  • usize::BITS gives the pointer width as a number: 64 on a 64-bit target, 32 on a 32-bit one
  • The answers describe the target, not your computer.
  • Cross-compile for another machine, and the target's answers are the ones baked in.
  • They read the same compile-time facts — one as text, one as true or false.
  • Target cfg values state the target machine's family, chip, byte order, and C library.

In this example, the program prints the target report about itself. The consts lines read the answers as text: linux, x86_64, unix. usize::BITS gives the pointer width as a number, 64. The cfg! line asks the byte-order question and picks the word to print. Every answer was fixed while the program compiled. Run the same source on a Windows machine and the program prints windows answers instead — the source never changes.

Note

env::consts and cfg! never disagree.

Try it Yourself

Edit the code, then press Run.

Running is simulated · Rust Playground

Exercise

A program is compiled for a 32-bit WebAssembly target. What does cfg!(target_pointer_width = "64") give?