Go modules
Упаковка Go-программ.
На этой странице
Go — язык программирования от Google. Система модулей Go управляет зависимостями и версиями.
Особенности упаковки Go
- Статическая линковка — бинарник самодостаточен
- Go modules — управление зависимостями
- Vendoring — включение зависимостей в репозиторий
- Быстрая компиляция (быстрее Rust)
Признаки Go-проекта
go.mod— описание модуля и зависимостейgo.sum— контрольные суммы зависимостейmain.goилиcmd/— точки входаvendor/— vendor’ные зависимости (опционально)
Подходы к упаковке
1. Vendoring (рекомендуется)
# В исходниках проекта
go mod vendor
2. Скачивание при сборке
Работает с GOPROXY, но не подходит для изолированной сборки.
Полный пример SPEC
%global goipath github.com/junegunn/fzf
%global forgeurl https://github.com/junegunn/fzf
%global commit abc123def
%global shortcommit %(c=%{commit}; echo ${c:0:7})
Name: fzf
Version: 0.46.0
Release: 1%{?dist}
Summary: Command-line fuzzy finder
License: MIT
URL: %{forgeurl}
Source0: %{forgeurl}/archive/v%{version}/%{name}-%{version}.tar.gz
BuildRequires: golang >= 1.21
BuildRequires: git
%description
fzf is a general-purpose command-line fuzzy finder.
%prep
%autosetup -n %{name}-%{version}
%build
export GOPATH=%{_builddir}/go
export GOCACHE=%{_builddir}/go-cache
export GOFLAGS="-mod=vendor"
go build -ldflags "-X main.version=%{version}" -o %{name}
%install
install -Dm 755 %{name} %{buildroot}%{_bindir}/%{name}
# Man-страница
install -Dm 644 man/man1/%{name}.1 %{buildroot}%{_mandir}/man1/%{name}.1
# Автодополнение
install -Dm 644 shell/completion.bash \
%{buildroot}%{_datadir}/bash-completion/completions/%{name}
install -Dm 644 shell/completion.zsh \
%{buildroot}%{_datadir}/zsh/site-functions/_%{name}
install -Dm 644 shell/completion.fish \
%{buildroot}%{_datadir}/fish/vendor_completions.d/%{name}.fish
# Key bindings для bash/zsh
install -Dm 644 shell/key-bindings.bash \
%{buildroot}%{_datadir}/%{name}/key-bindings.bash
install -Dm 644 shell/key-bindings.zsh \
%{buildroot}%{_datadir}/%{name}/key-bindings.zsh
install -Dm 644 shell/key-bindings.fish \
%{buildroot}%{_datadir}/%{name}/key-bindings.fish
%files
%license LICENSE
%doc README.md CHANGELOG.md
%{_bindir}/%{name}
%{_mandir}/man1/%{name}.1*
%{_datadir}/bash-completion/completions/%{name}
%{_datadir}/zsh/site-functions/_%{name}
%{_datadir}/fish/vendor_completions.d/%{name}.fish
%{_datadir}/%{name}/
%changelog
* Mon Feb 03 2025 Your Name <your@email.com> - 0.46.0-1
- Initial package
Подготовка исходников с vendoring
Шаг 1: Клонировать и vendor
git clone https://github.com/user/project
cd project
git checkout v1.0.0
# Создать vendor/
go mod vendor
# Архивировать
cd ..
tar czf project-1.0.0.tar.gz project/
Шаг 2: Или скачать vendor отдельно
# Скачать и создать отдельный vendor-архив
go mod download
go mod vendor
tar cJf project-1.0.0-vendor.tar.xz vendor/
В SPEC:
Source0: %{name}-%{version}.tar.gz
Source1: %{name}-%{version}-vendor.tar.xz
%prep
%autosetup
tar xf %{SOURCE1}
Переменные окружения Go
%build
# Каталог для скачанных модулей
export GOPATH=%{_builddir}/go
# Кеш сборки
export GOCACHE=%{_builddir}/go-cache
# Использовать vendor/
export GOFLAGS="-mod=vendor"
# Отключить скачивание
export GOPROXY=off
go build -o myapp ./cmd/myapp
Флаги сборки
%build
export CGO_ENABLED=0
export GOFLAGS="-mod=vendor -trimpath"
go build \
-ldflags "-s -w -X main.version=%{version}" \
-o %{name} \
./cmd/%{name}
| Флаг | Назначение |
|---|---|
-mod=vendor | Использовать vendor/ |
-trimpath | Удалить пути сборки из бинарника |
-ldflags "-s -w" | Удалить отладочную информацию |
-ldflags "-X main.version=..." | Встроить версию |
CGO
По умолчанию Go использует CGO для некоторых функций. Для полностью статического бинарника:
%build
export CGO_ENABLED=0
go build -o myapp
Если нужен CGO:
BuildRequires: gcc
%build
export CGO_ENABLED=1
export CGO_CFLAGS="%{optflags}"
go build -o myapp
Проекты с несколькими бинарниками
%build
export GOFLAGS="-mod=vendor -trimpath"
for cmd in cmd/*; do
name=$(basename $cmd)
go build -o $name ./$cmd
done
%install
for cmd in cmd/*; do
name=$(basename $cmd)
install -Dm 755 $name %{buildroot}%{_bindir}/$name
done
Макросы Go (Fedora)
В Fedora есть специальные макросы:
BuildRequires: go-rpm-macros
%build
%gobuild -o %{gobuilddir}/bin/myapp ./cmd/myapp
%install
%goinstall
Типичные проблемы
«go: cannot find module»
Проверьте наличие vendor/ или настройку GOFLAGS:
export GOFLAGS="-mod=vendor"
«cannot find package»
Зависимость отсутствует в vendor:
go mod tidy
go mod vendor
«cgo: C compiler not found»
BuildRequires: gcc
# Или отключить CGO
export CGO_ENABLED=0
Бинарник требует GLIBC
Для полностью статического бинарника:
export CGO_ENABLED=0
export GOFLAGS="-mod=vendor"
go build -ldflags "-extldflags '-static'" -o myapp
Тестирование
%check
export GOFLAGS="-mod=vendor"
go test -v ./...
Пропустить определённые тесты:
%check
go test -v ./... -skip TestNetwork
Обновление версии
- Скачать новые исходники
- Обновить зависимости:
go mod tidy - Пересоздать vendor:
go mod vendor - Обновить SPEC
- Пересобрать
Проверьте понимание
- Зачем нужен vendoring для Go-пакетов?
- Что делает флаг
-mod=vendor? - Как отключить CGO?
- Как встроить версию в бинарник?
- Как собрать проект с несколькими командами в
cmd/?
Следующий модуль: ABF и рабочий процесс