Is GOPATH really needed? Can we make do, without it?

xuanbao · · 1222 次点击    
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
<p>I&#39;m just starting to learn Go, and am trying to install it on my mac using HomeBrew. All articles I&#39;ve read regarding this involve setting the GOPATH environment variable, and adding it to the PATH variable.</p> <p>Does this mean that all my Go code has to reside within this folder? What if I wanted to organise my code in a different way, lets say, by project; or have my Go code as a part of another project?</p> <hr/>**评论:**<br/><br/>mwholt: <pre><p>I hesitated when I was new at Go too. Eventually I just wound up using one GOPATH and organizing not only my Go code inside it, but ALL my code (except some website stuff). It is simple and has worked really, really well. Especially with $GOPATH/bin in my PATH.</p></pre>ericanderton: <pre><p>It really depends on how you organize your sourcecode.</p> <p>I would recommend the following approach:</p> <ol> <li>Set <code>GOPATH=xyz</code> in your .profile or .bashrc file for your user account. This way, when you start a new shell, you have GOPATH pointing at your default workspace for all Go code.</li> <li>Consider lightweight scripts to set GOPATH for discrete projects. I tend to wrap <code>go build</code> etc. in Makefiles, so GOPATH usually gets set to <code>pwd</code> for those projects. This way, I can build software with depenencies that are distinct from what&#39;s going on elsewhere. But a one-liner BASH script to set the environment would work too.</li> <li>For one-off tasks, just <code>export GOPATH=$(pwd)</code> or set it inline (<code>GOPATH=$(pwd) go build</code>) when you need it.</li> </ol> <p>The reason why it&#39;s a variable is that you may have any number of strategies for managing your go code. Go doesn&#39;t care, just as long as it can find dependencies. Just pick what works for you and roll with it.</p></pre>shishir_sri: <pre><p>Hey. Thanks for the detailed response.</p> <p>Just to clarify, lets say, I setup my GOPATH to &#34;$HOME/go&#34;, and have my project repo in &#34;$HOME/project&#34;. Now, the project repo just has the source code. If I set my GOPATH to PWD in my make file, or set it inline, wouldn&#39;t it cause the Go compiler to be unable to find the bin folder or other dependencies?</p> <p>I guess what I&#39;m unclear about, at this point, is where the Go compiler and linker binaries are located. I was assuming that the entire Go environment is set-up within the &#34;workspace&#34;, but I&#39;m starting to feel that this is incorrect.</p> <p>If this is indeed incorrect, does it mean that I can setup a new workspace for each project, and just make sure the locations of these projects are included in the GOPATH variable?</p></pre>bertold: <pre><blockquote> <p>lets say, I setup my GOPATH to &#34;$HOME/go&#34;, and have my project repo in &#34;$HOME/project&#34;. </p> </blockquote> <p>This doesn&#39;t work. If you GOPATH is <code>$HOME/go</code>, your project necessarily must live at <code>$HOME/go/src/project</code>, or (canonically, assuming your project is hosted on GitHub) <code>$HOME/go/src/github.com/username/project</code>.</p> <p>If you <em>insist</em> on keeping your project in <code>$HOME/project</code> — which, to be clear, without further information, you almost certainly shouldn&#39;t — then you need to subvert the Go toolchain to build your code, either by setting up a GOPATH-like structure within the project (i.e. put your Go code in <code>$HOME/project/src/packagename</code> and set GOPATH to <code>$HOME/project</code>) or by invoking the compiler and linker manually. But let me emphasize that this almost certainly is a bad idea and you should do it the other way.</p></pre>fenduru: <pre><p>If a tool/compiler/etc is going to make demands of me, then there should be some benefit that I&#39;m gaining. The only benefit I see here is not having to deal with the shortcomings of the tooling... </p></pre>bertold: <pre><p>The tool exists and is the defacto standard for operations X, Y, Z. The benefit you get by complying with its conventions is that you&#39;re, er, standards-compliant. Nobody is going to use your package if the build instructions are anything other than <code>go get github.com/fenduru/package</code>.</p></pre>fenduru: <pre><p>The reasoning here is circular. Very similar to &#34;what benefit do I get from following the law&#34;...&#34; because otherwise you&#39;d be a criminal&#34;</p></pre>shazow: <pre><p>All good advice, just a little protip: You can use <code>$PWD</code> instead of <code>$(pwd)</code> which is an env var containing the same value.</p> <p>E.g. <code>export GOPATH=$PWD</code></p></pre>avrtno: <pre><blockquote> <p>trying to install it on my mac using HomeBrew</p> </blockquote> <p>People have had issues with the HomeBrew installation in the past. Perhaps it&#39;s good now. I recommend using the official <a href="http://golang.org/doc/install#osx" rel="nofollow">OS X installer</a>. </p> <blockquote> <p>setting the GOPATH environment variable, and adding it to the PATH variable</p> </blockquote> <p>Do not add GOPATH to PATH.</p> <blockquote> <p>Does this mean that all my Go code has to reside within this folder</p> </blockquote> <p>If you want to use the <code>go</code> tool to build, then yes. You can choose any organization that you want of you run the compiler and linker directly. Very few people do this, so it will be tough going if you take this path.</p></pre>MadPhoenix: <pre><blockquote> <p>Do not add GOPATH to PATH</p> </blockquote> <p>Perhaps s/he meant add $GOPATH/bin to PATH, which is recommended by <a href="https://golang.org/doc/code.html">How to Write Go Code</a></p></pre>shishir_sri: <pre><p>Yeah. This is what I meant. Sorry I wasn&#39;t clearer about it.</p></pre>demizer: <pre><p>IMHO GOPATH is one of the best and worst features of Go. </p> <p>Gopath is essentially what virtualenv is to Python and it is wonderful having development environments for Go projects. Unfortunately thanks to the go get command, a GOPATH can be quite rigid and frustrating to work with. But there are workarounds...</p> <p>The GOPATH per project is nice, and I have used it. The best thing about this is that only dependencies used by the current project are pulled in by go get and you know exactly what they are for. Another benefit is when using godoc -http=:6060 only the packages used by the project are picked up which makes for a cleaner documentation experience. However, it is expected that projects in the community be &#34;go get-able&#34;, which is broken with the one-gopath-per-project technique. Also, the Go devs advise against this technique.</p> <p>Eventually I got tired of messing with it and just set GOPATH=$HOME. This is the best and most direct way for setting the GOPATH.</p> <p>I also would advise NOT using go get on arbitrary packages you find on Github because it and it&#39;s dependencies will clog your GOPATH. When I want to test a package, I set GOPATH=$PWD in a temporary directory and then use go get. I have a ceremony every year where I wipe my GOPATH and start back fresh.</p> <p>I love Go, and the simplicity and that&#39;s what keeps me coming back. Also, Godeps!</p></pre>robertmeta: <pre><p>I don&#39;t mean to be harsh, but it is nonsensical to compare the GOPATH environmental variable to the virtualenv project. Virtualenv handles versions, dependencies, permissions, sand-boxing. </p> <p>GOPATH is simply where Go (specifically the go tool, and since then additional tools written by 3rd parties) reads from and writes to, nothing fancy or complex.</p></pre>demizer: <pre><p>Ok. Thanks. Go python!</p></pre>robertmeta: <pre><p>Or &#34;Boo Python!&#34; in my case, the fact that you have to use virtualenv is a goddamn nightmare... part of why I grew to loath Python was deploying it and its general break-ability... at one shop, they were maintaining 80+ virtualenvs.</p></pre>robertmeta: <pre><blockquote> <p>Does this mean that all my Go code has to reside within this folder?</p> </blockquote> <p>Not has to, but probably should. </p> <blockquote> <p>What if I wanted to organise my code in a different way, lets say, by project; or have my Go code as a part of another project?</p> </blockquote> <p>Go is opinionated, about how you structure you code, and how you format your code. It is all at the end of the day optional -- you can use GNU formatting style (when it doesn&#39;t break syntax rules) and a hand tuned makefile without ever using the go command line tool or GOPATH, but I wouldn&#39;t recommend it. If you go off the reservation and want to do you own wild thing, awesome, do it! But don&#39;t expect help or sympathy -- one you go off the well worn path, you are on your own.</p> <p>If you are just learning, just follow the norms of the language you are using (be it Go or some other language) -- once you reach expert status in the language you can make decisions about where you want to break from language norms (or if you are high enough in the community, try to reshape those language norms).</p></pre>dmikalova: <pre><p>Honestly just try going with the flow because otherwise you&#39;re just going to hate yourself because everything else in the Go ecosystem uses GOPATH paths. GOPATH is organized by project - under your ID and a URL. If you <em>really</em> want to organize it with your other projects or inside of another project, you could just symlink those folders into your GOPATH or vice versa.</p></pre>om0tho: <pre><p>Andrew Gerrand, who works on the Go project at Google, has explicitly said that 1 GOPATH is the official supported way to do things.</p> <p><a href="https://groups.google.com/forum/#!topic/golang-nuts/dxOFYPpJEXo" rel="nofollow">https://groups.google.com/forum/#!topic/golang-nuts/dxOFYPpJEXo</a></p></pre>fern4lvarez: <pre><p>You can, some people do, have a separated GOPATH per project.</p></pre>ggtsu_00: <pre><p>I usually just do <code>GOPATH=`pwd</code>`. But I vendor all my dependencies anyways so using that just gets GOPATH out of the way so I can build and run my code without having to deal with environment dependent builds.</p></pre>Jhsto: <pre><p>The <a href="https://github.com/moovweb/gvm" rel="nofollow">gvm</a> project allows you to have your Go applications scattered around your computer.</p> <p>Adding your local packages to your GOPATH is done via <code>gvm linkthis</code> command.</p> <p>Just try it, it&#39;s magnificent.</p></pre>: <pre><p>[deleted]</p></pre>lethalman: <pre><p>Nix uses GOPATH for composing libraries. Works very well and you just forget about the existence of GOPATH. You just tell nix which go packages you want for your project, and you have them ready to compile your project with <code>go build</code>: <a href="http://lethalman.blogspot.it/2015/02/developing-in-golang-with-nix-package.html" rel="nofollow">http://lethalman.blogspot.it/2015/02/developing-in-golang-with-nix-package.html</a></p> <p>Additionally, also the PATH is set automatically by nix in case some go dependencies has binaries.</p> <p>Think of it like a virtualenv of python, except for go (or anything else). Not sure if that might interest you :)</p></pre>kosokun: <pre><pre><code>export GOPATH=$HOME </code></pre></pre>dinkumator: <pre><p>I just set GOPATH=$HOME and put all my projects (go or otherwise) in src. It&#39;s actually made my organization a little more sane.</p></pre>dwevlo: <pre><p>You can symlink folders into the GOPATH folder. I do this for some projects that I want auto-synced via copy.com.</p></pre>bertold: <pre><blockquote> <p>Does this mean that all my Go code has to reside within this folder? </p> </blockquote> <p>Yes.</p> <blockquote> <p>What if I wanted to organise my code in a different way, lets say, by project; or have my Go code as a part of another project?</p> </blockquote> <p>You don&#39;t.</p> <p>(Technically, you can manipulate GOPATH as part of your build process. Practically, you shouldn&#39;t. The easiest way to resolve all of these problems is to set GOPATH=$HOME and check out all your projects in their canonical places, e.g. <code>$HOME/src/github.com/user/project</code>.)</p></pre>thomasfr: <pre><p>GOPATH can also contain multiple entries just like PATH.</p></pre>DavidDavidsonsGhost: <pre><p>Til! What is the effect of this?</p></pre>ngrilly: <pre><p>The effect is that a dependency will be searched in each path defined in GOPATH, until it is found or the end of the list is reached. That way, you can define many &#34;roots&#34; for your Go packages. But, and this is an important &#34;limitation&#34;, when building a package, stale dependencies will be automatically recompiled only when they are in the same &#34;root&#34; as the package that imports them. Stale dependencies in other roots are not automatically recompiled. It&#39;s by design, but it&#39;s good to know.</p> <p>Edit: Added 3 missing words.</p></pre>jerf: <pre><p>In addition to what ngrilly said, &#34;go get&#34; will put what it goes and gets into the first element of the GOPATH. Since I&#39;m currently manually handling vendoring (not enough use of other code to make anything else worthwhile), I have the first element of the GOPATH point into something that gets .gitignore&#39;d, so I don&#39;t pollute my repo with &#34;go get&#34;. It&#39;s pretty easy then to fetch out just what I want explicitly, and I can still use &#34;go get&#34; to get binaries and stuff for gocode, goimports, etc.</p></pre>thomasfr: <pre><p>I use it for running tests/builds against godep saved workspace dir inside the same repo that should be on the gopath. I can reproduce builds and not have to do import path rewriting or copying the files first for each build.. I also have a makefile that mounts one project inside a docker container to do cross platform builds using native build chains for win/osx/win and do the same thing there..</p></pre>manghoti: <pre><p>I don&#39;t?!</p> <p>I arrived at this thread because I&#39;m working on a multi language project <strong>right now</strong> that uses go as the language for one of our projects internal components. It doesn&#39;t belong in go&#39;s project structure, and it&#39;s libraries may fall out of sync with bleeding edge. We have a Vagrant project that acts as a central hub for all our components, and it as such, does not fit with go&#39;s ordained structure. </p> <p>What do you mean <em>I don&#39;t</em>?</p></pre>jerf: <pre><p>Some people have been adamant that you should only have one GOPATH for everything. It seems to me that the community has toned this down, though you&#39;ll still hear it.</p> <p>Personally I&#39;ve used multiple GOPATHs for a long time, and find myself suspecting that those who advocate so strongly for one big GOPATH simply don&#39;t have needs as complicated as mine. If nothing else, mixing &#34;work&#34; and &#34;personal&#34; is just a bad idea.</p></pre>bertold: <pre><p>If your Go code is tightly scoped to a specific large-scale project, and isn&#39;t intended to be part of the broader Go ecosystem, then congratulations for being part of the 1% — do whatever you want. Hell, invoke the compiler and linker manually using a Makefile.</p></pre>manghoti: <pre><p>I feel like businesses exploring golang for potential deployment and use into their existing infrastructure is a far more common use case than someone starting a stack from scratch. </p></pre>Raiyni: <pre><p>I would actually make a directory for go and set that to your GOPATH. Allows for easier management and less clutter in your home dir. </p></pre>shishir_sri: <pre><p>Awesome. Thank you!</p></pre>jamra06: <pre><p>If you program with other languages, it&#39;s going to get confusing having a src directory in your home folder.</p></pre>bertold: <pre><p>Projects in other languages can live under <code>src</code>, too.</p></pre>

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

1222 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传