英文:
Stringer tool complains about wrong archive header
问题
我正在尝试使用go generate/stringer (golang.org/x/tools/cmd/stringer
) 为枚举类型生成String()方法。我遇到了问题,我认为这是因为不同系统上.a包的格式略有不同。我有以下文件:
package main
import (
"math/rand"
)
//go:generate stringer -type=Foo
type Foo int;
const (
FooPrime Foo = iota
FooBis
)
func main() {
//Just use rand anywhere, otherwise we get a compiler error
rand.Seed(1)
}
在我的机器上运行go generate example.go
一切正常:生成了foo_string.go
文件。然而,在测试机器上我得到了以下错误:
stringer: checking package: example.go:4:2: could not import math/rand (reading export data: /usr/lib64/go/pkg/linux_amd64/math/rand.a: go archive is missing __.PKGDEF)
经过一些代码调查,我认为我得到这个错误是因为在我的机器上,rand.a
文件有以下头部:
!<arch>
__.PKGDEF 0 0 0 644 2051
而在测试机器上,它有以下头部:
!<arch>
__.PKGDEF/ 0 399 399 100644 2051
我认为关键的区别是在PKGDEF后面的斜杠。如果.a文件没有__.PKGDEF头部,gcimporter将拒绝处理该文件。
为了验证这一点,我手动编辑了gcimporter/exportdata.go
文件,并将其中一行更改为:
if name != "__.PKGDEF"
改为:
if name != "__.PKGDEF" && name != "__.PKGDEF\""
在进行了这个更改之后(并重新编译和安装了所有内容),我能够在example.go
上运行go generate
。
我的问题是:为什么会出现这个问题,以及如何摆脱这个问题(除了手动编辑外部库)?
英文:
I am trying to use go generate/stringer (golang.org/x/tools/cmd/stringer
) to generate String() methods on enums. I have problems, which I believe, are because of slightly different format of .a packages on different systems. I have this file:
package main
import (
"math/rand"
)
//go:generate stringer -type=Foo
type Foo int;
const (
FooPrime Foo = iota
FooBis
)
func main() {
//Just use rand anywhere, otherwise we get a compiler error
rand.Seed(1)
}
Now if I run go generate example.go on my machine everything is all right: foo_string.go is created. However, on a test machine I get:
stringer: checking package: example.go:4:2: could not import math/rand (reading export data: /usr/lib64/go/pkg/linux_amd64/math/rand.a: go archive is missing __.PKGDEF)
Now, after some digging in the code I think that I get this error, because on my machine rand.a has the following header:
!<arch>
__.PKGDEF 0 0 0 644 2051
`
while on test machine it has the following header:
!<arch>
__.PKGDEF/ 0 399 399 100644 2051
`
I think that the crucial difference is slash after PKGDEFF. gcimporter refuses to process .a file, if it doesn't have __.PKGDEF header.
To check this, I edited manually gcimporter/exportdata.go and changed one of the line from this:
if name != "__.PKGDEF"
to this:
if name != "__.PKGDEF" && name != "__.PKGDEF\"
After this change (and compiling and installing everything) I was able to run go generate on example.go.
My questions are: why do I get this problem and how do I get rid of it (other then manually editing external library)?
答案1
得分: 3
从 openSUSE 的打包规范中可以看出,他们在更新时禁用了标准库的重新安装。__.PKGDEF 是一个 Go 专用的信息部分,而 openSUSE 使用的某个链接器产生了不兼容的输出。
除了从官方来源安装一个健康的 Go,你无法做任何事情。
英文:
What I can see from the spec for openSUSE's packaging they are disabling reinstallation of the standard library at updates. __.PKGDEF is a Go specific informational section, and some linker OpenSUSE has used has simply produced incompatible output.
There's nothing you can do except install a healthy Go from the official source.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论