Search code examples
gorustcgosolana

Build Rust static library to use within CGO


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


Solution

  • 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