Сборка исполняемых файлов Go для различных платформ в Ubuntu 16.04
Язык программирования Go поставляется с богатым набором инструментов, что значительно упрощает создание пакетов и исполняемых файлов. Одной из самых мощных функций Go является возможность перекрестной сборки исполняемых файлов для любой платформы, поддерживаемой Go. Это облегчает тестирование и распространение пакетов, потому что для этого не нужно иметь доступ к определенной платформе.
Данное руководство научит пользоваться инструментами Go, получать пакеты из контроля версий и устанавливать исполняемые файлы автоматически и вручную. Также вы узнаете, как собирать исполняемые файлы для различных архитектур и автоматизировать процесс сборки (например, для Windows и macOS).
Требования
- Сервер Ubuntu 16.04.
- Пользователь с доступом к sudo.
- Настроенный брандмауэр (читайте руководство по начальной настройке).
- Установленный Go (инструкции можно найти в этом руководстве).
1: Установка программ Go из контроля версий
Прежде чем начать создавать исполняемые файлы из пакета Go, необходимо получить его исходный код. Инструмент go get может извлекать пакеты из систем управления версиями, таких как GitHub. Команда go get клонирует пакеты в подкаталоги $GOPATH/src/. Затем, если это возможно, она устанавливает пакет, создавая его исполняемый файл и помещая его в каталог $GOPATH/bin.
Если вы настроили Go, как описано в этом руководстве, каталог $GOPATH/bin включен в переменную окружения $PATH; это значит, что вы можете использовать установленные пакеты из любой точки системы.
go get package-import-path
где строка package-import-path – уникальный идентификатор пакета. Часто это местонахождение пакета в удаленном репозитории типа Github или подкаталог $GOPATH/src/ на локальной машине.
В команде go get часто используется флаг –u, который загружает зависимости (или обновляет их, если они уже есть на машине).
Для примера попробуйте установить Caddy, веб-сервер, написанный на Go.
Согласно инструкциям Caddy в качестве пути можно использовать github.com/mholt/caddy/caddy. Установите Caddy с помощью go get.
go get -u github.com/mholt/caddy/caddy
На установку уйдет некоторое время. Отсутствие вывода указывает, что команда выполнена успешно.
Когда команда будет выполнена, вы найдете исходный код Caddy в $GOPATH/src/github.com/mholt/caddy. Кроме того, у Caddy есть исполняемый файл, который создается автоматически и хранится в каталоге $GOPATH/bin. Проверьте наличие этого файла.
which caddy
/home/8host/work/bin/caddy
Примечание: Команда go get устанавливает пакеты из стандартной ветки репозитория Git, обычно это ветка master. Ознакомьтесь с инструкциями по работе с пакетом в файле README.
Чтобы выбрать другую ветку, используйте команду git checkout.
2: Сборка исполняемого файла
Команда go get загрузила исходный код и установила исполняемый файл Caddy. Если вы хотите пересобрать исполняемый файл или собрать его из собственного кода, используйте команду go build.
Хотя веб-сервер Caddy уже установлен, попробуйте собрать его вручную, чтобы ознакомиться с этим процессом.
go build github.com/mholt/caddy/caddy
Как и ранее, отсутствие вывода означает, что команда была выполнена успешно. Исполняемый файл будет сгенерирован в текущем каталоге и унаследует его имя. В этом случае исполняемый файл будет называться caddy.
Если вы находитесь в каталоге пакета, вы можете опустить путь к пакету и просто запустить go build.
Чтобы указать другое имя или место для исполняемого файла, используйте флаг -o. Попробуйте создать исполняемый файл caddy-server и поместить его в каталог build в текущем рабочем каталоге:
go build -o build/caddy-server github.com/mholt/caddy/caddy
Команда создаст исполняемый файл и каталог ./build (если его не существует).
3: Установка исполняемых файлов
Процесс сборки создает исполняемый файл в текущем (или в другом) каталоге. Установка исполняемого файла – это процесс создания исполняемого файла и его сохранения в $GOPATH/bin. Команда go install работает так же, как go build, но размещает выходной файл в нужном месте.
Чтобы установить исполняемый файл, укажите в команде go install путь импортируемого пакета. Например:
go install github.com/mholt/caddy/caddy
Исполняемый файл наследует имя каталога, в котором хранится пакет. На этот раз исполняемый файл хранится в $GOPATH/bin. Если $GOPATH/bin указан в переменной окружения $PATH, исполняемый файл будет доступен из любой точки вашей операционной системы. Вы можете проверить его местоположение:
which caddy
/home/8host/work/bin/caddy
Вы ознакомились с базовыми командами Go. Теперь рассмотрим одну из самых популярных функций Go: создание исполняемых файлов для различных платформ.
4: Создание исполняемых файлов для разных архитектур
Команда go build позволяет собирать на вашей платформе исполняемые файлы для любой целевой платформы, которую поддерживает Go. Это означает, что вы можете тестировать, выпускать и распространять свое приложение, не создавая эти исполняемые файлы на целевых платформах, которые вы хотите использовать.
Кросскомпиляция работает путем установки необходимых переменных среды, которые определяют целевую операционную систему и архитектуру. Переменная GOOS определяет целевую операционную систему, а GOARCH – целевую архитектуру. Чтобы создать исполняемый файл, нужно запустить такую команду:
env GOOS=target-OS GOARCH=target-architecture go build package-import-path
Команда env запускает программу в измененной среде. Это позволяет использовать переменные среды только для текущего выполнения команды. После выполнения команды переменные будут сброшены или переустановлены.
В этой таблице вы найдете возможные комбинации GOOS и GOARCH
GOOS – целевая ОС | GOARCH – целевая платформа |
android | arm |
darwin | 386 |
darwin | amd64 |
darwin | arm |
darwin | arm64 |
dragonfly | amd64 |
freebsd | 386 |
freebsd | amd64 |
freebsd | arm |
linux | 386 |
linux | amd64 |
linux | arm |
linux | arm64 |
linux | ppc64 |
linux | ppc64le |
linux | mips |
linux | mipsle |
linux | mips64 |
linux | mips64le |
netbsd | 386 |
netbsd | amd64 |
netbsd | arm |
openbsd | 386 |
openbsd | amd64 |
openbsd | arm |
plan9 | 386 |
plan9 | amd64 |
solaris | amd64 |
windows | 386 |
windows | amd64 |
Важно! Для кросскомпиляции исполняемых файлов для Android требуется Android NDK, а также некоторые дополнительные настройки, которые не входят в данное руководство.
Используя значения в таблице, можно построить Caddy для 64-битной системы Windows:
env GOOS=windows GOARCH=amd64 go build github.com/mholt/caddy/caddy
Исполняемый файл будет создан в текущем каталоге и унаследует имя пакета. Поскольку этот исполняемый файл предназначен для Windows, имя заканчивается суффиксом .exe.
Файл caddy.exe появится в текущем каталоге, это можно проверить с помощью команды ls.
ls caddy.exe
caddy.exe
Примечание: С помощью флага –о можно переименовать или переместить исполняемый файл. Переименовывая исполняемые файлы для Windows, не забудьте добавить суффикс .exe.
5: Сценарий для автоматической кросскомпиляции
Процесс создания исполняемых файлов для многих платформ может занять немало времени и сил, но его можно автоматизировать с помощью сценария.
Сценарий будет принимать путь импортируемого пакета в качестве аргумента, перебирать предопределенный список пар операционных систем и платформ и генерировать исполняемый файл для каждой пары, помещая вывод в текущий каталог. Каждый исполняемый файл будет наследовать имя пакета, а также указывать целевую платформу и архитектуру. Этот универсальный сценарий можно использовать в любом проекте.
Перейдите в домашний каталог и создайте файл go-executable-build.bash.
Начните сценарий с последовательности шебанг (символов #!). Эта строка определяет интерпретатор, спомощью которого будет запускаться исполняемый файл (в данном случае это будет bash).
Используйте путь импортируемого пакета как аргумент командной строки. Для этого можно использовать переменную $n, где n – неотрицательное число. Переменная $0 содержит имя выполненного сценария, а $1 и выше будут содержать аргументы, предоставленные пользователем. Добавьте эту строку в сценарий, который возьмет первый аргумент из командной строки и сохранит его в переменной package:
Затем нужно сделать так, чтоб пользователь предоставил это значение. Если значение не будет указано, сценарий прекратит работу и выведет сообщение с объяснением, как использовать сценарий:
.
if [[ -z «$package» ]]; then
echo «usage: $0
Оператор if проверяет значение переменной $package. Если он не установлен, сценарий выведет сообщение с помощью echo, а затем прекратит работу с помощью exit. Exit принимает возвращаемое значение в качестве аргумента (0, если выполнение прошло успешно, и любое ненулевое значение, если во время исполнения произошла ошибка). Поскольку сценарий не был выполнен успешно, используйте 1.
Примечание: Если вы хотите, чтобы этот сценарий работал с предопределенным пакетом, измените переменную package и укажите путь к пакету:
Затем нужно извлечь из пути имя пакета. Путь импортируемого пакета разделяется слешами (/), а имя пакета находится в самом конце. Для начала нужно преобразовать путь в массив с помощью разделителя /.
Имя пакета должно быть последним элементом нового массива $package_split. В Bash можно использовать отрицательный индекс массива, чтобы получить доступ к данным с конца, а не с начала. Добавьте эту строку, чтобы извлечь имя пакета из массива и сохранить его в переменной package_name:
Теперь нужно решить, для каких платформ и архитектур необходимо создавать исполняемые файлы. В этом примере показано, как создать исполняемые файлы для 64-битной MacOS, 64-битной и 32-битной системы Windows. Поместите целевые платформы в массив согласно формату OS/Platform. Каждую пару можно разделить на переменные GOOS и GOARCH, используя тот же метод, который использовался для извлечения имени пакета из пути. Добавьте платформы в сценарий:
.
platforms=(«windows/amd64» «windows/386» «darwin/amd64»)
Затем нужно выполнить итерацию массива платформ и разделить каждую запись на значения для переменных среды GOOS и GOARCH; их можно использовать для создания исполняемого файла. Для этого добавьте цикл for:
Переменная platform будет содержать запись из массива platforms в каждой итерации. Теперь нужно разделить значение platform на две переменные – GOOS и GOARCH. Добавьте следующие строки в цикл for:
Затем сгенерируйте имя исполняемого файла, объединив имя пакета с ОС и архитектурой. Файлы для Windows должны содержать суффикс .exe. Добавьте этот код в цикл for:
Установив переменные, можно использовать команду go build для создания исполняемого файла. Добавьте эту строку в тело цикла for перед ключевым словом done:
.
if [ $GOOS = «windows» ]; then
output_name+=’.exe’
fi
env GOOS=$GOOS GOARCH=$GOARCH go build -o $output_name $package
done
Наконец, нужно обеспечить обработку ошибок при создании исполняемого файла. Например, Go может столкнуться с ошибкой, если попытается создать пакет, для которого нет исходного кода. Можно проверить код возврата команды go build для ненулевого значения. Переменная $? содержит код возврата выполнения предыдущей команды. Если go build возвращает 0, значит, возникла проблема и сценарий прекратит работу. Добавьте этот код в цикл for, после команды go build и перед done.
.
env GOOS=$GOOS GOARCH=$GOARCH go build -o $output_name $package
if [ $? -ne 0 ]; then
echo ‘An error has occurred! Aborting the script execution. ‘
exit 1
fi
Теперь у вас есть сценарий, который будет собирать разные исполняемые файлы из пакетов Go. Вот полный код сценария:
#!/usr/bin/env bash
package=$1
if [[ -z «$package» ]]; then
echo «usage: $0
»
exit 1
fi
package_split=($
package_name=$
for platform in «$
do
platform_split=($
GOOS=$
if [ $GOOS = «windows» ]; then
output_name+=’.exe’
fi
env GOOS=$GOOS GOARCH=$GOARCH go build -o $output_name $package
if [ $? -ne 0 ]; then
echo ‘An error has occurred! Aborting the script execution. ‘
exit 1
fi
done
Убедитесь, что ваш сценарий выглядит так же. Сохраните и закройте файл.
Сделайте сценарий исполняемым:
chmod +x go-executable-build.bash
Протестируйте работу сценария. Соберите исполняемый файл для Caddy:
Если сценарий выполнен правильно, в текущем каталоге появятся исполняемые файлы. Отсутствие вывода означает, что сценарий выполнен успешно. Проверьте исполняемые файлы:
ls caddy*
caddy-darwin-amd64 caddy-windows-386.exe caddy-windows-amd64.exe
Чтобы изменить целевые платформы, измените значение переменной platforms.
Заключение
Теперь вы умеете пользоваться базовыми командами Go и выполнять кросскомпиляцию исполняемых файлов.
Кроме того, у вас есть сценарий, который можно использовать для автоматической кросскомпиляции одного пакета для нескольких платформ.
Чтобы убедиться, что приложение работает правильно, вы можете использовать Travis-CI и AppVeyor для тестирования в Windows.
Источник