Where does go get install packages? - go

I've been given instructions to run go get <some-remote-git-repo> which seems to succeed, but it's not clear to me where the package was installed to so I can run an executable from it.
Per https://golang.org/doc/code.html#remote it seems it will be installed in $GOPATH/bin but $GOPATH isn't defined in my shell (though the go get command seems to work fine). Go is installed via Homebrew.

I found the missing clue by running brew info go, which says:
==> Caveats
A valid GOPATH is required to use the `go get` command.
If $GOPATH is not specified, $HOME/go will be used by default:
https://golang.org/doc/code.html#GOPATH
From that I found the executable in question at $HOME/go/bin.

go env
you can get the path from GOMODCACHE

I had a similar problem which is why I found your question. However, in my case I did not have an empty GOPATH but one with multiple directories. I worked out the issue and describe it here...
If you run go get and you already have the package it says nothing (even with the -v option). This is confusing if it's not in the first directory of your GOPATH. Ie you run go get , there is no error or any message but when you check the first directory of the GOPATH (which is where the doc says it should be) you can't find it.
I eventually found it, but since I have a large GOPATH this was rather tedious.

Even if you don't have a $GOPATH variable you can see what it uses by doing go env GOPATH.
Try this to see what your path is:
echo `go env GOPATH`/bin

Using go build
Try this with main.go. In your greeter directory, run the following command:
go build
In this case, you built your greeter application into an executable file that was added to your current directory. Check this by running the ls command:
ls
./greeter

Related

After installing go and setting my path, I am still getting an error

After installing golang according to the instructions on the golang website, I set the path as it said to by using export PATH=$PATH:/usr/local/go/bin and whenever I use the command $HOME/go it says bash: /home/ken/go: No such file or directory
I can verify go is installed and I even reset my computer to make sure the changes took place. Does anybody know what I can do to resolve this issue? Am I missing something?
As per the instructions on the Go installation page, you do need to manually create the go folder:
cd $HOME
mkdir go
cd go
Then create your first go program: https://gobyexample.com/hello-world
And run with go run hello-world.go. Should be good ;)

How to find a Go package installed with 'go get -u' when no $GOPATH is defined?

I'm following the gRPC Quickstart tutorial for Go, https://grpc.io/docs/quickstart/go/, and have installed gRPC using the command
go get -u google.golang.org/grpc
I actually haven't defined a GOPATH environment variable:
> echo $GOPATH
which, as I understand it, means that it defaults to ~/go, or in my case /Users/kurt/go.
At the next step, I'd like to build the example by doing
cd $GOPATH/src/google.golang.org/grpc/examples/helloworld
However, I find that the directory doesn't exist, and there is also no google.golang.org directory in /Users/kurt/go/src:
~/g/src> ls *google*
fish: No matches for wildcard '*google*'. See `help expand`.
ls *google*
^
Should the package not be located here? That's what I understand from Where does go get install packages?.
Using Go Modules, you can find 'go get' downloaded files at:
~/go/pkg/mod/cache/download
However, it should be treated like an immutable copy of the source code.
If you want a mutable copy of the source code, you should clone the repository:
git clone https://github.com/grpc/grpc-go
In your example output, you are in ~/g/arc
Go path default would be ~/go/src
I think auto complete bit ya there
In the end, I worked around the problem by cloning https://github.com/grpc/grpc-go which appears to contain the examples/helloworld directory I'm looking for. Still curious to hear where the package downloaded with go get is located.

GOPATH not set in VSCode [duplicate]

I'm trying to install doozer like this:
$ goinstall github.com/ha/doozer
I get these errors.
goinstall: os: go/build: package could not be found locally
goinstall: fmt: go/build: package could not be found locally
goinstall: io: go/build: package could not be found locally
goinstall: reflect: go/build: package could not be found locally
goinstall: math: go/build: package could not be found locally
goinstall: rand: go/build: package could not be found locally
goinstall: url: go/build: package could not be found locally
goinstall: net: go/build: package could not be found locally
goinstall: sync: go/build: package could not be found locally
goinstall: runtime: go/build: package could not be found locally
goinstall: strings: go/build: package could not be found locally
goinstall: sort: go/build: package could not be found locally
goinstall: strconv: go/build: package could not be found locally
goinstall: bytes: go/build: package could not be found locally
goinstall: log: go/build: package could not be found locally
goinstall: encoding/binary: go/build: package could not be found locally
GOPATH is discussed in the cmd/go documentation:
The GOPATH environment variable lists places to look for Go code. On
Unix, the value is a colon-separated string. On Windows, the value is
a semicolon-separated string. On Plan 9, the value is a list.
GOPATH must be set to get, build and install packages outside the
standard Go tree.
GOROOT is discussed in the installation instructions:
The Go binary distributions assume they will be installed in
/usr/local/go (or c:\Go under Windows), but it is possible to install
the Go tools to a different location. In this case you must set the
GOROOT environment variable to point to the directory in which it was
installed.
For example, if you installed Go to your home directory you should add
the following commands to $HOME/.profile:
export GOROOT=$HOME/go
export PATH=$PATH:$GOROOT/bin
Note: GOROOT must be set only when installing to a custom location.
(updated version of Chris Bunch's answer.)
Here is a my simple setup:
directory for go related things: ~/programming/go
directory for go compiler/tools: ~/programming/go/go-1.4
directory for go software : ~/programming/go/packages
GOROOT, GOPATH, PATH are set as following:
export GOROOT=/home/user/programming/go/go-1.4
export GOPATH=/home/user/programming/go/packages
export PATH=$PATH:$GOROOT/bin:$GOPATH/bin
So, in short:
GOROOT is for compiler/tools that comes from go installation.
GOPATH is for your own go projects / 3rd party libraries (downloaded with "go get").
First run go env.
If you see that the go isn't installed, you can install it via homebrew or via package and/or other ways.
If you are seeing output then your Go is installed.
It shows you all the envs that are set and are not.
If you see empty for GOROOT:
Run which go (On my computer : /usr/local/go/bin/go)
then export like this export GOROOT=/usr/local/go
If you see empty for GOPATH:
Create any directory anywhere on your computer for go projects in my case: ~/GO_PROJECTS
Then export GOPATH=~/GO_PROJECTS
GOPATH is discussed here:
The GOPATH Environment Variable
GOPATH may be set to a colon-separated list of paths inside which Go
code, package objects, and executables may be found.
Set a GOPATH to use goinstall to build and install your own code and
external libraries outside of the Go tree (and to avoid writing
Makefiles).
And GOROOT is discussed here:
$GOROOT The root of the Go tree, often $HOME/go. This defaults to the
parent of the directory where all.bash is run. If you choose not to
set $GOROOT, you must run gomake instead of make or gmake when
developing Go programs using the conventional makefiles.
I read the go help gopath docs and was still incredibly confused, but found this little nugget from another go doc page:
The GOPATH environment variable specifies the location of your workspace. It is likely the only environment variable you'll need to set when developing Go code.
http://golang.org/doc/code.html#GOPATH
Starting with go 1.8 (Q2 2017), GOPATH will be set for you by default to $HOME/go
See issue 17262 and Rob Pike's comment:
$HOME/go it will be.
There is no single best answer but this is short and sweet, and it can only be a problem to choose that name if $HOME/go already exists, which will only happen for experts who already have go installed and will understand GOPATH.
The GOPATH should not point to the Go installation, but rather to your workspace (see https://golang.org/doc/code.html#GOPATH). Whenever you install some package with go get or go install, it will land within the GOPATH. That is why it warns you, that you most definitely do not want random packages from the internet to be dumped into your official installation.
You generally should not set GOROOT explicitly. The go command identifies the appropriate GOROOT automatically based on its own directory location.
GOPATH defaults to $HOME/go. You only need to set it explicitly if you want to put it somewhere else.
GOPATH contains:
Binaries installed using go install, located at $GOPATH/bin.¹
This location can be overridden using the GOBIN environment variable.
A cache of downloaded module source code and checksums, located at $GOPATH/pkg/mod.
This location can be overridden using the GOMODCACHE environment variable.
If you set both GOBIN and GOMODCACHE, and do not set GO111MODULE=off, then GOPATH itself should have essentially no effect.
In addition, in the legacy GOPATH mode (when GO111MODULE=off is also set), GOPATH contains:
Source code used to build packages, stored in a directory tree rooted at $GOPATH/src.
Non-binaries installed using go install, located at $GOPATH/pkg.
Installing non-binary packages is no longer particularly useful: the go command has a cache of built artifacts, which has been required since Go 1.12 even in GOPATH mode.
The build cache is not located within GOPATH. Its location can be set with the GOCACHE environment variable.
¹ Binaries can also be installed using go get on Go 1.17 and earlier, but go install is preferred as of Go 1.16; see https://golang.org/doc/go1.16.
In modern Go, you don't need to set GOPATH or GOROOT. In fact, unless you're doing something very specialized, it's best to have them unset on your system.
Use Go modules. Having installed Go, pick a directory where you want to work. Then:
$ mkdir example
$ cd example
$ go mod init example.com
Note that the module name example.com is arbitrary; if you keep your work on GitHub, this could be something like github.com/your-username/project-name.
The last command will have created a go.mod file; now you can grab dependencies with go get:
$ go get rsc.io/quote
Now your code using this dependency:
$ touch main.go
Place this in main.go:
package main
import (
"fmt"
"rsc.io/quote"
)
func main() {
fmt.Println(quote.Go())
}
And run with:
$ go run .
W.r.t. original question, you can now get your doozer dependency with:
$ go get github.com/ha/doozer
Now you can use the doozer module in your code. And so on. You can also examine the go.mod file in your directory to see the dependencies listed, along with their versions. Each module is self-contained, with its own versions of dependencies. You can have two modules alongside each other, each with its own go.mod file pointing to different versions of some dependency - this will all work OK because of the isolation between modules.
For additional information, start with the official tutorial here. In several chapters, it walks you through the steps shown above, as well as writing your own reusable modules and packages, and importing them from other modules. Additional interactive tutorials are available at https://play-with-go.dev/
GOPATH and GOROOT configurations are deprecated.
You can use the GO module instead.
For example:
mkdir go_app
cd go_app
go mod init go_app
Regarding GOROOT specifically, Go 1.9 will set it automatically to its installation path.
Even if you have multiple Go installed, calling the 1.9.x one will set GOROOT to /path/to/go/1.9 (before, if not set, it assumed a default path like /usr/local/go or c:\Go).
See CL Go Review 53370:
The go tool will now use the path from which it was invoked to attempt to locate the root of the Go install tree.
This means that if the entire Go installation is moved to a new location, the go tool should continue to work as usual.
This may be overriden by setting GOROOT in the environment, which should only be done in unusual circumstances.
Note that this does not affect the result of the runtime.GOROOT() function, which will continue to report the original installation location; this may be fixed in later releases.
As mentioned above:
The GOPATH environment variable specifies the location of your
workspace.
For Windows, this worked for me (in Ms-dos window):
set GOPATH=D:\my_folder_for_go_code\
This creates a GOPATH variable that Ms-dos recognizes when used as follows:
cd %GOPATH%
Lots of answers but no substance, like robots doing cut and paste on what's on their system. There is no need to set GOROOT as an environment variable. However, there is a beneficial need to set the GOPATH environment variable, and if not set it defaults to ${HOME}/go/ folder.
It is the PATH environment variable that you must pay attention because this variable is the variable that can change your go version. Not GOROOT! Forget GOROOT.
Now, if you switch or change to a new go version, your downloaded packages will use the default $HOME/go folder and it will mixed-up with whatever your previous go version was. This is not good.
Therefore, this is where GOPATH you need to define in order to isolate downloaded packages of the new go version.
In summary, forget GOROOT. Think more on GOPATH.
Run go help environment it has documentation for every environment variable that can be listed by go env command
Here is one solution (single user):
GOROOT=$HOME/.local # your go executable is in $GOROOT/bin
GOPATH=$HOME/.gopath
PATH=$GOROOT/bin:$GOPATH/bin:$PATH
go complains if you change .gopath to .go.
I wish they went with how the rust/cargo guys did and just put everything at one place.
There's a command you can use: go env GOPATH
You don't need to explicitly set GOROOT (Modern versions of Go can figure it out on their own based on the location of the go binary that you run).
Also, got the follow error when trying to work with vgo:
go: modules disabled inside GOPATH/src by GO111MODULE=auto; see 'go help modules'
Removing GOROOT, updating my GOPATH and export GO111MODULE="on" resolved the issue.
GOPATH see in here
GOPATH may be set to a colon-separated list of paths inside which Go code, package objects, and executables may be found.
Set a GOPATH to use goinstall to build and install your own code and external libraries outside of the Go tree (and to avoid writing Makefiles).
As of 2020 and Go version 1.13+, in Windows the best way for updating GOPATH is just typing in command prompt:
setx GOPATH C:\mynewgopath
I had to append
export GOROOT=/usr/local/Cellar/go/1.10.1/libexec
to my ~/.bash_profile on Mac OS X
There is also a case where when we use go it compiles all the go files.
So lets say we had one file main.go and later we changed the current file to main_old.go and then added our new main.go file. Then when we build our app all the go files will get compiled. So the error that's happening might be due to compilation error in some other go files.
Once Go lang is installed, GOROOT is the root directory of the installation.
When I exploded Go Lang binary in Windows C:\ directory, my GOROOT should be C:\go.
If Installed with Windows installer, it may be C:\Program Files\go (or C:\Program Files (x86)\go, for 64-bit packages)
GOROOT = C:\go
while my GOPATH is location of Go lang source code or workspace.
If my Go lang source code is located at C:\Users\\GO_Workspace, your GOPATH would be as below:
GOPATH = C:\Users\<xyz>\GO_Workspace
For all newcomers they could do a simply export GOPATH=$HOME/go if you are using Ubuntu or do go help gopath for more information.
in osx, i installed with brew, here is the setting that works for me
GOPATH="$HOME/my_go_work_space" //make sure you have this folder created
GOROOT="/usr/local/Cellar/go/1.10/libexec"
If you are using the distro go, you should point to where the include files are, for example:
$ rpm -ql golang | grep include
/usr/lib/golang/include
(This is for Fedora 20)
the values should be (MACOS):
GOROOT="/usr/local/go" --> all binaries file core go
GOPATH="/Applications/proyectos/go" --> the route to workspace (custom workspace)

Go newbie: how to run goroutines shell?

I tried running shell-basic but nothing happens. Here is what I tried:
To run this example, download and install it with go get:
go get goroutines.com/shell-basic
which finishes silently and I see it downloaded the shell basic script but when i execute shell-basic i get:
$ shell-basic
-bash: shell-basic: command not found
did I do something wrong, or am i missing something?
what i'm interested in is running go as scripts..
go get will fetch the source and put it in your Go path, try echo $GOPATH in the shell. This is what happens if go get finishes silently.
Then you want to go to that source:
cd $GOPATH/src/goroutines.com/shell-basic
aftwards, you must run go install inside the repo. (or you can run go install /path/to/the/code.
The source will then be put in $GOPATH/bin, and be executable.
Of course none of this will work if you don't have you GOPATH set up.
I think you not set GOBIN.
You can follow:
export PATH=$PATH:$GOPATH/bin
Or, try run $GOPATH/bin/shell-basic.Use your gopath replace $GOPATH.

Golang equivalent of npm install -g

If I had a compiled Golang program that I wanted to install such that I could run it with a bash command from anywhere on my computer, how would I do that? For example, in nodejs
npm install -g express
Installs express such that I can run the command
express myapp
and express will generate a file directory for a node application called "myapp" in whatever my current directory is. Is there an equivalent command for go? I believe now with the "go install" command you have to be in the directory that contains the executable in order to run it
Thanks in advance!
Update: If you're using Go 1.16, this answer still works, but go install has changed and is now the recommended method for installing executable packages. See Karim's answer for an explanation: https://stackoverflow.com/a/68559728/10490740
Using Go >= 1.11, if your current directory is within a module-based project, or you've set GO111MODULE=on in your environment, go get will not install packages "globally". It will add them to your project's go.mod file instead.
As of Go 1.11.1, setting GO111MODULE=off works to circumvent this behavior:
GO111MODULE=off go get github.com/usr/repo
Basically, by disabling the module feature for this single command, it will install to GOPATH as expected.
Projects not using modules can still go get normally to install binaries to $GOPATH/bin.
There's a lengthy conversation and multiple issues logged about this change in behavior branching from here: golang/go - cmd/go: go get should not add a dependency to go.mod #27643.
Starting with Go >= 1.16 the recommended way to install an executable is to use
go install package#version
For example, go install github.com/fatih/gomodifytags#latest.
Executables (main packages) are installed to the directory named by the GOBIN environment variable, which defaults to $GOPATH/bin or $HOME/go/bin if the GOPATH environment variable is not set. You need to add this directory to your PATH variable to run executables globally. In my case, I've added this line to my ~/.zshrc file. (if you are using bash, add it to the ~/.bash_profile file):
export PATH="$HOME/go/bin:$PATH"
Go team published a blog post about this change, here's the explanation quote:
We used to recommend go get -u program to install an executable, but this use caused too much confusion with the meaning of go get for adding or changing module version requirements in go.mod.
Refer to go install documentation for more details
As far as I know, there is no direct equivalent to npm install -g. The closest equivalent would not be go install, but go get. From the help page (go help get):
usage: go get [-d] [-f] [-fix] [-insecure] [-t] [-u] [build flags] [packages]
Get downloads and installs the packages named by the import paths,
along with their dependencies.
By default, go get installs binaries to $GOPATH/bin, so the easiest way to make those binaries callable from everywhere is to add that directory to your $PATH.
For this, put the following line into your .bashrc (or .zshrc, depending on which shell you're using):
export PATH="$PATH:$GOPATH/bin"
Alternatively, you could also copy or link the executables to /usr/local/bin:
ln -s $GOPATH/bin/some-binary /usr/local/bin/some-binary
Short solution for Linux users:
Use the go get command as usual
Add the following lines to .bashrc:
# This is the default GOPATH, you should confirm with the 'go env' command
export GOPATH=$HOME/go
export PATH=$PATH:$GOROOT/bin:$GOPATH/bin
Restart terminal or source it. Installed binaries will be available globally.
For Go v1.8+
go install package_name#latest
Caveat: this answer is outdated following the 2020 deprecation of go get. The solution presented here won't work with newer Go runtime installs.
The closest analogue of this in Go would be go get. By default, it will fetch a Go package from a supplied repository URL, and requires a $GOPATH variable to be set in your shell so that Go knows where to store the packages (and subsequently where to find them when compiling code depending on go get-ted packages).
Example syntax:
$ go get github.com/user/repo
The behaviour supplied by npm's -g flag is default, and packages installed using go get are normally available globally.
See go get --help for more information about the command.
As mentioned by #helmbert, adding your $GOPATH to your $PATH is useful if you're installing standalone packages.
if you are using zsh :
first: install your package using :
go install package#version
then , you edit your .zshrc file
nano ~/.zshrc
Add this line to the end of .zshrc file :
export PATH="$HOME/go/bin:$PATH"
last but not least :
source ~/.zshrc
then open a new terminal and execute your command :)
TL;DR at the bottom. I'm going to walk you through how I came to this conclusion, and why the more obvious solutions don't work.
Upon seeing this question, I thought "If I could set root's GOPATH=/usr, it would install things in /usr/bin/ and /usr/src!"
So I tried the obvious thing:
Add GOPATH=/usr to root's .bashrc.
And it worked!
Sort of.
Not really.
Turns out, sudo doesn't execute root's .bashrc. For "security" or something like that.
Do env_set or something in /etc/sudoers
Turns out, /etc/sudoers can only remove environment variables. There's no env_set directive.
(As far as I can find)
Dig through man sudoers.
Where does sudo get it's default set of environment variables from?
Well, the first one in the list is /etc/environment, so that's the one I used.
sudo echo "GOPATH=/usr" >> /etc/environment
sudo go get <repo>
Binaries will be put in /usr/bin, and sources will be put in /usr/src.
Running go as non-root will use GOPATH the "normal" way.
If you don't have go installed, you may use the gobinaries. it builds an on-demand binary of the project from github repo.
The command to install the go package would be:
curl -sf https://gobinaries.com/rakyll/hey | sh

Resources