Stringer工具抱怨错误的存档头。

huangapple go评论72阅读模式
英文:

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 (
    &quot;math/rand&quot;
)

//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:

!&lt;arch&gt;
__.PKGDEF       0           0     0     644     2051   

`
while on test machine it has the following header:

!&lt;arch&gt;
__.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 != &quot;__.PKGDEF&quot;

to this:

if name != &quot;__.PKGDEF&quot; &amp;&amp; name != &quot;__.PKGDEF\&quot;

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.

huangapple
  • 本文由 发表于 2015年4月22日 22:04:37
  • 转载请务必保留本文链接:https://go.coder-hub.com/29800079.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定