Issue
I’m a new golang developer and I wonder why $GOPATH
environment variable is needed to be set at the root of my project.
If I’m working on several projects at the same time, I need to each time re-set the $GOPATH
environment variable to point to a different location.
In my setup, I have $GOPATH
set to /Users/Projects/go/lib
. which is a generic directory for all of my golang projects.
Just to clarify: the projects data is placed in /Users/Projects/go/<Project Name>
If anyhow all $GOPATH
is used for (as far as I know) is to install 3rd party libraries, isn’t it safe to have one $GOPATH
directory for all my projects, so all the required 3rd party libraries are installed in the same lib directory, and whenever I compile on of the projects it just uses the libs it requires.
Is this bad in practice? Why?
Solution
(Q2 2018:
Note that with the vgo project, GOPATH
might end up being deprecated in favor of a project-based workflow. That would avoid the manual project-based GOPATH
I was proposing below, two years ago)
With Go 1.11 (August 2018), GOPATH
can be optional, with modules.
It is more and more supported with VSCode:
June 2016: You don’t have to rely on only one GOPATH
(ie one workspace).
My full GOPATH
includes:
- a global path (for all utilities like
goimports
),github.com/smartystreets/goconvey
, …), in$HOME/go
for instance, - a local path (for my current project), where my local
src
,pkg
andbin
will be.
That is two paths:
export GOPATH=/path/to/myproject:$HOME/go
Isn’t it safe to have one $GOPATH directory for all my projects, so all the required 3rd party libraries are installed in the same lib directory, and whenever I compile on of the projects it just uses the libs it requires.
Is this bad in practice? Why?
I don’t like that practice, as different projects could require different version of the same library.
That is why I have one GOPATH
per project, that my build script (versioned with the project) sets for me.
When I clone a go project of mine, I:
- set my
GOPATH
to that go project (local path, where the third-party libraries I need for that project will be installed, and moved to avendor
folder), - make a symlink to that path
<myproject>/src/<myproject> -> ../..
, sinceGOPATH
means go expects to find the sources ofmyproject
insrc/<apackage>
.
That organization:
- remains compatible with
go get
, - ensure any specific dependencies I need are installed by default in my project folder instead of being lost within the mass of global libraries/utilities present in the global
GOPATH
.
I have:
myproject
mysource.go
apackage
othersource.go
src
myproject -> ../..
vendor
third-party packages
On Windows, a typical build script would be:
λ more b.bat
@echo off
setlocal EnableDelayedExpansion
if not defined GOROOT (
echo Environment variable GOROOT must be defined, with %%GOROOT%%\bin\go.exe
exit /b 1
)
set PATH=C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem
set PATH=%PATH%;%GOROOT%/bin
set GOPATH=%~dp0;%HOME%/go
set prjname=%GOPATH:~0,-1%
for %%i in ("%prjname%") do set "prjname=%%~ni"
rem echo prjname='%prjname%'
if not exist src (
mkdir src
)
if not exist src\%prjname% (
mklink /J src\%prjname% %GOPATH%
)
pushd %~dp0
cd src\%prjname%
rem cd
go install
popd
endlocal
Anyone cloning my go project would simply type ‘b
‘.
Answered By – VonC
Answer Checked By – Pedro (GoLangFix Volunteer)