Стрингер не может генерировать константы со значениями из перечисления C
Я пытаюсь бежать
generate
в проекте CGO https://github.com/libgit2/git2go локально. Я успешно установил системную библиотеку и могу собрать и протестировать проект с помощью
go build -tags static,system_libgit2
а также
go test -tags static,system_libgit2
.
Проблема возникает, когда я пытаюсь создать дополнительные файлы с помощью
stringer
. Код, который я показываю, находится в главной ветке, поэтому я полагаю, что он должен работать правильно, и проблема на моей стороне.
В файле diff.go есть аннотация стрингера (удалены неважные части):
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 enum, часть
/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
Я пробовал запустить эти команды:
-
go generate ./diff.go
-
go generate -tags static,system_libgit2
-
go generate -tags static,system_libgit2 ./diff.go
Но всегда показывает одну и ту же ошибку.
Как правильно сгенерировать файл со стрингером для констант Go со значениями из перечисления C?
1 ответ
работает, просто анализируя исходный код Go с помощью
go.ast
для извлечения необходимых постоянных значений. Значения должны быть целочисленными литералами, указанными на сайте определения (см. Источник).
CGo работает путем создания прокладок Go для кода C. Например, константы C входят в
_cgo_gotypes.go
файл как
const _Ciconst_... = ...
прокладки. (Обычно CGo по завершении удаляет сгенерированные файлы, но вы можете сохранить их, вызвав его явно, например
go tool cgo main.go
)
Что значит
stringer
поскольку теперь у него нет шансов поддерживать константы CGo - по крайней мере, он должен иметь возможность разыменовать по крайней мере на 1 уровень глубже (от
const A = B
к
const B = 123
, в другом файле). Так что пиар приветствуется.