Стрингер не может генерировать константы со значениями из перечисления 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, в другом файле). Так что пиар приветствуется.

Другие вопросы по тегам