[英]Where should I place a static library so I can link it with a Rust program?
I do not know how to link a C library to Rust.我不知道如何将 C 库链接到 Rust。 Here's what I have done:
这是我所做的:
My lib.rs file contains我的lib.rs文件包含
#[link(name = "test")]
extern {
The library is built and has the name libtest.a
.该库已构建并具有名称
libtest.a
。
I do not know where to put it.我不知道把它放在哪里。 I have tried several places, but I still have errors of this type when doing
cargo run
我已经尝试了几个地方,但是在执行
cargo run
时仍然出现这种类型的错误
error: linking with `cc` failed: exit code: 1
//..
note: /usr/bin/ld: no se puede encontrar -ltest
note: /usr/bin/ld: no se puede encontrar -ltest
note: /usr/bin/ld:.......
//..
Translation of the above /usr/bin/ld: no se puede encontrar -ltest
-> usr/bin/ld: cannot find -ltest
上面的翻译
/usr/bin/ld: no se puede encontrar -ltest
-> usr/bin/ld: cannot find -ltest
I do not know where to put libtest.a so that /usr/bin/ld
can find it.我不知道将libtest.a放在哪里,以便
/usr/bin/ld
可以找到它。 Cargo does not tell me where the library should be in the project. Cargo 没有告诉我库应该在项目中的哪个位置。
My Cargo.toml contains我的Cargo.toml包含
[dependencies.test]
path = "./src/test"
[dependencies]
bitflags = "0.7"
libc = "0.2"
[build-dependencies]
make-cmd = "0.1"
After reading the FFI section of the documentation again, I thought that maybe the error messages from before were because I was looking for a shared library, so I made the following changes:再次阅读文档的FFI部分后,我认为可能之前的错误信息是因为我正在寻找共享库,因此我进行了以下更改:
#[link(name = "test", kind = "static")]
After these changes, I still do not know how to indicate where the library is, but the message now tells me this:在这些更改之后,我仍然不知道如何指示库的位置,但是现在消息告诉我:
error: could not find native static library `test`, perhaps an -L flag is missing?
Where should I place a static library
我应该在哪里放置静态库
Wherever you want.哪里都行。 You have to tell the compiler where to find it.
您必须告诉编译器在哪里可以找到它。
First, let's create a static library首先,让我们创建一个静态库
$ cat hello.c
int square(int value) {
return value * value;
}
$ gcc -c -o hello.o hello.c
$ ar rcs libhello.a hello.o
Next, we use a build script to set the value of rustc-link-search
to point to the directory where I put the library:接下来,我们使用构建脚本将
rustc-link-search
的值设置为指向我放置库的目录:
fn main() {
println!("cargo:rustc-link-search=/Projects/stack-overflow/using-c-static/");
}
We can now use the functions from the library:我们现在可以使用库中的函数:
#[link(name = "hello")]
extern "C" {
fn square(val: i32) -> i32;
}
fn main() {
let r = unsafe { square(3) };
println!("3 squared is {}", r);
}
That's the basic functionality.这就是基本功能。 You could also use the build script to specify which library to link, instead of having it in your code (
rustc-link-lib
).您还可以使用构建脚本来指定要链接的库,而不是将其包含在您的代码中 (
rustc-link-lib
)。 I prefer this because then the two configurations are right next to each other.我更喜欢这样,因为这两种配置彼此相邻。
You should also probably follow the *-sys
naming convention and create a crate dedicated to exposing the underlying API.您可能还应该遵循
*-sys
命名约定并创建一个专门用于公开底层 API 的板条箱。 Importantly, this crate should specify the link
manifest key to avoid duplicate symbols at linking time.重要的是,此 crate 应指定
link
清单键以避免link
出现重复符号。
If your build script needs more information, cargo passes many parameters via environment variables .如果您的构建脚本需要更多信息,cargo 通过环境变量传递许多参数。
If you are compiling C code as part of your crate, you should look into crates like cc or cmake , which make the act of building a piece of software much easier.如果您将 C 代码编译为 crate 的一部分,您应该查看 crate 之类的cc或cmake ,这使得构建软件的行为变得更加容易。
I just found a solution (two) but I do not know if it's the best way:我刚刚找到了一个解决方案(二),但我不知道这是否是最好的方法:
1- way 1路
build.rs file build.rs 文件
extern crate gcc;
fn main() {
println!("cargo:rustc-link-search=native=/home/path/to/rust/proyect/folder/contain/file.a");
println!("cargo:rustc-link-lib=static=test");
}
Cargo.toml Cargo.toml
//..
build = "build.rs"
//..
2- way 2路
Cargo.toml Cargo.toml
//..
rustc-link-search = ["./src/lib"]
rustc-link-lib = ["test"]
root = "/home/path/to/rust/proyect/"
//..
["./src/lib"]
-> place to lib.a refence to root ["./src/lib"]
-> 放置到 lib.a 对 root 的引用
If you don't want to specify the path to the library, and you are on Linux, you can just place it in "usr/local/lib" and say its name in main.rs like this :如果你不想指定库的路径,而且你在 Linux 上,你可以把它放在“usr/local/lib”中,然后在 main.rs 中说出它的名字,如下所示:
#[link(name = "theLibraryname", kind = "")]
Also, you can place any header files in the include folder.此外,您可以将任何头文件放在包含文件夹中。
Note: The library name is without the lib
prefix and .a
extension.注意:库名称没有
lib
前缀和.a
扩展名。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.