How to build an application that requires both libstdc++.so.5 and libstdc++.so.6?
I want to preface this with the important notice that I am not a C/C++ programmer, and know very little about how linkage of libraries works in C.
Our code uses libstdc++.so.6 (gcc 3.4, i think). We have third-party precompiled (closed source) libraries that use libstdc++.so.5 (gcc 2.something or 3.2, i think). This is on linux. We have both a .a and .so version of the third party lib.
Is it possible to build our app with the 3rd party libs? How? Is it possible to build/run our app without having libstdc++.so.5 installed our our machines, how?
If I've forgotten some critical information, please let me know - I hardly know whats relevant with this stuff. I realize that a complete answer probably won't be possible; I'm really looking for direction and guidance. Static link this, dynamic that, rebuild that, prebuild so-and-so, switch to version x, or symlink the quizdoodle, etc.
Update:
We tried using dlopen
with RTLD_LOCAL
to isolate the 3rd party library from the rest of our app. This seems to have mostly worked, however, we are left with large memory leaks for unknown reasons. We suspect that, when we call dlopen
, the third party 开发者_运维知识库library pulls in symbols like malloc
from the already loaded .so.6, and things get muddled up.
For giggles, we tried putting the third-party library into LD_PRELOAD
, then ran our app, and the memory leaks seems to completely disappear.
You may try to build a wrapper library around your 3rd party library: use the static version of that library + link it with the static standard library (-static-libgcc - make sure you pick up a proper version via -L). The important thing to do is to close this wrapper library properly, i.e only symbols from the original 3rd party library should be exported, everything else should be hidden. This way you wrapper library will expose all needed symbols for your application and encapsulate standard stuff inside. Note it is not guaranteed to work especially if some memory operations are shared between your code and 3rd party code (e.g. you allocate memory in your code and deallocate in 3rd party)... in such case the only option can be to keep this 3rd party lib in a different process space.
I don't think the dynamic option mentioned above would work because you will get exactly same problem - just later.
In general it is better not to mix binaries with different run-times in the same process space. It is almost always a recipe for disaster.
Ask your vendor for a newer version of the library that uses something not horribly out of date. Failing that, you could see if your new application still works with the older version of the library and if necessary port it back. Trying to have two different versions of the same library is asking for pain and I don't think you'll find an acceptable solution.
While it is easy to link both libstdc++.so.6 and libstdc++.so.5 to your application at the same time, its behavior will pretty much be undefined, because symbols are taken from either library basically by chance.
Best way to success IMO is to build an own application around your 3rd party lib on an old system (which is using a compatible gcc like, for instance, gcc 3.3), and let it communicate with your main application via IPC (eg. shared memory). This way, no
If you don't want to keep libstdc++.so.5 on your target system, then that's easy: use gcc's -static flag to link libstdc++.a to your wrapper application.
While one of the approaches given so far may work, I think it is safer to say that you can't do this directly a reliable fashion. If you write a wrapper using entirely C-based API's (only C-compatible structures, memory managed by malloc/free, etc.), then you might be able to use pobedim's solution. If you need to exchange C++ structures, however, it is not safe as, even if you could make the link happen, different standard libraries implementations would be used on the same objects. Also, the C++ ABI may not be compatible between .5- and .6-based code bases (I don't remember for sure how the major Gnu C++ ABI change happened a few years ago related to standard library sonames).
I think the safest approach to solving this is to use a multiprocess approach with some kind of IPC between your application and a resource/computing server process built on the library in question. You could use CORBA, D-Bus, Sun RPC, or some ad-hoc protocol over pipes or sockets to do the job. I've done this when trying to use closed-source 32-bit code in 64-bit apps, and it works well enough. You will see a performance hit, but you will also completely sidestep the problems inherent in trying to mix C++ runtimes in a single process.
精彩评论