Introduction
At a newbe to C++, I was very very very confused about the eco-system of C family. Quite often I find myself in the following situation.
- I want to use a open source library/software.
- I downloaded the source file.
- The default compile options does not work.
- I gave up.
Then I found this answer, which greatly improved my understanding about the library in C++. This is my own note about how to create static & dynamical libries.
Why this matters? I think 99% times a failed compile is because of wrong library path configuration. Once I understand how the C++ library works, I am more confident to fix the path by myself.
The code we have
The example code in three files
hello_world.hhello_world.cppmain.cpp
The goal is to create a library for hello_world so that main.cpp can use the library.
The source code
hello_world.h
class hello{
public:
void printHelloWorld();
};
hello_world.cpp
#include "hello_world.h"
#include <iostream>
void hello::printHelloWorld(){
std::cout << "Hello World!" << std::endl;
}
main.cpp
#include "hello_world.h"
int main(){
hello h;
h.printHelloWorld();
}
Compile with/without the library
Normal Way to Compile
I wrote down the normal way to compile C++ code in a file named compile.sh, with following content
g++ main.cpp hello_world.cpp -o out
./out
rm out
Calling bash compile.sh would print Hello World!
Use Static Library
The static library is an archive of object files (*.o) that are linked inside your final executables.
I wrote down the compile code in a file named static.sh, with following content
g++ -c hello_world.cpp # compile hello_world.cpp -> hello_world.o
ar rcs libhello_world.a hello_world.o # create *.a library
g++ main.cpp libhello_world.a -o out # use library to compile instead of *.cpp
./out
rm *.a
rm out
Calling bash static.sh would print Hello World! and create a static library libhello_world.a.
Use Shared Library
The shared libraries instead are loaded dynamically at run time.
I wrote down the compile code in a file named dynamical.sh, with following content
g++ -fPIC -c hello_world.cpp # compile hello_world.cpp & enable share -> hello_world.o
g++ -shared -o libhello_world.so hello_world.o # create *.so shared library
g++ main.cpp -L . -l hello_world -o out
./out
rm *.o
rm out
Calling bash dynamical.sh would print Hello World! and create a shared library libhello_world.so.
This line needs more words,
g++ main.cpp -L . -l hello_world -o out
-L .means “looking for libraries inside the current folder.”-l hello_worldmeans “looking for a library namedlibhello_world.so”. Yes, the prefixliband suffix.sowere deliberately ignored.