I have one crate which is Lib
In this Lib , it provided other
lib crate which is proc_macro and don"t want to change value type or conflict with source code.
But wonder how can I call some function and struct from the main Lib crate which there are coded and src/ folder to the this Lib which is its subdir and its type is proc_macro ?
I tried to add crate::struct_on_main_lib to the second Lib on Lib.rs but seems it has to be build somewhere or other reason which I can really understand .
Related
I have a workspace with two crates: lib and app, where I want to use code from lib in app.
Additionally, I want to have the following Cargo config only in the lib crate to insturment the lib crate with LLVMs SanitizeCoverage (I provide the callback functions of the SanitizeCoverage in the app crate, because they must not be instrumented, otherwise there would be a stack overflow):
[build]
rustflags = [
"-Cpasses=sancov-module",
"-Cllvm-args=-sanitizer-coverage-level=1",
"-Cllvm-args=-sanitizer-coverage-trace-pc-guard",
]
Unfortunately, Cargo does not use this config file if it is included in lib/.cargo/config.toml.
I tried to pass the config with a build.rs of the lib crate:
pub fn main() {
println!("cargo:rustc-env=RUSTFLAGS=\"-Cpasses=sancov-module -Cllvm-args=-sanitizer-coverage-level=1 -Cllvm-args=-sanitizer-coverage-trace-pc-guard\"");
}
But this also does not work (The code is not instrumented, as I've checked with the disassembly afterwards).
Is there any way to do this? I also tried to create two different crates, without a workspace, but then the Cargo config file of the lib crate is also ignored.
I also tried to manually create a rlib and link to it manually, but while this works more or less, it is really problematic as I have to export a C interface in that case. Also, this fails if I want to execute it in the Fortanix SGX framework (which is my ultimate goal).
This question already has answers here:
Rust modules confusion when there is main.rs and lib.rs
(4 answers)
Closed 1 year ago.
I'm creating an application in Rust. The problem is that I cannot import a module inside lib.rs file and I wonder how am I supposed to do that.
My folder structure looks like this:
src/
├─ lib.rs
├─ main.rs
├─ app.rs
Inside main.rs file I use mod lib to use the library's public functions. But inside lib.rs file I would like to get the public methods from app.rs file, but unlike in other files, I cannot because of a compiler error:
file not found for module `app`
help: to create the module `app`, create file "src\lib\app.rs" or "src\lib\app\mod.rs"rustc(E0583)
Strangely enough, when I move the app.rs file to newly created lib/app.rs, the compiler would like to find the file in the previous location, which is src/app.rs, nor src/lib/app.rs. It gives me a headache.
Thank you for your answers.
Do not write mod lib;, with that name in particular. While this is technically valid code, it results in your code being compiled twice, under different configurations:
cargo sees lib.rs, and tells rustc to compile a library with that as the “crate root”.
Under this condition, mod app; looks for a sibling file and succeeds.
cargo sees main.rs, and tells rustc to compile a binary with that as the crate root.
rustc reads main.rs and sees mod lib;, so it compiles lib.rs again as a module inside of the binary.
Then, submodules of modules are expected to be in subdirectories, which is why it's asking for src/lib/app.rs.
If you are intending to define a library crate (which can be depended on by other packages, or your own integration tests and examples separate from main), then instead of mod lib;, just write paths referring to the library: use foo::app::some_fn_in_app_rs;, where foo is whatever name is specified in your Cargo.toml's [package] section, because that's the name of the library. The library is automatically made available to the binary.
On the other hand, if you don't have any need for a library, then you can just declare modules starting from main. In that case, don't name any of the modules lib. Any name that's not lib or main is fine.
In either case, you can always move the code around later if your needs change. The only thing that is problematic is when you name a module one of the filenames that means something specific to Cargo.
I'm working on a project that need to call a C project shared lib in Windows.
Suppose I have the my-math.dll file under rust src folder. I already add libc crate in Cargo.toml and following is my main.rs code:
extern crate libc;
#[link(name = "my-math")]
extern {
}
fn main() {
}
When I tried to build the project, it came with the error note: LINK : fatal error LNK1181: cannot open input file 'my-math.lib'
Seems the #[link(name="my-math")] converted to my-math.lib automatically. But I only have the .dll file. Is there anyway to switch to dll file instead of lib file.
I don't want to use the header file with bindgen crate for some special reasons.
I have a project which contains three files main.rs,bytes.rs and provider.rs. I have created mod.rs file and I have included both crate bytes.rs and provider.rs as shown below. whenever I am trying to include mod bytes inside the provider.rs, I get the error, please help me to sort out this.
error: file not found for module bytes
---projectA
+ src
-- main.rs
-- mod.rs
-- bytes.rs
-- provider.rs
I have created mod.rs file
That was completely unnecessary:
mod.rs is only for subfolders of the root folder. For the root, there is already a crate root (main.rs or lib.rs) so there is no situation in which this file is useful
and in edition 2018 mod.rs is not necessary for sub-mods to work (though it is still allowed I think)
You should just have mod bytes; mod provider in the crate root (main.rs). Then, provider.rs can either:
use the item from bytes directly e.g. super::bytes::... or crate::bytes::... will resolve to the relevant symbol from the bytes sibling module
use a similar path in order to use "short forms" for symbols e.g. use super::bytes::Foo will let the module refer to Foo without needing the fully qualified path
See https://stackoverflow.com/a/30687811/8182118 for more, as well as a description of edition 2015.
I have a crate with both src/lib.rs and src/main.rs.
main.rs is just using extern crate programname (which is lib.rs) and uses certain functions from lib.rs and it's submodules.
The documentation on linking says:
Pure-Rust dependencies are statically linked by default so you can use created binaries and libraries without installing Rust everywhere.
How can I change this behavior so a binary created from main.rs will be dynamically linked to library produced by lib.rs?
I've added the following to Cargo.toml
[lib]
path = "src/lib.rs"
crate-type = ["dylib"]
[[bin]]
name = "programname"
path = "src/main.rs"
But it does not compile and gives me errors like:
error: cannot satisfy dependencies so `std` only shows up once
help: having upstream crates all available in one format will likely make this go away
If I add "rlib" to lib section, it compiles, but the binary is not linked against libprogramname.so