mirror of
https://github.com/golang/go.git
synced 2025-05-05 15:43:04 +00:00
Rewrite page to be about GOPATH variable vs mode and deprecation.
parent
a0d42a12ba
commit
6dcbd8cb73
105
GOPATH.md
105
GOPATH.md
@ -1,57 +1,78 @@
|
||||
# Introduction
|
||||
## GOPATH variable
|
||||
|
||||
The GOPATH environment variable is used to specify directories outside of $GOROOT that contain the source for Go projects and their binaries.
|
||||
Go development using dependencies beyond the standard library is done [using Go modules](https://blog.golang.org/using-go-modules). When using Go modules, the GOPATH variable (which defaults to `$HOME/go` on Unix and `%USERPROFILE%\go` on Windows) is used for the following purposes:
|
||||
|
||||
See the [go command](http://golang.org/cmd/go/#hdr-GOPATH_environment_variable) and [go/build package](http://golang.org/pkg/go/build/) documentation for more details.
|
||||
- The `go install` command installs binaries to `$GOBIN`, which defaults to `$GOPATH/bin`.
|
||||
- The `go get` command caches downloaded modules in `$GOMODCACHE`, which defaults to `$GOPATH/pkg/mod`.
|
||||
- The `go get` command caches downloaded checksum database state in `$GOPATH/pkg/sumdb`.
|
||||
|
||||
Since the $GOPATH variable can be a list, the rest of this document will use $GOPATH to mean the first element unless otherwise specified.
|
||||
See the [go command documentation](http://golang.org/cmd/go/#hdr-GOPATH_environment_variable) for full details about the GOPATH variable. The rest of this page concerns the GOPATH development mode, which is now deprecated.
|
||||
|
||||
## Integrating GOPATH
|
||||
## GOPATH development mode
|
||||
|
||||
On OS X or Linux (bash), adding the following expression to PATH will add all $GOPATH/bin directories.
|
||||
```
|
||||
${GOPATH//://bin:}/bin
|
||||
```
|
||||
Before Go modules, Go development using dependencies used “GOPATH development mode,” or “GOPATH mode” for short. In GOPATH mode, the `go` command used the GOPATH variable for the following purposes:
|
||||
|
||||
## Directory layout
|
||||
- The `go install` command installed binaries to `$GOBIN`, which defaults to `$GOPATH/bin`.
|
||||
- The `go install` command installed the compiled package file for ‘import "example.com/y/z"` to `$GOPATH/pkg/example.com/y/z.a`.
|
||||
- The `go get` command downloaded source code satisfying ‘import "example.com/y/z"` to `$GOPATH/src/example.com/y/z`.
|
||||
|
||||
## Deprecating and removing GOPATH development mode
|
||||
|
||||
The source for a package with the import path ` "X/Y/Z" ` is in the directory
|
||||
```
|
||||
$GOPATH/src/X/Y/Z
|
||||
```
|
||||
Go modules are the replacement for GOPATH development mode to add the concept of a package version throughout the Go ecosystem.
|
||||
|
||||
The binary for a package with the import path ` "X/Y/Z" ` is in
|
||||
```
|
||||
$GOPATH/pkg/$GOOS_$GOARCH/X/Y/Z.a
|
||||
```
|
||||
The transition from GOPATH development mode to Go modules has been gradual, spread across many Go releases:
|
||||
|
||||
The binary for a command whose source is in ` $GOPATH/src/A/B ` is
|
||||
```
|
||||
$GOPATH/bin/B
|
||||
```
|
||||
- **Go 1.11 (August 2018)** introduced the `GO111MODULE` variable, which defaulted to `auto`.
|
||||
With `GO111MODULE=off`, the `go` command used GOPATH mode always.
|
||||
With `GO111MODULE=on`, the `go` command used module mode always.
|
||||
With `GO111MODULE=auto` (or leaving `GO111MODULE` unset), the `go` command decided the mode based on the current directory. If the current directory was _outside_ `$GOPATH/src` and was within a source tree with a `go.mod` file in its root, then the `go` command used Go module mode. Otherwise the `go` command used GOPATH mode. This rule ensured that all commands run in `$GOPATH/src` were unaffected in `auto` mode but let users experiment with modules in other directories.
|
||||
|
||||
## Repository integration and creating "go gettable" projects
|
||||
When fetching a package the go tool looks at the package's import path to discover a URL. For instance, if you attempt to
|
||||
```
|
||||
go get github.com/go-kit/kit
|
||||
```
|
||||
the go tool will get the source from the project hosted at https://github.com/go-kit/kit/. It will clone the repository to
|
||||
```
|
||||
$GOPATH/src/github.com/go-kit/kit
|
||||
```
|
||||
- **Go 1.13 (August 2019)** adjusted `GO111MODULE=auto` mode to remove the `$GOPATH/src` restriction: if a directory inside `$GOPATH/src` has a `go.mod` file, commands run in or below that directory now use module mode. This allows users to continue to organize their checked-out code in an import-based hierarchy but use modules for individual checkouts.
|
||||
|
||||
As a result, if (from your repository project) you import a package that is in the same repository, you need to use its "full" import path - the place "go get" puts it. In this example, if something else wants to import the "kit" package, it should import "github.com/go-kit/kit" rather than "kit".
|
||||
- **Go 1.16 (February 2021)** will change the default to `GO111MODULE=on`, using module mode always. That is, GOPATH mode will be disabled entirely by default. Users who need one to use GOPATH mode for one more release can set `GO111MODULE=auto` or `GO111MODULE=off` explicitly.
|
||||
|
||||
## Tips and tricks
|
||||
- **Go 1.17 (August 2022)** will remove the `GO111MODULE` setting and GOPATH mode entirely, using module mode always.
|
||||
|
||||
### Use a single GOPATH
|
||||
|
||||
Even though the GOPATH may be a list of directories, it is generally sufficient to use a single GOPATH for all Go code on your machine. Since all packages retrieved with "go get" have a unique URL (and thus a unique path on disk), having more than one GOPATH is almost never necessary when building with the Go tool.
|
||||
|
||||
### `vendor/` directories ignored outside of `GOPATH`
|
||||
|
||||
Note that as of go 1.11, the `vendor` directories are only supported when `$PWD` is under `$GOPATH`; see https://github.com/golang/go/issues/29670 and https://stackoverflow.com/questions/54140415/go-1-11-ignores-the-vendor-directory-the-errors-give-the-impression-the-direc/54156547#54156547.
|
||||
Note that removing GOPATH development mode does _not_ mean removing the GOPATH variable. It will still be used for the purposes listed at the top of this page.
|
||||
|
||||
## FAQ
|
||||
### Why won't ` $GOPATH/src/cmd/mycmd/*.go ` build?
|
||||
When the go command is looking for packages, it always looks in ` $GOROOT ` first. This includes directories, so if it finds (as in the case above) a ` cmd/ ` directory in ` $GOROOT ` it won't proceed to look in any of the GOPATH directories. This prevents you from defining your own ` math/matrix ` package as well as your own ` cmd/mycmd ` commands.
|
||||
|
||||
### Is the GOPATH variable being removed?
|
||||
|
||||
No. The GOPATH variable (set in the environment or by `go env -w`) is **not** being removed. It will still be used to determine the default binary install location, module cache location, and checksum database cache location, as mentioned at the top of this page.
|
||||
|
||||
### Can I still write code in GOPATH/src/import/path?
|
||||
|
||||
Yes. Many Go developers appreciate the structure that this convention provides and check out their module repositories into it. All your code needs to get started with modules is a `go.mod` file. See [`go mod init`](https://golang.org/cmd/go/#hdr-Initialize_new_module_in_current_directory).
|
||||
|
||||
### How can I compile one repo in GOPATH/src against changes made in another?
|
||||
|
||||
If you want to use unpublished changes in one module when building another, you can add a `replace` line to the other module’s `go.mod`.
|
||||
|
||||
For example, if you have checked out `golang.org/x/website` and `golang.org/x/tools` to `$GOPATH/src/golang.org/x/website` and `$GOPATH/src/golang.org/x/tools`, then to make your local builds of `website` automatically use changes in `tools`, you would add this to `$GOPATH/src/golang.org/x/website/go.mod`:
|
||||
|
||||
replace golang.org/x/tools => ../tools
|
||||
|
||||
Of course, `replace` directives know nothing about `$GOPATH`. The same line would work fine if you had checked the two out into `$HOME/mycode/website` and `$HOME/mycode/tools`.
|
||||
|
||||
### Why is GOPATH development mode being removed?
|
||||
|
||||
At its core, GOPATH development mode essentially supplies all those kinds of `replace` lines automatically, so that the code you build for dependencies is the code you happen to have checked out on your computer. That means your build is affected by old checkouts you happen to have lying around that you might have forgotten about. It means that the build you get on one machine can be different from another, even starting with the same version of the same top-level repo. And it means that the builds you get can be different from the ones another developer in the same project gets. Go modules address all these reproducibility concerns. The root cause of all these problems is that GOPATH mode does not have any concept of a package _version_.
|
||||
|
||||
In addition to reproducibility, Go modules provide a clear way to handle proxying and secure downloads. When you `git clone` a project and then grab its dependencies, those dependencies are being cryptographically checked (using the `go.sum` file) to make sure they're the same bits the original developer used. The only trusted part is the top-level `git clone`. Here again, this is only possible because Go modules, in contrast to GOPATH mode, have a concept of a package version.
|
||||
|
||||
And for future evolution of Go itself, modules clearly mark which version of the Go language a particular tree of files is written in. This makes it possible to disable problematic features—for example, `string(1)`, which many people think produces `"1"` but actually produces `"\x01"` (Ctrl-A)—in later versions of Go while keeping older programs building (because they are explicitly marked as having been written for the older version of Go).
|
||||
|
||||
There are more examples like these.
|
||||
|
||||
None of this is possible with GOPATH development mode as it exists today. We can't move the ecosystem forward and start really depending on these important properties of Go modules without retiring GOPATH mode.
|
||||
|
||||
(You might also ask: why not just add those things to GOPATH mode? The answer is: we did, and the result is Go modules.)
|
||||
|
||||
### When was it decided to deprecate GOPATH development mode?
|
||||
|
||||
The [original plan](https://blog.golang.org/modules2019) was to deprecate GOPATH mode in Go 1.13, but we wanted to take extra time to make modules even more robust for as many Go users as possible, so the deprecation was pushed back from that release. Discussion on [issue #41330](https://golang.org/issue/41330) and in the golang-tools group did not identify any remaining blockers for deprecating GOPATH, so it is now scheduled for Go 1.16, with removal in Go 1.17, as stated in the timeline above.
|
||||
|
||||
### What if I have more questions about moving from GOPATH development mode to Go modules?
|
||||
|
||||
See [golang.org/help](https://golang.org/help/) for a list of resources. If none of those are appropriate, feel free to [file an issue](https://golang.org/issue) here. We want everyone to be successful adopting Go modules.
|
||||
|
Loading…
x
Reference in New Issue
Block a user