Go: Install package with -u command - go

I'm trying to install a Go package (https://github.com/jteeuwen/go-bindata#installation) by running this command
go get -u github.com/jteeuwen/go-bindata/...
I get this error:
package github.com/jteeuwen/go-bindata/...: cannot download, $GOPATH not set. For more details see: go help gopath
My GOPATH is set in the ordinary way. I understand this is caused by the -u command... how do I resolve this?

It depends on your OS, but make sure your GOPATH is set in your .bashrc (as in this question) or least set with
export GOPATH=/home/<username>/go
That way, other processes (like go get) will inherit that variable.
On Windows, you would declare that variable in your user environment variables.
To check what is already set ("Print Go environment information"):
go env
If the variable is already set, but a go get -u still fails, then this could be similar to issue 42:
Your issue is that you have installed go to a location that requires privilege escalation to install to.
Check also your GOROOT and where go is installed.

Related

Why doesn't `go env` command reflect change in environment variable?

In my system, GOBIN variable was unset (empty value). Now unlike some other GO env variables, this seems unset even in the output for go env command. (I'm user ubuntu, so ~ is /home/ubuntu/)
echo $GOBIN
//empty
echo $GOPATH
//empty
echo $GOROOT
//empty
go env GOBIN
//empty
go env GOPATH
/home/ubuntu/go
go env GOROOT
/usr/local/go
which go
/usr/local/go/bin/go
Why does go env give values different from the system environment variables? I couldn't find any documentation on this, but my assumption is that if env variables are not set at the system level, Golang sets default values - which are shown by go env. Is this assumption correct?
Why is GOBIN unset? I tried setting the system env variable explicitly, but it doesn't get reflected in go env, even though the system env variable seems to get modified. Why is that so?
echo $GOBIN
//empty
go env GOBIN
//empty
go env GOPATH
/home/ubuntu/go
GOBIN=‘/home/ubuntu/go/bin’
echo $GOBIN
/home/ubuntu/go/bin
go env GOBIN
//empty
The official documentation (https://pkg.go.dev/cmd/go) says:
Env prints Go environment information
but it doesn't mention where the said variables are sourced from.
Problem X (https://xyproblem.info/)
I am trying to install Delve (https://github.com/go-delve/delve), and my system has two go versions (go1.10.1 and go1.17.8), and I plan to use the latter (unfortunately can't remove the former)
go1.17.8 go install github.com/go-delve/delve/cmd/dlv#latest makes a new directory at /home/ubuntu => go and adds Delve here. But dlv version is unrecognized.
From go help env, GOBIN is where go install should install binaries - in my case it's unset, so I'm guessing Golang installs it at GOPATH. But even then, I expected the binary to be recognized. I also tried adding the location to my PATH, but that didn't work either.
Should I set my GOBIN to anything specific before installation via go1.17.8?
Is my system having 2 go versions (which go is pointing to the go1.10.1 version), causing this? (1.10.1 doesn't have Modules support, but I was trying the install via go.17.8, so I assumed this wouldn't be an issue)
These go env variables are variables set at the time of installation your binary.
Please refer the code of https://github.com/golang:
as per https://github.com/golang/go/blob/master/src/internal/buildcfg/cfg.go,
these variables are either taken from environment variables or default variables.
These default values are generated as per runtime https://github.com/golang/go/blob/master/src/cmd/dist/buildruntime.go#L48
Thus, these variables do not appear as part of Operating systems environment variables.
These variables can be overridden by config file at os.UserConfigDir or by command go env NAME=VALUE.
go on Linux will store persistent settings to this file:
$HOME/.config/go/env
via the go env -w command. Since the go tool loads settings from both this config and ENV VARS - this explains why you may see differing values. The go tool combines both.

Where does go get install packages?

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

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

How to set GOPATH on MAC after installing go1.4.1.darwin-amd64-osx10.8.pkg

I have run go1.4.1.darwin-amd64-osx10.8.pkg to install go on my MAC. It install go in /usr/local/go/bin/go.
Can you tell me what should my GOPATH set to? I tried '/usr/local/go' and '/usr/local/go/bin/go'. But both does not seem to be the right path.
Thank you.
GOPATH is an environmental variable used to define the location of your workplace directory. It's used by the Go tools for various reasons.
For example:
go get -u github.com/nsf/gocode
will download the source code and place it at
$GOPATH/src/github.com/nsfs/gocode
Compile that source code and
place the binary at $GOPATH/bin
Place symbol and package information at $GOPATH/pkg/architecture/github.com/nsfs
The path is also used in other tools:
go build github.com/nsf/gocode
go install github.com/nsfs/gocode
github.com/nsfs/gocode in the above commands is resolved automatically to $GOPATH/src/github.com/nsfs/gocode and thus you can run these commands without actually being in your workplace (the point of $GOPATH)
The $GOPATH location for your workplace directory can be put anywhere on your machine, but it must minimally have 3 folders (because go get and other tools need these folders).
bin
pkg
src
This environmental variable can be set like any other environmental variable. If you're using go from the Terminal.app, you can set it by opening the file:
vi ~/.bashrc
and then setting it
export GOPATH=~/goworkplace
~/goworkplace is a location to the workplace directory with those 3 folders. It can be anywhere on your system, such as, ~/Development/goworkplace, ~/Desktop/goworkplace, as long as it has those 3 folders
For information, take a look at this: https://golang.org/doc/code.html
Try this
First you can check the golang is install or not. Run go env
After that you can show the list of go env variables..
then you check where you can install the go
after that set $GOPATH
like:- export GOPATH=/var/projects/go
and also set $GOBIN
like:- export =$GOPATH/bin

Go : go get $GOPATH error, when GOPATH is set

When running the go get command :
sudo go get github.com/go-sql-driver/mysql
I get the following error
package github.com/go-sql-driver/mysql: cannot download, $GOPATH not
set. For more details see: go help gopath
However $GOPATH is already set.
Running echo $GOPATH gives /Users/userxyz/Desktop/Code
Running go env gives
.....
GOPATH="/Users/userxyz/Desktop/Code"
...
GOROOT="/usr/local/go"
.....
I have already tried setting GOPATH as an environment variable by adding the following lines
export GOPATH="$HOME/Desktop/Code"
export PATH=$PATH:$GOPATH/bin
to the following files, alternatively
~/.profile (/etc/profile)
~/.bashrc
~/.bash_profile
sudo go get github.com/go-sql-driver/mysql
This runs go get under root user, which does not have $GOPATH set.
Just do:
go get github.com/go-sql-driver/mysql
Generally, do:
go get
in the project folder, and it will install all dependencies. The following will install dependencies mentioned in tests:
go get -t
You just need to drop the sudo.
Your environment variables are defined at the user level. if you do sudo go env you'll see that GOPATH is not set there
You don't need sudo. If the "Agreeing to the Xcode/iOS license requires admin privileges" stops you, just re-open Xcode and accept the license agreement of Xcode.
Just realized after writing the response that it's almost 4 years too late but I'll leave it up just in case there are others who might need the answers...
So it seems like you might have created the directory with sudo or with root privileges. If you try $go get with a regular user you get a permissions error and when you try it with sudo you get a GOPATH unset error. I've had this problem recently, and I solved it by simply changing the ownership of the directory.
export GOPATH=/directory/of/your/goproject
chown -R ubuntu#staff $GOPATH
cd $GOPATH && go get
Here's just so you have some env variables to double check with:
export GOPATH=/home/ubuntu/work export
PATH=$PATH:$GOROOT/bin:$GOPATH/bin
Keep in mind that there shouldn't be a need for you to declare or change $GOROOT.
Finally, you might want to use [profile.d][1] to export env variables:
cat > /etc/profile.d/setgoenv.sh <<EOL
export GOPATH=/home/ubuntu/work
export PATH=$PATH:$GOROOT/bin:$GOPATH/bin
EOL
I hope that helped.
In my case, I had imported an incorrect GOPATH that did not exist and an incorrect GOROOT in my PATH
setting my export GOROOT=/opt/go then export GOPATH=$HOME/work, ensuring $HOME/work existed and had access for my user seems to have solved the problem for go get {whattoget}, then ensuring export GOPATH=$HOME/work
export PATH=$PATH:$GOROOT/bin:$GOPATH/bin was in my ~/.profile helped. Nothing in this thread seemed to quite fit.
Going forward I might just start using Docker to build my go projects, as it's a bit of a pain, and the documentation and errors are lengthy but don't seem to explain what is wrong in any meaningful and clear way (GOROOT and GOPATH were both setup, but PATH GOROOT and GOPATH all seemed to be a little off).

Resources