golang

Описание: Разработка и отладка приложений. Упор на 3D-графику.

dyvniy M
Автор темы, Администратор
Администратор
Аватара
dyvniy M
Автор темы, Администратор
Администратор
Возраст: 41
Репутация: 1
Лояльность: 1
Сообщения: 3579
Зарегистрирован: Ср, 10 октября 2012
С нами: 11 лет 5 месяцев
Профессия: Программист
Откуда: Россия, Москва
ICQ Сайт Skype ВКонтакте

#7 dyvniy » Вт, 5 сентября 2017, 14:18:01

Готовим сборку Go-приложения в продакшн
https://habrahabr.ru/post/337158/.com
Спойлер
В июне на конференции РИТ++ мы с коллегой Игорем Должиковым делились опытом автоматизации процесса разработки сервисов на Go — от первого коммита и до релиза в продакшн-окружение Kubernetes (да-да, видео начинается с 07:16, и нам тоже это не нравится). С момента публикации мастер-класса время от времени я получаю вопросы по тем или иным темам, затронутым в нем. Пожалуй, самые горячие вопросы достойны отдельного рассмотрения, и сегодня я хотела бы поговорить о процессе сборки приложения. Затрагиваемые темы актуальны не только при подготовке сервисов, но и вообще для любых приложений, написанных на Go.

Всё, что описано в этой статье, актуально для текущей версии Go — 1.9.

Заветный GOPATH и расположение кода

При подготовке приложения к продакшн нужно быть максимально уверенным в том, что в сборку попадёт именно тот код, который ожидает разработчик. По умолчанию Go по-прежнему не умеет работать с управлением зависимостями, а значит, при компиляции приложения все “внешние” зависимости инструменты Go будут искать внутри директории $GOPATH/src. Как узнать текущее значение GOPATH, если вы в нем не уверены? Это значение можно найти в списке переменных, выводимых командой go env.

Кроме того, код самого проекта также должен находиться внутри $GOPATH/src, и я рекомендую заранее продумать путь, по которому он будет лежать. Когда проект окажется под управлением системы контроля версий, при его затягивании с использованием, например, команды go get, он должен попадать именно по тому пути, который мы определили для проекта изначально. Например, код сервиса, который хранится в моем гитхаб-аккаунте в репозитории rumyantseva/mif развернут у меня внутри $GOPATH/src/github.com/rumyantseva/mif. Если бы этот же код лежал внутри репозитория mif некоторого закрытого хранилища example.com в неймспейсе services, то путь к нему на машине разработчика выглядел бы, скорее всего, как $GOPATH/src/example.com/services/mif. Для того, чтобы избежать в будущем проблем или неоднозначностей, правило расположения кода необходимо соблюдать.

Разные проекты можно хранить как внутри одной и той же директории GOPATH, так и внутри нескольких. Соответственно, во втором случае значение GOPATH придется переопределять. Для того, чтобы сделать это, необходимо будет переустановить соответствующую переменную окружения в нужное вам значение. В случае, если GOPATH не задан вообще, Go будет считать рабочим каталогом директорию go, находящуюся в домашнем каталоге пользователя. Чтобы лучше в этом всём разобраться, проведем несколько экспериментов с консолью:

Разбираемся с GOPATHОднако, если идея GOPATH вам всё же не по вкусу, можно обратиться к таким инструментам, как gb, который позволяет проводить сборки вне зависимости от расположения кода.

Работа с внешними зависимостями

Итак, в случае, если мы пишем приложение, использующее внешние (относительно текущего репозитория) зависимости, для успешной сборки нам необходимо, чтобы все эти зависимости находились внутри GOPATH. Притянуть зависимости автоматически можно с помощью вызова таких команд, как go get или go install внутри текущего рабочего проекта. При этом мы скачаем код зависимостей, находящихся в дефолтных ветках репозиториев. Этого достаточно для ситуации «здесь и сейчас», но в общем случае никто не гарантирует, что через 5 минут в тех же самых ветках внешних зависимостей не появятся обратно-несовместимые изменения. А значит, следующая попытка развернуть приложение (например, на билд-машине) может закончиться провалом. Что нам поможет в этой ситуации? Конечно же, вендоринг.

Про директорию vendor неоднократно писали и на Хабре, и много где еще, и повторяться я не буду. Однако, кратко напомню, что все те же зависимости, которые мы притягивали в GOPATH/src, можно сложить и в директорию vendor текущего приложения. Как это сделать? Или вручную, или с помощью менеджера управления зависимостями. В качестве примера утилиты для работы с зависимостями наконец-то можно упомянуть dep, официальный эксперимент Go. Несмотря на статус «официального эксперимента» dep по-прежнему не является ни абсолютно стабильным, ни рекомендуемым. Тем не менее, мы рискнули попробовать dep в наших рабочих проектах, и нам понравилось! Если вы впервые сталкиваетесь с вопросом управления зависимостями, я очень рекомендую вам десятиминутное видео с конференции Gophercon 2017, в котором подробно и наглядно показаны принципы работы dep.

Итак, по итогам использования менеджера управления зависимостями, мы получили директорию vendor, полную пакетов, и некоторый набор метафайлов, описывающих наши зависимости. Казалось бы, метафайлов с описанием используемых тегов и даже хэшей коммитов нам достаточно, и естественным желанием было бы убрать директорию vendor из-под управления системы контроля версий. Однако, в настоящих продакшн-проектах, не стоит этого делать. Хранение кода вместе с vendor — единственный путь защиты от таких аварий, как падение гитхаба или полное удаление своего репозитория сторонним разработчиком.

Версионирование бинарников

Пожалуй, почти все популярные консольные утилиты поддерживают команду или флаг version, позволяющую вывести информацию о текущий версии бинарника. Эта же практика может пригодиться и в случае с запущенным сервисом. Кроме того, иногда бывает полезно «зашить» в бинарник не только информацию о семантической версии, но и хэш коммита, дату сборки и другие полезные данные.

Подобную информацию удобно хранить в виде констант (или переменных — по вкусу), например, в специальном пакете. А при вызове линкера с флагом -X, мы сможем автоматически подменить значения этих констант или переменных.

Небольшой пример. Создадим файл hello.go с таким содержимым:

package main

import "fmt"

var hello = "Hello"
var world = "World"

func main() {
fmt.Printf("%s, %s!\n", hello, world)
}


При обычном запуске, например, с помощью команды go run hello.go, мы получим строку «Hello, World!»:

$ go run hello.go
Hello, World!


А теперь добавим вызов линкера с флагами -X и новыми значениями переменных:

$ go run -ldflags="-X main.hello=Привет -X main.world=Мир" hello.go
Привет, Мир!


Подменять можно не только переменные из пакета main, но и переменные и константы из любых пакетов вообще. Таким образом, во время сборки приложения можно зашить в него любую необходимую метаинформацию.

Набор инструкций по сборке приложения

Несмотря на солидный возраст, утилита make не теряет актуальности и популярности у тех, кому приходится собирать приложения (хотя бы под *nix). Вот и среди Go-разработчиков этот инструмент весьма распространен.

Рассмотрим конкретный пример Makefile для некоторого сервиса. Я подготовила репозиторий go-zeroservice, содержащий «нулевой» сервис, единственная функциональность которого — запуститься и показать информацию о сборке.

Команда make build собирает бинарный файл, подставляя указанную в Makefile версию, хэш последнего коммита и текущее время. При этом перед make build вызывается команда clean, которая удаляет уже существующий бинарник (если он был). Для обновления зависимостей предусмотрена команда make vendor, которая установит dep, если его еще нет, и выполнит команду dep ensure для актуализации пакетов внутри vendor. Для проверки качества кода предлагается команда make check, которая установит и запустит металинтер.

В наших продакшн-проектах мы выносим в Makefile любые более или менее повторяющиеся действия — запуск проверок на стандарты кодирования и запуск тестов, запуск менеджера управления пакетами, сборку приложения под нужную ОС с нужными флагами, команды для сборки и запуска Docker-контейнера и даже команды, позволяющие запустить релиз сервиса в Kubernetes с использованием Helm.

Наличие таких команд на разных окружениях позволяет быстро производить необходимые действия, например, запускать тесты и собирать и запускать контейнер на локальном окружении разработчика, или запускать тесты и сборку и проводить релиз в рамках процессов CI/CD. В случае с go-zeroservice можно посмотреть файл .travis.yml, который запускает сборку сервиса в рамках Travis CI и как раз состоит из команд, описанных в Makefile.

Заключение

Итак, для того, чтобы разобраться с вопросами сборки Go-приложений для продакшн, требуется не так уж много. Во-первых, нужно определиться с расположением кода приложения внутри GOPATH и убедиться, что оно соответствует расположению кода в системе контроля версий. Во-вторых, нужно решить, каким образом будет производиться взаимодействие с управлением внешними зависимостями и выбрать подходящий инструмент. В-третьих, удобно, когда под рукой есть все инструкции, которые приходится выполнять более или менее регулярно и на разных окружениях, в хранении таких инструкции помогает, например, Makefile.

Надеюсь, эта статья поможет новичкам мира Go быстрее разобраться с вопросами подготовки релизов. А если вы используете другие практики для сборки приложений, не стесняйтесь поделиться ими в комментариях и заранее спасибо за это.

P.S. Кстати, мы придумали продолжение мастер-класса про Go и Kubernetes и планируем представить его в сентябре на конференции DevFest Siberia. Присоединяйтесь к нам! ;-)

https://github.com/golang/go/wiki/GoForCPPProgrammers
Изображение

dyvniy M
Автор темы, Администратор
Администратор
Аватара
dyvniy M
Автор темы, Администратор
Администратор
Возраст: 41
Репутация: 1
Лояльность: 1
Сообщения: 3579
Зарегистрирован: Ср, 10 октября 2012
С нами: 11 лет 5 месяцев
Профессия: Программист
Откуда: Россия, Москва
ICQ Сайт Skype ВКонтакте

#8 dyvniy » Пн, 25 сентября 2017, 15:39:10

Игровые движки на нём, всё под убунту (
https://4gophers.ru/articles/igrovye-dvizhki-na-go/#.Wcj2o8gjFHY
Azul3D
Спойлер
это 3D движок написанный полностью с нуля на языке программирования Go. Azul3D подходит для создания 2D и 3D игр. Так же, его можно использовать для создания не игровых, а просто интерактивных приложений. В отличии от большинства современных движков(таких как Unity, JMonkey) у Azul3D нет дополнительных фич типа редакторов уровней, IDE. Это просто набор необходимых разработчику пакетов.

Это игровой движок от программистов для программистов. Он очень минималистичен, но легко расширяется в отличии от других движков.

Azul3D предоставляет самые необходимые инструменты, которые будут использоваться изо дня в день. И делает это действительно хорошо.

Установка
Начинаем с зависимостей для Ubuntu 14.04. Для других систем смотрим тут.

sudo apt-get install build-essential git mesa-common-dev \
libx11-dev libx11-xcb-dev libxcb-icccm4-dev \
libxcb-image0-dev libxcb-randr0-dev libxcb-render-util0-dev \
libxcb-xkb-dev libfreetype6-dev libbz2-dev \
libxxf86vm-dev libgl1-mesa-dev
Примеры
Теперь пробуем установить примеры. Они вынесены в отдельный пакет.

go get azul3d.org/examples.v1
нам понадобится куча других пакетов:

go get azul3d.org/keyboard.v1
go get azul3d.org/lmath.v1
go get azul3d.org/gfx.v1
go get azul3d.org/gfx/window.v2
go get azul3d.org/mouse.v1
go get azul3d.org/tmx.dev
Теперь можем посмотреть примеры. Заходим в src/azul3d.org/examples.v1/azul3d_tmx и запускаем пример

go run azul3d_tmx.go
Вы увидите что-то такое:



Были проблемы с версией Go ниже 1.3. Обновился до самой последней и все отлично заработало на моей ubuntu 14.04.
Изображение

dyvniy M
Автор темы, Администратор
Администратор
Аватара
dyvniy M
Автор темы, Администратор
Администратор
Возраст: 41
Репутация: 1
Лояльность: 1
Сообщения: 3579
Зарегистрирован: Ср, 10 октября 2012
С нами: 11 лет 5 месяцев
Профессия: Программист
Откуда: Россия, Москва
ICQ Сайт Skype ВКонтакте

#9 dyvniy » Вт, 10 октября 2017, 11:53:38

С++ in Go
http://rextester.com/TLV57435

Код: Выделить всё

package main
//int some0(){
//return 777;
//}
//
import "C"
import "fmt"

func main(){
    
fmt.Println(C.some0());
Изображение

dyvniy M
Автор темы, Администратор
Администратор
Аватара
dyvniy M
Автор темы, Администратор
Администратор
Возраст: 41
Репутация: 1
Лояльность: 1
Сообщения: 3579
Зарегистрирован: Ср, 10 октября 2012
С нами: 11 лет 5 месяцев
Профессия: Программист
Откуда: Россия, Москва
ICQ Сайт Skype ВКонтакте

#10 dyvniy » Вт, 7 ноября 2017, 16:36:59

Изображение

dyvniy M
Автор темы, Администратор
Администратор
Аватара
dyvniy M
Автор темы, Администратор
Администратор
Возраст: 41
Репутация: 1
Лояльность: 1
Сообщения: 3579
Зарегистрирован: Ср, 10 октября 2012
С нами: 11 лет 5 месяцев
Профессия: Программист
Откуда: Россия, Москва
ICQ Сайт Skype ВКонтакте

#11 dyvniy » Ср, 15 ноября 2017, 17:11:27

Чтобы сбилдить sqlite3 нужен mingw
https://stackoverflow.com/questions/37497354/comp ... gwin64-ld-cannot-find-lmingw32

Качать его отсюда
http://tdm-gcc.tdragon.net/download
и добавить в PATH
Изображение

dyvniy M
Автор темы, Администратор
Администратор
Аватара
dyvniy M
Автор темы, Администратор
Администратор
Возраст: 41
Репутация: 1
Лояльность: 1
Сообщения: 3579
Зарегистрирован: Ср, 10 октября 2012
С нами: 11 лет 5 месяцев
Профессия: Программист
Откуда: Россия, Москва
ICQ Сайт Skype ВКонтакте

#12 dyvniy » Пн, 20 ноября 2017, 16:32:55

Код: Выделить всё

GOBIN = C:/Go/bin

need to go install work everywhere
Изображение


Название раздела: Программирование (под Desktop и Android)
Описание: Разработка и отладка приложений. Упор на 3D-графику.

Быстрый ответ


Введите код в точности так, как вы его видите. Регистр символов не имеет значения.
Код подтверждения
:) ;) :hihi: :P :hah: :haha: :angel: :( :st: :_( :cool: 8-| :beee: :ham: :rrr: :grr: :* :secret: :stupid: :music: Ещё смайлики…
   

Вернуться в «Программирование (под Desktop и Android)»

Кто сейчас на форуме (по активности за 15 минут)

Сейчас этот раздел просматривают: 6 гостей