Reputation: 93
I have a question about making static libraries that use other static libraries.
I set up an example with 3 files - main.cpp, slib1.cpp and slib2.cpp. slib1.cpp and slib2.cpp are both compiled as individual static libraries (e.g. I end up with slib1.a and slib2.a) main.cpp is compiled into a standard ELF executable linked against both libraries.
There also exists a header file named main.h which prototypes the functions in slib1 and slib2.
main.cpp calls a function called lib2func() from slib2. This function in turn calls lib1func() from slib1.
If I compile the code as is, g++ will return with a linker error stating that it could not find lib1func() in slib1. However, if I make a call to lib1func() BEFORE any calls to any functions in slib2, the code compiles and works correctly.
My question is simply as follows: is it possible to create a static library that depends on another static library? It would seem like a very severe limitation if this were not possible.
The source code for this problem is attached below:
main.h:
#ifndef MAIN_H
#define MAIN_H
int lib1func();
int lib2func();
#endif
slib1.cpp:
#include "main.h"
int lib1func() {
return 1;
}
slib2.cpp:
#include "main.h"
int lib2func() {
return lib1func();
}
main.cpp:
#include <iostream>
#include "main.h"
int main(int argc, char **argv) {
//lib1func(); // Uncomment and compile will succeed. WHY??
cout << "Ans: " << lib2func() << endl;
return 0;
}
gcc output (with line commented out):
g++ -o src/slib1.o -c src/slib1.cpp
ar rc libslib1.a src/slib1.o
ranlib libslib1.a
g++ -o src/slib2.o -c src/slib2.cpp
ar rc libslib2.a src/slib2.o
ranlib libslib2.a
g++ -o src/main.o -c src/main.cpp
g++ -o main src/main.o -L. -lslib1 -lslib2
./libslib2.a(slib2.o): In function `lib2func()':
slib2.cpp:(.text+0x5): undefined reference to `lib1func()'
collect2: ld returned 1 exit status
gcc output (with line uncommented)
g++ -o src/slib1.o -c src/slib1.cpp
ar rc libslib1.a src/slib1.o
ranlib libslib1.a
g++ -o src/slib2.o -c src/slib2.cpp
ar rc libslib2.a src/slib2.o
ranlib libslib2.a
g++ -o src/main.o -c src/main.cpp
g++ -o main src/main.o -L. -lslib1 -lslib2
$ ./main
Ans: 1
Upvotes: 2
Views: 4317
Reputation: 84169
The order make the difference. Here's from gcc(1)
manual page:
It makes a difference where in the command you write this option; the linker searches and processes libraries and object files in the order they are specified. Thus, foo.o -lz bar.o searches library z after file foo.o but before bar.o. If bar.o refers to functions in z, those functions may not be loaded.
Upvotes: 2
Reputation: 2558
Please, try g++ -o main src/main.o -L. -Wl,--start-group -lslib1 -lslib2 -Wl,--end-group
.
Group defined with --start-group
, --end-group
helps to resolve circular dependencies between libraries.
See also: GCC: what are the --start-group and --end-group command line options?
Upvotes: 3