패키지와 크레이트

여기서 다룰 모듈 시스템의 첫 부분은 패키지와 크레이트입니다.

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

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

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

크레이트 루트 (crate root) 는 러스트 컴파일러가 컴파일을 시작하는 소스 파일이고, 크레이트의 루트 모듈을 구성합니다. (모듈은 ‘모듈을 정의하여 스코프 및 공개 여부 제어하기’에서 알아볼 예정입니다.)

패키지 (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 디렉터리 내에 파일을 배치하면 각각의 파일이 바이너리 크레이트가 되어, 여러 바이너리 크레이트를 패키지에 포함할 수 있습니다.