ld: 在从 Rust 调用 Go 函数时找不到库

huangapple go评论114阅读模式
英文:

ld: library not found when calling go function from Rust

问题

我想通过一个共享的 C 库从 Rust 中调用一个 Go 函数,但是遇到了一个库链接器的问题。

这是我的代码:

  1. 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 文件。

  1. 接下来,我创建了一个 rust-hello-world 项目,并将 Hello.hHello.so 文件移动到 main.rs 的同一目录 src 中,并在 main.rs 中调用了外部的 Hello 函数。
#[link(name = "Hello")]
extern "C" {
    fn Hello();
}

fn main() {
    unsafe {Hello()};
}
  1. 我进行了一些研究,并在 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:

  1. 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.

  1. Next I created a rust-hello-world project, and I moved Hello.h and Hello.so file to the same directory src of main.rs, and invoked the external Hello function in main.rs.
#[link(name = "Hello")]
extern "C" {
    fn Hello();
}

fn main() {
    unsafe {Hello()};
}
  1. 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_PATHLD_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

huangapple
  • 本文由 发表于 2023年3月9日 09:27:09
  • 转载请务必保留本文链接:https://go.coder-hub.com/75679643.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定