Reputation: 325
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
(which depends on foo.cpp
)foo.cpp
(which depends on 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;
}
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
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