C静态库是如何工作的?
How does a C static library work?
使用库时,最终的可执行文件中包含哪些代码?
例如,我们有两个文件:
/*main.c*/
int main (int argc, char* argv[]){
fc(1); /*This function is defined in fc.c*/
}
另一个文件:
/*fc.c*/
int fc(int x){
return fe(x);
}
int fe(int y){
return y + 1;
}
我们编译fc.c:
gcc -c fc.c
然后我们得到fc.o.
现在让我们构建一个名为 test 的库:
ar rcs libtest.a fc.o
我们现在有 libtest.a.
现在编译main.c
gcc -c main.c
然后我们得到main.o
让我们link我们的main.o到我们的libtest.a
gcc -L. main.o -ltest
我们得到了想要的a.out
检查它的符号:
nm a.out
在所有符号之间,我们发现:
080483cc T fc
080483df T fe
看起来不错。
但是!
如果我们的main.c为此改变?
/*main.c*/
int main (int argc, char* argv[]){
fe(1); /*This function is defined in fc.c*/
}
编译 main.c 并将新的 main.o link 编译到我们的库后,我仍然会找到 fc 的符号。但我不需要那个代码。
问题
-库"give me"不应该只有我在main.c中需要的代码吗?
- 在添加到库之前,函数是否需要在单独的模块中?
-如果我有 300 个函数怎么办?我需要制作 300 个模块吗?
是的,将每个函数放在一个单独的模块中。这样,linker 将 link 只在需要的项目中。
简而言之,有编译器标志可以从最终的可执行代码中删除未使用的函数,但默认情况下不启用。
如果添加这些标志,GCC 可以执行此 "garbage collection" 未使用的函数:
-ffunction-sections
作为 compile-time 标志。它指示编译器为每个函数创建一个单独的 部分 (请参阅 object file format)。还有 -fdata-sections
具有类似含义的标志,适用于变量。
-Wl,--gc-sections
作为 link-time 标志。 -Wl
部分指示 GCC 将以下选项传递给链接器。 --gc-sections
表示 "garbage select sections from which all code is unsed"。由于 compile-time 选项每个函数都有一个单独的部分,它有效地执行 function-level 修剪。
使用库时,最终的可执行文件中包含哪些代码?
例如,我们有两个文件:
/*main.c*/
int main (int argc, char* argv[]){
fc(1); /*This function is defined in fc.c*/
}
另一个文件:
/*fc.c*/
int fc(int x){
return fe(x);
}
int fe(int y){
return y + 1;
}
我们编译fc.c:
gcc -c fc.c
然后我们得到fc.o.
现在让我们构建一个名为 test 的库:
ar rcs libtest.a fc.o
我们现在有 libtest.a.
现在编译main.c
gcc -c main.c
然后我们得到main.o
让我们link我们的main.o到我们的libtest.a
gcc -L. main.o -ltest
我们得到了想要的a.out
检查它的符号:
nm a.out
在所有符号之间,我们发现:
080483cc T fc
080483df T fe
看起来不错。 但是!
如果我们的main.c为此改变?
/*main.c*/
int main (int argc, char* argv[]){
fe(1); /*This function is defined in fc.c*/
}
编译 main.c 并将新的 main.o link 编译到我们的库后,我仍然会找到 fc 的符号。但我不需要那个代码。
问题
-库"give me"不应该只有我在main.c中需要的代码吗?
- 在添加到库之前,函数是否需要在单独的模块中?
-如果我有 300 个函数怎么办?我需要制作 300 个模块吗?
是的,将每个函数放在一个单独的模块中。这样,linker 将 link 只在需要的项目中。
简而言之,有编译器标志可以从最终的可执行代码中删除未使用的函数,但默认情况下不启用。
如果添加这些标志,GCC 可以执行此 "garbage collection" 未使用的函数:
-ffunction-sections
作为 compile-time 标志。它指示编译器为每个函数创建一个单独的 部分 (请参阅 object file format)。还有-fdata-sections
具有类似含义的标志,适用于变量。-Wl,--gc-sections
作为 link-time 标志。-Wl
部分指示 GCC 将以下选项传递给链接器。--gc-sections
表示 "garbage select sections from which all code is unsed"。由于 compile-time 选项每个函数都有一个单独的部分,它有效地执行 function-level 修剪。