【发布时间】:2021-07-03 11:12:06
【问题描述】:
我有以下源代码:
-
foo.hvoid foo(); -
foo.cpp#include "foo.h" #include <iostream> void foo(){ std::cout << "This is foo" << std::endl; } -
main.cpp:#include "foo.h" int main(){ foo(); return 0; }
然后我运行以下命令来生成 foo.cpp 的静态和共享版本:
g++ -c -fPIC foo.cpp
ar rvs libfoo.a foo.o
g++ -shared -o libfoo.so foo.o
g++ -c main.cpp
如果我尝试使用静态 libfoo.a 和 main.o 生成可执行文件,则目标文件和库文件的顺序很重要:
g++ main.o libfoo.a -o main # works
g++ libfoo.a main.o -o main # fails with undefined references to `foo()`
正如this post 中所述,顺序很重要。
但是,如果我尝试使用共享的 libfoo.so 和 main.o 构建可执行文件,则目标文件和库文件的顺序不再重要:
g++ main.o libfoo.so -o main # works
g++ libfoo.so main.o -o main # also works without errors
这是否意味着当我们链接目标文件和共享库时顺序并不重要?或者这只是一个特例或我不知道的巧合?
以上代码和命令在以下平台测试:
- Linux:CentOS 7.4
- gcc:7.3.1 或 4.8.5(均已测试)
【问题讨论】:
-
链接到静态库只会拉入未解析符号的目标。 (静态库是保存目标文件的容器文件。)共享库包含整个库,即使您的代码只需要该共享库中的 1 个符号。共享库是在加载时解析的符号,而不是链接时。各有利弊;对于我编写静态库的应用程序来说是一个很大的胜利,而共享库是一个很大的痛苦。
标签: c++ gcc linker static-linking dynamic-linking