dangeroushobo dangeroushobo - 3 months ago 15
Linux Question

cgo cross-compile failing to find libraries

I've written a wrapper around the semaphore functions in linux. This worked for me in the past on Go 1.3 and Go 1.4, but I needed to rebuild my application using this wrapper and it no longer builds with Go 1.6.2 or Go 1.7rc5.

I wrote a simple test application that produces the same errors:

package main

import (
"fmt"
"os"
"linux/semaphore"
)

func main() {
var sema semaphore.Semaphore
if err := sema.Open("/test", 0644, 1); err != nil {
fmt.Printf("%v\n", err)
os.Exit(1)
}
if err := sema.TryWait(); err != nil {
fmt.Printf("%v\n", err)
os.Exit(1)
}
if err := sema.Post(); err != nil {
fmt.Printf("%v\n", err)
os.Exit(1)
}
}


Now the program does compile natively (linux/amd64), my issue is when I try to cross-compile for linux/arm (Ti am3352).

Previously all I had to do was:

GOOS=linux GOARCH=arm GOARM=7 CGO_ENABLED=1 CC=/am335x_toolchain/bin/armv7l-timesys-linux-gnueabi-gcc go build


Which now gives the following error:

# runtime/cgo
/tmp/go-build820923984/runtime/cgo/_obj/_cgo_export.c:2:20: fatal error: stdlib.h: No such file or directory
#include <stdlib.h>
^
compilation terminated.


So I specified the include path:

GOOS=linux GOARCH=arm GOARM=7 CGO_ENABLED=1 CC=/am335x_toolchain/bin/armv7l-timesys-linux-gnueabi-gcc CGO_CFLAGS="-I/am335x_toolchain/include" go build
# runtime/cgo
/am335x_toolchain/bin/../lib/gcc/armv7l-timesys-linux-gnueabi/4.8.3/../../../../armv7l-timesys-linux-gnueabi/bin/ld: cannot find Scrt1.o: No such file or directory
/am335x_toolchain/bin/../lib/gcc/armv7l-timesys-linux-gnueabi/4.8.3/../../../../armv7l-timesys-linux-gnueabi/bin/ld: cannot find crti.o: No such file or directory
/am335x_toolchain/bin/../lib/gcc/armv7l-timesys-linux-gnueabi/4.8.3/../../../../armv7l-timesys-linux-gnueabi/bin/ld: cannot find -lpthread
collect2: error: ld returned 1 exit status


Eventually I got to this, which still doesn't work:

GOOS=linux GOARCH=arm GOARM=7 CGO_ENABLED=1 CC=/am335x_toolchain/bin/armv7l-timesys-linux-gnueabi-gcc CGO_LDFLAGS="-L/am335x_toolchain/lib -pthread" CGO_CFLAGS="-I/am335x_toolchain/include" go build
# runtime/cgo
/am335x_toolchain/bin/../lib/gcc/armv7l-timesys-linux-gnueabi/4.8.3/../../../../armv7l-timesys-linux-gnueabi/bin/ld: cannot find Scrt1.o: No such file or directory
/am335x_toolchain/bin/../lib/gcc/armv7l-timesys-linux-gnueabi/4.8.3/../../../../armv7l-timesys-linux-gnueabi/bin/ld: cannot find crti.o: No such file or directory
/am335x_toolchain/bin/../lib/gcc/armv7l-timesys-linux-gnueabi/4.8.3/../../../../armv7l-timesys-linux-gnueabi/bin/ld: cannot find /lib/libpthread.so.0
/am335x_toolchain/bin/../lib/gcc/armv7l-timesys-linux-gnueabi/4.8.3/../../../../armv7l-timesys-linux-gnueabi/bin/ld: cannot find /usr/lib/libpthread_nonshared.a
collect2: error: ld returned 1 exit status


The pthread library does exist:

$ ls /am335x_toolchain/lib | grep "libpthread*"
libpthread-2.18.so
libpthread.a
libpthread_nonshared.a
libpthread.so
libpthread.so.0


Any pointers on what I need to do to cross-compile with CGO? Seems like with each release I've had more trouble cross-compiling with CGO.

EDIT:

I've discovered this is an issue with the host architecture. I get the above issues when running on an x86_64 machine (linux). When I compile with Go 1.6 on a 32bit x86 machine (linux), it builds without errors. Still haven't found a solution of compiling on the 64bit machine.

Answer

So the problem is that for the cross-compiler to properly find its headers and libraries it needs a --sysroot option, in your case --sysroot /am335x_toolchain/ added both to CGO_CFLAGS and CGO_LDFLAGS.

Comments