$ rustup target add wasm32-unknown-unknown
yewrs, dioxus, leptos 등을 사용해서 Rust로 Frontend 개발을 해봤다면 위와 같이 컴파일 타겟을 추가한 적이 있을 것이다.
Rust에 워낙 고인물들이 많기 때문에 대부분은 이미 알고 있는 내용이겠지만,
나같은 초보도 있는 관계로 내용을 정리해둔다.
wasm32-unknown-unknown 형식의 Target을 target triple이라고 부르는데,
clang에서 사용되는 컨벤션을 가져온 것이다.
clang도 LLVM 프로젝트의 일부이므로, LLVM 프로젝트에서 사용된다고 볼 수도 있겠다.
컨벤션을 자세히 살펴보면
<architecture>-<vendor>-<sys>-<env(Option)>
위와 같은 형식으로 구성된다.
env는 생략될 수 있으며, 생략되면 자동으로 unknown이다.
architecture는 CPU 아키텍쳐를 의미하며, x86_64, arm 등이 들어갈 수 있다.
i686(intel, amd 32bit)
x86_64(amd, intel 64bit)
arm(arm 32bit arch)
aarch64(arm 64bit arch)
riscv32i
riscv64
powerpc(IBM powerpc 32bit arch)
powerpc64le(IBM powerpc 64bit arch)
다양한 CPU 아키텍쳐 중 일부 유명한 것들만 가져온 것인데, x86과 arm은 익숙할 것이다.
i686이 그 유명한 386, 486 컴퓨터의 후속 아키텍쳐인데, 586 부터는 프로세서는 Pentium이라는 이름으로 나왔고 내부 아키텍쳐 명으로만 사용한 것으로 보인다.
참고로 1978년에 출시된 intel 8086 프로세서가 성공하면서 마지막 86을 딴 것이 x86의 유래다.
riscv는 아직 멀긴 했지만 차세대 CPU architecture로 유명하여 가지고 와봤다.
재미있는 것은 CPU architecture 자리에 wasm도 들어갈 수 있다.
WASM이 특정 하드웨어에 종속되지 않는 portable binary format으로 웹 브라우저를 포함한 wasm runtime에서 실행될 수 있기 때문에 hardware independent한 존재로써 독립적인 아키텍쳐로 취급하는 것 같다.
clang 공식 문서에서 예시로 든 다음 5개만 보겠다.
apple
pc
nvidia
ibm
unknown
Vendor가 가장 헷갈리는 개념이다.
역사적인 배경을 알아야 하기 때문이다.
결론만 말하면, vendor란 '이 vendor가 칩을 제조하거나 설계했다'라는 의미가 아니라,
'특정 vendor의 하드웨어에 호환되도록 설계되었다'라는 의미다.
pc는 원래 Personal Computer를 의미하는 말이다.
이후 1980년대에 IBM PC가 개인용 컴퓨터 시장을 지배했다.
processor로는 처음에는 Intel이 탑재되었으며,
후발 주자인 AMD, Cyrix 등도 IBM PC에 호환되도록 Processor를 만들었다.
IBM이 PC 시장을 지배한 덕분에 target pc라 함은 사실상 IBM PC를 의미하게 되었다.
HP, DELL 등의 다양한 제조사들도 PC 시장에 뛰어 들었지만, 이들 역시 IBM 호환 PC였다.
Processor던, PC던 새로운 시장 진입자들은 새로운 기존에 시장의 선두 주자인 IBM의 PC에 맞춰 호환시킬 수밖에 없었을 것이다.
고로 CPU Architecture 자체가 IBM 호환 PC를 위해서 설계 되었고, 이 때문에 하드웨어 벤더에 intel, amd 등은 존재하지 않았던 것이다.
그들이 탑재되는 데스크탑, 랩탑 등은 vendor에 pc가 붙게 된 것이다.
이것이 지금까지 쭉 이어져 오고 있는 것이다.
2007년 아이폰이 출시된 이후로 다양한 모바일, IoT 기기 등이 나왔는데,
이 때부터 컴퓨팅 환경의 급격한 다변화가 시작되었다.
이런 것들은 pc 외로 분류되며 대부분 unknown이 들어간다.
그러나 apple, nvidia는 이와 별개로 독자적인 하드웨어를 가지고 있으며,
자사의 하드웨어 만을 위한 전용칩을 설계하고 있다.
apple은 iPhone, iMac 등 다양한 자사 하드웨어에 특화된 칩을 설계하며,
nvidia는 자체적인 GPU 아키텍쳐 nvptx64를 가지며, 이를 직접 설계하는 vendor이기 때문에 포함되었다.
unknown은 모바일, IoT 등의 pc 외 환경에서 주로 사용된다고 했다.
마치 *과 같은 와일드 카드의 의미로 사용된다.
어떤 vendor를 호환 시키기 위해 만들었던 상관 없이 넣을 수 있다.
WASM을 아키텍처 취급하기 때문에 특정 vendor를 호환시키기 위해 만든 것이 아니라 어디서든 runtime만 있으면 돌아갈 수 있기 때문에, 자연스럽게 unknown이 될 수밖에 없다.
고로 요즘은 바야흐로 unknown의 시대다.
뒤에서 적겠지만, 이 vendor 부분은 언젠가 사라질 지도 모르겠다.
어차피 대부분이 pc or unknown이기 때문이다.
예시는 다음과 같다.
aarch64-apple-unknown apple 64bit architecture CPU
x86_64-pc-unknown x86(intel or amd) 64bit architecture CPU
nvptx64-nvidia-unknown nvidia GPU
i686-pc-unknown IBM Personal Computer x86 32bit architecture CPU
sys 자리는 뒤에서 자세히 보기 위해 일부러 unknown만 넣었다.
기재하진 않았지만, 봐도 모르겠는 다른 vendor 들도 조금 더 있었는데, 궁금하면 다음 명령어로 전체 리스트를 직접 볼 수 있다.
$ rustc --print=target-list
System의 약자로 대체로 OS 내에 사용된 Kernel을 의미한다.(반드시 그런 것은 아니다.)
보통 C, C++ 등의 컴파일 언어는 컴파일 시, 각 Kernel 별로 System Call, API 등이 차이가 존재하고, 파일 형식이나 메모리 관리 방식이 다르기 때문이다.
그래서 컴파일 할 때, target을 잘 명시해야 한다.
대표적으로 다음과 같은 OS가 있다.
linux
darwin(macOS Kernel)
windows
깔끔하게 3개만 정리했다.
Linux도 Debian, Ubuntu, Arch Linux 등 다양한 배포판이 존재하지만, Kernel 이름이 Linux이기 때문에 Linux로 불리듯이, macOS도 여기서는 kernel 명으로 불린다.
Windows는 Kernel 명이 Windows NT라고 알고 있는데 NT는 생략한 것 같다.
대충 4개만 적었다.
aarch64-apple-darwin
x86_64-pc-windows
x86_64-unknown-windows
x86_64-unknown-linux
여기까지 보면 이제 wasm32-unknown-unknown을 해석할 수 있게 되었다.
여기서 의문이 들었던 건 왜 64bit가 아니라 32bit 냐는 것이었다.
현대 CPU는 전부 64bit인데 말이다.
Leptos, Dioxus 등의 공식 가이드에서 모두 wasm32-unknown-unknown을 명시하길래,
$ rustc --print=target-list로 검색해보니 wasm64-unknown-unknown이 존재했다.
$ rustup target add wasm64-unknown-unknown
error: toolchain 'stable-aarch64-apple-darwin' does not support target 'wasm64-unknown-unknown'; did you mean 'wasm32-unknown-unknown'?
note: you can see a list of supported targets with `rustc --print=target-list`
note: if you are adding support for a new target to rustc itself, see https://rustc-dev-guide.rust-lang.org/building/new-target.html
그러나 보다시피 실행은 되지 않았다.
아마 아직 WASM이 실험 단계이기도 하고, WASM의 본연의 이름 그대로 Web 에서 돌리기 위한 목적이기 때문에 30년 된 레거시 시스템인 웹에서 워낙 다양한 기기가 돌아가므로,
오래된 architecture 들도 지원할 목적이 더 크기 때문에 wasm64는 좀 더 후순위에 두고 개발중인 것이 아닌가 싶다.
wasm64-unknown-unknown이 이미 리스트에 존재하는데 안 되는걸 보면 말이다.
지금으로서는 WASM으로 본격적인 개발이 진행되진 않기 때문에 대형 프로젝트를 진행할 일은 없을 것이고, wasm32가 레거시를 포함한 64bit까지 수용하기 때문에 우선 순위에서 밀린 것이 납득은 된다.
그리고 vendor, system이 unknwon인 것은 WASM 자체가 마치 JVM이나 Node처럼 어떠한 vendor, os든 WASM 코드만 있으면 크로스 플랫폼으로 실행이 되기 때문에 architecture, system independent 하여 와일드카드 의미의 unknown이 붙은 것도 이해가 될 것이다.
나처럼 이런 세부 스펙을 모르고 설명서만 보고 썼었다면 이제 좀 답답함이 풀렸을 것이라 생각한다.
이 부분은 Option이라 wasm32-unknown-unknown엔 포함조차 되지 않지만
앞서 언급했던 것처럼 생략하면 unknown이 된다.
사실은 wasm32-unknown-unknown-unknown인 것이다.
환경을 나타내는데, 예시로 linux의 몇가지 환경을 살펴보겠다.
x86_64-unknown-linux-gnu리눅스는 대개 x86 architecture와 gnu 컴파일러를 사용한다.
이를 잘 나타내는 target이다.
신기한 건, target 중에서 x86_64-pc-linux-gnu 같은 것은 없었다.
linux 자체가 애초에 PC로는 잘 사용되지 않으며,
모바일, 서버, 임베디드, IoT 등 다양한 환경에서 설치되기 때문에 unknown으로 취급한 것 같다.
x86_64-pc-windows-mscv윈도우가 설치된 PC에서 MSVC(Microsoft Visual C++)를 사용했다는 의미다.
MSVC는 윈도우에서 C++, C 컴파일러 및 다양한 리소스의 집합을 의미한다.
aarch64-unknown-linux-gnu요즘은 AWS에 arm VM도 있던데, target에도 arm + linux이 있다.
aarch64-unknown-fuchsia구글의 차세대 OS인 Fuchsia를 나타내는 target이다.
환경에 대한 명시는 따로 존재하지 않는다.
aarch64-apple-darwinmacOS도 특별하게 환경은 명시하지 않았다.
참고로 aarch64-apple-ios, aarch64-apple-tvos 등도 존재한다.
aarch64-linux-android여기는 vendor가 생략되었다.
재미있게도 vendor, env를 둘 다 생략한 경우도 있었다.
aarch64-fuchsia어차피 모든 vendor에게 오픈할 거, 쓸 데 없이 unknown 배제하고, target 명이 길어서 차세대 OS부터는 필요 없는 부분을 제거려는 큰 그림일지도 모르겠다.