보조 도구 정책
T-compiler의 임무는 제대로 작동하는 Rust 컴파일러(rustc)를 배포하는 데 필요한 일을 하는 것이지만, rustc는 한 번도 단독으로 동작한 적이 없습니다. 이 도구는 컴파일러 툴체인과 함께 제공되는 것이든 환경에 있을 것으로 기대되는 것이든, 사용하려면 언제나 추가 도구가 필요했습니다. 이 문서는 rustc 그리고 rustc와 함께 사용되거나 rustc가 필요로 하는 도구에 관한 몇 가지 기대 사항을 명확히 하고, 이미 암묵적으로 존재하는 일부 기대 사항을 명시하려는 시도입니다.
정의
- 컴파일 환경 - 제공 도구가 호출되는 호스트 시스템으로, 파일 시스템이나 환경 변수와 같은 일시적인 상태를 포함합니다.
- 호출 - 프로세스 생성, 라이브러리 로딩 또는 컴파일 환경이 지원하는 그 밖의 수단을 통해 임의의 산출물의 코드를 실행하는 것입니다.
- 중간 산출물 - 컴파일러 도구를 호출하여 출력되며, 다시 컴파일러 도구의 입력으로 제공될 산출물입니다.
- 컴파일러 도구 - 코드를 컴파일하고 링크하여 바이너리 코드 객체로 만드는 과정의 일부로 호출되는 산출물이며, 특히 Rust 툴체인의 일부로 배포되는 것을 가리킵니다.
- 바이너리 도구 - 바이너리 코드 객체를 생성하거나 편집하는 데 사용되는 컴파일러 도구입니다.
- 제공 도구 - T-compiler와 T-release의 지원을 받아 Rust 툴체인의 일부로 배포되는 바이너리 도구 또는 컴파일러 도구입니다. 여기에는 특히
rustc,rust-lld,rust-objcopy와 같은 바이너리 도구가 포함됩니다. - 보조 도구 - T-compiler와 T-release가 배포하지는 않지만 제공 도구와 함께 사용될 수 있는 컴파일러 도구입니다. 여기에는 특히
ld.bfd,link.exe,llvm-bolt, 그리고 “링커 스크립트”(Link Editor Command Language로 작성된 프로그램)와 같은 바이너리 도구가 포함됩니다.
보조 도구 사용 방식
rustc를 포함한 모든 제공 도구는 명시적인 사용자 입력을 요구하지 않고 보조 도구를 암묵적으로 호출할 수 있습니다. 제공 도구는 어떤 도구를 호출할지 결정하기 위해 컴파일 환경을 검사할 수 있습니다.1 보조 도구가 호출될 때 컴파일 환경이 관례적인 방식 및/또는 특유의 방식으로 구성되어 있다고 기대할 수 있습니다.
관례적 기대의 예는 다음과 같습니다.
link.exe라는 이름의 실행 파일이 인자로 주어진 경로에 있는 바이너리 코드 객체를 링크하는 작업을 수행하리라고 기대하는 것, 또는- Unix 도구가 POSIX에 명시된 방식으로 인자를 따르리라고 기대하는 것, 또는
$CC와 같은 환경 변수에 C 컴파일러의 경로가 들어 있으리라고 기대하는 것입니다.
특유의 기대는 관례적 기대와 비슷해 보이지만 이를 부당하게 적용한 것일 수 있습니다. 예를 들어 Unix 시스템이라면 macOS조차도 GNU 유저랜드를 갖춘 Linux 시스템과 비슷하다고 가정하는 경우입니다. 또는 순전히 새로 만들어 낸 기대일 수도 있습니다. 예를 들어 컴파일 환경의 데이터가 Rust 툴체인의 다른 제공 도구에 의해 생성되거나 수정되었다고 가정하는 경우입니다.
이러한 기대는 컴파일 환경의 내용이 사용하기에 안전한지, 올바르게 작동하는지, 이름이 올바르게 붙어 있는지 판단할 필요가 없다는 데까지 확장됩니다. 파일 시스템이 특정한 방식으로 구성되어 있다고 기대할 수 있으며, 파일에 붙은 이름은 무엇이든 올바른 레이블로 암묵적으로 신뢰할 수 있습니다. 보조 도구를 예상 경로에서 찾고, 우리가 어떤 도구에 어떤 방식으로 의존할 수 있는지 문서화하려는 합리적인 노력을 기울여야 하지만, 이것이 필수는 아닙니다. 환경에 있는 보조 도구를 계속 호출해야 할 의무조차 없습니다. 제공 도구는 T-release와 T-compiler의 재량에 따라 확장될 수 있으며, 환경에서 발견되는 보조 도구를 대체하려는 명시적인 목적으로 사용될 수 있기 때문입니다.
제공 도구가 보조 도구를 호출해야 하고 그 출력을 컴파일 과정의 다른 부분에서 중간 산출물로 사용해야 한다고 판단하면, 그 결과 출력은 해당 도구가 출력하는 형식을 엄격하게 따를 것으로 기대할 수 있습니다. 또한 이러한 출력이 다른 요구 사항도 충족하리라고 기대할 수 있습니다. 예를 들어 링크하거나 로드할 수 있는 바이너리 코드 객체, 나아가 실행할 수 있는 바이너리 코드 객체여야 하거나, 단순히 Rust 툴체인이 기대하는 추가 메타데이터 섹션을 보존해야 할 수 있습니다.
제공 도구에 대한 기대 사항이 하나도 위반되지 않았다고 가정하면, 제공 도구는 실행 가능하거나 동적으로 로드할 수 있는 바이너리 코드 객체를 생성할 때 적어도 해당 객체의 바이너리 형식 명세를 최소한으로 따르는 객체를 생성해야 합니다. 중간 산출물은 대개 바이너리 형식을 따르더라도 올바른 형식을 갖추지 않을 수 있습니다. 문서화가 부족한 바이너리 형식의 경우, 형식을 따른다는 것이 무엇을 뜻하는지는 T-compiler가 원하는 대로 해석할 수 있습니다.
컴파일러 팀에게 이는 대체로 환경에 있는 것을 원하는 대로 호출해도 된다는 뜻입니다. 예를 들어 소스에 정의되지 않은 동작이 없다고 가정하고, 출력을 올바르게 만드는 데 집중하십시오. 이상적으로는 디버거 등을 포함한 “네이티브” 툴체인이 우리 코드와 잘 작동할 만큼 관례를 충분히 따르는 것이 좋지만, 사람들이 사용하고 싶어 할 수 있는 도구의 목록은 끝이 없습니다.
보조 도구 이슈 트리아지
보조 도구와 관련된 이슈를 해결하기 전에, 우리 툴체인이 의존하는 전제가 “자명“하지 않다면 이를 문서화해야 합니다. 예를 들어 최소 도구 버전에 대한 의존성, 특히 그 버전이 운영 체제에 기본으로 포함된 버전보다 높은 경우가 이에 해당합니다. 자명하지 않은 전제만 문서화하는 이유는 이 문서 앞부분에 있는 장황한 정의의 정의 때문입니다. 아무것도 가정하지 않으면 컴파일러의 동작 방식을 설명하는 데 필요한 어휘를 정의하는 것만으로도 오랜 시간이 걸릴 수 있습니다.
누군가 컴파일러 플래그나 설정을 통해 보조 도구를 의도적으로 포함한 뒤 버그를 제보했다면, 보조 도구 없이도 오브젝트가 올바른 형식인지 확인해 보십시오. 그렇다면 대개 고치려 하지 말고 이슈를 닫아야 합니다
때로는 rustc가 암묵적으로 호출했기 때문에 보조 도구가 관여하기도 합니다. 툴체인이 기능적으로 이를 대체할 수 있는 도구를 제공한다면, 이슈를 해결하기 전에 그렇게 대체하는 것이 바람직합니다.
특정 운영 체제의 고유한 관례를 따르는 문제라면, 그 운영 체제를 위한 별도의 타깃이 있는 한 어느 정도 대응하려고 노력할 수 있습니다. 이를 위한 자원이 공개되어 있고 이용할 수 있다면, 대개 참여하려고 노력해야 합니다.
-
이는 운영 체제가 제공하는 방식으로 어떤 도구든 이름만으로 실행할 수 있거나 그렇게 하는 것이 바람직하다는 점에서 비롯되는 기능적 결과입니다. 이는 암묵적으로든 명시적으로든
$PATH를 뒤진다는 뜻이기 때문입니다. ↩