<p>I have been reading the blog post about the upcoming <code>rustup</code> tool:</p>
<p><a href="http://blog.rust-lang.org/2016/05/13/rustup.html" rel="nofollow">http://blog.rust-lang.org/2016/05/13/rustup.html</a></p>
<p>As far as I understand, it achieves two things:</p>
<ol>
<li>manage different rustc compiler versions installed on the same machine</li>
<li>handle cross-compilation</li>
</ol>
<p>For me, the second purpose is more interesting. For many types of applications, we can assume that a target system will already have C/C++ toolchains installed so that only the source code could be distributed, but this is not the case for Go. For this reason, it makes sense to distribute the binaries for those people who does not want to install Go compilers to their systems. There comes the need for cross-compilation.</p>
<p>I have been trying out some examples on my machine with Go 1.6 using a simple hello world program as a vanilla go example and another program using <code>string.h</code> as a cgo example and the current situation looks like this:</p>
<ul>
<li>For vanilla go applications, <code>go build</code> defaults to building static binaries.</li>
<li>For vanilla go applications, <code>$GOOS</code> and <code>$GOARCH</code> works as expected to build binaries for the target os and architecture.</li>
<li>For cgo applications, <code>go build</code> defaults to building dynamic binaries. To build a static binary instead, <code>go build -ldflags '-extldflags "-static"'</code> can be used. (Is this still the proper way to do it?)</li>
<li>For cgo applications, changing <code>$GOOS</code> and <code>$GOARCH</code> results in an error <code>can't load package: package .: no buildable Go source files in /tmp/asd</code>. I guess this should be expected as I shouldn't have a static libc installed on my machine for other os and architectures.</li>
</ul>
<p>So my questions are;</p>
<ol>
<li>Is there a way to cross-compile cgo applications? (and statically?)</li>
<li>In the rust article, they mention that it is not possible to statically link against GNU libc for technical reasons. To my knowledge, there is no other libc installed on my machine unless Go ships with its own version or so, but it seem that I can link against it just fine. Does anyone know anything about this?</li>
<li>I have been hearing a lot about this Docker thing lately although skimming through a few places I still don't understand what exactly it is. Is this somehow related to this issue?</li>
</ol>
<p>Thanks in advance.</p>
<hr/>**评论:**<br/><br/>AnAge_OldProb: <pre><p>As for 2) </p>
<p>Go doesn't use libc. Go's segmented stacks make calling c functions generally inefficient, so the go authors use sys calls directly. This can make porting easier or harder depending on how you look at it. It's a smaller surface area but many platforms, notably Windows do not consider sys calls a public api and change them between releases. </p></pre>lapingvino: <pre><ol>
<li>set the CC-variable to a corresponding C crosscompiler and explicitly enable CGO (CGO_ENABLED=1) in addition to the GOOS and GOARCH and it should work: <a href="https://gist.github.com/steeve/6905542" rel="nofollow">https://gist.github.com/steeve/6905542</a> (the crosscompile script is not necessary any more since the compiler went 100% Go)</li>
<li>Go can even be compiled without any dependency on libc, although it CAN be used, and indeed must be used if compiling with cgo.</li>
<li>Docker is very good for isolating different versions of anything, but runs on your OS kernel, so it won't solve crosscompiling issues.</li>
</ol></pre>scottjbarr: <pre><p>I believe there are tools to help you work with multiple versions of GO but it is so simple to work with multiple versions that is seems almost pointless to use the tool. I have multiple versions of Go installed under ~/.go/versions/</p>
<pre><code>$ ls -1 ~/.go/versions
go1.4.3
go1.5.3
go1.6.2
</code></pre>
<p>I then set GOROOT and GOPATH, and a suitable PATH in my .bashrc</p>
<pre><code>export GOROOT=$HOME/.go/versions/go1.6.2
export GOPATH=$HOME/p/go
export PATH=$GOPATH/bin
</code></pre>
<p>If I want to change my default Go version I either update my .bashrc, or I set the environment variables just for a particular shell.</p>
<p>As far as cross compilation goes, I use a Makefile to simplify things. It saves me remembering the GOOS and GOARCH values I need for the targets I care about. Take a look at one of my simple examples <a href="https://github.com/scottjbarr/bonusly-mp/blob/master/Makefile" rel="nofollow">https://github.com/scottjbarr/bonusly-mp/blob/master/Makefile</a>.</p>
<p>I hope this is useful :)</p></pre>bonv: <pre><p>Since Go has a sane backward compatibility I haven't felt the need to have multiple versions so far, it looks like a good way to do it, thanks.</p>
<p>Your example cross-compile script is I think for pure go applications. For cgo applications, things get a little bit complicated. I guess it is best to stick to only pure go libraries when cross-compile is in question.</p></pre>vldo: <pre><p>for 1) you could use <a href="https://github.com/moovweb/gvm" rel="nofollow">gvm</a></p></pre>haskell_suxor: <pre><p>Nothing. Go can cross compile for every platform out the box. Rustup is a symptom of the cost of basing your langauge of the bloated llvm toolkit.</p></pre>f2f: <pre><p>rustup exists because rust's environment is a mess of incompatibilities. in go you have the guarantee that your code will compile and work with any version everywhere. making a new directory for a new GOROOT and changing to it is not hard.</p></pre>
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889
- 请尽量让自己的回复能够对别人有帮助
- 支持 Markdown 格式, **粗体**、~~删除线~~、
`单行代码`
- 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
- 图片支持拖拽、截图粘贴等方式上传