লাইব্রেরি এবং বাইনারি উভয়ের সাথেই মরিচা প্যাকেজ?


190

আমি একটি জাস্ট প্যাকেজ তৈরি করতে চাই যাতে একটি পুনরায় ব্যবহারযোগ্য লাইব্রেরি (যেখানে বেশিরভাগ প্রোগ্রামটি বাস্তবায়িত হয়) এবং এটি ব্যবহার করে এমন একটি এক্সিকিউটেবল উভয়ই থাকে।

ধরে নিচ্ছি আমি মরিচা মডিউল সিস্টেমে কোনও শব্দার্থকে বিভ্রান্ত করি নি, আমার Cargo.tomlফাইলটি কেমন দেখতে হবে?

উত্তর:


205
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();
}

2
ধন্যবাদ ডগ, আমি চেষ্টা করব! তাহলে #! [ক্রেট_নাম =] এবং #! [ক্রেট_ টাইপ] টীকাগুলি কি তখন বিকল্প?
অ্যান্ড্রু ওয়াগনার

4
আপনি যখন কার্গো ব্যবহার করেন, এই বিকল্পগুলি অপ্রয়োজনীয় কারণ কার্গো সেগুলি সংকলক পতাকা হিসাবে পাস করে। আপনি যদি চালনা করেন তবে আপনি cargo build --verboseসেগুলি rustcকমান্ড লাইনে দেখতে পাবেন ।
ভ্লাদিমির মাত্তিভ

33
আপনি কি জানেন যে [[bin]]টেবিলগুলির একটি অ্যারে কেন ? কেন ব্যবহার [[bin]]এবং না [bin]? এটিতে কোনও নথিপত্র বলে মনে হচ্ছে না।
সিএমসিডিগ্রাগনকাই

40
@ সিএমসিডিগ্রাগনকাই এটি টমল ফর্ম্যাট স্পেসিফিকেশন [[x]] একবার ডিজিটালাইজড হয়ে যাওয়া একটি অ্যারে; অর্থাত। একটি ক্রেট একাধিক বাইনারি তৈরি করতে পারে, তবে কেবলমাত্র একটি গ্রন্থাগার (এইভাবে [লিবিব], [[লিবিব]] নয়))। আপনার একাধিক বিন বিভাগ থাকতে পারে। (আমি সম্মত, এটিকে অদ্ভুত দেখাচ্ছে, তবে টমল সর্বদা একটি বিতর্কিত পছন্দ ছিল)।
ডগ

1
বাইনারি সংকলন থেকে প্রতিরোধ করার কি কোনও উপায় আছে যখন আমি চাই সমস্ত লিব? বাইনারিটিতে অতিরিক্ত নির্ভরতা থাকে যা আমি "বাইনারি" নামে একটি বৈশিষ্ট্যের মাধ্যমে যুক্ত করি, যখন আমি সেই বৈশিষ্ট্যটি ছাড়াই এটি সংকলন করার চেষ্টা করি তখন এটি তৈরি করতে ব্যর্থ হয়। এটি অভিযোগ করে যে এটি বিন্যাসগুলি আমদানির চেষ্টা করছে এমন ক্রেটগুলি এটি খুঁজে পাচ্ছে না।
ব্যক্তি

150

আপনি কেবল বাইনারি উত্সগুলি এতে রাখতে পারেন 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 / বিন / 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


13
মরিচা কনভেনশন-ওভার-কনফিগারেশন পদ্ধতির সাথে ভাল ফিট করে! উভয় উত্তর একসাথে এবং আপনার কিছু দুর্দান্ত সুবিধা এবং নমনীয়তা আছে।
উড়ন্ত ভেড়া

9
extern crate example;মরিচা 2018 হিসাবে প্রয়োজনীয় নয়, আপনি সরাসরি use example::really_complicated_code;
স্কোপটির

47

একটি বিকল্প সমাধান হ'ল উভয় জিনিসকে একটি প্যাকেজের মধ্যে ক্র্যাম করার চেষ্টা না করা। বন্ধুত্বপূর্ণ এক্সিকিউটেবলের সাথে সামান্য বড় প্রকল্পগুলির জন্য, আমি একটি ওয়ার্কস্পেস ব্যবহার করে খুব সুন্দর পেয়েছি

আমরা একটি বাইনারি প্রকল্প তৈরি করি যা এর ভিতরে একটি লাইব্রেরি অন্তর্ভুক্ত করে:

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. ওয়ার্কস্পেস প্রতিটি উপাদানগুলির অপ্রয়োজনীয় বিল্ডগুলি প্রতিরোধ করে। যদি আমরা cargo buildউভয় mylibraryএবং the-binaryডিরেক্টরি পরিচালনা করি তবে গ্রন্থাগারটি দু'বার নির্মিত হবে না - এটি উভয় প্রকল্পের মধ্যে ভাগ করা আছে।


এটি আরও অনেক ভাল যাওয়ার মতো মনে হচ্ছে। স্পষ্টতই প্রশ্নটি জিজ্ঞাসা করার পরে বহু বছর হয়ে গেছে তবে লোকেরা এখনও বড় প্রকল্পগুলি পরিচালনা করে লড়াই করে। উপরের নির্বাচিত উত্তর বনাম কোনও ওয়ার্কস্পেস ব্যবহার করার কোনও প্রতিকূলতা আছে?
Jspies

4
@ জেসপিস সবচেয়ে বড় খারাপ দিক যা আমি আমার মাথার উপরের দিক থেকে ভাবতে পারি তা হ'ল এমন কিছু সরঞ্জাম রয়েছে যা কর্মক্ষেত্রগুলি মোকাবেলা করতে সম্পূর্ণরূপে জানে না know বিদ্যমান সরঞ্জামগুলির সাথে ইন্ট্যারাক্ট করার সময় এগুলি এক ধরণের অদ্ভুত জায়গা হয় যা কিছু প্রকারের "প্রকল্প" ধারণা রয়েছে have আমি ব্যক্তিগতভাবে একটি ধারাবাহিক পন্থা গ্রহণের প্রবণতা রাখি: আমি সমস্ত কিছু দিয়ে শুরু করি main.rs, তারপরে এটি বড় হওয়ার সাথে সাথে এটি মডিউলগুলিতে বিভক্ত করি, অবশেষে src/binএটি যখন একটু বড় হয় তখন বিভক্ত হয় , তারপরে আমি যখন মূল যুক্তিটি ভারীভাবে পুনরায় ব্যবহার শুরু করি তখন একটি কার্যক্ষেত্রে চলে আসছি।
শেপমাস্টার

ধন্যবাদ আমি এটি একটি স্পিন দিতে হবে। আমার বর্তমান প্রকল্পের বেশ কয়েকটি লিব রয়েছে যা এই প্রকল্পের অংশ হিসাবে বিকাশযুক্ত তবে বাহ্যিকভাবে ব্যবহৃত হয় used
Jspies

এটি তৈরি করে এবং সূক্ষ্মভাবে চালিত হয়, তবে cargo testlib.rs এ ইউনিট পরীক্ষা উপেক্ষা করে বলে মনে হচ্ছে
স্টেইন

3
@ স্টেইন আমি মনে করি আপনি চানcargo test --all
শেপমাস্টার

18

আপনি লাগাতে পারেন lib.rsএবং main.rsউৎস একসঙ্গে ফোল্ডারে। কোন বিরোধ নেই এবং কার্গো উভয় জিনিসই তৈরি করবে।

ডকুমেন্টেশন দ্বন্দ্ব সমাধান করতে আপনার এতে যুক্ত করুন Cargo.toml:

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

3
এটি " অতিরিক্ত হিসাবে, আপনি কেবলমাত্র একটি এসআরসি / মেইন.আর তৈরি করতে পারেন যা ডিফাক্টো এক্সিকিউটেবল হিসাবে ব্যবহৃত হবে "। অন্য উত্তরে, না? এবং ডকুমেন্টেশন সংঘাত গৃহীত উত্তর দিয়ে সমাধান করা হয়েছে, তাই না? এটি কেন অনন্য, তা জানাতে আপনার উত্তর পরিষ্কার করতে হবে। অন্যান্য উত্তরগুলি তৈরি করার জন্য এটি উল্লেখ করা ঠিক আছে।
শেপমাস্টার
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.