如何:在 windows 上的 bazel 中使用 rules_go 生成 .so 文件

我已经切换(或正在切换)使用 bazel,尽管我在 Windows 上这样做。我有兴趣从 Java 调用我的 Go 代码,所以我从本教程开始。


我能够使用与他们的 Github 示例相同的代码来完成这项工作,并且一切正常。我尝试将其调整为我的 bazel 构建。如果我将awesome.so生成的文件go build -o awesome.so -buildmode=c-shared awesome.go作为资源包含到 myjava_library中,我可以让一切正常工作。


相关文件如下所示。


然而,理想情况下,我希望通过 bazel 生成所有内容,但尽管到目前为止我做了所有尝试,但我的go_binary规则始终输出awesome.a(and awesome.x)。如果我切换到使用//go:awesome作为资源,java:client_lib我能够成功地将awesome.a输出视为资源,这表明让我go_binary的输出awesome.so是拼图的最后一块,但迄今为止我还没有正确组合标志。


基本上我只想让我的go_binary规则具有与运行相同的行为go build -o awesome.so --buildmode=c-shared awesome.go。


从理论上讲,如果我需要另一个规则来弥合差距,我没问题,但是由于我在 Windows 上并且到目前为止 bash 已经被击中或错过,因此genrule用作中间体目前看起来并不乐观。


请指教,谢谢!


工作空间


...


# bazelbuild/rules_go for golang support.

http_archive(

    name = "io_bazel_rules_go",

    sha256 = "b725e6497741d7fc2d55fcc29a276627d10e43fa5d0bb692692890ae30d98d00",

    urls = [

        "https://mirror.bazel.build/github.com/bazelbuild/rules_go/releases/download/v0.24.3/rules_go-v0.24.3.tar.gz",

        "https://github.com/bazelbuild/rules_go/releases/download/v0.24.3/rules_go-v0.24.3.tar.gz",

    ],

)


load("@io_bazel_rules_go//go:deps.bzl", "go_register_toolchains", "go_rules_dependencies")


go_rules_dependencies()


go_register_toolchains()

...

go/awesome.go 是从文章中复制而来的。

去/建立


load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library")


package(default_visibility = ["//visibility:public"])


go_binary(

    name = "awesome",

    srcs = glob(["*.go"]),

    cgo = True,

    copts = [

        "-fPIC",  # I tried adding this after some other reading about .a->.so

    ],

    gc_linkopts = [

        "-shared", # I think this is equivalent to the linkmode=c-shared below, but... <shrug>

    ],

    linkmode = "c-shared",

    static = "off",

)


# This one uses the pre-built awesome.so, and this works.

filegroup(

    name = "prebuilt_awesome_resource",

    srcs = ["awesome.so"],

)

java/Client.java 是从文章中链接的 github repo复制而来的(对库的位置稍作调整)。

爪哇/构建


package(default_visibility = ["//visibility:public"])


java_import(

    name = "jna",

    jars = ["jna.jar"],

)



宝慕林4294392
浏览 186回答 2
2回答

慕哥9229398

好吧,我想我需要在耻辱立方体里坐一会儿。在我为编译器寻找的所有选项中,我错过了检查go_binary.&nbsp;具体来说,显而易见的,out.&nbsp;实际对应于-o标志的那个go build我添加out = "awesome.so"了我的go_binary规则,果然,一切正常。好吧,这浪费了几个小时。感谢杰伊试图提供帮助,很抱歉问了一个愚蠢的问题。

慕姐4208626

这可能无法准确回答您的问题,但我可以举一个从 macOS 上的 C 程序调用 Go 共享库的示例。希望这可以让你大部分时间都在那里。对于go_binary,您只需要linkmode = "c-shared".&nbsp;您还需要cgo = True包含 cgo 代码或已导出定义的每个包。您不需要-shared,-fPIC或static = "off".导出的定义应标有//export注释。有一个隐式声明的目标,其后缀.c_hdrs为 Go 库构建头文件。它:go_hello.c_hdrs在下面的示例中。实际的头文件名称是go_hello.h,与目标名称匹配。您需要使用cc_import规则包装生成的文件,以使其可用作 C/C++ 依赖项。#2433是简化该过程的开放问题,但最近才在 Bazel 中实现。任何可以消耗 a 的东西都可以以同样的方式cc_library消耗cc_import目标。所以你应该能够通过 JNI 调用 Go 函数,尽管我从未尝试过。构建.bazelload("@io_bazel_rules_go//go:def.bzl", "go_binary")go_binary(&nbsp; &nbsp; name = "go_hello",&nbsp; &nbsp; srcs = ["hello.go"],&nbsp; &nbsp; cgo = True,&nbsp; &nbsp; linkmode = "c-shared",)cc_import(&nbsp; &nbsp; name = "c_hello",&nbsp; &nbsp; hdrs = [":go_hello.c_hdrs"],&nbsp; &nbsp; shared_library = ":go_hello",)cc_binary(&nbsp; &nbsp; name = "use",&nbsp; &nbsp; srcs = ["use.c"],&nbsp; &nbsp; deps = [":c_hello"],)你好.gopackage mainimport "fmt"import "C"//export SayHellofunc SayHello() {&nbsp; &nbsp; fmt.Println("hello")}func main() {}使用.c#include "go_hello.h"int main() {&nbsp; SayHello();&nbsp; return 0;}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go