Live data from Hacker News

Go is portable, until it isn't

simpleobservability.com

11–20 of 138 posts

Re: Go is portable, until it isn't

#11

Once you use CGO, portability is gone. Your binary is no longer staticly compiled. This can happen subtley without you knowing it. If you use a function in the standard library that happens to call into a CGO function, you are no longer static. This happens with things like os.UserHomeDir or some networking things like DNS lookups. You can "force" go to do static compiling by disabling CGO, but that means you can't u…

There are at least a couple of ways to run SQLite without CGO.

Re: Go is portable, until it isn't

#12
post #3
post #2

This seems to imply that Go's binaries are otherwise compatible with multiple platforms like amd64 and arm64, other than the issue with linking dynamic libraries. I suspect that's not true either even if it might be technically possible to achieve it through some trickery (and why not risc-v, and other architectures too?).

Of course you still need one binary per CPU architecture. But when you rely on a dynamic link, you need to build from the same architecture as the target system. At that point cross-compiling stops being reliable.

I happily and reliably cross build Go code that uses CGO and generate static binaries on amd64 for arm64.

Re: Go is portable, until it isn't

#13
post #11

Once you use CGO, portability is gone. Your binary is no longer staticly compiled. This can happen subtley without you knowing it. If you use a function in the standard library that happens to call into a CGO function, you are no longer static. This happens with things like os.UserHomeDir or some networking things like DNS lookups. You can "force" go to do static compiling by disabling CGO, but that means you can't u…

There are at least a couple of ways to run SQLite without CGO.

I think the standard answer here is modernc.org/sqlite.

Re: Go is portable, until it isn't

#14
post #10

Once you use CGO, portability is gone. Your binary is no longer staticly compiled. This can happen subtley without you knowing it. If you use a function in the standard library that happens to call into a CGO function, you are no longer static. This happens with things like os.UserHomeDir or some networking things like DNS lookups. You can "force" go to do static compiling by disabling CGO, but that means you can't u…

You can definitely use CGO and still build statically, but you do need to set ldflags to include -static.

You can even cross-compile doing that.

Re: Go is portable, until it isn't

#15
Interesting that it uses the C API to collect journals. I would’ve thought to just invoke journalctl CLI. On platforms like macOS where the CLI doesn’t exist it’s an error when you exec, not a build time error.

Re: Go is portable, until it isn't

#17
post #5

This is an (organizational) tooling problem, not a language problem - and is no less complicated when musl libc enters the discussion.

The conclusion of the article says that it's not the language problem either. Under the title "So, is Go the problem?" Or do you mean something else here?

Given that the title implies the opposite, I think it's a fair criticism. Pointing out clickbait might be tedious, but not more so than clickbait itself.

Re: Go is portable, until it isn't

#18
post #3
post #2

This seems to imply that Go's binaries are otherwise compatible with multiple platforms like amd64 and arm64, other than the issue with linking dynamic libraries. I suspect that's not true either even if it might be technically possible to achieve it through some trickery (and why not risc-v, and other architectures too?).

Of course you still need one binary per CPU architecture. But when you rely on a dynamic link, you need to build from the same architecture as the target system. At that point cross-compiling stops being reliable.

Is it some tooling issue? Why is is an issue to cross-compile programs with dynamic linking?

Re: Go is portable, until it isn't

#19
You hit this real quick when trying to build container images from the scratch. Theoretically you can drop a Go binary into a blank rootfs and it will run. This works most of the time, but anything that depends on Go's Postgres client requires libpq which requires libc. Queue EFILE runtime errors after running the container.

Re: Go is portable, until it isn't

#20

Once you use CGO, portability is gone. Your binary is no longer staticly compiled. This can happen subtley without you knowing it. If you use a function in the standard library that happens to call into a CGO function, you are no longer static. This happens with things like os.UserHomeDir or some networking things like DNS lookups. You can "force" go to do static compiling by disabling CGO, but that means you can't u…

> This happens with things like os.UserHomeDir or some networking things like DNS lookups.

The docs do not mention this CGO dependency, are you sure?

https://pkg.go.dev/os#UserHomeDir

Post reply on HN