Does Go depend on C runtime?
Asked Answered
H

3

13

I can't find info does Go depend on C runtime? If it depends on it, is it statically compiled into the binary to make the application written in Go work everywhere without dependencies?

Here is the topic about what C runtime is

Hannahhannan answered 18/1, 2017 at 12:59 Comment(5)
Could you elaborate what a "c runtime" is? Go does not depend on inexistent stuff...Prelusive
Go does not require any C libraries if that's what you're asking.Tails
RefWhipcord
JimB, so Go-devs reimplemented all low-level stuff?Hannahhannan
@user1432751: The answer depends on what you mean by "low-level stuff". The stdlib is of course implemented entirely in Go. Go however relies on an operating system to provide a number of basic syscalls to run the application.Tails
S
23

If you're talking about executable files provided by a Go compiler, then the answer is "yes or no—it depends":

In most cases, the resulting executable program does not depend on a C run-time library.

However, on some platforms under certain circumstances the C runtime library gets dynamically linked in. In particular, this was the case with Go versions < 1.5 on Linux when DNS resolution was used: the runtime depended on the platform's libc implementation to handle such resolution. In 1.5 this has been reworked.

Another possible case is (IIRC) Solaris which provides no stable way to access the kernel's syscalls directly and requires routing these calls through the platform's libc.

There is another case: using cgo which is a layer to interface Go code with foreign C code. Using cgo makes your Go program depend on the C runtime. Note that you might not use cgo directly but one or more of the third-party packages you might be using can use cgo, and—transitively—your program ends up depending on the C runtime library.

Switchboard answered 18/1, 2017 at 13:49 Comment(1)
The cgo documentation says that cgo is enabled by default for native builds. So, it looks like one has to set CGO_ENABLED=0 to make sure that there is no a dependency on C runtime.Calzada
B
7

I think the accepted answer is correct, but a binary which imports the 'net' package usually depends on a c runtime even in go 1.10 and Unix.

Here is the example of the simple echo server:

package main

import (
        "io"
        "log"
        "net"
)

func main() {
        ln, err := net.Listen("tcp", ":8080")
        if err != nil {
                log.Fatal(err)
        }

        for {
                conn, err := ln.Accept()
                if err != nil {
                        log.Print(err)
                        continue
                }

                _, err = io.Copy(conn, conn) // blocked until the client closes the conn.
                if err != nil {
                        log.Print(err)
                        continue
                }

                if err = conn.Close(); err != nil {
                        log.Print(err)
                }
        }
}

Build it and check its dependencies:

$ go build ./libc_check.go
$ ldd ./libc_check
        linux-vdso.so.1 =>  (0x00007ffe34fc1000)
        libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fc005d4e000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fc005984000)
        /lib64/ld-linux-x86-64.so.2 (0x00007fc005f6b000)

It is because 'the decision of how to run the resolver applies at run time, not build time' as the release note indicates.

To avoid this dependency, use the 'netgo' build tag like this:

$ go build -tags netgo ./libc_check.go
$ ldd ./libc_check
        not a dynamic executable
Breedlove answered 12/7, 2018 at 5:25 Comment(3)
Don't know which version of Go you used, but on 1.11.1 your example produces binary without any dependenciesBeaming
Ummm, today I checked my example with 1.11.1 and 1.11.4 on Linux, but the binary still depends on c runtime. I also checked it using the golang:1.11.1 docker image. So I'm not really sure why the example doesn't work in your env.Breedlove
try building with cgo turned off. I tested by cross-compiling on Windows and macOS. The binary had an empty dynamic section.Beaming
D
1

If you mean LibC, Go does not depend on it. Go has its own standard library that includes implementations of commonly used functions such as file I/O, networking, and memory management, so it does not rely on libc or any other external library.

Debris answered 22/1, 2023 at 22:19 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.