I'm trying to compile a static library (let's call it library.a). This library consumes resources of standard libraries. There is some way that the library can statically link a standard library.
I have proven something like:
g++ -c library -static-libstdc++ -o library.o
ar rcs library.o library.a
But if I do so there is no link to the standard libraries.
Then I have proved this way:
g++ library -static-stdlib -o library.o
ar rcs library.o library.a
But ask me to add a main function.
Is there any possibility of creating a static library by statically linking also standard libraries (std :: string, std :: vector, std :: cin, etc ...).
Thanks :)
No, because you cannot link anything to a static library. You can link things only into a file that is produced by the linker. Otherwise no linking is involved in its production.
The linker can produce two kinds of files: programs and shared libraries. Programs and shared libraries are similar: they're both composed of executable code that the program loader can load into a process. They are not similar to a static library. A static library is produced by the archiving program
ar
and is just a bag of object files - an archive - from which the linker can extract the ones it needs to complete the linkage of a program or shared library.A command like:
just compiles
library.cpp
intolibrary.o
and ignores the linkage option-static-libstdc++
because-c
means Just compile. Don't linkYour real problem only comes to light in one of your later comments1:
Now since a shared library is something that the linker can produce, you can statically link
libstdc++
into a shared library. So, instead of making your C wrapper library a static library, you could make it a shared libary.It seems you already know how to wrap C++ code in a C API. So let's write such a C wrapper that reverses the first N characters from an input buffer to an output buffer, using the standard C++ library to do all the work:
reverse.h
reverse.cpp
Then a C program that calls
reverse
:main.c
Now we'll build our shared wrapper library.
Compile our one library source file:
Notice
-fPIC
. All object files that we're going to link in a shared library must be Position Independent Code. And as we're compiling one source file --c reverse.cpp
- we can skip the-o
option and accept the default,-o reverse.o
Then link our shared library:
Now the shared library is
./libreverse.so
and it has no runtime dependency onlibstdc++
:Next compile our C program source file:
And finally link the program with
libreverse
:This program
./prog
has a runtime dependency on the shared librarylibreverse.so
. You can't statically link withlibreverse.so
because it's not a static library. Butlibreverse.so
has been statically linked withlibstdc++.a
, and has a C API.If
libreverse.so
was a serious library what we'd do now is is install it one of the runtime loader's standard search directories, so that programs could load it automatically at runtime. We could do that like:But since
libreverse.so
is just a toy library we won't modify our system for it. Instead we'll just run./prog
like:So you can make a wrapper library with a C API and C++ internals, with
libstdc++
statically linked, by making the wrapper library a shared library.But why bother?
It seems that you want to bother because you believe that "in C I can not use the standard C++ libraries".
That is a misconception. Here's how you can build the same program with a static wrapper library
First make your static wrapper library
Then compile your C source:
At this point, you have an object file
main.o
, a static librarylibreverse.a
that contains (only)reverse.o
, and to makeprog
you simply need to linkmain.o
andlibreverse.a(reverse.o)
together with the standard C library and the standard C++ library. There is no question of C not allowing you to do this. You finished with C when you compiledmain.c
. These object files and libraries will be linked by your system linker, which will not know or care what language any of them were compiled from.So you could invoke the linker via
g++
, like:and once more you have a program that does this:
Or you could invoke the linker via
gcc
, like:which is just the same linkage, with just the same result:
As you see, the one difference between linking via
g++
rather thangcc
is thatg++
automatically adds both the standard C library and the standard C++ library to the linker's inputs, andgcc
doesn't add the C++ library, so you have to do it yourself.For that matter, if you happened to have GNU Fortran installed on your computer you could do the same linkage with it:
although nothing in
prog
was written in Fortran.C doesn't stop you from linking
libstdc++
with anything. A possible, but unlikely, rational motive you might have for wishing to statically linklibstdc++
into a library with a C API is that you want somebody else to be able to link programs with this library on a system that doesn't havelibstdc++
or doesn't have one that is ABI compatible with yours. If that is your motivation, then make your library a shared one as shown above. Otherwise, just linklibstdc++
with any program that depends on it.[1] On Stackoverflow, always state your real problem in your question. See The XY Problem