librados (C++) linker error (undefined reference)
When compiling a patched librados C++ example (or other C++ programs-- see included patchfile), pointing to the headers in the git repository causes linker errors
against librados (note that the stock Makefile uses only the system-wide headers and libraries, so here we're manually pointing at
the local build):
g++ -g -c hello_world.cc -o hello_world.o -std=c++0x -I../../src/include
g++ -I../../src/include -g hello_world.o -o librados_hello_world -Wl,-rpath,../../../ceph/src/.libs -L../../../ceph/src/.libs/ -lrados
hello_world.o: In function `ceph::buffer::list::iterator_impl<false>::iterator_impl(ceph::buffer::list*, unsigned int)':
/home/jwilliamson/work/ceph/ceph/examples/librados/../../src/include/rados/buffer.h:289: undefined reference to `ceph::buffer::list::iterator_impl<false>::advance(int)'
Using the system-wide headers results in successful linkage:
g++ -g -c hello_world.cc -o hello_world.o -std=c++0x
g++ -g hello_world.o -o librados_hello_world -Wl,-rpath,../../../ceph/src/.libs -L../../../ceph/src/.libs/ -lrados
buffer: hide iterator_impl symbols
buffer::list::iterator_impl symbols are referenced by const_iterator
and iterator, and are exposed as weak symbols. if a source file is
compiled using the buffer.h, the produced object file will reference
these symbols as well, so we'd better hiding them and avoid using
them in the header file.
as a side-effect, buffer::list::const_iterator is also hidden, but
currently we don't have any librados client using this class, so
we can just leave it as an internal class at this moment.
#6 Updated by Kefu Chai almost 3 years ago
if that's the case which Jesse ran into. it's because the new buffer.h is referencing the symbols of
buffer::list::iterator_impl<false>::*. so, if the client code is compiled using the new header file, the resulting object code will need the (weak) symbols of
but if the client code is compiled using the old header file, it will linked just fine with the new library.
buffer::list::iterator_impl template class was introduced when adding
list::const_iterator, in hope to consolidate the shared bits of
list::iterator. but it introduced some ABI incompatibilities. #13429 addressed some of them by re-exposing the methods offered by
list::iterator in hammer using their old symbol names (signatures). but it does not remove the dependency to the
i will try to add
__attribute__ ((visibility ("hidden"))) to the template to hide its symbol to see how it works.