为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Go
宝慕林4294392 2022-07-11 10:49:11
我已经切换(或正在切换)使用 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"],)
查看完整描述

2 回答

?
慕哥9229398

TA贡献1877条经验 获得超6个赞

好吧,我想我需要在耻辱立方体里坐一会儿。

在我为编译器寻找的所有选项中,我错过了检查go_binary. 具体来说,显而易见的,out. 实际对应于-o标志的那个go build

我添加out = "awesome.so"了我的go_binary规则,果然,一切正常。

好吧,这浪费了几个小时。感谢杰伊试图提供帮助,很抱歉问了一个愚蠢的问题。


查看完整回答
反对 回复 2022-07-11
?
慕姐4208626

TA贡献1852条经验 获得超7个赞

这可能无法准确回答您的问题,但我可以举一个从 macOS 上的 C 程序调用 Go 共享库的示例。希望这可以让你大部分时间都在那里。

  • 对于go_binary,您只需要linkmode = "c-shared". 您还需要cgo = True包含 cgo 代码或已导出定义的每个包。您不需要-shared,-fPICstatic = "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 函数,尽管我从未尝试过。

构建.bazel

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


go_binary(

    name = "go_hello",

    srcs = ["hello.go"],

    cgo = True,

    linkmode = "c-shared",

)


cc_import(

    name = "c_hello",

    hdrs = [":go_hello.c_hdrs"],

    shared_library = ":go_hello",

)


cc_binary(

    name = "use",

    srcs = ["use.c"],

    deps = [":c_hello"],

)

你好.go


package main


import "fmt"

import "C"


//export SayHello

func SayHello() {

    fmt.Println("hello")

}


func main() {}

使用.c


#include "go_hello.h"


int main() {

  SayHello();

  return 0;

}


查看完整回答
反对 回复 2022-07-11
  • 2 回答
  • 0 关注
  • 185 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号