How to cross-compile Go 1.19 compiler for Solaris 11 on Linux

959 views
Skip to first unread message

Shane

unread,
Aug 17, 2022, 7:28:36 PM8/17/22
to golang-nuts
Hi fellow Gophers!

I am trying to follow what I believe to be the official instructions for building Go from source. (I am not trying to build my own Go code, I am trying to build the Go project itself.)

The reason I want to do this is to build a Go 1.19 compiler for Solaris, since there are no prebuilt Go 1.19 binaries for Solaris available on the Go downloads page.

On the official instructions page, under the "Optional environment variables" section, it says "The Go compilation environment can be customized by environment variables."

Later in this same section, it then says that the GOOS and GOARCH environment variables can be used to set the target operating system and compilation architecture.

I tried building like this, after cloning the source code and checking out the go1.19 tag, but the build fails:

$ GOOS=solaris GOARCH=amd64 GOROOT_FINAL=../publish ./all.bash
Building Go cmd/dist using /usr/local/go. (go1.19 linux/amd64)
Building Go toolchain1 using /usr/local/go.
Building Go bootstrap cmd/go (go_bootstrap) using Go toolchain1.
Building Go toolchain2 using go_bootstrap and Go toolchain1.
Building Go toolchain3 using go_bootstrap and Go toolchain2.
Building packages and commands for host, linux/amd64.
# runtime/cgo
linux_syscall.c: In function '_cgo_libc_setresgid':
linux_syscall.c:67:2: error: implicit declaration of function 'setresgid' [-Werror=implicit-function-declaration]
linux_syscall.c: In function '_cgo_libc_setresuid':
linux_syscall.c:73:2: error: implicit declaration of function 'setresuid' [-Werror=implicit-function-declaration]
cc1: all warnings being treated as errors
go tool dist: FAILED: /some/redacted/parent/dirs/go/goroot/pkg/tool/linux_amd64/go_bootstrap install std cmd: exit status 2

I am building on Linux. I have gcc and Go 1.19 installed on my Linux system, and both tools are on my PATH.

I am looking for help fixing these errors.

Best regards,
Shane

Ian Lance Taylor

unread,
Aug 17, 2022, 10:16:10 PM8/17/22
to Shane, golang-nuts
See src/bootstrap.bash for a script that can build a toolchain for a
different target.

That said, that's a strange error. What C library version are you using?

Ian

Shane

unread,
Aug 18, 2022, 8:05:37 PM8/18/22
to golang-nuts
I'm not sure what you mean when you ask which C library version I am using. Are you asking the version of my libc?

I am cross-compiling on Debian 10 using Go 1.19 and gcc 4.7.4 (but my understanding is that a C compiler is only used for the cgo parts of the Go source tree, and that most of the Go source tree is compiled by Go). My target is Solaris 11.

Ian Lance Taylor

unread,
Aug 18, 2022, 10:52:47 PM8/18/22
to Shane, golang-nuts
On Thu, Aug 18, 2022 at 5:05 PM Shane <skull...@gmail.com> wrote:
>
> I'm not sure what you mean when you ask which C library version I am using. Are you asking the version of my libc?
>
> I am cross-compiling on Debian 10 using Go 1.19 and gcc 4.7.4 (but my understanding is that a C compiler is only used for the cgo parts of the Go source tree, and that most of the Go source tree is compiled by Go). My target is Solaris 11.

I'm wondering why it appears that setresgid is not declared on your
system. So I am asking which libc you are using, and what version it
is. For example, on my system setresgid is declared in <unistd.h>; I
am running glibc 2.33.

But that is likely a side issue. To build a Go distribution for
Solaris, use the bootstrap.bash script that I mentioned.

Ian
> --
> You received this message because you are subscribed to the Google Groups "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/84132b4b-64ef-4250-a162-1783cfd559bcn%40googlegroups.com.

Shane

unread,
Aug 19, 2022, 7:55:45 PM8/19/22
to golang-nuts
Compiling with the boostrap.bash script also fails:

$ GOOS=solaris GOARCH=amd64 ./bootstrap.bash
#### Copying to ../../go-solaris-amd64-bootstrap

#### Cleaning ../../go-solaris-amd64-bootstrap
Removing src@tmp/

#### Building ../../go-solaris-amd64-bootstrap


Building Go cmd/dist using /usr/local/go. (go1.19 linux/amd64)
Building Go toolchain1 using /usr/local/go.
Building Go bootstrap cmd/go (go_bootstrap) using Go toolchain1.
Building Go toolchain2 using go_bootstrap and Go toolchain1.
Building Go toolchain3 using go_bootstrap and Go toolchain2.
Building packages and commands for host, linux/amd64.
# runtime/cgo
linux_syscall.c: In function '_cgo_libc_setresgid':
linux_syscall.c:67:2: error: implicit declaration of function 'setresgid' [-Werror=implicit-function-declaration]
linux_syscall.c: In function '_cgo_libc_setresuid':
linux_syscall.c:73:2: error: implicit declaration of function 'setresuid' [-Werror=implicit-function-declaration]
cc1: all warnings being treated as errors
go tool dist: FAILED: /builds/workspace/developer/Prime/Bishop/go/go-solaris-amd64-bootstrap/pkg/tool/linux_amd64/go_bootstrap install std cmd: exit status 2

I have multiple libc* files on my build machine. Of the ones that are not symlinks, I have /lib/x86_64-linux-gnu/libc-2.28.so, /sysroot/lib/amd64/libc.so.1, and /sysroot/lib/libc.so.1. So I think I have glibc 2.28 based on the first file, but I am not certain. My gcc is gcc 4.7.4.

I have multiple unistd.h files on my build machine, but none of them have setresgid (I checked by running find as root to find all the unistd.h files, and then I grepped each of them for setresgid).

Is there a minimum libc version that is needed to compile the boostrap?

Shane

unread,
Aug 27, 2022, 12:10:21 PM8/27/22
to golang-nuts
I wonder if the GOOS environment variable is being ignored? Is it expected that linux_syscall.c would be compiled when the GOOS environment variable is set to solaris?

I looked at the POSIX docs, and POSIX only has a setregid() function, and not a setresgid() function.

Brian Candler

unread,
Aug 27, 2022, 12:53:48 PM8/27/22
to golang-nuts
On Saturday, 27 August 2022 at 17:10:21 UTC+1 Shane wrote:
Is it expected that linux_syscall.c would be compiled when the GOOS environment variable is set to solaris?

I see the log output does include this line:

Building packages and commands for host, linux/amd64.

Although I'm not sure why it couldn't use the existing toolchain directly.

Shane

unread,
Aug 27, 2022, 1:16:08 PM8/27/22
to golang-nuts
I noticed bootstrap.bash just calls make.bash here, and make.bash runs go build with the GOOS and GOARCH set to empty strings here.

Does this mean that whatever I set for GOOS when I run either boostrap.bash or make.bash is always ignored?

Sean Liao

unread,
Aug 27, 2022, 2:25:30 PM8/27/22
to golang-nuts
The bootstrap process is a chain of builds that each build the next stage, to minimize any effects of the host system, in order to produce a consistent final artifact.
Your builds are failing before it has successfully built the final host stage, cross compiling hasn't come into the picture yet.
Where it fails is the (optional) cgo part, you'll want to fix that before attempting to cross compile.

- sean

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.

Shane

unread,
Aug 27, 2022, 2:40:52 PM8/27/22
to golang-nuts
I already have a working Go 1.19 for Linux with cgo support on my build machine that I downloaded and installed from https://go.dev. Given this, is it still necessary to build for the host? Is there some way I can skip straight to building Go for my Solaris target using my existing Linux Go tools? Or if I do that, does that break the guarantee of a consistent final artifact?

Shane

unread,
Aug 27, 2022, 2:54:02 PM8/27/22
to golang-nuts
>  Is there some way I can skip straight to building Go for my Solaris target using my existing Linux Go tools?
Sorry, this question was foolish. Of course I can skip straight to building for Solaris, by using the make.bash script.

But as I pointed out earlier,

> I looked at the POSIX docs, and POSIX only has a setregid() function, and not a setresgid() function.

And
>  make.bash runs go build with the GOOS and GOARCH set to empty strings here.

Please correct me if I am wrong, but my assumption is that if GOOS was properly set to solaris by make.bash, then linux_syscall.c would not be compiled, and then I would not get the compiler error I am seeing.

Sean Liao

unread,
Aug 27, 2022, 2:59:31 PM8/27/22
to golang-nuts
make.bash calls cmd/dist which does the build chaining, calling it directly doesn't skip the process.

- sean

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.

Shane

unread,
Aug 27, 2022, 3:15:18 PM8/27/22
to golang-nuts
Ah, I see now, sorry for not noticing that.

My understanding then is that cmd/dist first builds for the host here (in my case, for Linux) and then builds for the target starting here. Since there is always a build for the host first, then since my host OS is Linux, the linux_syscall.c is always part of the compilation (since I do not disable cgo). If anything is incorrect with my understanding, please correct me.

I believe then I need to have both Linux system headers and Solaris system headers available on my build machine for the cross-compile, if I want to build Go for Solaris with cgo support.

Is it possible for there to be two header files with the same name but different OS have the same #include path in the cgo source code? If so, could the C compiler get the correct header for the target of the cgo? For example, how could the C compiler know to use the Linux unistd.h header for the Linux build, and later use the Solaris unistd.h header for the Solaris build?

Ian Lance Taylor

unread,
Aug 27, 2022, 3:18:42 PM8/27/22
to Shane, golang-nuts
On Sat, Aug 27, 2022 at 12:15 PM Shane <skull...@gmail.com> wrote:
>
> My understanding then is that cmd/dist first builds for the host here (in my case, for Linux) and then builds for the target starting here. Since there is always a build for the host first, then since my host OS is Linux, the linux_syscall.c is always part of the compilation (since I do not disable cgo). If anything is incorrect with my understanding, please correct me.
>
> I believe then I need to have both Linux system headers and Solaris system headers available on my build machine for the cross-compile, if I want to build Go for Solaris with cgo support.
>
> Is it possible for there to be two header files with the same name but different OS have the same #include path in the cgo source code? If so, could the C compiler get the correct header for the target of the cgo? For example, how could the C compiler know to use the Linux unistd.h header for the Linux build, and later use the Solaris unistd.h header for the Solaris build?

I'm not sure whether this answers your question, but normally a system
will have a native compiler that will look for header files in
/usr/include. It can also have a cross-compiler that looks for header
files in some other location. A cross-compiler should never look in
/usr/include, it should only look at the cross-compilation header
files.

Ian

Shane

unread,
Aug 31, 2022, 4:35:13 PM8/31/22
to golang-nuts
I was finally able to compile the bootstrap on Linux (I had to install the missing libc).

However, after copying the .tbz file onto my Solaris 11u4 AMD64 machine to build the final Go tools, building fails:

$ GOROOT_BOOTSTRAP=/tmp/bootstap-goroot CGO_ENABLED=1 ./all.bash
Building Go cmd/dist using /tmp/bootstap-goroot. (go1.19 solaris/amd64)
dist: Cannot find /lib64/ld-linux-x86-64.so.2

Why does the bootstrap go expect /lib64/ld-linux-x86-64.so.2? Shouldn't it only be looking for Solaris libs?

Sean Liao

unread,
Sep 1, 2022, 4:11:16 AM9/1/22
to Shane, golang-nuts

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.

Shane

unread,
Sep 1, 2022, 9:13:04 AM9/1/22
to golang-nuts
Does that mean it is not possible to cross-compile Go for a Solaris target on a Linux host until one or both of those issues have been fixed?

Ian Lance Taylor

unread,
Sep 1, 2022, 2:18:25 PM9/1/22
to Shane, golang-nuts
On Thu, Sep 1, 2022 at 6:13 AM Shane <skull...@gmail.com> wrote:
>
> Does that mean it is not possible to cross-compile Go for a Solaris target on a Linux host until one or both of those issues have been fixed?

You can set the GO_LDSO environment variable to the correct value when
running make.bash. That might have to be edited into bootstrap.bash
if you are using that, I'm not sure.

Ian
> To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/7ffc15cc-3313-4d3c-be28-16201c7dbf49n%40googlegroups.com.
Reply all
Reply to author
Forward
0 new messages