dqef7931 2019-06-27 19:42
浏览 396

为什么Golang在Linux上使用libc [关闭]

By doing ldd /usr/local/go/bin/go in centos7, I see Go uses libc and some other runtime libraries:

$ ldd /usr/local/go/bin/go
    linux-vdso.so.1 (0x00007fff2c9bd000)
    libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fe5ebc6d000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fe5eba83000)
    /lib64/ld-linux-x86-64.so.2 (0x00007fe5ebccb000)

It is strange to me as I understand that since version 1.5, Golang has been bootstrapped. That means you can build Golang without a C compiler. And Go compiler in most cases builds binaries that are not dynamically linked.

Though I downloaded the source of the Golang and built it locally, I thought there might be a pre-Go compiler which was built by gcc on my machine and then it builds the final Go compiler.

Anyone has idea on it?

  • 写回答

1条回答 默认 最新

  • dreamy6301 2019-06-27 21:25
    关注

    What is libc:

    The main C library that contains the well-known POSIX functions such as printf, open, close, read, write, and so on

    And see:

    What is the role of libc(glibc) in our linux app?
    Is MSVCRT under Windows like glibc (libc) under *nix?
    http://www.etalabs.net/compare_libcs.html


    Go:
    For example On Linux, Go runtime uses libc when cgo is enabled.

    https://golang.org/doc/install/source#go14

    The Go toolchain is written in Go. To build it, you need a Go compiler installed. The scripts that do the initial build of the tools look for an existing Go tool chain in $GOROOT_BOOTSTRAP. If unset, the default value of GOROOT_BOOTSTRAP is $HOME/go1.4.

    There are many options for the bootstrap toolchain. After obtaining one, set GOROOT_BOOTSTRAP to the directory containing the unpacked tree. For example, $GOROOT_BOOTSTRAP/bin/go should be the go command binary for the bootstrap toolchain.

    To use a binary release as a bootstrap toolchain, see the downloads page or use any other packaged Go distribution.

    To build a bootstrap toolchain from source, use either the git branch release-branch.go1.4 or go1.4-bootstrap-20171003.tar.gz, which contains the Go 1.4 source code plus accumulated fixes to keep the tools running on newer operating systems. (Go 1.4 was the last distribution in which the toolchain was written in C.) After unpacking the Go 1.4 source, cd to the src subdirectory, set CGO_ENABLED=0 in the environment, and run make.bash (or, on Windows, make.bat).

    To cross-compile a bootstrap toolchain from source, which is necessary on systems Go 1.4 did not target (for example, linux/ppc64le), install Go on a different system and run bootstrap.bash.


    Here some links to the libc on Go source code:


    https://go.googlesource.com/go/+/master/src/cmd/cgo/doc.go

    For example, package net uses cgo for access to name resolution functions provided by libc.


    src/os/user/user.go:6

    Package user allows user account lookups by name or id.

    For most Unix systems, this package has two internal implementations of resolving user and group ids to names. One is written in pure Go and parses /etc/passwd and /etc/group. The other is cgo-based and relies on the standard C library (libc) routines such as getpwuid_r and getgrnam_r.

    When cgo is available, cgo-based (libc-backed) code is used by default. This can be overridden by using osusergo build tag, which enforces the pure Go implementation.


    src/cmd/link/internal/arm64/asm.go:96

    // adddynrel implements just enough to support external linking to
    // the system libc functions used by the runtime.
    func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool {


    src/cmd/vendor/golang.org/x/arch/x86/x86asm/testdata/libmach8db.c:34

     #include <libc.h>
    

    An important exception is builds using a pre-compiled copy of the standard library. In particular, package net uses cgo on most systems, and we want to preserve the ability to compile pure Go code that imports net without requiring gcc to be present at link time. (In this case, the dynamic library requirement is less significant, because the only library involved is libc.so, which can usually be assumed present.) This conflict between functionality and the gcc requirement means we must support both internal and external linking, depending on the circumstances: if net is the only cgo-using package, then internal linking is probably fine, but if other packages are involved, so that there are dependencies on libraries beyond libc, external linking is likely to work better. The compilation of a package records the relevant information to support both linking modes, leaving the decision to be made when linking the final binary.

    评论

报告相同问题?

悬赏问题

  • ¥15 c程序不知道为什么得不到结果
  • ¥40 复杂的限制性的商函数处理
  • ¥15 程序不包含适用于入口点的静态Main方法
  • ¥15 素材场景中光线烘焙后灯光失效
  • ¥15 请教一下各位,为什么我这个没有实现模拟点击
  • ¥15 执行 virtuoso 命令后,界面没有,cadence 启动不起来
  • ¥50 comfyui下连接animatediff节点生成视频质量非常差的原因
  • ¥20 有关区间dp的问题求解
  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 slam rangenet++配置