Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

go + cgo and linking

Tags:

go

linker

cgo

i want to use the following c as Go's cgo:

#include <X11/extensions/scrnsaver.h>

main() {
  XScreenSaverInfo *info = XScreenSaverAllocInfo();
  Display *display = XOpenDisplay(0);

  XScreenSaverQueryInfo(display, DefaultRootWindow(display), info);
  printf("%u ms\n", info->idle);
}

build with:

gcc -o idle printXIdleTime.c -lX11 -lXss

i re-wrote that code for Go's cgo:

package tools

// #cgo pkg-config: x11
// #include <X11/extensions/scrnsaver.h>
import "C"

func GetIdleTime() (idleTime uint32) {
    var info *C.XScreenSaverInfo
    var display *C.Display 

    info = C.XScreenSaverAllocInfo()
    display = C.XOpenDisplay(0)

    defaultRootWindow := C.XDefaultRootWindow(display)

    C.XScreenSaverQueryInfo(display, defaultRootWindow, info)
    idleTime = info.idle

    return
}

tried to compile with:

go build -gccgoflags="-lXss -lX11"

however i'm getting linker errors:

/tmp/go-build076004816/opensource.stdk/lib/tools/_obj/x11.cgo2.o: In function _cgo_c0e279f6f16e_Cfunc_XScreenSaverAllocInfo': ./x11.go:52: undefined reference toXScreenSaverAllocInfo' /tmp/go-build076004816/opensource.stdk/lib/tools/_obj/x11.cgo2.o: In function _cgo_c0e279f6f16e_Cfunc_XScreenSaverQueryInfo': ./x11.go:65: undefined reference toXScreenSaverQueryInfo' collect2: error: ld returned 1 exit status

what am i doing wrong?

like image 918
brian_j Avatar asked Feb 12 '13 22:02

brian_j


People also ask

Are Go programs statically linked?

Well, Go code is statically linked, but the runtime may try to dynamically load libc for DNS resolving. Use of cgo of course drastically change everything. By default, nowadays the toolchain also supports generating dynamic libraries.

How do I activate my CGO?

The cgo tool is enabled by default for native builds on systems where it is expected to work. It is disabled by default when cross-compiling. You can control this by setting the CGO_ENABLED environment variable when running the go tool: set it to 1 to enable the use of cgo, and to 0 to disable it.

Can you use C libraries in Go?

Go allows linking against C libraries or pasting in in-line code.

What is CGO When would you want to use it?

Cgo lets Go packages call C code. Given a Go source file written with some special features, cgo outputs Go and C files that can be combined into a single Go package.


1 Answers

This is how I got it to build. Note the #cgo LDFLAGS line which is probably what you are missing. I had to make a few other changes to make it build. It seems to be returning the right answer on my Linux machine!

package tools

// #cgo LDFLAGS: -lXss -lX11
// #include <X11/extensions/scrnsaver.h>
import "C"

func GetIdleTime() (idleTime uint32) {
    var info *C.XScreenSaverInfo
    var display *C.Display

    info = C.XScreenSaverAllocInfo()
    display = C.XOpenDisplay(nil)

    defaultRootWindow := C.XDefaultRootWindow(display)

    C.XScreenSaverQueryInfo(display, C.Drawable(defaultRootWindow), info)
    idleTime = uint32(info.idle)

    return
}
like image 152
Nick Craig-Wood Avatar answered Sep 20 '22 17:09

Nick Craig-Wood