이 문서는 2판 번역본입니다.

최신 2021 에디션 문서는 https://doc.rust-kr.org 에서 확인하실 수 있습니다.

부록 G: 러스트가 만들어지는 과정과 "Rust Nightly"

다음 내용은 러스트가 만들어지는 과정과 해당 과정이 러스트 개발자인 여러분에게 어떤 영향이 미치는지를 다룹니다. 앞서 이 책의 예제들은 러스트 stable 1.21.0 버전을 기준으로 만들었다고 했지만 모든 예제는 더 높은 버전에서도 작동할 겁니다. 어떻게 이런 일이 가능한지 알아보도록 합시다.

막힘 없이 안정된 발전 (Stability Without Stagnation)

러스트는 하나의 언어로서 여러분 코드를 여러 방면으로 관리하는 동시에 여러분이 안심하고 위에 무언가 지을 수 있는 단단한 기반을 마련해야 합니다. 언어가 자주 변경된다면 이 목표는 달성하기 힘들어지겠죠. 하지만 새로운 기능을 시험해보지 못한다면 심각한 문제가 있더라도 릴리즈 이전에 알아채지 못할 겁니다. 물론, 릴리즈 이후엔 고칠 방법이 없습니다.

이러한 문제의 해결법이 바로 러스트의 유도 원칙이기도 한 "막힘 없이 안정된 발전(Stability Without Stagnation)" 입니다: 모든 업데이트에서 발생하는 문제를 최소화하고, 새로운 기능은 착실히 추가하되, 버그를 줄이고 컴파일 속도를 높여서 사용자들이 마음 편히 업데이트할 수 있게 하는 것이 목표입니다.

릴리즈 채널 열차가 달려갑니다

러스트 개발은 열차 스케줄 (train schedule) 로 운영됩니다. 모든 개발은 러스트 저장소의 master 브랜치에서 완료됩니다. 릴리즈 방식은 Cisco IOS 를 비롯한 여러 소프트웨어 프로젝트에서 사용하는 "train model" 을 사용합니다. 다음은 러스트의 3 가지 릴리즈 채널 입니다:

  • Nightly
  • Beta
  • Stable

러스트 개발자는 대부분 stable 채널을 주로 사용하며, 새 기능을 사용해보려는 사람들은 nightly 나 beta 채널을 사용하기도 합니다.

개발 및 릴리즈 과정은 다음 예시처럼 돌아갑니다: 러스트 개발 팀이 러스트 1.5 버전 릴리즈 작업을 하고 있다고 가정해봅시다. (1.5 버전은 2015년 12월에 릴리즈되었지만, 현실적인 버전 가정을 위해 이와 같이 설정했습니다) 러스트에 새 기능이 추가됐습니다. 다시 말해, master 브랜치에 새 커밋이 올라갔습니다. 매일 밤, 러스트 nightly 버전이 릴리즈됩니다. 매일 밤 생성되는 이 릴리즈는 러스트 릴리즈 인프라가 자동으로 생성합니다. 시간이 지남에 따라 러스트 릴리즈는 다음과 같은 모습이 됩니다:

nightly: * - - * - - *

beta 브랜치는 6 주마다 nightly 에 사용되는 master 브랜치로부터 떨어져 나와 생성됩니다. 이제 릴리즈는 두 종류가 됐네요:

nightly: * - - * - - *
                     |
beta:                *

beta 릴리즈는 사용하는 사람이 그다지 많지 않지만, 러스트는 CI 시스템을 이용해 가능한 한 문제점을 찾으려고 노력합니다. 이 동안에도 nightly 는 매일 밤 릴리즈됩니다.

nightly: * - - * - - * - - * - - *
                     |
beta:                *

문제점이 발견됐다고 가정해봅시다. 오류가 stable 릴리즈로 넘어가기 전에 beta 릴리즈 테스트에서 잡아냈다는 게 불행 중 다행이네요. 오류 수정 내용을 master 브랜치에 반영하면 자연스레 nightly 버전이 고쳐집니다. 이후 해당 내용이 beta 브랜치에 백포트되고(backport, 상위 버전의 기능을 하위 버전에 반영하는 것을 말함) 나면 새로운 beta 릴리즈가 제공됩니다:

nightly: * - - * - - * - - * - - * - - *
                     |
beta:                * - - - - - - - - *

첫 베타 버전이 만들어지고 6 주가 지나면, stable 브랜치가 beta 브랜치로부터 만들어져 stable 릴리즈가 생성됩니다.

nightly: * - - * - - * - - * - - * - - * - * - *
                     |
beta:                * - - - - - - - - *
                                       |
stable:                                *

마침내 러스트 1.5 버전을 완성했습니다! 하지만, 그동안 6주가 지나버렸기 때문에 다음 버전이 될 1.6 버전에 대응할 새로운 beta 가 필요합니다. 따라서 beta 브랜치는 stable 버전이 만들어진 후에도 계속 nightly 브랜치로부터 떨어져 나옵니다:

nightly: * - - * - - * - - * - - * - - * - * - *
                     |                         |
beta:                * - - - - - - - - *       *
                                       |
stable:                                *

이 과정을 "train model" 이라고 부르는 이유는 6주마다 이루어지는 릴리즈가 "열차가 역을 지나는" 것과 유사하기 때문입니다. 그리고 열차는 다음 stable 릴리즈 역에 도착할 때까지 beta 채널 위를 달리겠죠.

러스트는 6주마다 일정하게 릴리즈됩니다. 릴리즈 날짜를 하나 알고 있다면 6주를 더해 다음 릴리즈 일을 알아낼 수도 있죠. 일정한 주기로 릴리즈 하여 얻는 장점은 언제가 될지 모를 릴리즈일을 하염없이 기다릴 필요가 없단 점입니다. 어떤 기능이 특정 릴리즈에 누락되더라도 곧 있으면 다음 릴리즈가 생성될 테니 걱정할 필요 없죠. 이 방식은 아직 다듬을 필요가 있는 기능을 개발 중인 개발자들의 릴리즈 기한을 맞춰야 한다는 압박감을 줄여주기도 합니다.

덕분에 여러분들은 언제나 다음 러스트 빌드를 확인할 수 있고 버전을 업그레이드 하는 데에도 부담이 없습니다: 다만 가끔씩 beta 릴리즈에서 문제가 발생하기도 합니다. 모든 소프트웨어에는 버그가 존재할 수 있는 법이고, rustc 도 소프트웨어니까요. 하지만 beta 릴리즈에 문제가 있더라도 개발팀에 제보하면 stable 릴리즈 이전에 해당 오류를 수정받을 수 있습니다.

불안정한 기능

릴리즈 모델에서 하나 더 짚고 넘어갈 게 있습니다: 바로 '불안정한 기능' 입니다. 러스트에는 "Feature flags" 라는 기술이 적용됐기 때문에 릴리즈에서 어떤 기능을 활성화 하거나, 비활성화 할 수 있습니다. 예를 들어, 아직 개발중인 기능이 master 에 추가되면 자연스레 nightly 에도 추가되지만 feature flag 에 가려진 상태로 추가됩니다. 따라서, 아직 개발중인 기능을 사용하고 싶은 분은 nightly 릴리즈에서 적절한 flag 를 소스코드에 명시하셔야 합니다.

알아두실 것은 feature flag 는 어디까지나 새로운 기능이 stable 에 정착되기 전에 연습해볼 수 있도록 하는 용도이기 때문에 beta 나 stable 릴리즈에선 feature flag 를 사용할 수 없습니다. 따라서 안정적인 환경을 원하는 사용자는 이 기능을 이용하지 않는 것을 추천드립니다.

본 책의 내용은 stable 릴리즈의 기능만 담고 있습니다. 개발 중인 기능에 관한 내용은 언제든 변경될 수 있으므로 책에 작성된 내용과 실제 stable 빌드에 추가된 내용이 전혀 다를 가능성이 있기 때문입니다. 따라서 nightly 에만 존재하는 기능은 온라인에서 관련 문서를 찾아보시기 바랍니다.

Rustup 과 Rust Nightly 의 역할

여러분은 stable 러스트를 설치하셨을 겁니다. 하지만 특정 프로젝트에선 특정 릴리즈 채널을 사용하도록 설정하거나, 혹은 글로벌 설정을 변경하고 싶다면 어떻게 해야 할까요? 답은 Rustup 입니다. rustup 으로 nightly 를 설치하는 방법은 다음과 같습니다:

$ rustup install nightly

rustup 으로 여러분이 설치한 모든 툴체인(toolchains) (여러 러스트 릴리즈와 관련 컴포넌트를 포함한 것을 말합니다)를 확인할 수도 있습니다. 필자의 윈도우 컴퓨터에서 실행한 결과를 예로 가져왔습니다:

> rustup toolchain list
stable-x86_64-pc-windows-msvc (default)
beta-x86_64-pc-windows-msvc
nightly-x86_64-pc-windows-msvc

보시다시피 기본 설정된 툴체인은 stable 입니다. 러스트 사용자들은 대부분 stable 을 사용하긴 하지만 최첨단 기능을 고려해야 하는 특정 프로젝트에선 nigthly 가 필요할 수도 있습니다. 이처럼 어떤 프로젝트만 다른 툴체인을 사용하고 싶을 땐 해당 프로젝트 디렉토리에서 rustup override 를 이용해 원하는 툴체인을 사용할 수 있습니다:

$ cd ~/projects/needs-nightly
$ rustup override add nightly

이제 rustup~/projects/needs-nightly 에서 rustccargo 가 호출될 때마다 기본값인 stable 대신 nigthly 를 사용하고 있는지 확인합니다. 덕분에 앞으로 여러분이 관리할 러스트 프로젝트가 많아지더라도 관리가 편해질 겁니다.

RFC 과정과 러스트 RFC 팀

이런 새로운 기능에 관한 정보는 어디서 볼 수 있을까요? 러스트 개발 모델은 RFC (Request For Comments) 과정 을 따릅니다. 따라서 러스트를 더 발전시키고 싶다면, 제안서, 즉 RFC 를 작성하면 됩니다.

RFC는 러스트를 발전시키고 싶은 사람이라면 누구든 작성할 수 있습니다. 여러분이 작성한 RFC는 해당 주제에 연관된 러스트 팀에서 제안 내용을 읽고, 토론과 리뷰를 진행한 뒤 직접 의견을 남기며, 최종적으로는 해당 기능을 받아들일지 말지 합의합니다. (러스트에는 언어 디자인, 컴파일러 구현, 인프라, 문서화 등 다양한 세부 분야에 대응하는 팀이 존재하며, 전체 팀 목록은 러스트 웹사이트 에서 확인하실 수 있습니다.)

제안이 받아들여지면 누군가 구현할 수 있도록 러스트 저장소에 이슈가 등록됩니다. 이때, 기능을 구현한 사람과 기능을 제안한 사람이 다를 수도 있습니다. 어찌 됐건 구현되고 나면 "불안정한 기능" 절에서 다룬 대로 feature flag 에 가려진 채 master 브랜치에 올라갑니다.

시간이 지나 nightly 릴리즈 사용자가 해당 기능을 사용할 수 있게 되면 러스트 팀은 해당 기능이 nightly 에서 유용하게 쓰였는지 의논하고, stable 에 포함할 것인지 결정합니다. 의논 결과가 긍정적이라면 feature flag 의 그림자로부터 나와 예비 stable 로 취급됩니다. 다음 stable 릴리즈 역에서 러스트 릴리즈 열차에 탑승하는 거죠.