Yesterday I spent the whole day trying to build a statically-linked binary of XSD for AIX. I have done this for numerous other platforms but on AIX the C++ exception handling stopped working once I linked
libstdc++ in statically. I was lucky to detect this problem at all; the application appears to work just fine as long as there is no throw on the execution path. The fix is to also link
g++ -static-libgcc ... -Wl,-bstatic -lstdc++ -Wl,-bdynamic \ -lsupc++
If all you are looking for is the fix, then you can stop reading here. Read on if you want to know why we need
libsupc++.a. When your application is linked to a number of shared libraries, it is important that they all use the same exception handling runtime to allow exceptions to propagate across library boundaries. To ensure this, GCC places the exception handling runtime into a shared library called
libgcc.a on AIX) which is then used by all shared C++ libraries and executables, including
-static-libgcc option instructs GCC to use a static equivalent of
libgcc_eh.a with the difference being that some of the exception handling code found in
libgcc_s.so is placed into the static
libstdc++.a (tell me if you know why). In other words, shared
libstdc++.so and static
libstdc++.a have a different amount of code in them. This fact is important to understand why things fail on AIX.
The second part of the problem is an eccentric shared library architecture implemented on AIX. In short, both shared libraries and static archives on AIX use the same file suffix—
.a. In fact, they are both archives. In such an archive there could be one or more shared object (which is just a normal XCOFF file with the
SHROBJ bit set) or normal object files. Furthermore, you can link a shared library (archive with shared objects) statically. That’s exactly what happens when you instruct
g++ to link
libstdc++.a statically by using the
-bstatic linker option.
We can see the cause of the problem clearly now: we are linking shared
libstdc++.a statically but it is missing some of the exception handling code that a proper static
libstdc++.a would have. The
libsupc++.a is a subset of
libstdc++.a. It provides core language support without STL and streams. It also includes the exception handling code we need. That’s why linking this library fixes the problem.