在 C++ 中解决静态库和共享库之间的依赖关系有什么区别?

What is the difference when resolving dependencies between static libraries and shared libraries in C++?

我正在研究 C++ linker(这里是 gnu linker)如何解决依赖关系
static libraries和shared libraries之间纠结了一段时间

有3个文件如下

// 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 作为库并 link 它们与 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.

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

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

# 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.