Cargo의 의존성 관리, 빌드 성능, 적응성 및 유지 관리를 개선하기 위한 워크플로와 संभाव한 단계에 관한 비전입니다.
Stack Overflow에 따르면 cargo는 가장 원하는 개발 도구입니다. 많은 사람이 Rust를 선택한 이유로 Cargo를 꼽습니다. Cargo가 이미 훌륭하며 개선할 방법을 떠올릴 수 없다는 사람들의 이야기도 많이 들었습니다. 저는 우리의 목표를 더 높게 잡고 싶습니다.
그리고 이상적인 워크플로가 어떤 모습일지, 또 그곳에 어떻게 도달할 수 있을지에 관한 여러분의 생각을 듣고 싶습니다. 이것은 제가 생각해 온 몇 가지일 뿐입니다. 저는 모든 워크플로를 알지 못하거나 쉽게 말할 수 없다는 것을 알고 있으며, 다른 사람들은 이를 해결할 더 나은 아이디어를 가지고 있을 수도 있습니다.
그곳에 도달하는 데 여러분의 도움도 필요합니다. 이 워크플로들은 Cargo에만 국한되지 않으며 Rust, crates.io 등에도 영향을 줍니다. 깊이 참여하고 도울 기회가 많습니다.
이 논의를 워크플로의 높은 수준의 관점을 중심으로 구성하고 싶습니다. 구체적인 문제 영역(예: 빌드 스크립트)은 이를 개선하는 방법에 관한 아이디어에서 다루겠습니다.
#[non_exhaustive]
“언제나 생태계에 투자하라”
저는 crates.io 생태계가 Rust의 초능력 중 하나였다고 강하게 생각합니다. 이 생태계가 없었다면 실용적이지 않았을 수준의 기능과 완성도를 갖춘 애플리케이션을 빠르게 만들 수 있게 해 주었기 때문입니다.
애플리케이션은 기존 기능뿐 아니라 미래의 모든 기능과 수정 사항도 활용할 수 있습니다. 예를 들어, ripgrep은 대규모 모노레포에 맞게 최적화되고 있으며, typos는 ignore를 재사용하기 때문에 자동으로 혜택을 받습니다. 새로 구현하거나 포크한 경우에는 이런 이점을 얻지 못합니다. 이는 공동 감사도 가능하게 합니다. 애플리케이션에서는 다른 이들도 사용하는 직렬화 프레임워크를 한두 개 사용할 수 있는 반면, 설정 시스템, 네트워크 통신 등에 흩어진 맞춤형 프레임워크 열 개를 감사해야 할 수도 있습니다.
의존성에는 비용과 위험이 따르며, 우리는 이를 줄이기 위해 노력해야 합니다.
어떻게 품질 좋은 의존성을 발견할 수 있을까요?
무엇을 써야 하는지 알고 있다면 사용할 수 있는 “잘 알려진” 의존성이 있습니다. 생산성은 내부자 지식에 의해 좌우되어서는 안 됩니다.
“잘 알려진” 의존성이 없을 때는 후보를 찾아야 하는데, 이것이 항상 쉽지는 않습니다. 비교하려면 안전한지, 목적에 맞는지, 장기적으로 의지할 수 있는지를 판단하기 위해 여러 신호를 살펴봅니다. 여기에는 다운로드 수, 누가 의존하는지, 수행된 검토 등이 포함될 수 있으며, 작성자의 다른 패키지에서 이어지는 신뢰도 포함됩니다. 이런 정보를 알고 종합하는 데는 많은 작업이 들 수 있습니다.
이상적인 세계에서는 모든 의존성이 검토될 것입니다. 우리는 이상적인 세계에 살지 않지만, 어떻게 더 가까워질 수 있을까요? Rust에는 추가 검토가 필요한 코드를 격리하는 방법으로 unsafe가 있습니다. 더 많은 종류의 감사 지점이 필요하며, 그 발견 가능성을 확장해야 합니다. 가능하다면 감사 지점은 옵트인이고, 성능이나 기능의 대가를 치르되 감사를 필요로 하지 않는 대체 경로가 있다면 더 좋습니다. 하지만 때로는 지름길을 택하고 다른 이의 검토를 신뢰하고 싶을 것입니다. 우리 자신의 검토나 다른 이의 검토를 추적하는 일은 의존성 사용에 통합되어야 합니다.
업그레이드 부담을 어떻게 최소화할까요?
먼저 유지 관리자를 위한 린팅과 테스트의 상태를 개선하여 버그와 의도치 않은 변경을 줄여야 합니다.
이제 의도된 변경에 관해 말한다고 가정하면, 쉬운 답은 호환성이 깨지는 변경을 지양하는 것입니다. 그러나 이는 일부 종류의 기술 부채를 제거할 수 없는 유지 관리자의 비용과, 기능·수정·빌드 성능에 가해지는 제약이라는 사용자의 비용을 수반합니다.
변경 사항을 문서화하고 이를 더 잘 드러내도록 장려해야 합니다. 그러나 이는 문제를 덮어 주는 임시방편입니다. 어떻게 더 나아질 수 있을까요?
영감의 한 원천은 에디션을 통해 옵트인 방식의 호환성 파괴 변경을 제공하는 Rust 언어입니다. Rust 프로젝트는 불안정 기능과 사용자용 마이그레이션을 제공하여 에디션을 준비합니다. 이는 패키지의 유지 관리자와 사용자에게 제공해야 할 최소한의 경험으로 보아야 합니다. 더 나아가, 이러한 변경을 사용자의 워크플로 안에서, 각자의 구체적 상황에 맞춰 더 잘 보여 줄 수 있습니다. 이는 특히 마이그레이션이 불가능할 때 중요합니다.
오늘 할 수 있는 일의 실험으로, clap에서는 가능한 경우 새 기능을 병렬 기능으로 도입하고 이전 동작을 마이그레이션 방법을 적은 메모와 함께 사용 중단하는 관행을 채택했습니다. 많은 사람이 사용 중단을 포함한 경고를 오류로 바꾸므로, deprecated 기능 플래그 뒤에 사용 중단을 두었습니다. 기본 활성화로 두면 업그레이드가 사용 중단 해결과 결합되어 비용과 위험이 증가합니다. 이는 마이그레이션 가이드를 “기능을 활성화하고 거기에 적힌 대로 하라”로 극적으로 단순화합니다. 병렬 기능이 불가능한 경우에는 궁극적인 호환성 파괴 변경 때문에 개발이 막히지 않도록 하고 피드백을 쉽게 받도록 unstable-vX 기능을 사용합니다.
여기서 제가 보는 문제는 다음과 같습니다.
deprecated 기능에 대한 인지도unstable-vX 기능은 놀라운 효과를 낼 수 있으므로 사용을 확장하려면 더 많은 안전장치가 필요함빌드 성능 개선은 2% 더 빠르게 만드는 일이 아니라, 사용자의 작업 방식을 바꾸고 Rust가 더 많은 사용자에게 매력적이게 하는 일입니다. 사용자의 비교 대상은 미리 빌드된 프레임워크를 고려하기 전까지는 더 유사한 C++부터, 빌드가 없는 스크립트 언어까지 다양합니다.
또한 rustc의 성능을 넘어 사용자의 워크플로를 살펴봐야 합니다.
사용자는 스택의 하단에서 작은 변경을 할 때 즉각적인 피드백을 원하지만, 안타깝게도 이는 전체 스택을 다시 빌드하게 하며 cargo check조차 시간이 걸립니다.
이들은 동작이 정확해질 때까지 테스트 실패를 반복합니다. 반복문에서 cargo test --workspace 전체를 실행하거나(“쉬우니까”), 더 빠른 반복 시간을 위해 각 실패마다 cargo test -p application-library --test area -- some::test::name 같은 명령을 손수 구성하여 실행 흐름을 끊습니다.
위 둘 중 하나를 작업하다 main을 리베이스했고, 의존성 업데이트 때문에 전체 스택이 다시 빌드될 수도 있습니다. 디스크 공간이 부족해 rm -rf target을 실행했을 수도 있습니다. 혹은 알 수 있는 이유 없이 다시 빌드되었을 수도 있습니다.
또는 위 둘 중 하나를 작업하는 동안 rust-analyzer, 캐시를 공유하려는 다른 워크트리, 혹은 캐시를 공유하는 시스템의 다른 프로젝트 때문에 병렬 호출에서 Cargo가 막힐 수도 있습니다.
일부 사용자는 병합되지 않은 코드 위에 너무 많은 변경을 쌓아 값비싼 병합 충돌 위험을 높이지 않도록 CI 완료를 기다리는 동안 작업을 전환합니다. CI 시스템에는 캐시가 있지만, 너무 많이 캐시하면 네트워크 전송과 압축 해제 시간 때문에 이점이 사라질 수 있습니다. 로컬 디버깅에는 잘 맞는 기본값도 캐시 크기를 키우고 빌드를 느리게 만듭니다. 빌드 결과는 캐시되지만 테스트 결과는 캐시되지 않아 전체 테스트 모음이 다시 실행됩니다.
제 RustNL 2025 발표도 참고하세요: 영상 / 슬라이드
Cargo는 의견을 강하게 반영하도록 의도되었습니다. 하지만 그것과 하위 호환성 사이에서, 향상된 docker 캐싱, 복잡한 애플리케이션 요구, 혹은 더 큰 기업 환경과의 통합처럼 서로 다른 요구에 적응하기는 어려울 수 있습니다.
Git에서는 작업을 플러밍과 포슬린으로 나눕니다. Cargo는 거의 모두 포슬린 명령이고 프로그래밍 방식의 사용은 매우 제한적입니다. 플러밍 명령을 추가하고 포슬린 명령의 프로그래밍 방식 출력을 확장하면 사람들이 자신의 요구에 맞춰 Cargo를 적응시키는 데 큰 도움이 될 것입니다.
Cargo 개선에 관한 모든 논의의 바탕에는, Cargo 팀이 운영을 유지하는 일에 더해 이런 노력을 지원할 충분한 역량이 필요하다는 점이 있습니다. 이전에 Cargo는 팀의 역량 부족으로 인해 수년간 기능 동결을 겪었습니다. 그 일을 되풀이할 정도로 얼마나 가까운지 걱정됩니다.
기능 동결 중과 그 후 한동안, Cargo 유지 관리의 효율을 높이기 위해 프로세스와 도구 개선에 집중했습니다. 예를 들어, 요구에 맞는 스냅샷 테스트 라이브러리를 개발하고 이전하여 광범위한 UX 변경을 쉽게 만들었습니다(snapbox, #14039 참조).
이제 우리를 가장 느리게 만들고 변경 범위를 제한하는 것은 Cargo의 아키텍처입니다. Cargo는 오래되었고 맞춤형 프레임워크, 동시 작업의 제약, Rust 라이브러리로 대체 가능한 C 라이브러리를 사용하며, 변경을 만들거나 검토할 때 전역 지식이 필요한 명확한 경계가 없습니다.
모든 사람이 그런 작업에 자금을 댈 수 있는 것도 아니며, 새로운 설계 및 코드 검토자를 빠르게 늘릴 수도 없습니다. 외부 기여자가 Cargo 팀에 가장 크게 도움을 줄 수 있는 곳은 코드가 아니라 사고입니다. 사고를 돕는 핵심 수단은 스레드의 관련 정보를 모두 모아 한곳에 두고 쉽게 소비할 수 있도록 요약하는 것입니다. 예를 들어 다른 프로젝트에서 천천히 진행되는 PR이 있는데, 다시 볼 때 그 PR이 구현하려는 동작을 이해하려면 전체 이슈 스레드를 다시 읽어야 합니다. 이는 많은 작업이며 검토에 전용 시간®이 필요하게 만들어 영원히 “언젠가” 범주에 넣습니다. 에이전트에게 이상적인 일이 들릴 수도 있습니다. 그래도 출처를 검증하고 에이전트의 분석을 검토하는 데는 시간이 걸립니다. D-SUMMARIZE도 참고하세요.
Rust 성공의 큰 부분은 사람을 사람으로 대하는 것에 들인 노력입니다. 이는 우연히도 많은 요구가 겹치기 때문에 에이전트 기반 개발에서 Rust에 이점을 주었습니다. 에이전트가 계속 개선될 것이라는 가정 아래, 장기적으로 인간에 계속 집중하는 것이 최선의 전략이라고 생각합니다. 에이전트 기반 개발의 요구를 살펴보는 일이 성과를 낼 수 있는 지점은, 인간이 겪는 같은 문제가 너무 큰 규모로 확대되어 “충분히 좋은” 10% 개선에 안주하지 않게 만드는 데 있습니다.
제가 보기에 인간과 에이전트가 겹치는 세 기둥은 다음과 같습니다.
신호 품질: Rust가 에이전트 기반 개발에 잘 맞는 이유 중 하나는 제공하는 피드백입니다. 과도하게 장황하지 않게 Cargo의 기존 신호를 명확히 해야 합니다. 또한 린트, 감사 지점(unsafe를 생각해 보세요) 등의 도구를 통해 더 많은 신호를 제공해야 합니다.
의존성 관리: 의존성 선택과 감사에 관한 신호, 그리고 의존성 보유 비용을 줄이는 방법도 고려해야 합니다.
빌드 성능: 많은 에이전트 기반 개발이 백그라운드에서 이루어지지만, 에이전트가 실행하는 명령의 성능은 중요합니다. 특히 더 촘촘한 피드백 루프를 원한다면 그렇습니다(예: bun은 Rust 포팅의 첫 단계에서 cargo check를 건너뛰었습니다). 작업이 빠를수록 더 내부 루프에 가깝게 사용되고 결과의 품질도 좋아집니다.
이 목록은 길지만, 망라하려는 의도는 아닙니다. 쓰다가 지쳤습니다. 이 주제들 중 일부는 제가 말할 자격이 부족하거나 충분한 경험이 없어 많이 이야기할 수 없습니다.
요즘 MSRV를 올릴 만큼 Rust에 병합되는 것이 없다는 의견을 자주 봅니다. 이 목록을 보면 기대할 일이 많습니다.
#[non_exhaustive]
유지 관리성
배터리 팩
감사
API 진화
성능
async화Cargo는 async / await보다 앞서며 curl을 실행기로 사용하는 자체 맞춤형 비동기 프레임워크를 갖고 있습니다.
이는 Cargo가 비동기 실행기 주변의 기존 도구를 활용할 수 없고, 코드베이스가 기여자에게 익숙한 패턴을 따르지 않으며, 수천 개 매니페스트 파싱처럼 더 많은 작업을 병렬로 실행하도록 코드베이스를 확장하는 데 많은 작업이 든다는 뜻입니다.
또한 curl에서 Rust 네이티브 네트워킹 라이브러리로 전환하고 싶지만, 이것은 우리를 막고 있는 몇 가지 요소 중 하나입니다.
영역:
추적 이슈: #16845
libgit2에서 이전Cargo가 시작했을 때 git은 아직 보편적으로 배포되지 않았지만, Cargo 팀은 레지스트리 인덱스의 전송 수단으로 이를 사용하기로 했습니다. libgit2는 이 공백을 메우고 진행 상황에 맞춘 사용자 경험을 가능하게 했습니다. 사용자가 마주치는 기능 공백을 위해 git을 사용할 수 있는 탈출구도 제공했습니다.
10년 이상 지난 지금 git은 어디에나 있으며 대부분의 Cargo 레지스트리에는 더 이상 사용되지 않습니다. git 의존성을 가진 사람은 git을 설치했을 가능성이 높습니다. git 탈출구를 기본값으로 만들어 가져오기 성능과 네트워크 호환성을 개선할 적기입니다.
언젠가는 libgit2 네트워크 전송을 완전히 제거할 수도 있습니다. 그러면 curl에 대한 또 하나의 의존성이 제거되어 Cargo가 Rust 네이티브 네트워킹 라이브러리와 일반적인 비동기 실행기로 전환할 길이 열립니다.
언젠가는 gix나 git으로 대체하여 libgit2 자체도 제거하고, Cargo 빌드에서 또 하나의 C 구성 요소를 없앨 수도 있습니다. 이는 Cargo 시작 오버헤드도 줄입니다.
영역
추적 이슈: #17227
Cargo의 의존성 해석기에는 버그, 좋지 않은 오류, 누락된 기능이 있습니다. 하지만 사람들은 변경을 만들거나 검토할 자신이 없습니다. 차등 테스트 모음의 참조 SAT 구현을 어떻게 업데이트할지도 알기 어려울 수 있습니다.
PubGrub은 일반화된 의존성 해석기입니다. Cargo 논리와 알고리즘을 분리하여 변경을 쉽게 만들고 차등 테스트의 필요를 없앨 수 있습니다. 출력이 훨씬 풍부하여 더 나은 오류를 제공할 수 있습니다.
PubGrub은 사전 릴리스 작동 방식 변경 같은 변경의 용이성을 포함하여 Astral의 uv에서 검증되었습니다.
영역
추적 이슈: #5284
Cargo는 bash와 zsh 완성을 제공하지만, 이들은 수작업으로 작성되며 좋은 테스트 체계 없이 모든 CLI 변경이 여기에 반영될 것으로 기대합니다. 기여자와 검토자에게 bash와 zsh 완성 전문가이거나 시스템에 모든 셸을 설치해 둘 것을 기대해서는 안 됩니다.
Cargo는 생성된 완성을 제공하는 clap을 사용하지만, Cargo에는 clap이 개발 중인 기능을 통해서만 지원하는 동적으로 생성된 완성이 있습니다. 그 기능을 안정화하고 Cargo의 완성을 새 시스템으로 전환하면, 새 시스템에서 동적 완성을 제공하기가 훨씬 쉬우므로 유지 관리가 쉬워지고 기능도 더 풍부해집니다.
영역:
추적 이슈: #14520
cargo check를 가능한 한 가장 작은 작업 단위로 나누고, 이를 플러밍 명령 파이프라인을 통해 API로 노출하고자 합니다. 이를 통해 호출자는 단계 사이의 데이터를 변경하거나 단계를 맞춤 구현으로 완전히 교체하는 등 Cargo가 수행하는 작업을 제어할 수 있습니다.
입력과 출력이 명확한 이 작업 파이프라인을 가지면, Cargo 코드베이스에도 필연적으로 같은 일을 해야 합니다. 예를 들어 기능 해석은 입력에서 출력으로 가는 고립된 순수 변환이 됩니다. 그러면 기여자와 검토자는 다룰 관심 영역이 유한해져 기여가 쉬워지고, 검토자는 변경을 수용하는 데 더 자신감을 갖게 됩니다.
언젠가 이 리팩터링은 사람들이 사용할 수 있는 더 작은 라이브러리들로 Cargo를 나누게 할 수도 있습니다. 하지만 이는 cargo 내부의 설계를 제약하고, CLI 전용 가정을 추상화하기 더 복잡하게 만들 수 있으며, 호출자를 하나의 cargo 버전에 묶는다는 절충점이 있습니다. 저는 cargo를 호출하는 서드파티 도구를 유지 관리해 보았는데, 사용자가 “알 수 없는 키” 경고나 “이 기능은 불안정합니다” 오류(그 도구 체인에서는 안정적이었음)를 받는 것은 성가셨습니다. 범용 확장에는 플러밍 명령이 여전히 기본 경로여야 할 것입니다.
영역:
프로젝트 목표: 새로운 Cargo “플러밍” 명령 세트의 프로토타입
cargo check --timings는 그 빌드에 걸린 시간만 보여 줄 수 있습니다. 마찬가지로 cargo check -v는 그 빌드에서 무언가가 왜 재빌드되었는지만 알려 줄 수 있습니다. 많은 경우 빌드가 문제가 될 것이라는 사실은 문제가 발생할 때까지 알 수 없습니다. 구조화된 로깅을 사용하면 이전 빌드에 관한 보고서를 얻어 문제를 더 잘 진단할 수 있습니다.
구조화된 로깅과 포슬린 명령의 프로그래밍 방식 출력에 대한 요구는 크게 겹칩니다. 구조화된 로깅을 반복 개선하면서 프로그래밍 방식 출력 개선 방법도 탐색하고 있습니다.
영역:
추적 이슈: #15844
다른 언어에서 네임스페이스는 명시적이며 확장에 열려 있습니다. Rust에서는 모듈 시스템에 결합되어 있고 확장에 닫혀 있습니다.
이 기능은 다른 패키지가 다른 패키지의 mod인 것처럼 보일 수 있도록 Rust의 네임스페이스를 부분적으로 확장에 열려 있게 만드는 것입니다.
예를 들어 Clap을 살펴봅시다.
| 기존 이름 | 잠재적 이름 | 비고 |
|---|---|---|
clap | clap | |
clap_derive | clap::derive | |
clap_complete | clap::complete | |
clap_mangen | clap::man | |
clap_lex | clap_lex | 자사 제공이지만 clap의 비공개 의존성 |
clap-cargo | clap-cargo | 서드파티이지만 clap API의 확장 |
이는 API 설계에 영향을 주는 언어 기능에 더 가깝습니다. 기능의 단점을 피하면서 응집성 있는 API를 구성할 대안을 제공하고, 모든 조각의 주 버전을 함께 묶지 않은 채 더 작은 영향으로 호환성 파괴 변경을 허용한다는 측면에서 의존성 관리와도 연결됩니다.
crates.io와 docs.rs 같은 곳의 패키지 UX를 확장해 이들 사이를 탐색 가능하게 만들면, 이 응집성을 UX로 확장하여 의존성 관리에 더욱 도움이 될 수 있습니다.
영역
추적 이슈: #13576
사람들이 이것을 원할 이유는 많습니다. 이 문서의 범위에서 가장 관련 있는 이유는 패키지가 신뢰할 수 있는 출처에서 왔음을 알고, 회사의 서로 분리된 API처럼 그 출처의 다른 패키지를 찾는 것입니다.
영역
참고: Cargo 및 Crates.io를 위한 조직 소유권과 레지스트리 네임스페이스 설계 조사
의존성(및 그 공개 의존성)이 공개 API의 일부임을 표시할 수 있는 것은 작고 점진적인 개선처럼 보입니다.
가장 기본적으로는 공개 API에서 의존성이 실수로 노출되는 일을 잡는 데 도움이 됩니다. 가장 무해한 예는 impl From<dep::Error> for Error입니다.
cargo-semver-checks 같은 도구는 이를 바탕으로 의존성을 업그레이드할 때 의도치 않은 호환성 파괴 변경을 식별하도록 도울 수 있습니다. 실수는 이해할 수 있으며, 도구가 문제를 잡아 주는 것은 도움이 됩니다. 이것이 “당신의 실수”에서 “시스템적 실패”로 바뀌는 곳은 workspace.dependencies입니다. 이를 변경할 때 어디에서 사용되는지 놓치기 쉽습니다. 상속된 의존성을 가진 라이브러리를 릴리스 준비할 때, 마지막 릴리스 이후 무엇이 바뀌었는지 알려면 더 이상 라이브러리만 볼 수 없습니다. 이 문제가 해결되기 전에는 cargo add(#10608) 등을 통해 workspace.dependencies를 더 깊이 뿌리내리게 하는 일을 주저합니다. 사람들을 실패하도록 만들까 두렵기 때문입니다.
이는 성능에도 영향을 줍니다. 개발 중 문서를 생성하고 싶다면 가장 간단한 일은 cargo doc이지만, 이는 windows-sys처럼 빌드가 느린 의존성을 포함한 모든 의존성의 문서를 생성합니다. 찾아보면 cargo doc --no-deps를 발견할 수 있고 어쩌면 충분할 수 있지만, 행복한 경로가 지식에 의해 막혀서는 안 됩니다. 공개 의존성이 있으면 Cargo는 프로젝트에서 도달 가능한 의존성을 알고 그 의존성들에 대해서만 문서를 생성할 수 있어 문서 빌드가 빨라집니다.
영역
추적 이슈: #44663
일부 패키지는 보조를 맞춰 업그레이드해야 하지만, 오늘날 이를 돕는 도구는 없습니다. 다음처럼 의존성의 소스가 다른 의존성에서 온다고 사용자가 지정하도록 허용하여 이를 개선할 수 있습니다.
[package]
name = "some-cli"
[dependencies]
clap = { from = ["clap_complete", "clap_mangen"] }
clap_complete = "4.6.0"
clap_mangen = "4.6.0"
이 선언은 다소 거꾸로 되어 있으며, 유지 관리자가 “배포판” 패키지를 제공하면 개선할 수 있습니다.
[package]
name = "some-cli"
[dependencies]
clap_distribution = "4.6.0"
clap.from = "clap_distribution"
clap_complete.from = "clap_distribution"
clap_mangen.from = "clap_distribution"
이는 배터리 팩과 유사해 보이기 시작하며, 이 개념을 Cargo에 상류로 통합하는 방법이 될 수 있습니다.
막힌 항목:
영역
참조된 곳: RFC 3516: 미래 가능성
cargo new는 고정된 템플릿에서 전체 패키지 생성만 수행합니다.
하지만 템플릿에는 여러 종류가 있습니다.
일반적으로 이들은 모두 저장소나 패키지 템플릿으로 묶입니다(#5151도 참조). 그러면 설계 범위가 상당히 커져 Cargo에서 설계를 진전시키기 어려워집니다.
저장소 템플릿의 한 가지 문제는 다른 모든 종류의 템플릿 요구를 포괄하려 한다는 것입니다. 그 결과 사용자는 필요에 맞게 축소해야 하는 “풀 스택” 애플리케이션 템플릿을 받거나, 템플릿 논리와 사용자 프롬프트로 시스템이 복잡해집니다.
예제를 템플릿으로 활용하여 cargo new를 크레이트/모듈 템플릿으로 확장할 수 있습니다.
주제별 예제를 가진 rust_cli 패키지 배포판이 있다면, 다음으로 패키지를 시작할 수 있습니다.
$ cargo new --bin --from rust_cli:async_main
$ cargo new --mod --from rust_cli:args
$ cargo new --mod --from rust_cli:watch
$ cargo new --test --from rust_cli:cli_tests
$ fd
Cargo.toml
src/main.rs
src/args.rs
src/watch.rs
tests/cli_tests.rs
참고: 이는 아이디어를 강조하기 위한 대략적인 스케치일 뿐입니다
얻는 것은 다음과 같습니다.
main 예제에서 실행 가능한 src/main.rssrc/main.rs에 mod해야 하는 추가 모듈여전히 다양한 모듈을 편집하고 src/main.rs에 mod해야 합니다.
영역
xz 백도어는 다른 문제들과 함께 릴리스가 VCS에서 갈라질 위험을 부각했습니다. 게시된 .crate 파일에 연결된 git sha가 없을 때, 그 sha의 소스에서 갈라졌을 때, 그리고 그 sha가 사칭 커밋일 때를 위한 감사 지점이 필요합니다.
영역
참조된 곳: 블로그: 벽 위의 Rust 크레이트 999개
불순 패키지(파일, 환경, 네트워크, RNG 등에 접근할 수 있는 패키지)를 식별하는 것은 또 다른 감사 지점이 될 수 있습니다. core, alloc, std 의존성을 Cargo의 [dependencies]에 통합하려는 build-std 프로젝트의 노력을 통해 이를 얻을 수 있습니다.
이는 특히 패키지를 검토하는 동안 환경에서 실행할 수 있는 프로시저 매크로에 중요합니다. 따라서 Cargo는 프로시저 매크로 실행을 캐시해도 안전한지 알 수 있으며, 특히 캐싱 시스템에 바이너리 재현성이 필요하다면 간단한 HashMap으로도 재현성이 깨질 수 있습니다.
물론 alloc 전용 패키지는 unsafe, FFI, asm! 때문에 이야기의 일부만 알려 줍니다.
영역
추적 이슈: #16960
lang:unsafe방금 다룬 것처럼 alloc 전용 의존성이 있어도 unsafe, FFI, asm!처럼 감사 지점 적용 범위에는 여전히 빈틈이 있습니다. 여기서의 아이디어는 언어 기능 접근을 Cargo에 통합하는 것입니다.
가능한 방법 중 하나는 [features]가 `