Как распространить модуль Go с C зависимостями - PullRequest
0 голосов
/ 15 января 2020

У меня есть пакет Go - назовите его foo - я построил на основе существующего кода C и пытаюсь определить, как лучше его распространить.

Немного фона ... Вот упрощенная версия моей структуры каталогов:

foo/
  |_ include/
      |_ <several other header files>
  |_ libs/
      |_ <several .so files>
  |_ foo.c
  |_ foo.h
  |_ foo.go

Урезанная голова 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"

...

Где _foo.so - это динамическая c lib генерируется как часть процесса сборки. Я могу нормально запускать и тестировать свой код, но я хочу иметь возможность распространять его и использовать в отдельном проекте, который использует go mod. Здесь все становится немного сложнее, и мое понимание Go становится слабым. Концептуально, я просто хочу иметь возможность распространять каталог foo/ (.so файлы и все) в месте, где другое приложение может найти и импортировать его, однако есть несколько камней преткновения, с которыми я столкнулся:

  • Я не могу сделать это бинарным пакетом, так как мы находимся на Go 1.13 и, насколько я понимаю, эта возможность была отброшена после 1.12.
  • Процесс сборки для Файл .so довольно существенный, и я не хочу, чтобы другие разработчики тратили 30 минут на создание этого объекта.

Я нашел много CGO демонстраций и блоги, но не много объяснений о том, как распространять CGO пакетов. Есть идеи?

Стоит отметить, что это для моей компании, где среда стандартная, поэтому мне не нужно контролировать разные ОС, и т. Д. c.

Редактировать

Я забыл упомянуть, что пытался вставить библиотеку в GOPATH образа Docker и просто построить из этой базы микросервис, который зависит от него. Однако при создании службы с -mod=vendor она не может найти библиотеку в 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

1 Ответ

0 голосов
/ 17 января 2020

Для тех, кто может столкнуться с подобным вопросом в будущем, вот шаги, которые я предпринял, чтобы сделать эту работу.

  1. Я запекла сгенерированные артефакты в базовое docker изображение, la:
FROM golang:1.13.4

COPY ./foo /go/src/foo/foo
COPY ./foo.mod /go/src/foo

Это позволяет обмениваться файлами .so с контролем исходного кода, вместо этого просто помещая образ docker в реестр.

Любая служба, для которой требуется эта библиотека, построена из этого базового образа:
FROM my-foo-base:latest

COPY ./vendor ./vendor
COPY ./go.mod ./
COPY ./go.sum ./

# Put foo in /vendor so it's discoverable, and put its libs where they
# can be discovered
RUN mv /go/src/foo ./vendor && \
    mv ./vendor/foo/foo/libs/*.so /usr/lib/ && \
    mv ./vendor/foo/foo/include/* /usr/include/

# Copy in app code
COPY ./my-app ./my-app

# Required so the app can find the _foo.so shared object
ENV LD_LIBRARY_PATH="/vendor/foo/foo:/usr/lib:${LD_LIBRARY_PATH}"

# Build into a single binary
RUN GOOS=linux \
    GOARCH=amd64 \
    CGO_ENABLED=1 \
    GOFLAGS=-mod=vendor \
    GO111MODULE=on \
    go build \
    -o service ./cmd/serve/main.go

Это работает, и служба может обнаружить пакет CGO.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...