Как скомпилировать программу на golang

Обновление от 2022-08-09: процесс компиляции несколько изменился с момента написания оригинальной статьи, из-за чего она была актуализирована до версии Go 1.19.

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

Golang

build компилирует пакеты, названные путями импорта, вместе с их зависимостями, но не устанавливает результаты.

Если аргументы для build представляют собой список файлов .go, build обрабатывает их как список исходных файлов, указывающих один пакет.

При компиляции единичного основного пакета (main package) build записывает полученный исполняемый файл в выходной файл, названный в честь первого исходного файла («go build ed.go rx.go» записывает «ed» или «ed.exe») или в каталог исходного кода («go build unix/sam» записывает «sam» или «sam.exe»). Суффикс «.exe» добавляется при записи исполняемого файла Windows.

Golang с нуля до Junior | Go ROADMAP | Подробный план обучения

При компиляции нескольких пакетов или одного неосновного пакета, build компилирует пакеты, но отбрасывает полученный объект, служа только для проверки возможности сборки пакетов.

При компиляции пакетов build игнорирует файлы, заканчивающиеся на «_test.go».

Флаг -o, разрешен только при компиляции одного пакета, он заставляет build записывать полученный исполняемый файл или объект в именованный выходной файл вместо поведения по умолчанию, описанного выше.

Флаг -i устанавливает пакеты, которые являются зависимостями от цели.

Флаги сборки (build flags) используются командами build, clean, get, install, list, run и test:

-a заставляет пересобрать (rebuild) пакеты, которые и так уже имеют последнюю версию (up-to-date). -n печатает команды, но не запускает их. -p n количество программ, таких как команды сборки или тестирования бинарных файлов, которые можно запускать параллельно. По умолчанию равно количеству доступных ядер процессоров. -race включить обнаружение гонки данных.

Поддерживается только в linux/amd64, freebsd/amd64, darwin/amd64 и windows/amd64. -msan включить взаимодействие с очистителем памяти. Поддерживается только на linux/amd64, linux/arm64 и только с Clang/LLVM в качестве C компилятора хоста. -v печатать имена пакетов по мере их компиляции. -work распечатать имя временного рабочего каталога и не удалять его при выходе. -x распечатать команды. -asmflags ‘[pattern =] arg list’ аргументы для передачи при каждом вызове go tool asm. -buildmode mode режим сборки для использования.

Читайте также:
Примеры программ с random

Смотрите ‘go help buildmode’ для более подробной информации. -compiler name имя используемого компилятора, как в runtime.Compiler (gccgo или gc). -gccgoflags ‘[pattern =] arg list’ аргументы для передачи при каждом вызове компилятора/компоновщика gccgo (gccgo compiler/linker). -gcflags ‘[pattern =] arg list’ аргументы для передачи при каждом вызове go tool compile. -installsuffix suffix суффикс для использования в имени каталога установки пакета, чтобы сохранить вывод отдельно от сборок по умолчанию. При использовании флага -race суффикс установки автоматически устанавливается равным race или, если задано явно, к нему добавлен _race.

Год программирую на Go | Стоит ли учить Golang 2023

Аналогично для -msan флага. Использование параметра -buildmode, который требует нестандартных флагов компиляции имеет аналогичный эффект. -ldflags ‘[pattern =] arg list’ аргументы для передачи при каждом вызове go tool link. -linkshared ссылка на общие библиотеки, ранее созданные с -buildmode=shared. -mod mode Режим (mode) загрузки модуля для использования: readonly или vendor.

См. ‘go help modules’ для получения дополнительной информации. -pkgdir dir установить и загрузить все пакеты из dir вместо обычных мест. Например, при сборке с нестандартной конфигурацией, используйте -pkgdir для хранения сгенерированных пакетов в отдельном месте. -tags ‘tag list’ разделенный пробелами список тегов сборки, которые необходимо учитывать во время сборки.

Для получения дополнительной информации о тегах сборки см. Описание ограничения сборки в документации для пакета go/build. -toolexec ‘cmd args’ программа, используемая для вызова таких программ, как vet и asm. Например, вместо запуска asm будет запущена команда go ‘cmd args /path/to/asm ‘.

Флаги -asmflags, -gccgoflags, -gcflags и -ldflags принимают разделенный пробелами список аргументов для передачи базовому инструменту во время сборки. Чтобы вставить пробелы в элемент списка, заключите его в одинарные или двойные кавычки.

Списку аргументов может предшествовать паттерн пакета и знак равенства, который ограничивает использование этого списка аргументов до построения пакетов, соответствующих этому паттерну (описание паттернов пакетов см. в «go help packages»). Без паттерна список аргументов применяется только к пакетам, указанным в командной строке. Флаги могут повторяться с разными паттернами, чтобы указывать разные аргументы для разных наборов пакетов. Если пакет соответствует паттернам, указанным в нескольких флагах, побеждает последнее совпадение в командной строке. Например, ‘go build -gcflags=-S fmt’ печатает разборку (disassembly) только для пакета fmt, а ‘go build -gcflags=all=-S fmt’ печатает разборку (disassembly) для fmt и всех его зависимостей.

Читайте также:
Программа которая поет слова

Подробнее об указании пакетов см. в разделе ‘go help packages’. Чтобы узнать больше о том, где установлены пакеты и бинарные файлы, запустите ‘go help gopath’. Чтобы узнать больше о вызовах между Go и C/C++, запустите ‘go help c’.

Примечание: build придерживается определенных соглашений, таких как те, которые описаны в ‘go help gopath’. Однако не все проекты могут следовать этим правилам. Установки, которые имеют свои собственные соглашения или используют отдельную систему сборки программного обеспечения, могут использовать вызовы более низкого уровня, такие как ‘go tool compile’ и ‘go tool link’, чтобы избежать некоторых накладных расходов и проектных решений инструмента сборки.

Смотрите также: go install, go get, go clean.

  • Команды Go: введение
  • Инструмент go, команды
  • Как писать Go код

Источник: golang-blog.blogspot.com

Разбираемся с компилятором Go

Golang

Компилятор Go занимает важное место в экосистеме Go. Компиляция — необходимый этап создания исполняемого двоичного кода. Компилятор проходит долгий путь: его пишут на C, переносят на Go и постоянно оптимизируют.

Фазы компиляции

Компилирование Go состоит из четырёх фаз, которые можно объединить в два этапа:

  • На первом выполняется анализ исходного кода и по мере синтаксического разбора создаётся абстрактная синтаксическая структура исходного кода, которая называется АСД (абстрактное синтаксическое дерево).
  • На втором этапе вместе с многочисленными оптимизациями происходит трансформация представления исходного кода в машинный код.

Для лучшего понимания используем простую программу:

package main func main() < a := 1 b := 2 if true < add(a, b) >> func add(a, b int)

Синтаксический разбор

Первая фаза предельно проста. Её описание можно найти в README:

После маркирования проводится синтаксический анализ и строится синтаксическое дерево.

Преобразование в АСД

Преобразование в абстрактное синтаксическое дерево можно вывести на экран командой go tool compile -W :

Читайте также:
Какой сериал идет по 1 программе

На первой фазе также проводятся оптимизации. Например, встраивание. В нашем примере метод add уже может быть встроенным, так как никаких инструкций CALLFUNC с методом add мы здесь не видим. Теперь снова выполним команду с флагом -l для отключения встраивания:

АСД позволяет компилятору перейти к низкоуровневому промежуточному представлению SSA (Static Single Assignment — статическое одиночное присваивание).

Генерация SSA

Создание формы статистического одиночного присваивания — это фаза оптимизации: устранение мёртвого кода, замена выражений на константы и т.д. Код SSA можно вывести командой GOSSAFUNC=main go tool compile main.go open ssa.html , с помощью которой создаётся HTML-документ со всеми проходами, сделанными в пакете SSA:

SSA находится во вкладке start:

Переменные a и b здесь выделены, как и условие if : позже можно отследить, как меняются эти строки. Код также показывает, каким образом компилятор управляет функцией println , которая разбивается на четыре: printlock , printint , printnl , printunlock . Компилятор автоматически добавляет блокировку и, в зависимости от типа аргумента, вызывает соответствующий метод для корректного вывода.

В нашем примере a и b известны на стадии компиляции, поэтому компилятор может посчитать конечный результат и отметить переменные как ненужные. Проход opt оптимизирует эту часть:

v11 здесь заменён результатом добавления v4 и v5 , обозначенных как мёртвый код. Проход opt deadcode удалит его:

Что касается условия if , проход opt отмечает константу true как мёртвый код, он будет удалён:

Затем другой проход упростит поток управления, отметив ненужный блок и условие как бесполезные. Эти блоки будут после удалены другим проходом, работающим с мёртвым кодом:

После всех проходов компилятор Go создаёт промежуточный код на ассемблере Go:

На следующей фазе создаётся машинный код для бинарного файла.

Создание машинного кода

Заключительный этап компиляции — это создание объектного файла ( main.o в нашем случае). Его можно дизассемблировать с помощью команды go tool objdump . Ниже схема работы компилятора:

После создания объектного файла можно перейти непосредственно к компоновщику. Используйте команду go tool link — и ваш двоичный код готов!

  • Как я встраивал ресурсы в Go
  • Почему Go прекрасно подходит для DevOps
  • Топ-10 самых распространенных ошибок в проектах Go. Часть 1

Источник: nuancesprog.ru

Рейтинг
( Пока оценок нет )
Загрузка ...
EFT-Soft.ru