LSB gcc

I have spent a lot of time in the last few days arguing with the Linux Standards Base compiler, which is an altered version of GCC that links against LSB-standardised libraries and such. It should act exactly the same as regular GCC, at least in terms of functionality and command-line argument parsing.

The main issue I ran into was exporting symbols on a shared library that are being exported from a static library. What am I talking about? Well, if you speak gcc…

g++ -shared mylib.a mylib2.a -o mysuperlib.so

(Notice I’m using static libraries as filenames, not with the -l library option. It doesn’t make a difference which you use.)

So imagine mylib.a exports some symbols that I want my mysuperlib.so (shared library) to also export. By default, these symbols aren’t needed, so they won’t be exported. This is intended behaviour of the linker since it doesn’t have any knowledge that it should export the symbols, since the linker will only pull out symbols from the static library that it thinks it needs. This is why if you did the same above with object files, it will work as you would probably want. The linker knows you want to link against the entire object file when you link against one — but when you link against a library archive (a static, .a file), it only knows the parts it should “pull into” the linking by what you’re linking against.

The solution to this is to tell the linker to include the whole library (archive).

g++ -shared -Wl,--whole-archive,mylib.a -Wl,--no-whole-archive,mylib2.a -o mysuperlib.so

The -Wl switch passes instructions to the linker. We only want to include the entire library of mylib.a, not mylib2.a — which is why we use –no-whole-archive afterward.

The above code works great. As does the following variation:

g++ -shared -Wl,--whole-archive mylib.a -Wl,--no-whole-archive mylib2.a -o mysuperlib.so

Notice the space instead of the comma after the –whole-archive switch. g++ deals with this fine.

Would you believe lsbc++ (the LSB c++ compiler) does not work with the altered version? It’s true. There seems to be a difference in the way it parses command-line options, even though they are both based on the same code-base. Any guesses as to how long it took me to figure that out?

Comments are closed.