재사용 가능한 라이브러리 (대부분의 프로그램이 구현되는 곳)와 그것을 사용하는 실행 파일이 모두 들어있는 Rust 패키지를 만들고 싶습니다.
Rust 모듈 시스템에서 시맨틱을 혼동하지 않았다고 가정하면 Cargo.toml
파일은 어떻게 생겼습니까?
답변
Tok:tmp doug$ du -a
8 ./Cargo.toml
8 ./src/bin.rs
8 ./src/lib.rs
16 ./src
Cargo.toml :
[package]
name = "mything"
version = "0.0.1"
authors = ["me <me@gmail.com>"]
[lib]
name = "mylib"
path = "src/lib.rs"
[[bin]]
name = "mybin"
path = "src/bin.rs"
src / lib.rs :
pub fn test() {
println!("Test");
}
src / bin.rs :
extern crate mylib; // not needed since Rust edition 2018
use mylib::test;
pub fn main() {
test();
}
답변
바이너리 소스를 넣고 src/bin
나머지 소스는에 넣을 수도 있습니다 src
. 내 프로젝트 에서 예제를 볼 수 있습니다 . 전혀 수정하지 않아도 Cargo.toml
되며 각 소스 파일은 동일한 이름의 이진 파일로 컴파일됩니다.
그런 다음 다른 답변의 구성은 다음으로 대체됩니다.
$ tree
.
├── Cargo.toml
└── src
├── bin
│ └── mybin.rs
└── lib.rs
Cargo.toml
[package]
name = "example"
version = "0.0.1"
authors = ["An Devloper <an.devloper@example.com>"]
src / lib.rs
use std::error::Error;
pub fn really_complicated_code(a: u8, b: u8) -> Result<u8, Box<Error>> {
Ok(a + b)
}
src / bin / mybin.rs
extern crate example; // Optional in Rust 2018
fn main() {
println!("I'm using the library: {:?}", example::really_complicated_code(1, 2));
}
그리고 그것을 실행하십시오 :
$ cargo run --bin mybin
I'm using the library: Ok(3)
또한 src/main.rs
사실상 실행 파일로 사용될 파일을 만들 수 있습니다 . 불행히도 이것은 cargo doc
명령 과 충돌합니다 .
라이브러리와 바이너리가 동일한 이름을 가진 패키지를 문서화 할 수 없습니다. 이름을 바꾸거나 대상을 다음과 같이 표시하십시오.
doc = false
답변
다른 해결책은 실제로 두 가지를 하나의 패키지에 넣지 않는 것입니다. 친숙한 실행 파일이있는 약간 더 큰 프로젝트의 경우 작업 공간 을 사용하는 것이 매우 좋습니다.
우리는 그 안에 라이브러리를 포함하는 바이너리 프로젝트를 만듭니다 :
the-binary
├── Cargo.lock
├── Cargo.toml
├── mylibrary
│ ├── Cargo.toml
│ └── src
│ └── lib.rs
└── src
└── main.rs
Cargo.toml
이것은 [workspace]
키를 사용하며 라이브러리에 따라 다릅니다.
[package]
name = "the-binary"
version = "0.1.0"
authors = ["An Devloper <an.devloper@example.com>"]
[workspace]
[dependencies]
mylibrary = { path = "mylibrary" }
src / main.rs
extern crate mylibrary;
fn main() {
println!("I'm using the library: {:?}", mylibrary::really_complicated_code(1, 2));
}
mylibrary / src / lib.rs
use std::error::Error;
pub fn really_complicated_code(a: u8, b: u8) -> Result<u8, Box<Error>> {
Ok(a + b)
}
그리고 그것을 실행하십시오 :
$ cargo run
Compiling mylibrary v0.1.0 (file:///private/tmp/the-binary/mylibrary)
Compiling the-binary v0.1.0 (file:///private/tmp/the-binary)
Finished dev [unoptimized + debuginfo] target(s) in 0.73 secs
Running `target/debug/the-binary`
I'm using the library: Ok(3)
이 체계에는 두 가지 큰 이점이 있습니다.
-
바이너리는 이제 의존성 만 적용 할 수 있습니다. 예를 들어, 명령 줄 구문 분석기 또는 터미널 형식화와 같이 사용자 환경을 개선하기 위해 많은 상자를 포함 할 수 있습니다. 이들 중 어느 것도 라이브러리를 “감염”시키지 않습니다.
-
작업 공간은 각 구성 요소의 중복 빌드를 방지합니다. and 디렉토리
cargo build
에서 모두 실행 하면 라이브러리가 두 번 빌드되지 않으며 두 프로젝트간에 공유됩니다.mylibrary
the-binary
답변
lib.rs
및 main.rs
소스 폴더를 함께 넣을 수 있습니다 . 충돌이 없으며 화물이 두 가지를 모두 쌓을 것입니다.
documentaion 충돌을 해결하려면 다음을 추가하십시오 Cargo.toml
.
[[bin]]
name = "main"
doc = false