Учимся ходить. Прогулка первая.

Значит, тебе стало скучно? Опять заныли старые неповоротливые извилины, проснулась тяга к приключениям?
Да, старик. Это пришло время учить новый язык программирования.

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

Я надеюсь, вы знаете, что такое компилятор/линковщик, и хотя бы немного знаете C/C++ или Java. Если нет — вам будет немного трудно и непривычно.

Шаг 0. Установка

Если вы все еще сидите на ОС Windows, то эта статья не для вас. Вам — сюда. Остальные счастливые обладатели Linux/FreeBSD/Darwin — проследуйте за мной.

Для языка go существует два основных компилятора. Первый разрабатывается в рамках проекта googlecode, часто обновляется и очень быстро работает. Второй — это gcc, собранный с поддержкой go. Мы остановимся на первом, хотя его и считают экспериментальным. Для нового языка неплохо быть в курсе всех новинок.

Устанавливается этот компилятор довольно специфически. Я решил выделить отдельную папку в $HOME для go-язычных проектов и среду разработки тоже решил разворачивать в этой папке. Назовем её $HOME/golang

В ней я создал файлик $HOME/golang/golang.conf с окружением для go:

# В этой папке мы будем работать
export GODIR=$HOME/golang

# В этой папке будут лежать исходники среды разработки
export GOROOT=$GODIR/go

# Сюда установятся бинарники компилятора/линковщика и т.д
export GOBIN=$GODIR/bin

# Ваша ОС (linux/freebsd/darwin)
export GOOS=linux

# Ваша архитектура (386/amd64/arm)
export GOARCH=386

# Добавим путь к средствам разработки в PATH
export PATH=$PATH:$GOBIN

Выполняем source ~/golang/golang.conf, чтобы подгрузить эти переменные (иначе работать с go не получится). Можно вписать эту команду в ваш .bashrc/.zshrc, чтобы она выполнялась всякий раз, когда вы входите в систему. Убедимся, что все указано верно, и создадим необходимые папки:

env | grep '^GO'
mkdir -p $GOROOT
mkdir -p $GOBIN

Мы все подготовили, теперь скачаем исходники go (я надеюсь у вас уже установлены gcc/make/libc/mercurial и другие полезные вещи для разработчика, потому что средства разработки для go мы будем собирать из исходников):

hg clone -r release https://go.googlecode.com/hg/ $GOROOT

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

cd $GOROOT/src
hg pull
hg update release

Чтобы собрать/пересобрать средства разработки нужно:

cd $GOROOT/src
./all.bash

Идем пить кофе. А когда допьем, то увидим отчет об ошибках. Хорошо, если все полученные ошибки «known». Хуже, если «unexpected».
В папке $GOBIN среди прочих файлов вы увидите:

  • 8g (или 6g, иkи 5g — в завиcимости от архитектуры) — это ваш компилятор
  • 8l (аналогично, может 6l/5l) — ваш линковщик
  • gofmt — марафетит ваш код, чтобы было красиво и читабельно
  • godoc — создает html-документацию на основе исходника (как javadoc/Doxygen)

Вообще названия компилятора/линковщика выглядят довольно странно, но так повелось еще в Plan 9 (разработанной теми же Робом Пайком и Кеном Томпсоном, что и язык go). Первой цифрой идет код архитектуры (в частности, 8=i386, 6=x86-64, 5=arm), а второй — код языка (a=ассемблер, c=си, g=го). Линковщику досталась буква «l».

А теперь подробнее рассмотрим как работать с go.

Шаг 1. Учимся пользоваться

Давайте начнем с такой банальщины, как hello world.
Создаем файлик hello.go с содержимым:

package main

import "fmt"

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

Код чем-то похож на Java. Наш код находится в пакете main, мы вызываем функцию Printf() из пакета fmt, который предварительно подключили.

Компилируем и собираем, а потом запускаем:

8g -o hello.8 hello.go
8l -o hello hello.8
./hello

Как видно, наш исходник в процессе компиляции превращается в промежуточный объектный файл hello.8, из которого линковщик создает бинарник hello. Кстати, расширение объектных файлов тоже меняется в зависимости от архитектуры.

Лично я привык к команде make, поэтому сделал такой Makefile (использую его как шаблон для других проектов тоже):

# включаем системный makefile, в котором объявлены
#   $(GC) - компилятор
#   $(LD) - линковщик
#   $(O)  - архитектура

#
# UPD: В более ранних версиях языка использовался такой Makefile:
#
# include $(GOROOT)/src/Make.$(GOARCH)
#
include $(GOROOT)/src/Make.inc

# Имя собираемого бинарника
TARG    := hello

# Исходные файлы проекта
GOFILES := hello.go

# На основе исходных файлов получаем список объектных 
GOOBJS  := $(GOFILES:.go=.$O)

all: $(TARG)

$(TARG): $(GOOBJS)
	@echo LD $(GOOBJS)
	@$(LD) -o $(TARG) $(GOOBJS)

%.$O: %.go
	@echo GC $^
	@$(GC) -o $@ $^

clean:
	@echo RM $(GOOBJS)
	@rm -f $(GOOBJS) 
	@echo RM $(TARG)
	@rm -f $(TARG)

.PHONY: all clean

Для других проектов меняете TARG и GOFILES. В остальном этот Makefile универсален.

Любители экзотики могут использовать make написанный на go. Только не забудьте «6» поменяйть на «8» для 32-битных машин.

Спасение утопающих

Я надеюсь, что основные аспекты языка будут описаны в следующих статьях. Но если хочется знать больше, то ответы найдутся в:

На сегодня все. Good luck!


Домашнее задание

  1. Установить Go у себя на компьютере
  2. Написать и собрать hello world

5 comments on “Учимся ходить. Прогулка первая.

  1. Анонимный Круглик:

    Можно даже написать зависимость названия линковщика и компилятора от архитектуры. Для ленивых как я

    • Спасибо, добавил. Если язык наберет популярность, то появится еще много «интуитивных» названий — kg для SPARC, qg для PowerPC, vg для MIPS, 1g/2g для процессоров Motorola

  2. locky37:

    Спасибо за статью.
    Домашнее задание это хорошо :).

  3. locky37:

    6=i386, 8=x86-64
    наоборот 6 это amd64, а 8 это x86

Оставьте комментарий