Собираем GTK3 приложения на Go для Windows прямо из Linux: Обходим ошибки в Docker
Вы создали крутое приложение на Go с красивым интерфейсом на GTK3, и оно отлично работает в Linux. Но как только вы пытаетесь собрать его для Windows, вас встречает стена непонятных ошибок. Знакомо? `fatal error: libintl.h: No such or directory` — это лишь цветочки.
Вам не нужно переходить на Windows или часами искать волшебные библиотеки. Есть способ проще и надежнее. Мы покажем вам, как обернуть этот хаотичный процесс в аккуратный контейнер Docker.
Забудьте о проблемах с зависимостями в Ubuntu и настройке Mingw. Вы сможете получать готовый `.exe` файл для Windows, не покидая свой любимый Linux-дистрибутив. Всё, что вам нужно, — это несколько команд в терминале.
Мы подготовили для вас пошаговое руководство и готовый Dockerfile, который уже настроен и содержит все необходимые компоненты. Вам не придется вручную исправлять сломанный `glibc` или искать ключи для `pacman`. Мы уже прошли этот путь и устранили все подводные камни.
Хотите быстро и без головной боли компилировать свои Go-приложения для пользователей Windows? Тогда переходите к полной статье и забудьте о проблемах кросскомпиляции навсегда!
Библиотека Gotk3 - это набор биндингов инструмента создания графических приложений GTK3, популярного в Linux для языка программирования GoLang. В Linux для Linux всё собирается быстро и без каких-либо ошибок. Но программы на Golang кроссплатформенные, их можно собирать также и для Windows и тут возникают проблемы.
Поднять всё необходимое окружение в Windows занимает время, а в Ubuntu возникает море ошибок во время компиляции. Например, ошибка fatal error: libintl.h: No such file or directory. Она означает, что у GoLang проблемы с поиском нужных заголовочных файлов языка Си. Но такой проблемы нет в ArchLinux. В этой статье я поделюсь способом как выполнять кросскомпиляцию Gotk3 приложений для Windows в Docker контейнере ArchLinux.
Кросскомпиляция Gotk3 приложений для Windows в Linux
Для кросскомпиляции можно использовать последний образ ArchLinux с DockerHub. Время от времени там появляются ошибки и после загрузки образа вам надо будет их исправить. Сначала загрузите образ и запустите контейнер, пробросив в него с помощью volume монтирования папку со своим проектом. Например, в папку /project:
docker run -it --rm -v ~/go/src/KeywordsMixer/:/project archlinux/archlinux bash
Опция --rm позволяет удалить контейнер после выхода из него, чтобы он не занимал место на диске. В свежем образе ArchLinux есть проблема с glibc, из-за неё не работает pacman. Для исправления выполните такую команду:
patched_glibc=glibc-linux4-2.33-4-x86_64.pkg.tar.zst &&
curl -LO "https://repo.archlinuxcn.org/x86_64/$patched_glibc" &&
bsdtar -C / -xvf "$patched_glibc"
Время от времени возникают проблемы с ключами. Это не рабочая система, поэтому я предпочитаю просто отключить верификацию пакетов чтобы каждый раз не искать решение этой проблемы. Для этого в секции [options] файла /etc/pacman.conf измените значение параметра SigLevel на Never:
vim /etc/pacman.conf
[options]
SigLevel = Never
Дальше обновите базу данных пакетов:
pacman -Sy
Установите необходимые пакеты:
pacman -S git go vim mingw-w64-gcc cairo pango pkg-config gtk3
Ещё нам понадобится один пакет из AUR. Для его загрузки добавьте такую секцию в /etc/pacman.conf:
vim /etc/pacman.conf
[ownstuff]
SigLevel = Never
Server = http://martchus.no-ip.biz/repo/arch/$repo/os/$arch
Затем установите пакет:
pacman -S mingw-w64-gtk3
Обратите внимание, что в последней версии Golang уже включены модули Go. Если ваш проект ещё их не испольует, придется начать использовать. Настроить модули и зависимости проекта лучше в вашей рабочей системе и проверить что всё верно собирается для Linux. Версию gotk3 стоит брать из ветки master, потому что более старые версии не собираются с этой версией языка:
got get github.com/gotk3/gotk3 master
Дальше перейдите в папку с проектом и выполните команду сборки:
cd /project
CGO_CFLAGS_ALLOW=".*" CGO_LDFLAGS_ALLOW=".*"
PKG_CONFIG_PATH=/usr/x86_64-w64-mingw32/lib/pkgconfig CC=x86_64-w64-mingw32-gcc CGO_ENABLED=1
GOOS=windows GOARCH=amd64 go build -v -tags gtk_3_24 -gcflags "-N -l" -ldflags "-s -w -H=windowsgui" -o main-windows-amd64.exe main.go
Сборка может занять довольно продолжительное время, но после её завершения вы увидите готовый файл в папке проекта:

Для того чтобы не делать все выше перечисленные действия каждый раз я подготовил Dockerfile. Он работает на данный момент, но будет ли работать в будущем не известно, возможно вам его придется немного поправить:
vi Dockerfile
FROM archlinux/archlinux
RUN patched_glibc=glibc-linux4-2.33-4-x86_64.pkg.tar.zst &&
curl -LO "https://repo.archlinuxcn.org/x86_64/$patched_glibc" &&
bsdtar -C / -xvf "$patched_glibc"
RUN sed 's/SigLevel = Never/SigLevel = Never/g' /etc/pacman.conf
RUN pacman -Syu --noconfirm
RUN pacman -S git go mingw-w64-gcc cairo pango pkg-config gtk3 --noconfirm
RUN pacman -S vim --noconfirm
RUN echo "[ownstuff]" >> /etc/pacman.conf
RUN echo "SigLevel = Never" >> /etc/pacman.conf
RUN echo ''Server = http://martchus.no-ip.biz/repo/arch/$repo/os/$arch'' >> /etc/pacman.conf
RUN pacman -Sy --noconfirm
RUN pacman -S mingw-w64-gtk3 --noconfirm
Для сборки образа достаточно создать пустую папку, поместить в неё этот Dockerfile и выполнить такую команду:
docker build .
В конце команда выведет идентификатор нового контейнера:

Затем можно запустить контейнер на основе полученного образа командой:
docker run -it --rm -v ~/go/src/KeywordsMixer/:/project 028451c45c15 bash
Дальше всё можно сразу же переходить в папку проекта и выполнять компиляцию, никаких компонентов устанавливать не надо, все они уже установлены в образе.