【问题标题】:What is the difference when resolving dependencies between static libraries and shared libraries in C++?在 C++ 中解决静态库和共享库之间的依赖关系时有什么区别?
【发布时间】:2021-01-05 10:28:43
【问题描述】:

我正在研究 C++ 链接器(此处为 gnu 链接器)如何解决依赖关系
在静态库和共享库之间,停留在下面的问题中一段时间​​

下面有3个文件

  • main.cpp(取决于foo.cpp
  • foo.cpp(取决于boo.cpp
  • boo.cpp
// main.cpp
#include <iostream>

extern int foo();

int main()
{
  std::cout << foo() << std::endl;
}

// foo.cpp
extern int boo();

int foo()
{
  return boo();
}

// boo.cpp
int boo()
{
  return 10;
}

如果我将 foo.cppboo.cpp 作为库并将它们与 main.cpp 链接以生成可执行文件
然后结果在以下四种不同情况下有所不同
为什么只有第一个失败,而其他人成功?
静态库做静态库不能自己解决依赖?

(1) 构建失败

# static library boo
$ g++ -static -c -o boo.o boo.cpp
$ ar rcs libboo.a libboo.o

# static library foo
$ g++ -static -c -o foo.o foo.cpp -lboo -L.
$ ar rcs libfoo.a foo.o

# pass libfoo.a only for the executable
$ g++ -o a.out main.cpp -lfoo -L.

/usr/bin/ld: ./libfoo.a(libfoo.o): in function `foo()':
foo.cpp:(.text+0x9): undefined reference to `boo()'
collect2: error: ld returned 1 exit status

(2) 构建成功

# static library boo
$ g++ -static -c -o boo.o boo.cpp
$ ar rcs libboo.a libboo.o

# static library foo
$ g++ -static -c -o foo.o foo.cpp -lboo -L.
$ ar rcs libfoo.a foo.o

# pass libfoo.a and libboo.a for the executable
$ g++ -o a.out main.cpp -lfoo -lboo -L.

(3) 构建成功

# static library boo
$ g++ -static -c -o libboo.o boo.cpp
$ ar rcs libboo.a libboo.o

# shared library foo
$ g++ -shared -fpic -o libfoo.so foo.cpp -lboo -L.

# pass libfoo.so only for the executable
$ g++ -o a.out main.cpp -lfoo -L.

(4) 构建成功

# shared library boo
$ g++ -shared -fpic -o libboo.so boo.cpp

# shared library foo
$ g++ -shared -fpic -o libfoo.so foo.cpp -lboo -L.

# pass libfoo.so only for the executable
$ g++ -o a.out main.cpp -lfoo -L.

【问题讨论】:

标签: gcc linker g++ shared-libraries


【解决方案1】:

编译时(-c 选项存在),-static -L -l&lt;lib&gt; 选项无效。静态库不能携带对其他库的依赖。

要修复您的构建错误,正确的命令是:

# static library boo
$ g++ -c -o boo.o boo.cpp
$ ar rcs libboo.a libboo.o

# static library foo
$ g++ -c -o foo.o foo.cpp
$ ar rcs libfoo.a foo.o

# link both libfoo.a and libboo.a
$ g++ -o a.out main.cpp -lfoo -lboo -L.

【讨论】:

  • 首先,感谢您的回答,这是否意味着所有相互依赖的静态库都必须在可执行文件的命令行上,对吗?
  • @hyukmyeong 你是对的。通常,构建系统会维护静态库的依赖项列表,因此当您链接它时,它也会链接到其所有依赖项。
  • 谢谢,现在清楚了!所以静态库不能被编译器合并,只能由描述stackoverflow.com/questions/3821916/…的其他工具完成
  • @hyukmyeong 静态库只是具有特殊链接器处理的多个目标文件合二为一。不像 ELF 可执行文件和共享库(一个文件可以是两个),它们可以引用他们需要的其他 ELF 文件。
  • 是的,我知道那部分,非常感谢
猜你喜欢
  • 2023-04-07
  • 1970-01-01
  • 2019-11-15
  • 2021-06-04
  • 2011-02-08
  • 1970-01-01
  • 1970-01-01
  • 2018-01-01
相关资源
最近更新 更多