英文:
ld: library not found when calling go function from Rust
问题
我想通过一个共享的 C 库从 Rust 中调用一个 Go 函数,但是遇到了一个库链接器的问题。
这是我的代码:
- hello.go
package main
import "fmt"
import "C"
//export Hello
func Hello() {
fmt.Println("Hello Go C-Shared")
}
func main() {}
运行 go build -o Hello.so -buildmode=c-shared hello.go
会生成 Hello.h
文件和 Hello.so
文件。
- 接下来,我创建了一个 rust-hello-world 项目,并将
Hello.h
和Hello.so
文件移动到 main.rs 的同一目录src
中,并在 main.rs 中调用了外部的 Hello 函数。
#[link(name = "Hello")]
extern "C" {
fn Hello();
}
fn main() {
unsafe {Hello()};
}
- 我进行了一些研究,并在
cargo build
之前尝试了以下环境变量:LD_LIBRARY_PATH=~/dev/rust-hello-world/src/
LD_LIBRARY_PATH=~/dev/rust-hello-world/src/Hello.so
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:~/dev/rust-hello-world/src/
export LIBRARY_PATH=$LIBRARY_PATH:~/dev/rust-hello-world/src/
但是它们都生成了相同的错误:
error: linking with `cc` failed: exit status: 1
|
= note: LC_ALL="C" PATH="..."
= note: ld: library not found for -lHello
clang: error: linker command failed with exit code 1 (use -v to see invocation)
版本信息:
cargo 1.69.0-nightly (9d5b32f50 2023-02-22)
go version go1.19 darwin/amd64
os version: MacOS Ventura 13.1 (22C65)
如果需要更多详细信息,请告诉我。
英文:
I want to call a go function from Rust trough a shared c library but running into a library linker issue.
Here is my code:
- hello.go
package main
import "fmt"
import "C"
//export Hello
func Hello() {
fmt.Println("Hello Go C-Shared")
}
func main() {}
go build -o Hello.so -buildmode=c-shared hello.go
outputs the Hello.h
file and Hello.so
file.
- Next I created a rust-hello-world project, and I moved
Hello.h
andHello.so
file to the same directorysrc
of main.rs, and invoked the external Hello function in main.rs.
#[link(name = "Hello")]
extern "C" {
fn Hello();
}
fn main() {
unsafe {Hello()};
}
- I did some research and tried the following environment variables before
cargo build
LD_LIBRARY_PATH=~/dev/rust-hello-world/src/
LD_LIBRARY_PATH=~/dev/rust-hello-world/src/Hello.so
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:~/dev/rust-hello-world/src/
export LIBRARY_PATH=$LIBRARY_PATH:~/dev/rust-hello-world/src/
But all of them generated the same error
error: linking with `cc` failed: exit status: 1
|
= note: LC_ALL="C" PATH="..."
= note: ld: library not found for -lHello
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Version info:
cargo 1.69.0-nightly (9d5b32f50 2023-02-22)
go version go1.19 darwin/amd64
os version: MacOS Ventura 13.1 (22C65)
Let me know if you need more details.
答案1
得分: 1
这些步骤适用于我的情况。
构建库:
go build -o libHello.so -buildmode=c-shared hello.go
链接到库:
export DYLD_LIBRARY_PATH=/绝对路径/到/库
RUSTFLAGS="/绝对路径/到/库" cargo build
当设置RUSTFLAGS
时,我从@cafce25的答案中删除了-lstatic
,因为它需要一个libHello.a文件。由于我是用Go构建的libHello.so库,所以在这种情况下,我找不到libHello.a文件,因为它是特定于Rust的静态库文件。
DYLD_LIBRARY_PATH
和LD_LIBRARY_PATH
是动态链接器用于搜索共享库(也称为动态链接库)的环境变量。
DYLD_LIBRARY_PATH
用于macOS,而LD_LIBRARY_PATH
用于Linux/Unix系统。
英文:
These steps worked for my case.
Build the library:
go build -o libHello.so -buildmode=c-shared hello.go
Link to the library:
export DYLD_LIBRARY_PATH=/absolute/path/to/the/library
RUSTFLAGS="/absolute/path/to/the/library" cargo build
I removed the -lstatic
from @cafce25's answer when setting RUSTFLAGS
as it requires a libHello.a file. Since I have built the libHello.so library with Go instead of Rust, in this case, I won't be able to find a libHello.a file because it is a static library file specific to Rust.
DYLD_LIBRARY_PATH
and LD_LIBRARY_PATH
are environment variables used by dynamic linkers to search for shared libraries (aka dynamic link libraries).
DYLD_LIBRARY_PATH
is used on macOS, while LD_LIBRARY_PATH
is used on Linux/Unix systems.
答案2
得分: 0
你可以像这样链接一个你创建的共享对象:
go build -o libhello.so --buildmode=c-shared hello.go
然后告诉 cargo
使用正确的目录来搜索你的库文件和要包含的库:
RUSTFLAGS="-Lnative=/absolute/path/to/your/library -lstatic=hello" cargo build
在运行时,你需要将共享对象包含在你的 LD_LIBRARY_PATH
中:
LD_LIBRARY_PATH=/absolute/path/to/your/library target/debug/your_crate_name
英文:
You can link a shared object that you created like this:
go build -o libhello.so --buildmode=c-shared hello.go
and then telling cargo
to use the proper directory to search for your library file and the library to include:
RUSTFLAGS="-Lnative=/absolute/path/to/your/library -lstatic=hello" cargo build
and at runtime you have to include the shared object in your LD_LIBRARY_PATH
:
LD_LIBRARY_PATH=/absolute/path/to/your/library target/debug/your_crate_name
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论