[Rust] 플랫폼별 로직 분기하기 (Conditional Complie)
일반적인 사용사례에서는 별로 생각할 필요가 없지만, 극단적인 unsafe 최적화가 필요하거나 low한 부분에서 특별한 처리가 필요하다면, 플랫폼마다 다른 로직을 수행하도록 코드를 짜야할 수도 있다.
이럴때 쓰는게 cfg라는 녀석이다.
cfg! 함수형 매크로 사용
가장 간단한 방법은 cfg!라는 미리 정의된 매크로를 활용하는 것이다.
cfg에 linux 등의 식별자를 전달하면, 그 값이 정의되어있는지를 검사해서 플랫폼 체크를 수행할 수 있다.
위와 같이 한다면, 윈도우즈 환경에서 linux는 정의되어있지 않으니 false로 판단, windows는 정의되어있으니 true로 판단된다.
따라서 다음과 같은 결과를 출력할 것이다.

위에서는 그냥 값의 존재여부로만 체크했지만, 더 명시적인 방법은 속성명을 지정해주는 것이다.
예를 들어, OS를 알 수 있는 속성명은 target_os다.
명시적인 방법으로 위의 코드를 대체한다면 아래와 같이 재구성할 수 있을 것이다.


여기서 사용할 수 있는 값의 목록은 다음 문서에서 확인할 수 있다.
https://doc.rust-lang.org/reference/conditional-compilation.html#target_arch




그래서 만약, x86_64 인텔계열 CPU면서 윈도우즈고, 리틀 엔디안을 쓰면서, SSE2 명령어셋을 지원하는 경우의 분기를 처리하고 싶다면 다음과 같이 작성할 수 있는 것이다.

내 경우에는 완벽히 부합한다.
cfg 어트리뷰트 매크로
위에서는 함수형 매크로로 단순 로직만을 분기했지만, 아예 컴파일타임에 사용을 할 수 없게 막아버릴 수도 있다.
가령, 함수 위에 cfg 매크로를 어트리뷰트의 형태로 붙인다면, 조건에 부합하지 않는 것들은 컴파일에서 아예 제외처리가 되어버린다.
윈도우즈 환경에서 다음과 같은 코드를 작성할 경우, only_linux는 아예 존재하지 않는 함수가 되어 컴파일 수준에서 오류를 뿜는다.

이건 함수뿐만이 아니라 모듈, 구조체 등 거의 모든 요소에 적용할 수 있다.
cfg: 부정문
부정문은 not 함수를 사용해서 처리할 수 있다.
리눅스가 아닌 경우에만 동작하게 하고 싶다면 다음과 같이 작성할 수 있다.

참조
https://doc.rust-lang.org/reference/conditional-compilation.html
https://doc.rust-lang.org/std/macro.cfg.html