러스타시안(러스트를 사용하는 사람들을 지칭하는 말)이라면 대부분 사용하는 러스트 빌드 시스템 및 패키지 매니저
외부 라이브러리를 다운로드할때나, 라이브러리를 제작할 때 겪는 외존성을 크게 줄여주는 편리한 도구
러스트 프로젝트 대부분이 카고를 사용하고 있다.
러스트를 이미 설치했다면 카고가 설치되어 있다.
cargo --version
버전명이 나오면 설치가 된 것이고 그렇지 않다면 command not found가 발생한다.
프로젝트 폴더로 와서 다음 명령어로 프로젝트를 생성할 수 있다.
cargo new hello_cargo
cd hello_cargo
new 뒤에 붙는 건 프로젝트 명이다. 프로젝트 폴더로 이동하면 src 디렉터리 내에 main.rs라는 파일을 확인할 수 있고, 만약 Github 저장소에 카고를 생성하지 않았다면 .gitignore 파일과 함께 Git 저장소가 초기화 된다.
이 파일을 열면 다음처럼 나온다.
[package]
name = "hello_cargo"
version = "0.1.0"
edition = "2021"
[dependencies]
이 파일은 TOML(Tom's Obvious, Minimal Language) 포맷으로 되어있고, 카고 설정에서 사용하는 포맷이다.
첫 번째 줄은 섹션 헤더로 뒤에 패키지 설정 구문들이 따라온다.
다음 세 줄은 카고가 코드를 컴파일하는 데 필요한 정보로, 패키지명, 버전, 작성자, 사용하는 러스트 에디션이 있다.
의존성 목록으로 러스트에서는 코드 패키지를 크레이드(crate)라고 부른다.
main.rs를 열어서 보면 기본적인 Hello, world!를 출력하는 코드가 작성되어 있다.
fn main()
{
println!("Hello, world!");
src 폴더 내에 있는 이유는 프로젝트와 관련 없는 파일과 프로젝트와 관련 있는 파일을 구분하여 저장함으로써 프로젝트 관리를 원활히 하기 위함이다.
최상위 디렉터리 : README, 라이선스, 설정 파일 등
src 내 : main.rs
프로젝트 생성 시 카고를 사용하지 않더라도 Cargo.toml 파일을 알맞게 작성하고 프로젝트 코드를 src 디렉토리로 옮기면, 카고를 사용하는 프로젝트로 변경할 수 있다.
위의 예시에서 프로젝트를 빌드하는 법은 다음 명령어를 터미널에 입력한다.
$ cargo build
이 명령어를 통해 target/debug/hello_cargo에 실행 파일을 생성한다.
기본 빌드가 디버그 빌드이기 때문에 카고는 debug라는 디렉터리에 바이너리를 생성한다.
다음 명령어로 실행할 수 있다.
$ ./target/degbug/hello_cargo
기본 코드의 결과는 Hello, world!가 나올 것이다.
빌드 명령어를 실행하면 최상위 디렉토리에 Cargo.lock이라는 파일이 생성되는데, 이 파일은 프로젝트에서 사용하는 의존성을 자동으로 기록하는 파일이다.
코드를 작성하는 사람이 이 파일을 수정할 필요가 없다.
위에서 빌드(컴파일) 후 실행을 직접 다 하는 방식으로 작성해보았는데, 사실 이 과정을 한 번에 하는 방법이 있다.
$ cargo run
물론, 직접 실행해도 문제가 되지 않지만, 상당히 복잡하기 때문에 대부분은 cargo run을 사용한다.
지금까지 방식을 따라오면 한 가지 다른 점을 확인할 수 있다.
cargo run을 했을 때 컴파일 관련 내용이 로그로 안나온다는 점이다.
이 이유는 카고가 파일 변경 사항이 없기 때문에 자동으로 기존 바이너리를 그대로 실행했기 때문이다.
코드를 수정 후 cargo run을 수행하면 컴파일 과정이 로그로 보인다는 점을 확인할 수 있다.
$ cargo check
이 방식은 직접 바이너리를 생성하지 않고 작성한 코드가 문제없이 컴파일되는지만 확인하는 명령어이다.
이 방식은 build와 차이가 있는데, 바로 build는 바이너리를 생성하고 check은 바이너리를 생성하지 않는다는 점이다.
대부분 러스타시안은 build보다는 check를 사용해 컴파일 되는지를 확인하고, 실행 파일이 필요할 때만 build를 수행한다.
카고를 이용하면 운영체제 별로 명령어가 다르지 않다는 장점이 있다. 원래는 macOS와 Windows에 따라 명령어가 달랐지만 cargo로 실행하는 것은 명령어가 같다는 점을 확인할 수 있다.
그렇기 때문에 러스트를 사용할 때는 cargo로 명령어를 수행하는 것이 좋다.
배포(release) 준비가 끝나면 cargo build --release를 통해 배포용 실행파일을 만들 수 있다. 일반 빌드와 차이점은 target/debug가 아니라 target/release에 실행 파일이 생성된다는 점이다.
그리고 컴파일 시 최적화를 진행하여 컴파일이 오래걸리는 대신 러스트 코드가 더 빠르게 동작한다.
개발 중에는 빌드를 자주 진행한다. 만약, release를 계속해서 만들면 최적화를 해야 해서 작업의 흐름이 끊기게 된다. 그래서 debug 빌드에서는 최적화를 진행하지 않는다.
반면, 배포용 프로그램은 빌드 속도보다 실행속도가 더 중요하다.
이런 점 때문에 만약 코드 작동 속도를 벤치마크 해볼 때에는 release를 기준으로 해야한다.
단순한 프로젝트에서는 rustc를 사용할때와 큰 차이가 없어 보이지만, 의존성이 커지고 프로그램이 복잡해지면 cargo를 사용하는 편이 매우 편리하다. 특히, 카고에서 빌드 조정하는 것이 훨씬 쉽다.