Do Linux golang binaries depend on libc?

blov · · 809 次点击    
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
<p>Do Go binaries built with pure Go code and the <code>go</code> compiler, targeting GNU/Linux, link to glibc, or do they merely use the Go stdlib?</p> <hr/>**评论:**<br/><br/>justinisrael: <pre><p>You usually get a static binary unless you use something like the user or net package (?). But you can tell the Go build to use the pure Go implementation via <code>go build -tags netgo</code> or by setting <code>CGO_ENABLED=0</code> in your env. By default you will also get a dynamic binary if you link against go packages that use cgo, and you don&#39;t explicitly static link them. </p></pre>pzduniak: <pre><p>Depends on what you&#39;re trying to achieve. They will depend on it by default, but you can just use the following command to generate a static library (I usually do that with musl on Alpine, the binaries are quite small then):</p> <p><code>go build --ldflags &#39;-linkmode external -extldflags &#34;-static&#34;&#39;</code></p></pre>tv64738: <pre><p>Others have explained how to avoid it, here&#39;s the reasoning why glibc gets dynamically linked:</p> <p>User/group resolution, and the non-DNS aspects for host resolution, are code that only exists in the libc, and the way glibc implements those is by dynamically loading libraries based on config files. Unless you explicitly opt out (use pure-Go implementations that imitate <em>some</em> of the behavior), if you use either of those facilities, you will get a dynamically linked glibc.</p></pre>Creshal: <pre><p>Depends on the libc you use. musl libc allows fully static compilation, glibc doesn&#39;t (since it needs dynamic linking to allow nsswitch to work, a feature musl doesn&#39;t have).</p></pre>rangeCheck: <pre><p>No they don&#39;t depend on libc (unless they used cgo)</p></pre>3MuchCaffeine5Me: <pre><p>Everything has to link to glibc at some point in traditional GNU/Linux, otherwise it can&#39;t run. If you aren&#39;t, your runtime or library is.</p></pre>practical_lem: <pre><p>That&#39;s not true, you can write pure assembly code that has access to syscalls through int 0x80.</p></pre>FORGOT123456: <pre><p>seems like a comment i&#39;d expect from <a href="/u/impractical_lem" rel="nofollow">u/impractical_lem</a> , tbh</p></pre>3MuchCaffeine5Me: <pre><p>This is interesting to me. Could you explain how this works? I was pretty much taught glibc is the main interface programs need to run in Linux</p></pre>williewillus: <pre><p>Pretty much the only interface Linux the kernel exposes to user space is the system call interface, which is kept extremely stable.</p> <p>Glibc is just a (very fancy) wrapper around the system call interface that implements the functions required by the standard. Alternate implementations of these functions exist, such as musl.</p> <p>As another comment suggested, you could have C code that doesn&#39;t use libc and solely talks to the OS using assembly to invoke system calls.</p></pre>epiris: <pre><p>So glibc is just another library, albeit a massive one and Linux is just one of the systems it supports. I find myself digging through it every few years for some reason or another, usually to find size / alignment or just general reference for an architecture I don&#39;t have access to. Which last I counted it supported something like 45 architectures which is pretty impressive, even for a 30 year old code base.</p> <p>Thinking about it if you ever have some time to kill check it out from <code>git://sourceware.org/git/glibc.git</code> and head to <code>./sysdeps/unix/sysv/linux</code> from there to get a view of what a fully implemented system call interface interface looks like. It makes it clear why Go only implements the bare minimum system calls it needs because it&#39;s a real pain to implement them, and Go only supports a small subset of popular architectures. It&#39;s actually not very difficult to make system calls to the Linux kernel, all of the effort comes from the nuances of architecture specific details. POSIX structure padding, alignment, endianness and specific system calls that may have a subtle divergence from POSIX due to some bug being immortalized due to importance of ABI. Maybe glibc had a bug the kernel worked around or maybe vice versa, who knows, but some times it just doesn&#39;t make sense why something is the way it is. But it got that way some how and I think it&#39;s neat, lol.</p> <p>Go actually piggybacks off all the effort of glibc, even though it doesn&#39;t <em>need</em> to link to it directly to run. I discovered this when I wanted some additional structures (posix signal.h) that the Go syscall package actually fires up a docker container and generates all the structures for each platform using clang, which is pretty clever. But it still can leave a good bit of manual hacking to take in a fresh posix header. This is turning into a wall of text considering you asked a simple question, sort of.</p> <p><strong>tldr;</strong> System calls to Linux are simple while portability is not, given Go is less portable it has less crusty stuff, making it a great place to observe user&lt;-&gt;kernel space interaction.</p></pre>

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

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