RPM/Golang

Материал из ALT Linux Wiki
< RPM

Сборка Golang-пакета c использованием макросов

Примечание: Данный раздел содержит только общие рекомендации, и здесь не ставится цель дать вам всеобъемлющее руководство по сборке пакета на Golang

Сборка на локальном компьютере

Goroot.jpg

Запуск команд go неочевидным образом тесно связан с каталогом /proc. Так, с использованием /proc устанавливается переменная среды GOROOT[1][2], без которой, например, команды go build и go install завершатся ошибкой. При сборке golang-пакетов для ALT Linux это учтено в пакете golang, который включен в rpm-build-golang, строчкой:

Requires: /proc

Таким образом, чтобы собрать golang-пакеты с помощью инструментов hasher локально, необходимо предварительно сконфигурировать hasher следующим образом:

1. В /etc/hasher-priv/system добавим строку:

allowed_mountpoints=/proc

2. Далее при каждой сборке добавляем опцию --mountpoints=/proc для команды hsh или, что рекомендуется, раз и навсегда в файле ~/.hasher/config добавляем строчку:

known_mountpoints=/proc

Вендоринг

В обычных проектах запустите вендоринг, добавьте завендоренные файлы в git-репозиторий:

$ go mod vendor
$ git add vendor -f
$ git commit -m "go mod vendor"

Если в проекте используются несколько golang-модулей и в нем содержится файл go.work, вместо go mod vendor используйте go work vendor.

Spec-файл

Первой строчкой установим глобальную переменную, которая соответствует переменной module из файла go.mod:

%global import_path github.com/prometheus/promu

Ограничим архитектуры сборки:

ExclusiveArch:  %go_arches

Установим сборочные зависимости:

BuildRequires(pre): rpm-build-golang
Примечание: Более идиоматичный способ установить сборочные зависимости:
BuildRequires(pre): rpm-macros-golang
BuildRequires: rpm-build-golang


Секция %build

Из-за того что Makefile golang-проектов часто не учитывает нюансы оффлайн-сборки и многие другие моменты, мы вместо него используем макросы.

Подготовим проект к сборке с помощью макроса %golang_prepare. Он требует в обязательном порядке установить переменные среды BUILDDIR и IMPORT_PATH. При отсутствии какой-либо из них исполнение макроса завершиться с ошибкой.

export BUILDDIR="$PWD/.build"
export IMPORT_PATH="%import_path"

%golang_prepare

Для макроса %golang_build, кроме BUILDDIR, желательно установить ещё одну переменную среды:

export GOPATH="$BUILDDIR:%go_path"

Здесь макрос %go_path раскрывается в путь /usr/share/gocode/. Таким образом, компилятор golang при сборке проекта будет искать исходный код по обоим путям: из $BUILDDIR и %go_path. Иначе, если мы не установим переменную среды GOPATH, по умолчанию она будет содержать только путь $BUILDDIR.

На всякий случай проверьте Makefile проекта и другие файлы, которые учитываются при нативной компиляции в upstream-командой. Там могут быть некоторые нюансы, которые тоже надо учитывать, например, могут использоваться ldflags. В таком случае мы также устанавливаем их через переменную среды (пример из пакета oauth2-proxy):

export LDFLAGS="-X github.com/oauth2-proxy/oauth2-proxy/v7/pkg/version.VERSION=%version"

Далее используем сам макрос, который в качестве аргумента требует указание путей, по которым будет выполняться команда go install:

%golang_build .
Примечание: Обратите внимание, что в качестве аргумента мы передали макросу точку. Например, так сделано в проекте oauth2-proxy. Это значит, что макрос %golang_build сделает условный переход в текущую директорию и после этого запустит команду go install. Макросу можно также передавать несколько путей. Например, в проекте prometheus: go install должна выполнится во всех папках директории cmd, и поэтому мы передаём макросу в качестве аргументов эти директории следующим образом:
%golang_build cmd/*


Секция %install

В секции %install мы дублируем экспорт переменной $BUILDDIR:

export BUILDDIR="$PWD/.build"

Так как мы будем использовать макрос %golang_install, необходимо учитывать, что он по умолчанию стремится сохранить исходники программы по пути, взятому из переменной среды GOPATH. Так как в ALT Linux исходники golang располагаются по пути, раскрывающемуся в макросе %go_path, часто в spec-файлах мы видим следующее:

export GOPATH="%go_path"

Но если мы не собираемся копировать исходники в систему в секции %files, то правильнее отключить поведение по умолчанию, установив переменную среды IGNORE_SOURCES в ненулевое значение:

export IGNORE_SOURCES=1

Таким образом, мы устанавливаем или переменную GOPATH, или IGNORE_SOURCES.

Далее используем макрос:

%golang_install

Примеры пакетов на Golang

Ссылки

  1. [1] - cmd/go: use os.Executable to find GOROOT
  2. [2] - os.Executable использует /proc/self/exe в linux