简体   繁体   English

我应该在哪里放置一个静态库,以便我可以将它与 Rust 程序链接?

[英]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 之类的cccmake ,这使得构建软件的行为变得更加容易。

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM