【问题标题】:Install gccgo for testing Protocol Buffers 3 along with Go安装 gccgo 和 Go 一起测试 Protocol Buffers 3
【发布时间】:2020-03-25 22:22:02
【问题描述】:

我正在尝试安装 gccgo 以使用 Golang 测试 Protocol Buffers 3...我必须承认,我在 8 年后重新开始开发(而且我不是母语人士)所以,谢谢你的放纵。谢谢你:)

所以,经过几次阅读,我决定从这个 repo 的 README 开始:https://github.com/golang/protobuf

第一个要点:检查!

我的 Mac 上安装了协议缓冲区的最后一个版本(protobuf-cpp-3.11.4.tar.gz 据我了解)https://github.com/protocolbuffers/protobuf/releases/tag/v3.11.4

$ ls $GOBIN
dlv*           gocode*        godef*         gopkgs*        protoc-gen-go*
go-outline*    gocode-gomod*  golint*        goreturns*

第二个要点:在这里我花了几个小时......没有成功:/

当然,从https://golang.org/ 安装 Go 编译器和工具见 https://golang.org/doc/install 了解详细信息,或者,如果您使用的是 gccgo,请按照 https://golang.org/doc/install/gccgo 的说明进行操作

我的理解是我需要安装gccgo,它是gcc编译器的一个分支。然后我读到gccgo 实际上只是配置了--enable-languages=c,c++,go 选项(src https://golang.org/doc/install/gccgo)的gcc 编译器的自定义构建......那么为什么在repos 上有一个特殊的分支以及它在哪里? (https://gcc.gnu.org/git.html) 我

我只是放弃尝试从git仓库下载gccgo分支并找到一个svn repo:

$ svn checkout svn://gcc.gnu.org/svn/gcc/branches/gccgo gccgo`
gccgo$ ./configure --enable-languages=c,c++,go
...
configure: error: Building GCC requires GMP 4.2+, MPFR 3.1.0+ and MPC 0.8.0+.
Try the --with-gmp, --with-mpfr and/or --with-mpc options to specify
their locations.  Source code for these libraries can be found at
their respective hosting sites as well as at
<https://gcc.gnu.org/pub/gcc/infrastructure/>.  See also
<http://gcc.gnu.org/install/prerequisites.html> for additional info.  If
you obtained GMP, MPFR and/or MPC from a vendor distribution package,
make sure that you have installed both the libraries and the header
files.  They may be located in separate packages.

所以,我从https://gmplib.org/ 下载了gmp-6.2.0.tar.lz,这导致我在解压缩存档之前安装lzip

$ brew install lzip
$ lunzip gmp-6.2.0.tar.lz
$ tar - xvzf gmp-6.2.0.tar
$ cd gmp-6.2.0
gmp-6.2.0$ ./configure
gmp-6.2.0$ make
gmp-6.2.0$ make install
gmp-6.2.0$ make check ( a few warnings but every test have been passed successfully )

然后,安装mpfr-3.1.6.tar.gz

$ tar -xvzf mpfr-3.1.6.tar.gz
$ cd mpfr-3.1.6
mpfr-3.1.6$ ./configure
mpfr-3.1.6$ ./make
mpfr-3.1.6$ ./make install

...再试一次

gccgo$ ./configure --enable-languages=c,c++,go
...
The following requested languages could not be built: go
Supported languages are: c,brig,c,c++,d,fortran,lto,objc,obj-c++

最后

我不确定他们在最后一步中谈论的目录...

使用“make go”在此目录中构建 Go 示例。这将创建以下可执行文件 当前目录下的文件: add_person_go list_people_go

makegcc 一起引入了一个单独的“规则”文件,它描述了如何从源代码转到完成的程序,解释这个文件,找出需要编译的内容,然后调用gcc . (来源https://stackoverflow.com/a/768379/1216281)。所以,如果 gcc 没有正确编译,它就不能工作。

protocolbuffer$ ls
add_person.go        add_person_test.go   addressbook.proto    list_people_test.go
add_person.go.txt    addressbook.pb.go    list_people.go
protocolbuffer$ make go
make: *** No rule to make target `go'.  Stop.

额外的技术。需要的信息:

~$ echo $GOPATH
/Users/me/Dev/Go/golib:/Users/me/Dev/Go/code
$GOBIN is /Users/me/Dev/Go/golib/bin
$ echo $GOBIN
/Users/me/Dev/Go/golib/bin

【问题讨论】:

  • 您能否澄清一下您的“最终目标”是什么?你想使用go 来玩protobuf 还是特别想使用gccgo 来编译*.go 文件?
  • 嗨@Ilya,我想我把这个过程弄混了,认为gccgo 和Go 编译工具都是需要的。所以,我知道 protoc-gen-go(protobuf 的插件部分)只需要通过检查 $GOBIN 目录找到 Go 编译工具(已经与 Golang 一起安装)。然后,我使用protoc(protobuf 的编译器部分)和选项--go_out=DEST_FOLDER *.proto 编译.protofiles,我就完成了,对吧? (这让我想起了 Java RMI 的过去)
  • 是的,基本上如果你需要在golang中编译一些protobuf示例,你需要做两个主要步骤:使用protoc生成*.pb.go文件,然后使用go build编译示例(标准构建工具)

标签: go gcc


【解决方案1】:

为了在go中编译protobufs,你需要有go compiler和以下包

go get github.com/golang/protobuf
go get github.com/golang/protobuf/proto

如果您的 GOPATH 包含在您的 PATH 环境中,您应该能够从终端执行 protoc 二进制文件。

让我们尝试一个简单的例子。您首先定义一个protobuf 模式,它代表一些对象。它可能看起来像

syntax="proto3";

package main;

message Person {
      string name = 1;
      int32 age = 2;
}

person.proto

下一步是将其编译成 go 源代码,使用 protoc

protoc --go_out=. *.proto

它将生成一个 go 源代码文件,代表您的 proto message 和一个文件 person.pb.go

让我们看看如何在我们的main.go 中使用它

package main

import (
    "fmt"
    "os"

    "github.com/golang/protobuf/proto"
)

func main() {

    p := &Person{
        Name: "John Doe",
        Age:  30,
    }

    data, err := proto.Marshal(p)
    if err != nil {
        fmt.Printf("marshaling error: %v", err)
        os.Exit(1)
    }

  fmt.Printf("our raw protobuf object looks like: %+v\nits type is %T\n", data, data)

  // let's unmarshal it (from byte array) to an object we can use as Person
    newP := &Person{}
    err = proto.Unmarshal(data, newP)
    if err != nil {
        fmt.Printf("unmarshaling error: %v", err)
        os.Exit(1)
  }

  // now we can use our unmarshaled data as a struct
  fmt.Printf("newP name: %v\nnewP age: %v\nnewP type: %T\n", newP.GetName(), newP.GetAge(), newP)

}

让我们运行它

→ go run .
our raw protobuf object looks like: [10 8 74 111 104 110 32 68 111 101 16 30]
its type is []uint8
newP name:  John Doe
newP age:  30
newP type: *main.Person

您可以在 person.pb.go 中查看自动生成的源代码。 希望这会有所帮助。

【讨论】:

  • 感谢您分享这个清晰的示例。我已经找到了我在两者之间缺少的东西,但它仍然很有价值,谢谢你:)
猜你喜欢
  • 2013-06-05
  • 1970-01-01
  • 2018-12-20
  • 1970-01-01
  • 2015-10-26
  • 1970-01-01
  • 2021-09-14
  • 2020-08-15
  • 2011-09-15
相关资源
最近更新 更多