【问题标题】:Bazel go_binary c-shared link mode: Where is the header?Bazel go_binary c-shared链接模式:header在哪里?
【发布时间】:2019-12-04 00:08:05
【问题描述】:

我正在尝试使用 Bazel (v1.0.0) rules_go 来构建头文件 + 库,就像我使用 go build -buildmode=c-archive 一样。我在 BUILD.bzl 文件中设置了以下规则:

go_binary(
   name="go_cpp_bridge",
   srcs = ["cpp_bridge.go"],
   cgo = True,
   gc_linkopts=["-buildmode=c-shared"],
   linkmode = "c-archive",
   visibility = ["//visibility:public"],
 )

cpp_bridge.go的当前代码只是一个hello world,看看是否有效:

package main

import "C"

//export Add
func Add(a, b int) int { return a + b }

func main(){}

Bazel 确实生成了一个库文件,但我在 bazel-bin 输出中缺少相关的头文件。使用 go build 进行测试会产生头文件和库。我如何让巴泽尔给我同样的东西。

【问题讨论】:

    标签: go bazel


    【解决方案1】:

    在定义 linkmode = "c-shared"linkmode = "c-archive" 时,通过在 go_binary 名称的末尾添加后缀来定义一些额外的目标。因此,例如,您可以构建go_cpp_bridge.c_hdrs 来获取头文件。您可以为可与其他 C/C++ 目标链接的 cc_library 构建 go_cpp_bridge.cc。标头以go_binary 规则命名(所以go_cpp_bridge.h)。

    为了扩展您的示例,这是一个有效的构建文件:

    load("@io_bazel_rules_go//go:def.bzl", "go_binary")
    
    go_binary(
        name = "go_cpp_bridge",
        srcs = ["cpp_bridge.go"],
        cgo = True,
        linkmode = "c-archive",
    )
    
    cc_binary(
        name = "main",
        srcs = ["main.c"],
        deps = [":go_cpp_bridge.cc"],
    )
    

    还有一个链接到 Go 的 C 程序:

    #include <stdio.h>
    #include "go_cpp_bridge.h"
    
    int main() {
      printf("%lld\n", Add(21, 21));
      return 0;
    }
    

    这没有记录,因为它不是一个很好的界面。自从实现了这一点,Bazel 已经添加了更好的方法来编写 C/C++ 兼容规则,但 rules_go 还不支持。 #2176 是跟踪问题。

    【讨论】:

    • 感谢您的广泛回答!这看起来很棒。但是,在编译C部分时,仍然找不到头文件,尽管它是在Bazel bin目录中生成的。
    • 好的,解决方案有效,非常好!然而,难题的最后一块是定义包含的正确路径,这将遵循您的工作空间结构。即,如果 main.c 在“foo/bar/”中,那么您需要包含“foo/bar/go_cpp_bridge.h”
    猜你喜欢
    • 1970-01-01
    • 2012-10-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-24
    • 2023-03-30
    相关资源
    最近更新 更多