Czytam książkę O'Reilly 21st Century C, w której autor stwierdza, że podczas łączenia z biblioteką statyczną "kompilator [skutecznie] kopiuje odpowiednią zawartość biblioteki do ostatecznego pliku wykonywalnego".W jaki sposób kod obiektowy jest kopiowany do pliku wykonywalnego podczas łączenia z biblioteką statyczną?
Próbowałem to sprawdzić, tworząc własną bibliotekę statyczną składający się z tym module:
static char szStr[64];
char* single_func() {
strcpy(szStr, "Hello string!\r\n");
return szStr;
}
void func0() {
strcpy(szStr, "Hello");
}
char* func1() {
strcat(szStr, " string!\r\n");
return szStr;
}
do testowania stworzony do plików C, gdzie jeden dzwoni single_func() i func0 innych połączeń() i func1().
Wynikowe pliki wykonywalne to 751290B w obu przypadkach. Jeśli wywołasz strcpy i strcat bezpośrednio z modułów, oba pliki stają się 7215B.
Czy nie jest to sprzeczne z powyższym stwierdzeniem, czy też brakuje mi szczegółów dotyczących łączenia?
Powiązanym pytaniem jest to, że biblioteka statyczna ma 1600B, więc skąd wziął się ten wzrost?
dodatkowe:
Oba główne formaty składają się z niczym więcej niż wywołanie funkcji i drukowanie wyników, tak:
main0:
#include <stdio.h>
#include "sharedlib.h"
int main() {
char* szStr = single_func();
printf("%s", szStr);
return 0;
}
Main1:
#include <stdio.h>
#include "sharedlib.h"
int main() {
char* szStr;
func0();
szStr = func1();
printf("%s", szStr);
return 0;
}
Pliki zostały opracowane tak:
gcc -static main0.c -L. -lsharedlib -o main0
Platforma jest linux i kompilator gcc v4.6.3 jest.
Mam zaktualizowane moje pytanie z dodatkowymi informacjami, o które prosiłeś, ale myślę, że mogę zacząć widzieć, gdzie to się dzieje. 1: Podczas korzystania z pojedynczej funkcji z pliku obiektu biblioteki cały plik obiektowy jest zwijany do pliku wykonywalnego. 2: przy użyciu opcji -static biblioteki _all_ są wyrzucane do końcowego pliku wykonywalnego, tworząc większy rozmiar pliku. Czy mam rację? – Kenneth
Tak; masz rację w obu szczegółach. Jeśli spojrzysz na książkę "Standardowa biblioteka C" (dla standardu C89), zobaczysz, że większość plików źródłowych ma jedną zewnętrznie widoczną funkcję, więc nie przeciągasz tego, czego nie używasz do pliku wykonywalnego. Prawdopodobnie można znacznie zmniejszyć rozmiar pliku wykonywalnego, dodając '-shared' do wiersza poleceń po' -lsharedlib'. –
Jestem trochę zaskoczony, że biblioteka C jest (wydaje się być) połączona statycznie. Pewnego razu (prawdopodobnie dziesięć lat temu) pomyślałem, że biblioteka C nie została dostarczona jako biblioteka statyczna (więc musiała być udostępniona).Być może błędnie oceniam, lub może to być wariant uniksowy, a nie Linux. Możesz sprawdzić, co jest ładowane jako biblioteka współdzielona z 'ldd main0'. Wyświetli listę udostępnionych obiektów. –