Stringer 无法使用 C 枚举中的值生成常量

Stringer can't generate constants with values from C enum

我正在本地尝试 运行 generate CGO 项目 https://github.com/libgit2/git2go。我已成功安装 libgit2 系统库,可以使用 go build -tags static,system_libgit2go test -tags static,system_libgit2.

构建和测试项目

当我尝试使用 stringer 生成附加文件时出现问题。我显示的代码位于 master 分支,所以我想它应该可以正常工作,问题出在我这边。

文件diff.go有stringer注释(删除了不重要的部分):

package git
/*
#include <git2.h>

...
*/
import "C"
import (
    "errors"
    "runtime"
    "unsafe"
)

...

type Delta int

const (
    DeltaUnmodified Delta = C.GIT_DELTA_UNMODIFIED
    DeltaAdded      Delta = C.GIT_DELTA_ADDED
    DeltaDeleted    Delta = C.GIT_DELTA_DELETED
    DeltaModified   Delta = C.GIT_DELTA_MODIFIED
    DeltaRenamed    Delta = C.GIT_DELTA_RENAMED
    DeltaCopied     Delta = C.GIT_DELTA_COPIED
    DeltaIgnored    Delta = C.GIT_DELTA_IGNORED
    DeltaUntracked  Delta = C.GIT_DELTA_UNTRACKED
    DeltaTypeChange Delta = C.GIT_DELTA_TYPECHANGE
    DeltaUnreadable Delta = C.GIT_DELTA_UNREADABLE
    DeltaConflicted Delta = C.GIT_DELTA_CONFLICTED
)

//go:generate stringer -type Delta -trimprefix Delta -tags static

...

此类型引用 libgit2 C 枚举,/usr/include/git2/diff.h 的一部分:

/**
 * What type of change is described by a git_diff_delta?
 *
 * `GIT_DELTA_RENAMED` and `GIT_DELTA_COPIED` will only show up if you run
 * `git_diff_find_similar()` on the diff object.
 *
 * `GIT_DELTA_TYPECHANGE` only shows up given `GIT_DIFF_INCLUDE_TYPECHANGE`
 * in the option flags (otherwise type changes will be split into ADDED /
 * DELETED pairs).
 */
typedef enum {
    GIT_DELTA_UNMODIFIED = 0,  /**< no changes */
    GIT_DELTA_ADDED = 1,      /**< entry does not exist in old version */
    GIT_DELTA_DELETED = 2,    /**< entry does not exist in new version */
    GIT_DELTA_MODIFIED = 3,    /**< entry content changed between old and new */
    GIT_DELTA_RENAMED = 4,     /**< entry was renamed between old and new */
    GIT_DELTA_COPIED = 5,      /**< entry was copied from another old entry */
    GIT_DELTA_IGNORED = 6,     /**< entry is ignored item in workdir */
    GIT_DELTA_UNTRACKED = 7,   /**< entry is untracked item in workdir */
    GIT_DELTA_TYPECHANGE = 8,  /**< type of entry changed between old and new */
    GIT_DELTA_UNREADABLE = 9,  /**< entry is unreadable */
    GIT_DELTA_CONFLICTED = 10, /**< entry in the index is conflicted */
} git_delta_t;

当我 运行 命令 go generate 时出现错误:

stringer: can't happen: constant is not an integer DeltaUnmodified
diff.go:43: running "stringer": exit status 1

我尝试运行这些命令:

但它总是显示相同的错误。

如何使用 C 枚举中的值为 Go 常量正确生成带有 stringer 的文件?

stringer 只需 parsing Go source with go.ast to extract the needed constant values. The values must be integer literals specified at the definition site (see source).

CGo 通过为 C 代码生成 Go shim 来工作。例如,C 常量作为 const _Ciconst_... = ... 垫片进入 _cgo_gotypes.go 文件。

通常 CGo 会在完成后删除生成的文件,但您可以通过显式调用它来保留它们,例如go tool cgo main.go.

所以你应该可以这样做:

go tool cgo main.go
mv _obj/_cgo_gotypes.go _obj/cgo_gotypes.go
stringer -type Delta -trimprefix Delta ./_obj
cp _obj/delta_strings.go .