Chuck R
Chuck R

Reputation: 741

Dynamically linking from a static libarary?

I'm currently attempting to rebuild FlightGear on my Ubuntu 14.04 machine. Everything went smoothly until I decided to build fgrun which requires Qt. I decided to compile Qt as a static library since I didn't want self-built libraries overrunning any on the system.

I statically built Qt on the system like so:

./configure -static -opensource -nomake tests -gtkstyle -prefix /home/user/Qt/5.4/Src/qtbuild -no-rpath -no-compile-examples -system-proxies -skip qtwebkit -skip qtwebkit-examples -nomake tools -nomake examples -skip script -release -skip multimedia -verbose -l dl -skip location -skip multimedia -skip quick1 -skip quickcontrols -skip sensors -skip serialport -skip svg -skip tools -skip translations -skip wayland -skip webchannel -skip webengine -skip xmlpatterns -skip activeqt -skip connectivity -skip declarative -skip doc -skip enginio -skip graphicaleffects -skip imageformats -skip websockets

I showed FlightGear's CMake where to find the libraries and everything appeared fine until the final linking stage:

Linking CXX executable fgfs
/usr/bin/ld: /home/user/Qt/5.4/Src/qtbuild/lib/libQt5Core.a(qlibrary_unix.o): undefined reference to symbol 'dlclose@@GLIBC_2.2.5'
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu/libdl.so: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status

Now, I've run into this issue before and it was a matter of not linking the the dynamic linker library via -ldl. However, I've ensured that both Qt and FlightGear are built with the -ldl flag, yet I still get this error.

So now, this begs the question in my mind: is it even possible to dynamically link from a static library? I would imagine that -ldl would have to be included in the static library which would be a Bad Idea, is this correct?

Upvotes: 3

Views: 2113

Answers (1)

Aaron Digulla
Aaron Digulla

Reputation: 328770

The error message says you're missing dlclose@@GLIBC_2.2.5 which is part of glibc (the GNU C Library used by GCC). This symbol is part of dl.so which maps to /lib/x86_64-linux-gnu/libdl.so.2 on my system.

When you add it to the build, make sure -ldl is at the end of the command. The linker will collect missing symbols as it processes libraries but it will process each library exactly once. So you need to be sure that -dl is after the library which needs it.

is it even possible to dynamically link from a static library?

Yes. A static library is added to your code as if it was part of your own source, i.e. library is just a bunch of compiled object (*.o) files. The function names are the key to look up the object files. You could also unpack the library and write:

gcc -o exe main.o qtfoo.o -ldl

where qtfoo.o is an entry from libQt5Core.a

Another solution is to build Qt with dynamic loading and install it into $HOME/local/. The build setup should allow to specify the install folder.

When you build FlightGear, you can pass $HOME/local/lib as additional folder for shared libraries. To start FlightGear, you need to set the environment variable LD_LIBRARY_PATH. If you do this in a start script, only FlightGear will be able to see/use your own version of Qt.

Upvotes: 4

Related Questions