I have a Go package—call it foo
—I've built around some existing C code, and I'm trying to determine how best to distribute it.
A bit of background... Here's a simplified version of my directory structure:
foo/
|_ include/
|_ <several other header files>
|_ libs/
|_ <several .so files>
|_ foo.c
|_ foo.h
|_ foo.go
A stripped down head of foo.go
package foo
// #cgo CFLAGS: -I${SRCDIR}/include
// #cgo LDFLAGS: ${SRCDIR}/_foo.so -L${SRCDIR}/libs
// #include <stdlib.h>
// #include "foo.h"
import "C"
...
Where _foo.so
is a dynamic lib generated as part of the build process. I am able to run and test my code fine, but I want to be able to distribute it and use it in a separate project, one that uses go mod
. This is where things get a bit tricky, and my understanding of Go gets flimsy. Conceptually, I simply want to be able to distribute the foo/
directory (.so
files and all) in a place where another application can find and import it, however there are a couple stumbling blocks I've run into:
- I can't make this a binary package, as we're on Go 1.13 and as far as I understand that capability was dropped after 1.12.
- The build process for the
.so
file is quite substantial, and I don't want other developers to have to spend 30 mins+ just building that object.
I have found a lot of CGO demos and blogs, but not a lot of explanations around how to distribute CGO packages. Any ideas?
It's worth noting that this is for my company, where the environment is standard, so I do not have to control for different OS's, etc.
Edit
Something I forgot to mention that I've tried is baking the library into the GOPATH
of a Docker image, and just building from that base for the microservice that depends on it. However, when building the service with -mod=vendor
, it's unable to find the library in the GOPATH
:
RUN GOOS=linux \
GOARCH=amd64 \
CGO_ENABLED=1 \
GOFLAGS=-mod=vendor \
GO111MODULE=on \
go build \
-o service ./cmd/serve/main.go
./service
# build foo: cannot load foo: open /.../svc/vendor/foo: no such file or directory