hyuk myeong
hyuk myeong

Reputation: 325

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

I'm studying how the C++ linker (gnu linker here) resolves dependencies
between static libraries and shared libraries and stuck in a question as below for a while

There are 3 files as below

// 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;
}

If I make foo.cpp and boo.cpp as libraries and link them with main.cpp to make an executable
Then the result varies in four different cases as below
Why only the first one fails, and others succeed?
Making a static library from static libraries can't resolve the dependency by itself?

(1) build fail

# 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) build success

# 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) build success

# 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) build success

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

Upvotes: 0

Views: 198

Answers (1)

Maxim Egorushkin
Maxim Egorushkin

Reputation: 136208

When compiling (-c option is present), -static -L -l<lib> options have no effect. Static libraries cannot carry dependencies on other libraries.

To fix your build error correct commands are:

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

Upvotes: 1

Related Questions