gpt4 book ai didi

go - 如何分发具有 C 依赖项的 Go 模块

转载 作者:行者123 更新时间:2023-12-01 22:26:27 24 4
gpt4 key购买 nike

我有一个 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 是作为构建过程的一部分生成的动态库。我能够很好地运行和测试我的代码,但我希望能够分发它并在一个单独的项目中使用它,一个使用 go mod 的项目。这就是事情变得有点棘手的地方,我对 Go 的理解变得脆弱。从概念上讲,我只是希望能够将 foo/ 目录( .so 文件和所有文件)分发到另一个应用程序可以找到并导入它的地方,但是我遇到了几个绊脚石:
  • 我不能把它做成一个二进制包,因为我们在 Go 1.13 上,据我所知,这个功能在 1.12 之后被删除了。
  • .so 文件的构建过程非常庞大,我不希望其他开发人员必须花费 30 分钟以上的时间来构建该对象。

  • 我找到了很多 CGO 演示和博客,但没有很多关于如何分发 CGO 包的解释。有任何想法吗?

    值得注意的是,这是针对我公司的,环境是标准的,所以我不必控制不同的操作系统等。

    编辑

    我忘了提到我尝试过的是将库烘焙到 Docker 镜像的 GOPATH 中,并从该基础构建依赖于它的微服务。但是,使用 -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

    最佳答案

    对于将来可能遇到类似问题的任何人,以下是我为完成这项工作而采取的步骤。

  • 我将生成的工件烘焙到基础 Docker 镜像中,例如:
  • 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 包。

    关于go - 如何分发具有 C 依赖项的 Go 模块,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59741795/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com