3

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?

Chuck R
  • 731
  • 1
  • 7
  • 15
  • [This question](http://stackoverflow.com/questions/19901934/strange-linking-error-dso-missing-from-command-line) suggests that you might've placed the `-ldl` flag in the wrong place. – Iwillnotexist Idonotexist Apr 30 '15 at 11:08
  • Qt doesn't give me an options as to where to place -ldl (this is the -l option of the configure), nor to I understand the tangled mess that is the Qt source >.>. I'm trying to locate it in order to see if there's a better place to put it, but no luck so far. I was fairly easily able to change its placement in FlightGear (just in case) and was left with a a flood of errors about almost every other external library call being undefined. – Chuck R Apr 30 '15 at 11:16

1 Answers1

4

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.

Aaron Digulla
  • 321,842
  • 108
  • 597
  • 820
  • FlightGear uses CMake, which I'm not too familiar with, but I found the .txt file that is the linking command and added -ldl to the end of it (after libQtCore.a as you suggested) and I got a flood of errors to a slew of suddenly undefined symbols that weren't there before. As I was writing this I tried it again and it suddenly worked. Well, thanks for the answer though I have no idea how or why it worked this time and not the last time! – Chuck R Apr 30 '15 at 12:24
  • `dl.so` needs some other stuff (not much, though). So make sure it's one of the last `-l` options that you pass. The order of `-L` (path) options is not important; you should just have them before the first `-l`. – Aaron Digulla Apr 30 '15 at 12:31
  • I reset my Qt and FlightGear builds and just added the -ldl in the FlightGear cmake nonsense and I got the same errors I described in the comment to my question. So, that alone didn't fix it. In my haste to get it built I started throwing `-ldl` a lot of places it probably shouldn't have been and some combination worked -- now I'm tediously going through and trying to figure out which one did it. The cleaning process for the Qt base package takes like 15 minutes each time though... – Chuck R Apr 30 '15 at 13:07
  • 1
    Alright, so I think my initial successful build was an accident -- I had forgot to tell CMake where I had put Qt and it continued without out. I finally got it going, but it turns out I have to link every single library that Qt links to, which is quite a few to say the least but after all that hassle it's working like a charm. – Chuck R Apr 30 '15 at 17:24