[rust] 라이브러리와 바이너리가 모두있는 녹 패키지?

재사용 가능한 라이브러리 (대부분의 프로그램이 구현되는 곳)와 그것을 사용하는 실행 파일이 모두 들어있는 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)

이 체계에는 두 가지 큰 이점이 있습니다.

  1. 바이너리는 이제 의존성 만 적용 할 수 있습니다. 예를 들어, 명령 줄 구문 분석기 또는 터미널 형식화와 같이 사용자 환경을 개선하기 위해 많은 상자를 포함 할 수 있습니다. 이들 중 어느 것도 라이브러리를 “감염”시키지 않습니다.

  2. 작업 공간은 각 구성 요소의 중복 빌드를 방지합니다. and 디렉토리 cargo build에서 모두 실행 하면 라이브러리가 두 번 빌드되지 않으며 두 프로젝트간에 공유됩니다.mylibrarythe-binary


답변

lib.rsmain.rs소스 폴더를 함께 넣을 수 있습니다 . 충돌이 없으며 화물이 두 가지를 모두 쌓을 것입니다.

documentaion 충돌을 해결하려면 다음을 추가하십시오 Cargo.toml.

[[bin]]
name = "main"
doc = false


답변