Cargo는 러스트의 빌드 시스템 및 패키지 매니저입니다.
C로 치면 cmake, Python으로 치면 pip와 유사한 장치라고 생각하시면 됩니다.
명령 한 줄이면 쉽게 외부 패키지를 다운받거나 버전관리, 의존성 관리를 할 수 있는 도구입니다.
일반적인 rust 설치 과정을 따라오셨다면 자동으로 설치되어 있습니다.
이 포스트에서는 일반적으로 많이 사용하는 파이썬을 자주 예시로 듭니다.
파이썬을 잘 모르신다면 신경쓰지 않으셔도 되는 부분입니다.
현재 설치되어 있는 cargo의 버전을 확인할 수 있는 명령어입니다. 다음 세 명령어는 동일한 결과를 보여줍니다.
$ cargo version
cargo 1.59.0 (49d8809dc 2022-02-10)
$ cargo --version
cargo 1.59.0 (49d8809dc 2022-02-10)
$ cargo -V
cargo 1.59.0 (49d8809dc 2022-02-10)
cargo new 명령을 통해 새로운 프로젝트를 만들 수 있습니다.
실행 가능한 바이너리 프로젝트(실행 가능한 애플리케이션)를 만드는 명령어입니다.
인수를 주지 않으면 default로 바이너리 프로젝트가 생성됩니다.
$ cargo new "package-name" (--bin)
$ cargo new hello-cargo
Created binary (application) `hello-cargo` package
$ cargo new hello-cargo2 --bin
Created binary (application) `hello-cargo2` package
라이브러리 프로젝트를 만드는 명령어입니다.
$ cargo new "binary-name" --lib
$ cargo new hello-cargo3 --lib
Created library `hello-cargo3` package
cargo를 통해 만든 프로젝트는 기본적으로 .git
폴더와 .gitignore
파일을 포함하는 Git
디렉토리입니다. 만약 vcs(Version Control System)을 사용하고 싶지 않거나 다른 것으로 바꾸고 싶다면 vcs 인수를 사용하여 바꿀 수 있습니다.
$ cargo new "package-name" --vsc "vcs-name"
$ cargo new hello-cargo4 --vcs git
Created binary (application) `hello-cargo4` package
$ cargo new hello-cargo5 --vcs none
Created binary (application) `hello-cargo5` package
만약 폴더명과 패키지 이름을 다르게 하고 싶다면 --name
인수를 사용해서 바꿀 수 있습니다.
물론 Cargo.toml
파일을 수정해서 쉽게 바꿀수도 있습니다.
$ cargo new "folder-name" --name "package-name"
new와 같은 작업을 수행합니다. 차이점은 new가 패키지 이름을 정해서 새로운 디렉토리를 만들어 프로젝트를 생성한다면 init은 현재 있는 빈 폴더에 러스트 프로젝트를 생성합니다.
$ mkdir hello-cargo6
$ cd hello-cargo6
$ cargo init
Created binary (application) package
cargo init
과 cargo new
는 같은 인수를 사용할 수 있습니다.
cargo init
명령을 이용해서 프로젝트를 생성하면 현재 폴더 이름을 그대로 프로젝트명으로 사용합니다. 만약 바꾸고 싶다면 --name
인수를 사용해서 바꿔줄 수 있습니다. 물론 폴더 이름은 바뀌지 않고 프로젝트 이름만 바뀝니다. new
명령을 사용했을 때처럼 단순히 Cargo.toml
파일의 내용을 바꿔도 가능합니다.
러스트 개발자들은 crates.io에서 자신이 만든 바이너리나 라이브러리를 공유하고 있습니다. 파이썬으로 치면 PyPi인 셈이죠.
cargo search
명령은 특정 키워드를 포함하는 크레이트를 검색할 수 있습니다.
cargo search "crate-name"
만약 exif parser와 관련된 크레이트를 찾고 싶어 cargo search exif
를 입력하면 다음과 같은 결과를 얻을 수 있습니다.
$ cargo search exif
exif = "0.0.1" # Rust wrapper for libexif
kamadak-exif = "0.5.4" # Exif parsing library written in pure Rust
s.
imagemeta = "0.1.0" # Support for manipulating image metadata (exif, etc) in Rust.
img-parts = "0.2.3" # Low level crate for reading and writing Jpeg, Png and RIFF image containers
exifmv = "0.1.3" # Moves images into a folder hierarchy based on EXIF tags
gexiv2-sys = "1.1.2" # This library provides Rust FFI declarations for the gexiv2 library, which is a GObject-based wrapper …
rexiv2 = "0.9.1" # This library provides a Rust wrapper around the gexiv2 library, which is a GObject-based wrapper arou…
... and 24 crates more (use --limit N to see more)
search 명령어를 통하여 crates.io에서 찾은 크레이트를 pip
명령어로 설치하듯 cargo install
을 통하여 쉽게 설치할 수 있습니다.
cargo install "binary-name"
rust로 구현된 grep 라이브러리 중 하나인 ripgrep
크레이트를 설치하는 예제입니다.
$ cargo install ripgrep
Updating crates.io index
Downloaded ripgrep v13.0.0
Downloaded 1 crate (272.1 KB) in 0.85s
Installing ripgrep v13.0.0
.
.
.
Finished release [optimized + debuginfo] target(s) in 32.99s
Installing C:\Users\d2h10s\.cargo\bin\rg.exe
Installed package `ripgrep v13.0.0` (executable `rg.exe`)
방금 만든 따끈따끈한 패키지의 tree를 살펴보면 다음과 같습니다.
C:.
│ .gitignore
│ Cargo.toml
│
└─src
main.rs
항상 Cargo.toml
이라는 파일이 만들어져 있는 것을 확인할 수 있습니다.
이 파일은 Cargo의 설정 파일로 package부분에는 프로젝트 이름
, 버전
, 러스트 버전
등이 자동으로 입력됩니다.
dependancies 부분에는 이 패키지에 의존성을 가지는 라이브러리를 기술하고 버전을 관리합니다.
[package]
name = "exif-fixer"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
예를 들어 exif를 parsing하는 라이브러리가 필요해서 다음과 같이 크레이트의 이름과 버전을 명시하고
[package]
name = "exif-fixer"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
kamadak-exif = "0.5.4"
cargo build
를 해주게 되면 다음과 같이 자동으로 다운로드 하는 것을 볼 수 있습니다.
$ cargo build
Updating crates.io index
Downloaded mutate_once v0.1.1
Downloaded kamadak-exif v0.5.4
Downloaded 2 crates (56.0 KB) in 0.48s
Compiling mutate_once v0.1.1
Compiling kamadak-exif v0.5.4
Compiling exif-fixer v0.1.0 (C:\Users\d2h10s\repository\exif-fixer)
Finished dev [unoptimized + debuginfo] target(s) in 3.06s
cargo build
명령을 통해서 러스트 프로젝트를 빌드할 수 있습니다. 빌드란 바이너리 파일을 생성하는 것을 의미합니다.
$ cargo build
Finished dev [unoptimized + debuginfo] target(s) in 0.01s
cargo run
명령을 통해서 빌드와 실행을 한번에 할 수 있습니다. 물론 이전에 바이너리 파일을 만든 후 코드의 변화가 없다면 Cargo는 똑똑하게 다시 빌드를 하지 않고 실행만 합니다.
$ cargo run
Finished dev [unoptimized + debuginfo] target(s) in 0.01s
Running `target\debug\hello-world.exe`
Hello, world!
cargo check
명령을 통해 실행파일을 생성하는 과정만 생략한 채 컴파일만 수행할 수도 있습니다.
오류가 있는지 테스트할 때 쉽게 사용할 수 있는 기능입니다.
물론 간단한 프로그램을 만든다면 굳이 쓸 일이 없을지도 모르지만 한 번 빌드에 10분 이상이 소요된다면 매우 유용한 기능입니다.
$ cargo check
Checking mutate_once v0.1.1
Checking kamadak-exif v0.5.4
Checking exif-fixer v0.1.0 (C:\Users\d2h10s\repository\exif-fixer)
Finished dev [unoptimized + debuginfo] target(s) in 0.72s
테스트 기능은 자세하게 다룰 필요가 있기 때문에 다른 포스트에서 추후에 다루겠습니다.