Back to writing
Programming Apr 19, 2026 3m read

Memahami Conditional Compilation di Rust

Rust merupakan bahasa cross-platform, tapi kenapa hasil kompilasi binary-nya sangat kecil? Kenapa Rust lebih unggul dari bahasa cross-platform lainnya? Tidak seperti bahasa lainnya, di Rust kita bisa menambahkan logika untuk mengecualikan kode tertentu selama proses kompilasi, jadi ini yang membuat hasil kompilasi Rust menjadi sangat efisien.

Hutomo S. Kartiko
Hutomo S. Kartiko
Fullstack & Web3 Engineer

Conditional Compilation di pemrograman adalah konsep yang digunakan oleh kompiler untuk menyertakan atau mengecualikan bagian kode tertentu selama proses kompilasi. Di Rust sendiri ada beberapa metode yang bisa kita gunakan, yaitu:

A. Attribute #[cfg(...)]

Attribute  #[cfg(...)] yang berarti kode akan dikompilasi jika kondisi di dalam attribute itu terpenuhi. Jadi, jika di luar dari kondisi itu kode akan diskip. Beberapa kondisi yang tersedia di attribute ini yaitu:

Platform & OS

text
#[cfg(target_os = "macos")]
#[cfg(target_os = "linux")]
#[cfg(target_os = "windows")]
#[cfg(unix)]       // semua sistem Unix-like
#[cfg(windows)]    // semua sistem Windows

Arsitektur CPU

text
#[cfg(target_arch = "x86_64")]
#[cfg(target_arch = "aarch64")]  // ARM 64-bit
#[cfg(target_arch = "wasm32")]   // WebAssembly

Tipe Kompilasi

text
#[cfg(debug_assertions)]   // aktif saat `cargo build` (debug)
#[cfg(test)]               // aktif saat `cargo test`

Endianness & Pointer Width

text
#[cfg(target_endian = "little")]
#[cfg(target_pointer_width = "64")]

Operator Logika

text
// AND - semua kondisi harus terpenuhi
#[cfg(all(target_os = "linux", target_arch = "x86_64"))]
fn linux_x64_only() { }

// OR — salah satu kondisi
#[cfg(any(target_os = "linux", target_os = "macos"))]
fn unix_like() { }

// NOT — kebalikan kondisi
#[cfg(not(windows))]
fn non_windows() { }

// Kombinasi
#[cfg(all(unix, not(target_os = "macos")))]
fn linux_bsd_only() { }

Selain itu, kita bisa custom cfg dengan --cfg flag saat proses kompilasi, seperti berikut ini:

text
#[cfg(feature_x)]
fn experimental() {
    println!("Fitur eksperimental aktif!");
}

Kemudian saat running, kita bisa seperti ini:

text
RUSTFLAGS='--cfg feature_x' cargo build

B. Macro cfg!(...)

Berbeda dengan attribute sebelumnya, macro ini digunakan sebagai ekspresi boolean di dalam kode. Macro ini tetap mengkompilasi semua ekspresi, tapi memilih satu ketika runtime. Berikut contoh penerapannya:   

text
fn main() {
    if cfg!(debug_assertions) {
        println!("Mode: DEBUG");
    } else {
        println!("Mode: RELEASE");
    }
}

C. Features

Ini merupakan jenis Conditional Compilation yang paling sering digunakan. Berikut cara penerapannya:

Definisikan di cargo.toml

text
[features]
default = ["logging"]      # fitur aktif secara default
logging = []
database = ["dep:sqlx"]    # fitur dengan dependensi opsional
advanced = ["logging", "database"]  # fitur gabungan

Gunakan di kode:

text
#[cfg(feature = "logging")]
fn setup_logger() {
    println!("Logger diinisialisasi");
}

fn main() {
    #[cfg(feature = "logging")]
    setup_logger();

    println!("App berjalan");
}

Kompilasi dengan:

text
cargo build --features "logging,database"
cargo build --features "advanced"
cargo build --all-features    # aktifkan semua fitur
cargo build --no-default-features  # nonaktifkan default

D. Attribut cfg_attr

Dengan metode ini akan menerapkan attribute lain secara kondisional, contohnya:

text
// Hanya tambahkan derive(Debug) saat testing
#[cfg_attr(test, derive(Debug))]
struct Config {
    value: u32,
}

// Hanya aktifkan serde saat fitur "serde" diaktifkan
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
struct Data {
    name: String,
}

E. Build.rs

File build.rs dijalankan sebelum kompilasi dan bisa mengatur cfg secara dinamis. Berikut contoh di build.rs

text
fn main() {
    // Set cfg berdasarkan kondisi saat build
    if std::env::var("CARGO_CFG_TARGET_OS").unwrap() == "linux" {
        println!("cargo:rustc-cfg=use_epoll");
    }

    // Emit cfg berdasarkan versi atau environment lain
    println!("cargo:rustc-cfg=my_custom_flag");
}

Dan ini di main.rs

text
#[cfg(use_epoll)]
fn io_backend() {
    println!("Menggunakan epoll (Linux)");
}

Kesimpulan

  • #[cfg(...)] - Exclude item secara keseluruhan
  • cfg!(...) - Cek kondisi sebagai ekspresi bool
  • [features] di Cargo.toml - Fitur opsional yang bisa diaktifkan oleh pengguna
  • #[cfg_attr(...)] - Terapkan attribute secara kondisional
  • build.rs - Set cfg dinamis berdasarkan environment build

References

  • https://doc.rust-lang.org/reference/conditional-compilation.html
  • https://lightwavephotonics.com/lig/rise-of-the-rust-empire-how-rust-crossplatform-development-is-revolutionizing-the-industry