Кто как с $GOPATH ?

1,351 views
Skip to first unread message

Konstantin Cherkasoff

unread,
Jan 17, 2014, 1:32:22 PM1/17/14
to gola...@googlegroups.com
Привет!
Мне лично не нравится глобальный GOPATH.
Не хочется, чтобы кривые зависимости сломали другие сборки.
Поэтому я его для каждого проекта задаю локально:
$ export GOPATH=$(pwd) 
и потом из этого терминала запускаю редактор (Sublime Text) и go build

Но это тоже как-то не удобно.

А как у вас?

Anton Ageev

unread,
Jan 18, 2014, 4:48:59 AM1/18/14
to gola...@googlegroups.com
В консоли GOPATH меняется через smartcd.
А GoSublime автоматически определяет directory layout (src, pkg) и выставляет GOPATH (ну или можно прописать в настройках проекта вручную).


2014/1/17 Konstantin Cherkasoff <k.cher...@gmail.com>

--
Вы получили это сообщение, поскольку подписаны на группу GoLang Russian.
 
Чтобы отказаться от подписки на эту группу и перестать получать из нее сообщения, отправьте электронное письмо на адрес golang-ru+...@googlegroups.com.
Настройки подписки и доставки писем: https://groups.google.com/groups/opt_out.



--
WBR, Anton

Maxim Dementyev

unread,
Jan 18, 2014, 10:15:49 AM1/18/14
to gola...@googlegroups.com
Использую, как правило, Makefile, в котором выставляется GOPATH. Что-нибудь, вроде `pwd`/vendor:`pwd`.

Kir S.

unread,
Jan 18, 2014, 10:18:49 AM1/18/14
to gola...@googlegroups.com
Есть отличная штука gom (https://github.com/mattn/gom), который
заменяет PATH при компиляции через хелпер и может скачивать нужные
пакеты в vendor, описанные в специальном файле.

2014/1/18 Maxim Dementyev <orof...@gmail.com>:
> Использую, как правило, Makefile, в котором выставляется GOPATH. Что-нибудь, вроде `pwd`/vendor:`pwd`.
>
> --
> Вы получили это сообщение, поскольку подписаны на группу Golang Russian.

Konstantin Cherkasoff

unread,
Jan 18, 2014, 4:53:54 PM1/18/14
to gola...@googlegroups.com
А можно про GoSublime поподробнее? Что и как надо написать, чтобы
Sublime как-то по-умному GOPATH понимал?
--
Konstantin Cherkasoff


18 января 2014 г., 13:48 пользователь Anton Ageev <ant...@gmail.com> написал:

Anton Ageev

unread,
Jan 19, 2014, 4:47:19 AM1/19/14
to gola...@googlegroups.com
2014/1/19 Konstantin Cherkasoff <k.cher...@gmail.com>

А можно про GoSublime поподробнее? Что и как надо написать, чтобы
Sublime как-то по-умному GOPATH понимал?

В настройках плагина нужно прописать опцию:

"env": {
    "GOPATH": "$GOPATH:$GS_GOPATH"
}

или

"env": {
    "GOPATH": "$GS_GOPATH"
}


Подробнее описано тут:


--
WBR, Anton

itcraft...@gmail.com

unread,
Jan 21, 2014, 5:44:47 AM1/21/14
to gola...@googlegroups.com
Проясните по поводу пакетов уровня приложения. Как их оформлять и использовать?
import "./pkg/conf"
вызывает ошибку can't load package: ... local import "./pkg/conf" in non-local package


или пакеты могут быть вызваны только из GOPATH и необходимо для каждого приложения с локальным пакетами формировать свой GOPATH?

Alexey Palazhchenko

unread,
Jan 21, 2014, 5:47:15 AM1/21/14
to gola...@googlegroups.com
Привет,

> Проясните по поводу пакетов уровня приложения. Как их оформлять и использовать?
> import "./pkg/conf"
> вызывает ошибку can't load package: ... local import "./pkg/conf" in non-local package

Да, локальные импорты работают только в некоторых случаях.

> или пакеты могут быть вызваны только из GOPATH и необходимо для каждого приложения с локальным пакетами формировать свой GOPATH?

GOPATH может содержать список путей. Рекомендуемый стиль импортов – от GOPATH/src, вроде «github.com/foo/bar/conf».

–-–
Алексей "AlekSi" Палажченко

Dmitriy Kovalenko

unread,
Jan 21, 2014, 5:55:17 AM1/21/14
to gola...@googlegroups.com
> Мне лично не нравится глобальный GOPATH.
> А как у вас?

Все примерно также. Еще до Go выработал следующий субъективный подход.

1. Все проекты имеют одинаковую структуру (ниже минимально достаточная
структура):

.git
.out - выходные результаты (гитигнорится)
_ - командные файлы для работы с проектом, еще и как разделитель
частей выглядит :)
ext - исходный код зависимостей проекта (сторонние библиотеки)
src - исходный код проекта
.gitignore
README.md

2. В папке _ собраны "батники", к примеру:

get-deps.sh - прокачка/установка зависимостей проекта
git-
git-diff.sh - вызов визуальной приблуды типа git gui или gitg
git-hist.sh - вызов gitk или gitg для осмотра дерева коммитов
git-pull.sh - забор изменений с сервера
git-push.sh - отправка изменений на сервер
go-
go-bld.sh - сборка go build
go-fmt.sh - форматирование исходников
go-run.sh - запуск go run
go-st3.sh - старт текстового редактора Sublime Text 3
go-tst.sh - запуск тестов
others
prj-sweep.sh - зачистка проекта от разного рода "мусора"
project-vars.inc - переменные конкретного проекта (гитигнорится)
project-vars.txt - образец с переменными проекта (под контролем версий)

Пустые файлы git-, go- и others играют роль визуальных разделителей.

3. Теперь по существу вопроса. Когда разработчик получает проект через
git clone, то первым делом он копирует project-vars.txt как
project-vars.inc и переопределяет нужные ему переменные согласно своих
привычек и религиозных соображений, что выглядит в результате примерно
так:

# Override
export GOROOT=$HOME/Development/go-1.2
export EXEOUT=myapp.out

# Don't override!
ROOT=$(dirname `pwd`)
export GOPATH=$ROOT/ext
export PATH=$GOROOT/bin:$GOPATH/bin:$PATH

У меня несколько версий Go и для каждого проекта, я определяю нужную.
Например, что-то делаю на go-dev, который постоянно синхронизирую, а
то, что уже работает в продакшене, собирается с последним релизом Go.
Переменная GOPATH всегда относительна корня проекта.

Вторым делом, после git clone, следует получить зависимости. И это
все, что надо для сборки - 1) определить переменные, 2) получить
зависимости, 3) собрать проект.

Файл get-deps.sh может выглядеть так:

#!/bin/sh

. $(dirname $0)/project-vars.inc

echo "Update external packages"
go version

cd $ROOT
mkdir -p $ROOT/.out

cd $ROOT
rm -rf $ROOT/ext/*

go get -d "labix.org/v2/mgo"
rm -rf $ROOT/ext/src/labix.org/v2/mgo/.bzr*
cd $ROOT/ext/src/labix.org/v2/mgo/
go install

go get -d "github.com/gorilla/mux"
rm -rf $ROOT/ext/src/github.com/gorilla/context/.git*
rm -rf $ROOT/ext/src/github.com/gorilla/mux/.git*
cd $ROOT/ext/src/github.com/gorilla/mux
go install

go get -d "launchpad.net/gocheck"
rm -rf $ROOT/ext/src/launchpad.net/gocheck/.bzr*
rm -rf $ROOT/ext/src/launchpad.net/gocheck/.git*
cd $ROOT/ext/src/launchpad.net/gocheck/
go install

Краткое пояснение. Каждый раз при вызове get-deps.sh все зависимости
удаляются, перекачиваются (из них по возможности вычищается их
собственная "версионность") и пересобираются с переустановкой в
проект. В самом начале подключается project-vars.inc с искомыми
переменными среды для конкретного проекта. Если git-diff.sh показал,
что были изменения в сторонних библиотеках, прошли тесты после сборки
проекта и нет каких-то особых противопоказаний, то они коммитятся в
дерево самого прикладного проекта. Таким образом, история исходного
кода проекта версионируется совместно с исходным кодом его сторонних
библиотек и может быть произведен согласованный проект+библиотеки
откат в любую точку.

Вызов текстового редактора для работы над проектом проиходит через
файл go-st3.sh, примерно такого содержания:

#!/bin/sh

. $(dirname $0)/project-vars.inc
sublime-text-3 &


В общем, как-то так... Возможно есть уже какая-то автоматизация всего
этого дела (?)


--
Banzai!
Dmitriy Kovalenko

itcraft...@gmail.com

unread,
Jan 21, 2014, 5:55:38 AM1/21/14
to gola...@googlegroups.com


On Tuesday, January 21, 2014 4:47:15 PM UTC+6, Alexey Palazhchenko wrote:

GOPATH может содержать список путей. Рекомендуемый стиль импортов – от GOPATH/src, вроде «github.com/foo/bar/conf».

это хорошо для общих пакетов, а если пакеты используются только в конкретном приложении то локальные импорт было бы очень удобно, странно что они не работают.

Dmitriy Kovalenko

unread,
Jan 21, 2014, 6:16:09 AM1/21/14
to gola...@googlegroups.com
> Таким образом, история исходного
> кода проекта версионируется совместно с исходным кодом его сторонних
> библиотек и может быть произведен согласованный проект+библиотеки
> откат в любую точку.

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

.gitignore
--------------------------------------
.out
_/project-vars.inc
ext/bin
ext/pkg


--
Banzai!
Dmitriy Kovalenko

Igor Yurchenko

unread,
Jan 22, 2014, 3:53:41 AM1/22/14
to gola...@googlegroups.com


вторник, 21 января 2014 г., 18:44:47 UTC+8 пользователь itcraft...@gmail.com написал:
Проясните по поводу пакетов уровня приложения. Как их оформлять и использовать?
import "./pkg/conf"
вызывает ошибку can't load package: ... local import "./pkg/conf" in non-local package


Надо явно указывать головной файл проекта. Это тот который в package main и содержит func main().
 

или пакеты могут быть вызваны только из GOPATH и необходимо для каждого приложения с локальным пакетами формировать свой GOPATH?


Локальные пакеты могут быть только в контексте приложения/проекта. Поэтому компилятору надо явно указывать, приложение которое собираете...
Проблема в том, что язык позволяет использовать в приложении разные пакеты с одинаковыми называниями. Типа:

import (
    globPack "coolpack",
    localPack "./coolpack"
)

Компилятор это еще может разрулить, а линкер уже нет. Для него это будут конфликтующие модули...

itcraft...@gmail.com

unread,
Jan 22, 2014, 7:07:15 AM1/22/14
to gola...@googlegroups.com


On Wednesday, January 22, 2014 2:53:41 PM UTC+6, Igor Yurchenko wrote:
>Надо явно указывать головной файл проекта. Это тот который в package main и содержит func main(). 

где указывать ? покажите пример указания если можно. 

Igor Yurchenko

unread,
Jan 22, 2014, 7:53:00 AM1/22/14
to gola...@googlegroups.com
Зависит от того в чем разрабатываете. В командной строке "go build myprog.go".
В соседнем треде про плагин IDEA об этом же шла речь...

среда, 22 января 2014 г., 20:07:15 UTC+8 пользователь itcraft...@gmail.com написал:

itcraft...@gmail.com

unread,
Jan 23, 2014, 12:09:54 AM1/23/14
to gola...@googlegroups.com


В самом деле работает,
главное проверял go build main, а надо с расширением go build main.go

где бы ещё в LiteIDE подкрутить чтоб он имя файла добавлял к пути ?

а по поводу 

>Проблема в том, что язык позволяет использовать в приложении разные пакеты с одинаковыми называниями. Типа: 
>
>import (
>    globPack "coolpack",
>    localPack "./coolpack"
>)

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

itcraft...@gmail.com

unread,
Jan 24, 2014, 12:02:19 AM1/24/14
to gola...@googlegroups.com
мля поторопился.
если пакет состоит из нескольких файлов то go build main.go перестаёт работать

Igor Yurchenko

unread,
Jan 24, 2014, 5:52:00 AM1/24/14
to gola...@googlegroups.com
Что именно перестает работать? И зачем делать пакет из нескольких файлов?

пятница, 24 января 2014 г., 13:02:19 UTC+8 пользователь itcraft...@gmail.com написал:

itcraft...@gmail.com

unread,
Jan 24, 2014, 7:45:10 AM1/24/14
to gola...@googlegroups.com
Изначально я думал что мы указываем имя пакета который собираем в go build pkg_name, оказывается мы там указываем не имя пакета а имя файла.
Пакеты могут состоять из нескольких файлов расположенных в одном каталоге, это удобно разнося объекты(структуры) одного пакета по разным файлам если пакет большой. Однако при этом если пакет инклудит локальные пакеты и мы вызываем сборку go build file_name.go то go не видит структуры этого же пакета но объявленные в других файлах. 

Igor Yurchenko

unread,
Jan 24, 2014, 8:42:20 AM1/24/14
to gola...@googlegroups.com
Думаю вам стоит перечитать документацию по gotools.

пятница, 24 января 2014 г., 20:45:10 UTC+8 пользователь itcraft...@gmail.com написал:
Изначально я думал что мы указываем имя пакета который собираем в go build pkg_name, оказывается мы там указываем не имя пакета а имя файла.

Many commands apply to a set of packages:

        go action [packages]

Usually, [packages] is a list of import paths.

An import path that is a rooted path or that begins with
a . or .. element is interpreted as a file system path and
denotes the package in that directory.

 
Пакеты могут состоять из нескольких файлов расположенных в одном каталоге, это удобно разнося объекты(структуры) одного пакета по разным файлам если пакет большой. Однако при этом если пакет инклудит локальные пакеты и мы вызываем сборку go build file_name.go то go не видит структуры этого же пакета но объявленные в других файлах. 
 

As a special case, if the package list is a list of .go files from a
single directory, the command is applied to a single synthesized
package made up of exactly those files, ignoring any build constraints
in those files and ignoring any other files in the directory.

Это цитаты из 'go help packages'. У вас чрезмерные ожидания по поводу интеллекта компилятора Go. Он работает очень просто и логично, никакой магии в нем нет.

С уважением...
 

Konstantin Cherkasoff

unread,
Jan 24, 2014, 8:54:58 AM1/24/14
to gola...@googlegroups.com
> Что именно перестает работать? И зачем делать пакет из нескольких файлов?

А как? Всегда всё в один файл валить?
В стандартной библиотеке очень много пакетов из нескольких файлов.

--
Konstantin Cherkasoff

Igor Yurchenko

unread,
Jan 24, 2014, 9:22:29 AM1/24/14
to gola...@googlegroups.com
Я понял, что тут речь идет о пакете main. Есть разница между пакетом main  и пакетами c другими именами.

Для иных (не main) пакетов нет никаких проблем находится в разных файлах. Более того, это как бы подразумевается самой семантикой команды go build, которой указывается директория в которой лежит собираемый пакет...
Для main пакетов ситуация другая. Например у вас в проекте подразумевается несколько исполняемых файлов. То есть в корне проекта будет лежать несколько файлов пакета main и в каждом свой func main().

А теперь представьте что у вас есть там еще один файл с пакетом main, но не имеющий своего func main(). И? Что будет делать компилятор когда вы запустите общую сборку проекта 'go build'?

В общем я придерживаюсь принципа: "Один package main - один исполняемый файл." Все остальное рассовываем по пакетам с другими названиями...   
 

пятница, 24 января 2014 г., 21:54:58 UTC+8 пользователь Konstantin Cherkasoff написал:

Konstantin Cherkasoff

unread,
Jan 24, 2014, 10:38:35 AM1/24/14
to gola...@googlegroups.com
> А теперь представьте что у вас есть там еще один файл с пакетом main, но не
> имеющий своего func main(). И? Что будет делать компилятор когда вы
> запустите общую сборку проекта 'go build'?

Хм, а я и main по разным файликам раскладываю:

src/myprog/
main.go << тут func main()
options.go << тут, например, разбор параметров командной строки
foo.go
bar.go


Просто потом для сборки нужно так писать

go build -o myprog src/myprog/*.go


Но тут Makefile из 3-х строчек приходит на помощь.
Заодно в Makefile и правила для кросскомпиляции добавить можно (я
собираю на Mac OS).


--
Konstantin Cherkasoff

Anton Ageev

unread,
Jan 24, 2014, 11:49:00 AM1/24/14
to gola...@googlegroups.com
2014/1/24 Konstantin Cherkasoff <k.cher...@gmail.com>

> А теперь представьте что у вас есть там еще один файл с пакетом main, но не
> имеющий своего func main(). И? Что будет делать компилятор когда вы
> запустите общую сборку проекта 'go build'?

Хм, а я и main по разным файликам раскладываю:

src/myprog/
    main.go         << тут func main()
    options.go     << тут, например, разбор параметров командной строки
    foo.go
    bar.go


Просто потом для сборки нужно так писать

go build -o myprog src/myprog/*.go


Если src/ в $GOPATH, то можно же просто go install myprog и файл будет в $GOPATH/bin/myprog.

--
WBR, Anton

Igor Yurchenko

unread,
Jan 24, 2014, 2:06:12 PM1/24/14
to gola...@googlegroups.com
Дык, положи в корень проекта простенький helloworld.go и посмотри как у тя всё соберется по команде go build *.go.
Но make, да - это решение.

суббота, 25 января 2014 г., 0:49:00 UTC+8 пользователь Антон Агеев написал:

itcraft...@gmail.com

unread,
Jan 28, 2014, 4:57:35 AM1/28/14
to gola...@googlegroups.com
Господа, подскажите как настроить LiteIDE чтоб она работала с локальными пакетами, не работает:
1. подсказка кода из локальных пакетов 
2. сборка пакетов

Evgeny Rachlenko

unread,
Apr 12, 2014, 3:38:53 PM4/12/14
to gola...@googlegroups.com
а можно посмотреть какой нибудь живой файл для сборки под разные платформы ..
(новичек.)

пятница, 24 января 2014 г., 17:38:35 UTC+2 пользователь Konstantin Cherkasoff написал:
Message has been deleted

Konstantin Cherkasoff

unread,
Apr 13, 2014, 4:34:24 AM4/13/14
to gola...@googlegroups.com
> а можно посмотреть какой нибудь живой файл для сборки под разные платформы

ну, я довольно наивно делал (я make-то особо не знаю)

linux:
GOOS=linux GOARCH=amd64 go install ...

А вот сейчас какой-то большой Makefile нагуглил - потом посмотреть надо будет.
https://github.com/silven/go-example

--
Konstantin Cherkasoff

Oleg Lebedev

unread,
Apr 25, 2014, 3:13:56 AM4/25/14
to gola...@googlegroups.com
У меня ы .zshrc функция activate. Делает текущую папку $GOPATH. Подробно можно глянуть здесь: https://github.com/olebedev/dotfiles/blob/master/zshrc#L55

суббота, 18 января 2014 г., 0:32:22 UTC+6 пользователь Konstantin Cherkasoff написал:
Привет!
Мне лично не нравится глобальный GOPATH.

Void Nugget

unread,
May 5, 2014, 10:07:17 AM5/5/14
to gola...@googlegroups.com
GVP и GST
Два простых bash скрипта для локального per-shell gopath'а в папке с проектом, и version-lock всех зависимостей.

Пʼятниця, 17 січня 2014 р. 20:32:22 UTC+2 користувач Konstantin Cherkasoff написав:

Void Nugget

unread,
May 5, 2014, 10:08:09 AM5/5/14
to gola...@googlegroups.com
Опечаточка.
https://github.com/pote/gvp
https://github.com/pote/gpm

Понеділок, 5 травня 2014 р. 17:07:17 UTC+3 користувач Void Nugget написав:
Reply all
Reply to author
Forward
0 new messages