1

I am trying to compile some cgo code for Solaris. I get these errors when I try to build:

$ CGO_LDFLAGS="-L$(pwd)/solaris-11.4-amd64-libs" CGO_CFLAGS='-I/home/shane/src/ioctl-experimentation/solaris-11.4-headers -Wno-unknown-pragmas' CGO_ENABLED=1 GOOS=solaris GOARCH=amd64 go build
# runtime/cgo
/usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu/Scrt1.o: in function `_start':
(.text+0x16): undefined reference to `__libc_csu_fini'
/usr/bin/ld: (.text+0x1d): undefined reference to `__libc_csu_init'
/usr/bin/ld: (.text+0x2a): undefined reference to `__libc_start_main'
/usr/bin/ld: $WORK/b003/_x003.o: in function `_cgo_release_context':
gcc_context.c:(.text+0x5c): undefined reference to `__stack_chk_fail'
/usr/bin/ld: $WORK/b003/_x004.o: in function `x_cgo_sys_thread_create':
gcc_libinit.c:(.text+0x87): undefined reference to `__stack_chk_fail'
/usr/bin/ld: $WORK/b003/_x004.o: in function `_cgo_wait_runtime_init_done':
gcc_libinit.c:(.text+0x121): undefined reference to `__stack_chk_fail'
/usr/bin/ld: $WORK/b003/_x004.o: in function `_cgo_try_pthread_create':
gcc_libinit.c:(.text+0x291): undefined reference to `__stack_chk_fail'
/usr/bin/ld: $WORK/b003/_x006.o: in function `x_cgo_init':
gcc_solaris_amd64.c:(.text+0xb6): undefined reference to `__stack_chk_fail'
/usr/bin/ld: $WORK/b003/_x006.o:gcc_solaris_amd64.c:(.text+0x214): more undefined references to `__stack_chk_fail' follow
collect2: error: ld returned 1 exit status

I am cross-compiling on Linux. Here is my Go version:

$ go version
go version go1.18.3 linux/amd64

The solaris-11.4-amd64-libs directory contains a copy of all files under /lib/amd64 from a Solaris 11.4 AMD64 machine. The solaris-11.4-headers directory contains a copy of all files under /usr/include from a Solaris 11.4 AMD64 machine.

Here is my Go code in main.go:

//go:build solaris
// +build solaris

package main

import "C"

func main() {
}

I know cgo is fully supported for Solaris as of Go 1.5, and I am using Go 1.18.

I'm looking for help understanding why these linker errors are happening, even when I copied across all libs from the /lib/amd64 directory. Is it possible there are more libs I also need to copy over from somewhere else?

Edit

At the suggestion of Liam Kelly, I looked at this question about how to link against a different libc. I tried passing -Xlinker -rpath=$(pwd)/solaris-11.4-amd64-libs as part of CGO_LDFLAGS, but I got the same errors as before. I tried using -nodefaultlibs and -nostdlib both separately and together along with -Xlinker -rpath=$(pwd)/solaris-11.4-amd64-libs, but using either of these two flags either separately or together just increased the number of linker errors.

Shane Bishop
  • 3,905
  • 4
  • 17
  • 47
  • Which symbols are undefined if you leave out the `-lxnet` library? – Martin Rosenau Aug 06 '22 at 20:57
  • I never specify the `-lxnet` library myself, it is automatically used by `go build`. I don't know how to prevent `go build` from passing this flag to `gcc`. – Shane Bishop Aug 06 '22 at 21:04
  • It doesn’t matter if there’s an equivalent for Linux, you need the Solaris libraries (well, at least the headers) to build for Solaris. Figure out what it takes to cross compile general C code, and it’s the same for using CGO – JimB Aug 06 '22 at 21:45
  • @JimB, please see my updated question. Even with the Solaris libraries and headers copied over from a Solaris machine, cross-compiling from my Linux host fails with several linker errors. – Shane Bishop Aug 10 '22 at 16:09
  • @ShaneBishop what is your host OS? the easiest way forward is to use a gcc version that is already hardcoded with solaris parameters (IE: `x86_64-w64-mingw32-gcc` for windows) – Liam Kelly Aug 10 '22 at 17:03
  • @LiamKelly, my host OS that I am cross-compiling on is Linux (specifically Ubuntu). I would assume that the `go build` tool would automatically use the appropriate compiler when I use `GOOS=solaris`, am I wrong? Also, I don't believe I have any `*-solaris*-gcc` on my Linux system. – Shane Bishop Aug 10 '22 at 17:33
  • @ShaneBishop just to clarify, are you compiling for a SPARC or Solaris running on a typical AMD64 platform? – Liam Kelly Aug 11 '22 at 16:31
  • @LiamKelly I am compiling for Solaris AMD64. You can see this from what I set as the `GOOS` and `GOARCH` in my `go build` command at the top of my question. – Shane Bishop Aug 11 '22 at 19:38
  • @ShaneBishop I think you are going to need to link against the Solaris libc not the gnu libc for the c portion of code to work. Basically trying some of the techniques metioned here: https://stackoverflow.com/questions/2728552/how-to-link-to-a-different-libc-file. – Liam Kelly Aug 11 '22 at 19:50
  • @LiamKelly, I tried the suggestions for both answers in that question, but I continued to get linker errors. See my edit for more details. – Shane Bishop Aug 12 '22 at 20:30

1 Answers1

0

I am going to assume that libxnet is needed for Solaris and that is why is is being automatically added.

First confirm that the libxnet library is where is should be with sudo find /lib libxnet*. I expect you will see one line of the output show:

lib/64/libxnet.so

Assuming you see the above output, I believe you just need to tell the linker to look in that location with CGO_LDFLAGS="-L/lib/64" CGO_ENABLED=1 GOOS=solaris GOARCH=amd64 go build. If that works then you should be able to embedded that LDFlag in your main.go file with:

// #cgo LDFLAGS: -L/lib/64
import "C"

Once embedded you will not need to explicitly set CGO_LDFLAGS

Liam Kelly
  • 3,524
  • 1
  • 17
  • 41
  • Please see my updated question. I copied the `libxnet.so` file from a Solaris machine to my host Linux machine that I am cross-compiling on. For some reason, my `#cgo` directive is being ignored. – Shane Bishop Aug 10 '22 at 15:19
  • Actually, in my new update to my question, I left out the `#cgo` directive for now, and instead I just use `CGO_LDFLAGS`. – Shane Bishop Aug 10 '22 at 15:40