I'm the original poster. I've looked into this more and I might have an explanation for
what's going on.
Just for yuks, I started with perhaps the simplest Go program, which I called t.go:
package main
func main() {
}
As root, I was able to build both a dynamically (21512 bytes) and a statically
(1203019 bytes)
linked executable.
This is with go version go1.19.4 linux/amd64.
I then ran
go build -linkshared -x t.go
This showed all the commands the go tool executed. I saved these commands in a file
so I could look more closely at what was going on.
Here's what I think is going on. When running go build -linkshared go attempts to create a new
version of the shared runtime library. At first glance, it appears that only the code that's necessary
to run the executable is put there (I'm not 100% sure about this). But it's clear that a new file
called
/usr/local/go/pkg/linux_amd64_dynlink/libstd.so
is created. As a normal user I create or write to this file, which is why I get all
the permission denied error messages. So, the main question is why does go build create
this library when I already ran
go install
-buildmode=shared std
to create the shared library?
To continue, as root I changed the ownership of
/usr/local/go/pkg/linux_amd64_dynlink
to me, and then, as me, was finally able to create the dynamically linked executable!
So, to answer my original question, the reason I can't create a dynamically linked
executable is because the go build tool attempts to create a new shared library in
a location that a normal user can't write to. Whether it's actually necessary to
create this shared library I can't say, but if so, it should be done an a directory
that a normal user can write to.
This also answers the second question, which is why it takes longer to create a dynamically
linked executable than a statically linked executable. This is due to the time it takes to
build the possibly-extraneous shared library.
I welcome any comments and/or corrections to any of this.
Cordially,