Updated conditional-compilation.md

AinL authored
revision 94a850820d8f97cd163893296a269ee23304cd23
conditional-compilation
# 4.3. 조건부 컴파일 (Conditional Compilation) - 70%

Rust는 컴파일러에게 전달되는 플래그 값에 기반해 코드를 컴파일하도록 해주는 `#[cfg]`라는 특별한 속성을 가지고 있습니다. 여기에는 두가지 형식이 있습니다.

```rust
#[cfg(foo)]
# fn foo() {}

#[cfg(bar = "baz")]
# fn bar() {}
```

또 몇가지 helper 도 가지고 있습니다.

```rust
#[cfg(any(unix, windows))]
# fn foo() {}

#[cfg(all(unix, target_pointer_width = "32"))]
# fn bar() {}

#[cfg(not(foo))]
# fn not_foo() {}
```

이것들은 임의로 겹칠 수도 있습니다.

```rust
#[cfg(any(not(unix), all(target_os="macos", target_arch = "powerpc")))]
# fn foo() {}
```

만약 Cargo를 사용한다면, `Cargo.toml`의 [`[features]` [section][features] 속성값을 통해 이 기능들을 사용할 지 여부를 설정할 수 있습니다.

[features]: http://doc.crates.io/manifest.html#the-%5Bfeatures%5D-section

```toml
[features]
# no features by default
default = []

# The “secure-password” feature depends on the bcrypt package.
secure-password = ["bcrypt"]
```

위와 같이 구현하면, Cargo는 flag값들을 `rustc`로 전달합니다.

```text
--cfg feature="${feature_name}"
```

이렇게 정의된 `cfg` flag값들은 어떤 속성들이 활성화 되어야 하고, 이를 통해 어떤 코드들이 컴파일 되어야 하는지를 결정하게 됩니다. 아래 코드를 살펴보도록 하겠습니다.

```rust
#[cfg(feature = "foo")]
mod foo {
}
```

위 코드를 `cargo build --features "foo"`로 컴파일 할 경우, `--cfg feature="foo"`플래그값을 `rustc`로 전달하고 결과물에는 `mod foo`가 포함되게 됩니다. 반대로, 일반적인 `cargo build`로 컴파일할 경우에는 어떤 flag값도 전달되지 않으며, 따라서 `foo`모듈도 존재하지 않습니다.

# cfg_attr

`cfg_attr`라는 명령어를 사용해서 `cfg` 에 기반한 다른 속성들을 설정하는 것도 가능합니다.

```rust
#[cfg_attr(a, b)]
```

`a`가 `cfg` 속성에 설정되어 있을 경우, 위 코드는 `#[b]`와 동일한 결과를 출력하며, 그 이외의 차이점은 없습니다.

# cfg!

`cfg!` [syntax extension][compilerplugins] 를 아래와 같은 방식으로 자신의 코드에 추가할 수 있습니다.

```rust
if cfg!(target_os = "macos") || cfg!(target_os = "ios") {
println!("Think Different!");
}
```

[compilerplugins]: compiler-plugins.html

프로젝트의 설정값에 따라 위 선택문들은 컴파일 중 `true` 나 `false`로 대체됩니다.