I'm trying to build additional "filter" shared libs for
ulogd. The (Linux) ulogd daemon reads its .conf file, which specifies the filesystem location of shared libs, then according to how configured, it dynamically loads the shared libs. There isn't a "callback" function that the shared lib is supposed to export, but all of the working (c-lang) examples of such shared libraries simply declare an initializer function (called before dlopen(...) returns) that itself calls ulogd_register_plugin(...), which is a symbol defined in the ulogd daemon (main process which causes the shared libs to be loaded).
All of that is to say, my shared lib needs to be able to call (from C code) a function whose definition is available at the time my shared lib will be loaded. Where golang comes into the equation is that in the plugin struct that I'm passing to the host register function, I'm setting callbacks that are golang functions. I want to be able to write this ulogd filter plugin mostly in golang, with just the small c-lang shim I've already described.
I've got a .c file which declares the initializer function, which itself directly calls the ulogd_register_plugin function. That .c file sits adjacent to a .go file which declares a main package, as well as //export'ed cgo functions that are referenced in the plugin struct.
I think I've got everything that is needful, but I end up with:
# go.myorg.org/cf/ulog-dropsonde-output
/tmp/go-build604363162/go.myorg.org/cf/ulog-dropsonde-output/_obj/dropsonde.o: In function `init':
dropsonde.c:(.text+0xc): undefined reference to `ulogd_register_plugin'
collect2: error: ld returned 1 exit status
when trying to build via the command:
env CGO_CFLAGS="-I${PWD}/ulogd-source/include -I${PWD}/ulogd-source" GOPATH="${PWD}" /usr/lib/go-1.6/bin/go build -work -buildmode=c-shared -x go.myorg.org/cf/ulog-dropsonde-output
(all relevant files, including a copy of ulogd.h from ulogd source distribution can be found
here).
I'm assuming that I'm missing some linker option (CGO_LDFLAGS) to make this work, but I don't know enough about the linker or cgo to know what I'm missing. Basically, I just want to tell it to leave the symbol undefined in the .so, so that at load time the linkage will be fixed-up by the time dlopen() calls the library initialization function. I'm pretty sure this is more to do with how the linker is getting invoked than cgo in particular, but I don't know enough about the workings of the linker to know what I'm wanting to tell it.
~ Tommy K