Golang中cmd/go: go:binary-only-package在Go 1.10版本无法正常工作的问题讨论 #24318

Golang中cmd/go: go:binary-only-package在Go 1.10版本无法正常工作的问题讨论 #24318 我知道问题 #24318 已经关闭,但还没弄清楚如何修复这个问题并能够使用二进制包。

新文档说明:

这些变更带来的一个新要求是:二进制包现在必须在存根源代码中声明准确的导入块,这样在链接使用该二进制包的程序时,这些导入才能可用。

来源:Go 1.10 发布说明 - Go 编程语言

然而,个人觉得这并没有明确说明开发者应该采取什么具体操作,它指向了 go 命令 - cmd/go - Go 包,但我觉得它只是提到了以下内容:

非测试 Go 源文件也可以包含 //go:binary-only-package 注释,表示该包源代码仅用于文档目的,不得用于构建包二进制文件。这使得可以仅以编译形式分发 Go 包。即使是二进制包也需要准确的导入块来列出所需的依赖项,以便在链接最终命令时能够提供这些依赖项。

但没有提示如何理解"准确的导入块",此外二进制包文档没有说明如何将 go/importer 包用于二进制包。

如果有人能提供在 1.10 版本中如何使用它的示例,将不胜感激!谢谢!抱歉带来麻烦。


更多关于Golang中cmd/go: go:binary-only-package在Go 1.10版本无法正常工作的问题讨论 #24318的实战教程也可以访问 https://www.itying.com/category-94-b0.html

2 回复
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/ocu/.cache/go-build"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/home/ocu/octa"
GOPROXY=""
GORACE=""
GOROOT="/usr/local/go"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64"
GCCGO="gccgo"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build660160604=/tmp/go-build -gno-record-gcc-switches"

更多关于Golang中cmd/go: go:binary-only-package在Go 1.10版本无法正常工作的问题讨论 #24318的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


在Go 1.10中,//go:binary-only-package注释要求二进制包必须包含准确的导入块,以便在链接时解析依赖关系。这意味着即使包是预编译的二进制形式,其源文件仍需包含完整的import声明,列出所有依赖包。

以下是一个示例,展示如何正确创建和使用二进制包:

首先,创建一个简单的包mypkg

mypkg.go(源代码形式,用于生成二进制包):

//go:binary-only-package

package mypkg

import (
    "fmt"
    "strings"
)

func Hello() {
    fmt.Println(strings.ToUpper("hello from binary package"))
}

使用以下命令编译该包为二进制形式(假设在Linux amd64环境):

go build -o mypkg.a

现在,分发该包时,需要同时提供编译后的mypkg.a文件和包含准确导入块的源文件mypkg.go。注意源文件中的//go:binary-only-package注释告诉Go工具链不要重新编译此包,而是使用预编译的二进制文件。

在另一个程序中使用此二进制包:

main.go

package main

import "mypkg"

func main() {
    mypkg.Hello()
}

确保二进制包文件mypkg.a位于适当的路径下,例如在$GOPATH/pkg/linux_amd64/目录中,或者通过-o标志指定路径。同时,包含导入块的源文件mypkg.go必须存在于$GOPATH/src/mypkg/目录中,即使它是空的(除了package声明和import块)。

关键点:

  • 二进制包的源文件必须包含所有依赖包的准确import声明(如示例中的fmtstrings)。
  • Go工具链在链接时会读取这些import块来解析依赖,但不会重新编译包。
  • 如果import块不完整或错误,链接阶段将失败,提示缺少依赖。

此机制确保了二进制包在分发后仍能正确链接,而不需要完整的源代码。

回到顶部