构建 Rust 静态库以在 CGO 中使用

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

Build Rust static library to use within CGO

问题

我正在尝试将我的Rust crate构建为静态库,以便通过FFI在Golang中进一步使用它。
到目前为止,我尝试了很多不同的链接方法,但最终的Go二进制文件仍然出现了“undefined reference”类型的错误:

    /usr/bin/ld: ./lib/libsolana_mint.a(nix-6da6fd938c826d01.nix.e161731d-cgu.5.rcgu.o): 在函数 `nix::mqueue::mq_open' 中:
nix.e161731d-cgu.5:(.text._ZN3nix6mqueue7mq_open17hd889faf637ea61f3E+0xd): 对 `mq_open' 的引用未定义
/usr/bin/ld: nix.e161731d-cgu.5:(.text._ZN3nix6mqueue7mq_open17hd889faf637ea61f3E+0x1e): 对 `mq_open' 的引用未定义
/usr/bin/ld: ./lib/libsolana_mint.a(nix-6da6fd938c826d01.nix.e161731d-cgu.5.rcgu.o): 在函数 `nix::mqueue::mq_unlink' 中:
nix.e161731d-cgu.5:(.text._ZN3nix6mqueue9mq_unlink17hc51e2d94961b863cE+0x6): 对 `mq_unlink' 的引用未定义
/usr/bin/ld: ./lib/libsolana_mint.a(nix-6da6fd938c826d01.nix.e161731d-cgu.5.rcgu.o): 在函数 `nix::mqueue::mq_close' 中:
nix.e161731d-cgu.5:(.text._ZN3nix6mqueue8mq_close17h53f48d4def20adadE+0x3): 对 `mq_close' 的引用未定义

所有的错误都涉及到来自依赖项的一些Rust crates,比如nixsolana_sdk

这是我用来构建的Dockerfile:

# syntax=docker/dockerfile:1
FROM rust:1.58 as build

RUN apt-get update
RUN apt-get install -y libudev-dev && apt-get install -y pkg-config

WORKDIR /solana
COPY lib/solana_mint ./solana_mint

WORKDIR /solana/solana_mint
RUN RUSTFLAGS='-C target-feature=+crt-static' cargo build --target x86_64-unknown-linux-gnu --release


FROM golang:1.17

WORKDIR /cardforge
COPY --from=build /solana/solana_mint/target/release/libsolana_mint.a ./lib/
COPY ./lib/solana_mint.h ./lib/

COPY go.mod ./
COPY go.sum ./
RUN go mod download

COPY controllers ./controllers
COPY models ./models
COPY *.go ./

RUN go build main.go

EXPOSE 8080

CMD [ "RUST_LOG=trace ./main" ]

非常感谢任何信息,因为关于cgo,没有太多高级示例的资源,除了简单的hello-world和单个函数绑定。

英文:

I am trying to build my Rust crate as static lib to furter use it within Golang through FFI.
So far tried buch of different approaches regarding linking, but still having undefined reference kind error from final go binary:

    /usr/bin/ld: ./lib/libsolana_mint.a(nix-6da6fd938c826d01.nix.e161731d-cgu.5.rcgu.o): in function `nix::mqueue::mq_open':
nix.e161731d-cgu.5:(.text._ZN3nix6mqueue7mq_open17hd889faf637ea61f3E+0xd): undefined reference to `mq_open'
/usr/bin/ld: nix.e161731d-cgu.5:(.text._ZN3nix6mqueue7mq_open17hd889faf637ea61f3E+0x1e): undefined reference to `mq_open'
/usr/bin/ld: ./lib/libsolana_mint.a(nix-6da6fd938c826d01.nix.e161731d-cgu.5.rcgu.o): in function `nix::mqueue::mq_unlink':
nix.e161731d-cgu.5:(.text._ZN3nix6mqueue9mq_unlink17hc51e2d94961b863cE+0x6): undefined reference to `mq_unlink'
/usr/bin/ld: ./lib/libsolana_mint.a(nix-6da6fd938c826d01.nix.e161731d-cgu.5.rcgu.o): in function `nix::mqueue::mq_close':
nix.e161731d-cgu.5:(.text._ZN3nix6mqueue8mq_close17h53f48d4def20adadE+0x3): undefined reference to `mq_close'

All errors refer bunch of Rust crates from dependencies, such as nix, solana_sdk

Here is my Dockerfile, from Which I build it:

# syntax=docker/dockerfile:1
FROM rust:1.58 as build

RUN apt-get update
RUN apt-get install -y libudev-dev && apt-get install -y pkg-config

WORKDIR /solana
COPY lib/solana_mint ./solana_mint

WORKDIR /solana/solana_mint
RUN RUSTFLAGS='-C target-feature=+crt-static' cargo build --target x86_64-unknown-linux-gnu --release


FROM golang:1.17

WORKDIR /cardforge
COPY --from=build /solana/solana_mint/target/release/libsolana_mint.a ./lib/
COPY ./lib/solana_mint.h ./lib/

COPY go.mod ./
COPY go.sum ./
RUN go mod download

COPY controllers ./controllers
COPY models ./models
COPY *.go ./

RUN go build main.go

EXPOSE 8080

CMD [ "RUST_LOG=trace ./main" ]

Will greatly appreciate any info, as for cgo there isn't much resources with advanced examples, exept plain hello-workd with single function binding

答案1

得分: 1

问题出在CGO的正确标志上。
这是main.go中CGO头文件的样子:

/*
#cgo LDFLAGS: ./lib/libsolana_mint.a -ldl -ludev -lrt -lm
#include "./lib/solana_mint.h"
*/
import "C"

添加-ludev -rt -lm解决了链接器和Docker镜像编译时的所有错误。

不过奇怪的是,在任何FFI文档中都没有提到这一点。

英文:

The problem was in right flags for CGO.
This is how header for CGO in main.go looks now

/*
#cgo LDFLAGS: ./lib/libsolana_mint.a -ldl -ludev -lrt -lm
#include "./lib/solana_mint.h"
*/
import "C"

Adding -ludev -rt -lm solved all errors from linker and Docker image compiled.

Strange though, that this moment isn't lightened in any docs for FFI

huangapple
  • 本文由 发表于 2022年1月18日 20:59:59
  • 转载请务必保留本文链接:https://go.coder-hub.com/70756015.html
匿名

发表评论

匿名网友

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

确定