我正在閱讀O'Reilly的書籍21st Century C,其中作者指出,當與靜態庫鏈接時,「編譯器[有效地]將庫的相關內容複製到最終可執行文件中」。當與靜態庫鏈接時,對象代碼如何被複制到可執行文件中?
我試圖通過創建由該模塊的我自己的靜態庫,以測試這一點:
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;
}
用於測試的創建到c文件,其中一個是調用single_func()和其它呼叫func0()和func1的()。
在這兩種情況下生成的可執行文件都是751290B。如果我直接從模塊中調用strcpy和strcat,那麼這兩個可執行文件最終都是7215B。
這是不是與上述聲明衝突或我缺少關於鏈接的一些細節?
一個相關的問題是靜態庫是1600B,所以這個增加的大小來自哪裏?
附加:
兩個主文件包含的無非調用功能和打印結果,這樣更多:
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;
}
個文件彙編這樣的:
gcc -static main0.c -L. -lsharedlib -o main0
平臺是Linux和編譯器是gcc v4.6.3。
我已經更新了我的問題,並提供了您詢問的額外信息,但我想我可以開始瞭解這方面的進展情況。 1:當從一個庫的目標文件中使用單個函數時,整個目標文件將被放入可執行文件中。 2:通過使用-static選項_all_庫被捲入最終的可執行文件,產生更大的文件大小。我在這裏糾正? – Kenneth
是的;你在兩個細節上都是對的。如果你看Plauger的書「The Standard C Library」(用於C89標準),你會發現大多數源文件都有一個外部可見的函數,這樣你就不會將沒有使用的文件拖入可執行文件。通過在'-lsharedlib'之後在命令行中添加'-shared',可以大大減少可執行文件的大小。 –
我有點驚訝,C庫正在(似乎是)靜態鏈接。有一段時間(也許是十年前),我認爲C庫不是作爲一個靜態庫提供的(所以它必須被共享)。我可能會誤解,或者它可能在Unix上而不是在Linux上。您可以使用'ldd main0'來檢查正在加載的共享庫。它將列出使用的共享對象。 –