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