RPM/Golang
Сборка Golang-пакета c использованием макросов
Сборка на локальном компьютере
Запуск команд 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 .%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