Static linking of libcouchbase - 'undefined reference to'

Hi there,

I’ve built libcouchbase (2.10.4) locally with -enable-static which has produced libcouchbase.a

however when linking in my application (just a simple app open connection and perform a retrieval) I get a number of errors…
Cmake references:

include_directories(/usr/local/include /usr/local/include/libcouchbase)
target_link_libraries(main PRIVATE /usr/local/lib/libcouchbase.a)

errors:

[100%] Linking CXX executable main
/usr/bin/cmake -E cmake_link_script CMakeFiles/main.dir/link.txt --verbose=1
g++     CMakeFiles/main.dir/main.cpp.o  -o main /usr/lib/x86_64-linux-gnu/libboost_thread.a /usr/local/lib/libcouchbase.a /usr/lib/x86_64-linux-gnu/libboost_chrono.a /usr/lib/x86_64-linux-gnu/libboost_system.a /usr/lib/x86_64-linux-gnu/libboost_date_time.a /usr/lib/x86_64-linux-gnu/libboost_atomic.a -lpthread 
/usr/local/lib/libcouchbase.a(dns-srv.cc.o): In function `lcb::dnssrv_query(char const*, lcb::Hostlist&)':
/couchbase/libcouchbase/src/dns-srv.cc:33: undefined reference to `__res_search'
/couchbase/libcouchbase/src/dns-srv.cc:38: undefined reference to `ns_initparse'
/couchbase/libcouchbase/src/dns-srv.cc:43: undefined reference to `ns_msg_getflag'
/couchbase/libcouchbase/src/dns-srv.cc:58: undefined reference to `ns_parserr'
/couchbase/libcouchbase/src/dns-srv.cc:75: undefined reference to `ns_get16'
/couchbase/libcouchbase/src/dns-srv.cc:76: undefined reference to `ns_get16'
/couchbase/libcouchbase/src/dns-srv.cc:77: undefined reference to `ns_get16'
/couchbase/libcouchbase/src/dns-srv.cc:82: undefined reference to `ns_name_uncompress'
/usr/local/lib/libcouchbase.a(iofactory.c.o): In function `get_create_func':
/couchbase/libcouchbase/src/iofactory.c:208: undefined reference to `dlopen'
/couchbase/libcouchbase/src/iofactory.c:220: undefined reference to `dlsym'
/couchbase/libcouchbase/src/iofactory.c:211: undefined reference to `dlerror'
/couchbase/libcouchbase/src/iofactory.c:224: undefined reference to `dlerror'
/couchbase/libcouchbase/src/iofactory.c:228: undefined reference to `dlclose'
/usr/local/lib/libcouchbase.a(iofactory.c.o): In function `close_dlhandle':
/couchbase/libcouchbase/src/iofactory.c:240: undefined reference to `dlclose'
/couchbase/libcouchbase/src/iofactory.c:240: undefined reference to `dlclose'

Are there other options required or is this an issue with the static build of libcouchbase?

The dlopen and friends are from dynamic linking, so my guess is you’re running this in an environment where we cannot have the runtime linker pull in the IO backend. For the other errors, the ns_ functions come from other dependencies which may not be available as static libs. If you don’t need DNS SRV records, it might be possible to just disable that feature.

A higher level question though: are you deploying to an environment where you need static linking? If not, what are you hoping to gain by doing this?

I do agree this looks like an issue though if we depend on dl*. @avsej: can you comment?

while the libcouchbase will be linked statically, it still requires some system libraries like libdl.so and libresolv.so. If you link them, you should be good to go

@ingenthr yeah we’re building a single binary to be deployed in the docker scratch image, moving dynamic libs across hasn’t worked for me to date.

I’ll try moving those two libs into the image and also try with an image that will have those libs (some sort of distroless image)

I’m curious, is this for startup time or maximum efficiency or minimal image size or some kind of serverless deployment need? Or maybe it’s just because dependency management on a docker image is hard?

Thanks for the feedback-- I am just curious about the use case so we can support it better overall.

is this for startup time or maximum efficiency or minimal image size or some kind of serverless deployment need? Or maybe it’s just because dependency management on a docker image is hard?

The listed items are all things considered, however it’s more for security. Our security team are sticklers for detail, even alpine images with a shell are considered a risk.

I’ve managed to get it running in the google distroless base image by adding the following to my CMakeLists

target_link_libraries(main PUBLIC resolv dl)

Had to make the link public.

I do plan on trying to build a minimal image with libcouchbase pre installed for dynamic linking so will see how that goes.