패키지, 크레이트
우리가 다뤄볼 모듈 시스템의 첫 구성 요소는 패키지와 크레이트입니다.
크레이트 (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.rs와
src/lib.rs를 가지고 있다면 해당 패키지는 패키지와 같은 이름의 바이너리,
라이브러리 크레이트를 포함하게 됩니다. src/bin 디렉토리 내에 파일을 배치하면
각각의 파일이 바이너리 크레이트가 되어, 여러 바이너리 크레이트를 패키지에 포함할 수 있습니다.