[Rust] Cargo: 종속성 관리

Rust는 C++과 다르게 Cargo를 통한 편리한 종속성 관리를 제공한다.
사실 안전한 신택스 체크를 떠나서 이것 때문에 Rust를 선호하는 사람이 꽤 많다.



기본 구성요소

rust는 Cargo.toml의 dependencies 섹션을 통해서 종속성을 관리한다.

저기에다가 직접 종속성을 작성하거나, cargo add 같은 명령어를 통해서 종속성을 추가할 수 있다.

만약 tokio라는 라이브러리를 추가하고 싶다면, 이런 식으로 할 수 있는 것이다.

그 시점에서 최신 버전을 넣어준다.

그리고 컴파일을 시도하면

공식 저장소인 crates.io에서 소스코드를 내려받아서 컴파일을 해준다.

내려받은 소스코드는 user 디렉토리의 .cargo 디렉토리.

그리고 registry의 index 디렉터리를 까보면 확인할 수 있다.

여기서 글로벌로 관리된다.
cargo에서는 이걸 받아놓고 링크해서 컴파일을 수행하는 것이다.




Cargo.lock

뭔가 컴파일을 한번이라도 해봤다면, Cargo.lock이란 영문모를 파일이 생길 것이다.

nodejs 환경을 사용해봤다면, package lock과 동등한 물건이라고 이해하는 것이 쉽다.
이건 종속성 사용 내역에 대한 명확한 히스토리를 기록하는 파일이다. Cargo에 의해서 자동으로 관리되기 때문에 직접 건드리는 것은 권장되지 않는다.


아무튼 안에는 이런 식으로, 어떤 레지스트리에서 어떤 버전으로 무엇을 다운받았는지를 상세하게 기록한다.

일반적으로 이걸 직접 건드리거나 까볼 일이 많지는 않다.





Cargo tree로 종속성 분석하기

cargo tree 명령을 사용하면 현재 프로젝트에서 사용중인 프로젝트의 종속성 그래프를 트리 형태로 관측할 수 있다.

-i 옵션을 쓰면 해당 패키지를 기준으로 종속성 관계를 거꾸로 볼 수도 있다.




버전 표현법

종속성에서 사용되는 버전 표현법은 좀 혼동할 수도 있고, 경우에 따라서 위험한 상황이 연출될 수도 있다.
잘 알아두고 사용해야 한다.


이렇게 버전을 1.37.0로 쓰더라도, 이건 반드시 1.37.0 버전을 가져오겠다는 의미가 되지는 않는다.

그에 대한 증거로, 돌려보면

계속해서 최신버전인 1.38을 가져오고만 있다.

사실 저 "1.37.0"는 "^1.37.0"와 완전히 같은 표현이다.
이게 뭐냐면, 1.37.0 이상이면서 2.0.0 미만인 것을 가져오라는 의미라는 것이다.
저건 최소조건만을 요구하는 기능이다.

그래서 메이저 버전을 유지했으면서도 하위호환이 파괴되는 업데이트가 은근히 섞여있다면 큰 낭패를 볼 수 있는 것이다.

정확히 그 버전만 가져오려고 한다면 ~를 앞에 붙여야만 한다.

그럼 잘 가져올 것이다.




features를 이용한 조건부 컴파일

라이브러리를 가져다 쓰다보면 features라는 플래그를 통해서 기능을 선택할 일이 잦다.
이건 컴파일 시간을 단축하기 위해서 기능 단위를 매크로를 통해서 분리하고, 사용 시점에서 선택할 수 있게 하는 것이다.

자세한 내용은 별도 포스트를 참조한다.
https://blog.naver.com/sssang97/223353947366




라이브러리를 레지스트리로 가져올 수도 있지만, 로컬 수준에서 가져오거나 git을 통해서 가져올 수도 있다.
아래 포스트는 해당 내용은 정리한 내용이다.
https://blog.naver.com/sssang97/222373492319




폐쇄망에서의 사용

흔한 사용사례는 아니지만, 인터넷 사용이 불가능한 환경에서 사용할 일이 있을 수도 있다.
그럴 때 사용할 수 있는 방법은 vendor를 통해 파일을 모아놓고 사용하는 것, 아니면 사설 레지스트리를 구성하는 방법 2가지 정도가 있다.

https://blog.naver.com/sssang97/222937559361
https://blog.naver.com/sssang97/222904399354




[dev-dependencies]

dev dependenties는 test 컨텍스트에서만 사용할 종속성을 정의하는 기능이다.

이걸 통해 넣은 종속성은 테스트를 돌릴 때만 들어가고, 일반 빌드를 할 때는 포함되지 않는다.




플랫폼별 종속성

cfg 컨텍스트를 이용하면 특정 플랫폼 타겟에서만 종속성을 받을 수 있게 구성하는 것이 가능하다.

이런 식으로 구성하면, axums은 windows에서만 설치되고, anyrust는 macos에서만 설치되는 것이다.


그러면 mac 환경에서는 실제로 mac 종속성만 설치된다.

cfg를 적극적으로 활용하면 더 많은 분기와 활용이 가능하다.
더 자세한 것은 별도 자료를 참조한다.
https://blog.naver.com/sssang97/222706768955
https://doc.rust-lang.org/reference/conditional-compilation.html#target_os



아래는 더 알면 좋은 것들이다.


cargo workspace

https://blog.naver.com/sssang97/223114443419




cargo audit

https://blog.naver.com/sssang97/223363451930



참조
https://doc.rust-lang.org/cargo/commands/cargo-tree.html
https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html
https://doc.rust-lang.org/rust-by-example/testing/dev_dependencies.html
https://doc.rust-lang.org/cargo/reference/overriding-dependencies.html