¿Cuál es la diferencia entre usar bibliotecas estáticas y usar código fuente directamente en C++?
¿Por qué no hay diferencia? Veamos el proceso general de compilación de varios archivos:
El compilador compila cada archivo .cpp de origen en un archivo .o de destino. El archivo objeto contiene una tabla de símbolos, que registra funciones y los símbolos que utilizan, variables globales, etc.
El vinculador vincula todos los archivos .o en archivos binarios o "imágenes" reconocibles por el sistema. El vinculador reasigna funciones y descarta funciones no utilizadas.
Incluso agregar una biblioteca estática no hace ninguna diferencia porque la biblioteca estática en sí es solo un archivo de archivos .o. Tomando el ar de GCC como ejemplo, echemos un vistazo al contenido de la biblioteca estática.a:
$ ar -t libfltk.a
Fl.o
Fl_Adjuster.o
Fl_Bitmap.o
Fl_Browser.Browser_.o
Fl_Browser_load.o
Fl_Box.o
Fl_Button.o
Fl_Chart.o
Fl_Check_Browser.o
Fl_Check_ Button.o
Fl_Choice.o
Fl_Clock.o
Fl_Color_Chooser.o
Fl_Copy_Surface.o
Fl_Counter.o
Fl_Dial.o
Fl_Device.o
Fl_Double_Window.o
Fl_File_Browser.o
Fl_File_Chooser.o
Fl_File_Chooser2.o
Fl_File_Icon.o
Fl_File_Input.o
Fl_Group.o
Fl_Help_View.o
Fl_Image.o
Fl_Image_Surface.o
...
En realidad, hay muchos .o ahí. La compilación desde el código fuente (el primer paso) también generará un montón de .o, la descompresión desde la biblioteca estática también generará un montón del mismo .o, y el resto de los pasos permanecerán sin cambios. En otras palabras, supongamos que tiene un libexample.a con dos archivos objeto src1.o y src2.o. Usar el modificador ld -lexample al vincular una biblioteca estática es exactamente lo mismo que descomprimirla con ar -x libexample.a y luego vincularla con ld src1.o src2.o.
Los símbolos no utilizados se cortarán automáticamente, por lo que no habrá ningún impacto en el tamaño en comparación con la compilación directa desde la fuente.