Подробное объяснение процесса составления GO notes и выполнения GO.

Go

Предыдущая статьяПредставлена ​​установка Golang под разные системы, и классический кейс Hello World завершен. В этом процессе мы использовали команду go run, которая завершает весь процесс от компиляции до выполнения исходного кода.

Сегодня мы подробно опишем этот процесс. Простое понимание, запуск может быть эквивалентен сборке + выполнение.

Краткое описание команды сборки

В Golang процесс сборки в основном выполняется командой go build. Он завершает компиляцию исходного кода и генерацию исполняемого файла.

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

Создать новый приветственный случай

Перед официальным введением в процесс компиляции давайте еще раз продемонстрируем кейс Hello World и создадим новый файл hello.go.Код выглядит следующим образом:

package main

import "fmt"

func main() {
	fmt.Println("Hello World")
}

Выполните команду go build hello.go, чтобы сгенерировать исполняемый файл hello в каталоге. Выполните hello и выведите Hello World.

Представляем варианты сборки

Демонстрация процесса компиляции требует помощи нескольких опций, предоставляемых go build, и выполните go help build для просмотра. следующим образом:

$ go help build
...

-n 不执行地打印流程中用到的命令
-x 执行并打印流程中用到的命令,要注意下它与-n选项的区别
-work 打印编译时的临时目录路径,并在结束时保留。默认情况下,编译结束会删除该临时目录。

...

Эти параметры также применяются к команде go run. Как вы думаете, это похоже на опцию команды sh, видно, что многие знания в компьютере одинаковы.

поток выполнения печати

Используйте параметр -n, чтобы просмотреть ход выполнения go build без выполнения команды, как показано ниже:

$ go build -n hello.go
#
# command-line-arguments
#

mkdir -p $WORK/b001/
cat >$WORK/b001/importcfg << 'EOF' # internal
# import config
packagefile fmt=/usr/local/go/pkg/darwin_amd64/fmt.a
packagefile runtime=/usr/local/go/pkg/darwin_amd64/runtime.a
EOF
cd /Users/polo/Public/Work/go/src/study/basic/hello
/usr/local/go/pkg/tool/darwin_amd64/compile -o $WORK/b001/_pkg_.a -trimpath $WORK/b001 -p main -complete -buildid fVbBEz0nTJc3r6VxU5ye/fVbBEz0nTJc3r6VxU5ye -goversion go1.11.1 -D _/Users/polo/Public/Work/go/src/study/basic/hello -importcfg $WORK/b001/importcfg -pack -c=4 ./hello.go
/usr/local/go/pkg/tool/darwin_amd64/buildid -w $WORK/b001/_pkg_.a # internal
cat >$WORK/b001/importcfg.link << 'EOF' # internal
packagefile command-line-arguments=$WORK/b001/_pkg_.a

...

packagefile internal/race=/usr/local/go/pkg/darwin_amd64/internal/race.a
EOF
mkdir -p $WORK/b001/exe/
cd .
/usr/local/go/pkg/tool/darwin_amd64/link -o $WORK/b001/exe/a.out -importcfg $WORK/b001/importcfg.link -buildmode=exe -buildid=P1Y_fbNXAEG6zEEGqFsM/fVbBEz0nTJc3r6VxU5ye/fVbBEz0nTJc3r6VxU5ye/P1Y_fbNXAEG6zEEGqFsM -extld=clang $WORK/b001/_pkg_.a
/usr/local/go/pkg/tool/darwin_amd64/buildid -w $WORK/b001/exe/a.out # internal
mv $WORK/b001/exe/a.out hello

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

  • Создайте временный каталог, mkdir -p $WORK/b001/;
  • Найти информацию о зависимости, cat >$WORK/b001/importcfg
  • Выполнить компиляцию исходного кода, /usr/local/go/pkg/Tool/Darwin_AMD64/Compile...
  • Собрать файлы библиотеки ссылок, cat >$WORK/b001/importcfg.link
  • Сгенерировать исполняемый файл, /usr/local/go/pkg/tool/darwin_amd64/link -o ...;
  • Переместите исполняемый файл, mv $WORK/b001/exe/a.out hello;

С этим объяснением процесс сборки становится очень понятным. Если вы знакомы с разработкой на C/C++, этот процесс покажется вам знакомым. Конечно, в отличие от этого, c/c++ будет иметь еще один этап предварительной обработки.

Затем оптимизируйте предыдущую блок-схему следующим образом:

Уточняем процесс сборки на две части, compile and link, то есть компилируем и связываем. Здесь используются две очень важные команды: complie и link. Все они являются подкомандами инструмента go.

Расскажите о процессе бега

После понимания процесса сборки запустить его легко. Мы используем go run -x hello.go для просмотра процесса выполнения следующим образом:

...
/usr/local/go/pkg/tool/darwin_amd64/link -o $WORK/b001/exe/hello -importcfg $WORK/b001/importcfg.link -s -w -buildmode=exe -buildid=fveq2guPMmsyv8t4cV_M/xYBkVZeN1BHy2ygmstrB/pWJerx2-jOU98BpvIFO6/fveq2guPMmsyv8t4cV_M -extld=clang $WORK/b001/_pkg_.a
$WORK/b001/exe/hello
Hello World

Сосредоточьтесь на конечной части В отличие от сборки, после того, как ссылка сгенерирует файл hello, он не перемещает его в текущий каталог, а выполняет программу через $WORK/b001/exe/hello. При компиляции рисуется следующая блок-схема:

На данный момент весь процесс запуска очень ясен.

Pass --work, чтобы сохранить исполняемые файлы

Так можно ли получить этот временно сгенерированный исполняемый файл? Значение по умолчанию неприемлемо, временный каталог будет удален в конце запуска. Мы можем сохранить этот каталог с --work. Процесс демонстрации выглядит следующим образом:

$ go run -x --work hello.go
WORK=/var/folders/bw/8yw8h4yj2vb6mxtb6t8t41f00000gn/T/go-build149627400

...

$WORK/b001/exe/hello
Hello World

После печати пути к временному каталогу WORK мы можем скопировать файл приветствия, сгенерированный run, в текущий каталог с помощью команды mv, как показано ниже:

$ mv /var/folders/bw/8yw8h4yj2vb6mxtb6t8t41f00000gn/T/go-build149627400b001/exe/hello hello

Вы можете выполнить hello, чтобы убедиться, что это то, что мы ожидали.

Суммировать

В этой статье представлен процесс компиляции и выполнения Golang из go run. Используя несколько вариантов отладки, предоставляемых сборкой, мы реализовали пошаговую декомпозицию процесса и, наконец, подробно представили каждый этап всего процесса компиляции и выполнения.


波罗学的微信公众号