패키지, 크레이트

우리가 다뤄볼 모듈 시스템의 첫 구성 요소는 패키지와 크레이트입니다.

크레이트 (crate) 는 러스트가 컴파일 한 차례에 고려하는 가장 작은 코드 단위입니다. (1장의 “러스트 프로그램 작성하고 실행하기”절에서 했던 것처럼) cargo 대신 rustc를 실행하여 단일 소스 코드 파일을 넘겨주더라도, 컴파일러는 그 파일이 크레이트라고 생각합니다. 크레이트는 여러 모듈을 담을 수 있고, 모듈은 다음 절에서 곧 알게 되겠지만 이 크레이트와 함께 컴파일되는 다른 파일들로 정의되어 있을 수 있습니다.

크레이트는 바이너리일 수도 있고, 라이브러리일 수도 있습니다. *바이너리 크레이트 (binary crate)*는 커맨드 라인 프로그램이나 서버처럼 실행 가능한 실행파일로 컴파일할 수 있는 프로그램입니다. 바이너리 크레이트는 실행파일이 실행되면 어떻게 되는지 정의되어 있는 main 함수를 포함하고 있어야 합니다. 여태까지 우리가 만들어 본 모든 크레이트는 바이너리 크레이트였습니다.

*라이브러리 크레이트 (library crate)*는 main 함수를 가지고 있지 않고 실행파일 형태로 컴파일되지 않습니다. 그 대신, 여러 프로젝트에서 공용될 의도로 만들어진 기능들이 정의되어 있습니다. 예를 들어, 2장에서 사용한 rand 크레이트는 랜덤한 숫자를 생성하는 기능을 제공합니다. 러스타시안들이 “크레이트”라고 말하면 대부분은 이 라이브러리 크레이트를 의미하는 것이고, “크레이트”라는 단어는 일반적인 프로그래밍 개념에서의 “라이브러리”와 혼용됩니다.

러스트 컴파일러는 크레이트 루트라는 소스 파일부터 컴파일을 시작해서 여러분이 작성한 크레이트의 루트 모듈을 구성합니다. (모듈은 “모듈을 정의하여 스코프 및 공개 여부 제어하기”에서 알아볼 예정입니다.)

*패키지 (package)*는 어떤 기능 세트를 제공하는 하나 이상의 크레이트로 된 묶음입니다. 패키지에는 이 크레이트들을 빌드하는 법이 설명된 Cargo.toml 파일을 가지고 있습니다. 카고는 실은 여러분의 코드를 빌드하는 데 사용해 온 커맨드 라인 도구를 위한 바이너리 크레이트를 포함한 패키지입니다. 카고 패키지는 또한 이 바이너리 크레이트가 의존하고 있는 라이브러리 패키지도 포함하고 있습니다. 다른 프로젝트들도 카고의 커맨드 라인 도구가 사용하는 로직과 똑같은 것을 사용하기 위해 카고의 라이브러리 크레이트에 의존할 수 있습니다.

패키지에는 여러 개의 바이너리 크레이트를 원하는 만큼 포함시킬 수 있지만, 라이브러리 크레이트는 하나만 넣을 수 있습니다. 패키지에는 적어도 하나 이상의 크레이트를 포함해야 하며, 이는 라이브러리이건 바이너리이건 상관없습니다.

패키지를 생성할 때 어떤 일이 일어나는지 살펴보죠. 먼저 cargo new 명령어를 입력합니다.

$ cargo new my-project
     Created binary (application) `my-project` package
$ ls my-project
Cargo.toml
src
$ ls my-project/src
main.rs

cargo new를 실행한 후 ls 명령을 사용하여 카고가 만든 것들을 살펴봅니다. 프로젝트 디렉토리에는 Cargo.toml 파일이 있는데, 이것이 패키지를 만들어 줍니다. main.rs 파일을 가지고 있는 src라는 디렉토리도 있습니다. Cargo.toml을 텍스트 편집기로 열어보면 src/main.rs 가 따로 적시되진 않음을 알 수 있습니다. 카고는 패키지명과 같은 이름의 바이너리 크레이트는 src/main.rs가 크레이트 루트라는 관례를 준수합니다. 마찬가지로, 패키지 디렉토리에 src/lib.rs 파일이 존재할 경우, 카고는 해당 패키지가 패키지명과 같은 이름의 라이브러리 크레이트를 포함하고 있다고 판단합니다. 물론 그 라이브러리 크레이트의 크레이트 루트는 src/lib.rs고요. 카고는 라이브러리 혹은 바이너리를 빌드할 때 이 크레이트 루트 파일을 rustc로 전달합니다.

현재 패키지는 src/main.rs 만 포함하고 있으므로 이 패키지는 my-project라는 이름의 바이너리 크레이트만으로 구성되어 있습니다. 만약 어떤 패키지가 src/main.rssrc/lib.rs를 가지고 있다면 해당 패키지는 패키지와 같은 이름의 바이너리, 라이브러리 크레이트를 포함하게 됩니다. src/bin 디렉토리 내에 파일을 배치하면 각각의 파일이 바이너리 크레이트가 되어, 여러 바이너리 크레이트를 패키지에 포함할 수 있습니다.