Before proceeding to answer your question, as described, I will notice that in the end it is not entirely clear what you are trying to achieve, and probably the best solution to your problem.
However, there are two main problems with trying to do what you described:
One of them is that you need to decompose libpthread and libstdc++ into the files of the objects with which they are made. This is because the ELF binaries (used on Linux) have two levels of the “runtime” library loading - even when the static executable file is loaded, the loader must load the statically linked libraries in the executable binary file and display the correct memory addresses. This is done before the general link of libraries that are dynamically loaded (shared objects) and displayed in shared memory. Thus, a shared object cannot be statically linked to libraries such as at the time the object was loaded; all static linked libraries have already been loaded. This is one difference between linking to a static library and a simple object file - a static library does not just stick together, like any object file, into an executable file, but it still contains separate tables that are mentioned during loading. (I believe this runs counter to the much simpler static libraries in MS-DOS and the classic Windows .LIB , but maybe more than I remember).
Of course, you do not need to decompose libpthread and libstdc++ , you can just use the object files created when they were created. Collecting them can be a little tricky (looking for objects that are referenced by the final Makefile rule of these libraries). And you will need to use ld directly, not gcc / g++ for reference, so as not to mess with dynamic versions.
The second problem is indirect. If you do this, you will definitely get the shared / dynamic library that you want to create. However, this will not be very useful, because as soon as you try to link a regular executable file that uses these libpthread / libstdc++ (the last of which is any C ++ program) with this shared object, it will fail with character conflicts - characters of the static libpthread / libstdc++ objects that you linked your shared object to will encounter characters from the standard libpthread / libstdc++ used by this executable, regardless of whether it is dynamically or statically linked to standard libraries.
You could, of course, try either to hide all the symbols in the static objects from libstdc++ / libpthread used by your shared library, make them private, or rename them automatically in some way, so that there will be no conflict. However, even if you get this to work, you will find some unwanted results at runtime, since both libstdc++ / libpthread save quite a bit of state in global variables and structures that you will now have a duplicate and each one does not know the other. This will lead to inconsistencies between this global data and the underlying state of the operating system, such as file descriptors and memory limits (and possibly some values from the standard C library, such as errno for libstdc++ , and signal handlers and timers for libpthread .
To avoid an overly broad interpretation, I will add a remark: at times there may be reasonable grounds for static linking against even such basic libraries as libstdc++ and even libc , and even if it becomes a bit more complicated with the latest systems and versions of these libraries (due to a small link with the bootloader and special intermediary tricks), this is definitely possible - I have done this several times and know other cases in which it is still done. However, in this case, you need to link the entire executable statically. Static linking with standard libraries in combination with dynamic linking with other objects is usually not possible.
Edit: One of the issues that I forgot to mention but is very important is C ++. C ++, unfortunately, was not well designed for the classical model of binding and loading objects (used on Unix and other systems). This makes C ++ shared libraries not very portable, as it should be, because many things, such as type information and templates, are not shared between objects (often taken along with a lot of actual library code at compile time from the headers) . libstdc++ for this reason is closely related to GCC, and code compiled with one version of g++ will only work with libstdc++ with this (or very similar) version of g++ . Since you will probably notice that you will ever try to create a program with GCC 4 with any non-trivial library on your system that was built using GCC 3, it is not just libstdc++ . If your reason for this is to make sure your shared object is always associated with the specific versions of libstdc++ and libpthread with which it was created, this will not help, because a program using another / incompatible libstdc++ will also be built with an incompatible compiler C ++ or g++ version and thus will not be able to communicate with your shared object in any way, except the actual libstdc++ conflicts.
If you are wondering, “Why wasn’t it easier?”, The general reflection is worth considering: for C ++ it’s good to work with dynamic / shared libraries (which means compatibility between compilers and the possibility of replacing the dynamic library with another version with a compatible interface without rebuilding everything that uses it) requires not only standardization of the compiler, but also the level of the bootloader of the operating system, the structure and interface of files of objects and libraries, and the work of the linker should be significantly expanded besides the relatively simple classical Unix used in common operating systems (Microsoft Windows, Mach-based systems and NeXTStep siblings such as Mac OS, VMS siblings, and some mainframe systems are also included) for self-tuning code today. The linker and the dynamic loader would need to know about things such as templates and typing, to some extent have the functionality of a small compiler , in order to actually adapt the library code to the type given to it - and (personal subjective observation here) it seems that the intermediate intermediate code at a higher level (together with higher-level languages and compilation "just in time") they catch the earth faster and are likely to be standardized earlier than such extensions for their own object formats and layouts shchikov.