使用 bazel 使用 cgo 构建并 运行 Go

Build and run Go using cgo using bazel

page 上有简单的 cgo 项目可用。它依赖于预构建的 c 共享库,并且在使用 go build 时效果很好,只需稍作改动即可构建。

我想用 Bazel 做同样的事情。

使用的源代码与此 github link 上的相同,未使用 hello.c 文件。 综上所述,最终代码如下所示。

/*
 * person.c
 * Copyright (C) 2019 Tim Hughes
 *
 * Distributed under terms of the MIT license.
 */

#include <stdlib.h>
#include "person.h"

APerson *get_person(const char *name, const char *long_name)
{

    APerson *fmt = malloc(sizeof(APerson));
    fmt->name = name;
    fmt->long_name = long_name;

    return fmt;
};
/*
 * person.h
 * Copyright (C) 2019 Tim Hughes
 *
 * Distributed under terms of the MIT license.
 */

#ifndef PERSON_H
#define PERSON_H

typedef struct APerson
{
    const char *name;
    const char *long_name;
} APerson;

APerson *get_person(const char *name, const char *long_name);

#endif /* !PERSON_H */

package main

/*
#cgo CFLAGS: -g -Wall
#cgo LDFLAGS: -L. -lperson
#include "person.h"
*/
import "C"

import (
    "github.com/kubernetes/klog"
)

type (
    Person C.struct_APerson
)

func GetPerson(name string, long_name string) *Person {
    return (*Person)(C.get_person(C.CString(name), C.CString(long_name)))
}

func main() {
    klog.Info("it is running")
    var f *Person
    f = GetPerson("tim", "tim hughes")
    klog.Infof("Hello Go world: My name is %s, %s.\n", C.GoString(f.name), C.GoString(f.long_name))
}

Bazel 构建文件如下。

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

go_library(
    name = "listing_lib",
    srcs = [
        "person.c",
        "person.h",
        "runner.go",
    ],
    cgo = True,
    clinkopts = ["-Lpersons/listing -lperson"],
    copts = ["-g -Wall"],
    importpath = "github.com/example/project/persons/listing",
    visibility = ["//visibility:private"],
    deps = ["@com_github_kubernetes_klog//:klog"],
)

go_binary(
    name = "listing",
    embed = [":listing_lib"],
    visibility = ["//visibility:public"],
)

通过运行 bazelisk build //persons/listing构建时仍然发生错误,这是一般链接器错误。

/usr/bin/ld.gold: error: cannot find -lperson
collect2: error: ld returned 1 exit status
compilepkg: error running subcommand /usr/bin/gcc: exit status 1

我需要清理一些东西。

are c libraries built automatically? My assumption is that those are not.

为什么?官方回购的测试表明,它是 done automatically

is it possible to use cc_library rule to build shared library that can be used in cgo? if so, how to connect those?

参见 here

中的示例