使用了 cgo 的库该如何分发? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
CoolSpring
V2EX    Go 编程语言

使用了 cgo 的库该如何分发?

  •  
  •   CoolSpring 2020-10-14 18:04:28 +08:00 3347 次点击
    这是一个创建于 1827 天前的主题,其中的信息可能已经有所发展或是发生改变。

    有一个 Rust 写的库提供了 C ABI 的调用方式,我觉得这个库挺有趣的,就尝试给它写了一个 binding:

    https://github.com/CoolSpring8/go-lolhtml
    (存在的问题还比较多,无意推广,只是考虑到给出问题的具体情境更好理解)

    问题来了,虽然在 go build 时指定 CGO_ENABLED=1 可以让 CC 参数指定的编译器编译工作目录下的 C/C++ 源文件,但是这个库需要调用 cargo 来编译。

    我在开发时采用的方案是预先使用 cargo build --release 得到静态库或者动态库,然后在 Go 文件头部指定以下注释:

    #cgo CFLAGS: -I${SRCDIR}/lol-html/c-api/include #cgo LDFLAGS: -L${SRCDIR}/lol-html/c-api/target/release -llolhtml 

    但是到了 push 到 GitHub 后,尝试新建一个项目引用 import path 写 demo 时,才发现问题:

    在启用 go mod 的情况下,go get 之后( go get 不会下载 git submodule 是另一个问题了,容易解决),它依赖的 Rust 库怎么办呢?

    cd 到 $GOPATH/pkg/mod/github.com/... 去 make 之类的应该不可行,修改文件夹内容之后 module 的 sum 会改变,会无法使用。

    总结起来:

    cgo \

    + non-main package (不能通过发布预编译二进制的方案)\

    + no official library distribution (不能像大部分 binding 一样要求用户用包管理器安装对应包后,调用系统动态库,例如 ffmpeg 的 binding )\

    + go module (不能先 git clone 再 make 最后 go install 。所以看起来如果要用 go module 只能将依赖的 Rust 库事先安装为动态库了?)

    看了网络上能搜索到的资料,都无法解决我的问题。感觉难点都撞在一起了,好纠结……

    第 1 条附言    2020-10-16 00:51:41 +08:00
    感谢各位的建议,最终参考 https://github.com/bytecodealliance/wasmtime-go/ 在 repo 里放了预编译的静态库文件,之后的 go get 安装过程非常简便。

    另外,发现之前起的标题不太准确,应该是“调用了 Rust 库的 cgo binding 该如何作为 Go Module 分发”。
    8 条回复    2020-10-15 09:39:54 +08:00
    janxin
        1
    janxin  
       2020-10-14 18:26:02 +08:00
    为什么不能包含预编译 lib 的?
    timonwong
        2
    timonwong  
       2020-10-14 18:53:50 +08:00
    依赖 cgo 的 library 是这样的,因为也不像 npm 或者 python setup.py 可以运行自定义的安装脚本,所以会比较麻烦(以前「可以」,但是是个漏洞被修复了)

    ldflags 和 cflags (或者对应的环境变量)这两个可以让 caller 在 go build 的时候转入
    或者提供 pkg-config,然后 # cgo pkg-config xxx
    include 的头文件,跟 go 文件放在一起,能稍微提高点实用性
    wangyzj
        3
    wangyzj  
       2020-10-14 19:28:48 +08:00
    docker
    CoolSpring
        4
    CoolSpring  
    OP
       2020-10-14 21:38:50 +08:00
    @janxin
    谢谢,这个方式我之前没有想到,确实可以,但是似乎不是很“优雅”

    @timonwong
    感谢,可以传入参数就相对灵活一些了,或许可以写一个 shell 脚本

    @wangyzj
    docker 与 cgo 的组合我所了解到的是 https://stackoverflow.com/questions/59741795/how-to-distribute-a-go-module-with-c-dependencies 提问者自己的回答,也算是一种方法吧,但我主要还是想让自己的库能够在启用 Go Modules 的情况下通过 go get 的方式来安装
    reus
        5
    reus  
       2020-10-14 23:32:17 +08:00
    编译成 .a 文件,然后用 #cgo LDFLAGS: foo.a 链接即可
    maoxs2
        6
    maoxs2  
       2020-10-15 00:42:19 +08:00 via Android   1
    我看下来基本上用 c-binding 的库都是自带各个 platform 的.a 文件,我自己写的也都是这么做的。同样是 go 调用 rust,你可以看看 Mozilla 的字节码联盟它们的 wasmtime-go
    missdeer
        7
    missdeer  
       2020-10-15 08:28:06 +08:00
    我就是自带预编译的.a,.so
    然后还写了个 Makefile
    buzailianxi
        8
    buzailianxi  
       2020-10-15 09:39:54 +08:00
    基本上都是搞 lib 带过去,不关是不是 cgo
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5719 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 35ms UTC 02:52 PVG 10:52 LAX 19:52 JFK 22:52
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86