Compiling C++ Codes into shared library and linking them
Let's say you have files print.h and print.cpp, shown below that contains C++ codes you wish to compile as .so (shared object) file and they are stored in ~/demo/lib folder.
#ifndef __PRINT__
#define __PRINT__
#include <iostream>
#include <stdio.h>
void print(const char* p, bool endl = true);
#endif
#define __PRINT__
#include <iostream>
#include <stdio.h>
void print(const char* p, bool endl = true);
#endif
#include <print.h>
void print(const char* p, bool endl)
{
std::cout << "print: " << p;
if (endl) std::cout << std::endl;
}
void print(const char* p, bool endl)
{
std::cout << "print: " << p;
if (endl) std::cout << std::endl;
}
You can compile the above code into .o (static library) file with the command
~/demo/g++ -o lib.o -c ./lib/print.cpp
But we want to compile it as .so (shared library) file so we use the command instead
~/demo/g++ -o ./lib/liblib.so -shared -fpic ./lib/print.cpp
Note that with the above commands, liblib.so and lib.o is created in ~/demo/lib folder upon successful compilation.
Now let's say you have another set of C++ files loop.cpp and loop.h, shown below and you wish to compile them together with another C++ file into an .so file...
#ifndef __LOOP__
#define __LOOP__
#include <iostream>
#include <unistd.h>
class loop
{
public:
loop()
{
std::cout << "loop constructor"<< std::endl;
}
virtual ~loop()
{
std::cout << "loop destructor"<< std::endl;
}
void run(int i, int r);
};
#endif
#define __LOOP__
#include <iostream>
#include <unistd.h>
class loop
{
public:
loop()
{
std::cout << "loop constructor"<< std::endl;
}
virtual ~loop()
{
std::cout << "loop destructor"<< std::endl;
}
void run(int i, int r);
};
#endif
#include <loop.h>
void loop::run(int i, int r)
{
while(r)
{
sleep(i);
std::cout << "loop..." << std::endl;
r--;
}
}
void loop::run(int i, int r)
{
while(r)
{
sleep(i);
std::cout << "loop..." << std::endl;
r--;
}
}
To compile print.cpp and loop.cpp files into a single .so file, do the command as shown below
~/demo/g++ -o ./lib/liblib.so -shared -fpic ./lib/print.cpp ./lib/loop.cpp
Now that we have .so file already, let's create a C++ program that will use this shared library and use the function and class it contains.
The C++ file below will be our C++ program. It is stored as main.cpp in ~/demo folder.
It uses print() from print.cpp to print "hello world" and uses loop class to perform a loop of 5 intervals.
#include <iostream>
#include <print.h>
#include <loop.h>
int main()
{
print("hello world");
loop p;
p.run(1,5);
return 0;
}
#include <print.h>
#include <loop.h>
int main()
{
print("hello world");
loop p;
p.run(1,5);
return 0;
}
Let's compile this code and link the shared library with it. The command below shows how to compile it into "run".
g++ -o run main.cpp -L/lib -llib -I./lib -I./
If compile is successful, and executable named 'run' should appear in ~/demo folder. If you execute it, you might encounter an error as shown below. This is because when executing a program that has dependency on a shared library, it needs to know where the library is.
run: error while loading shared libraries: liblib.so: cannot open shared object file: No such file or directory
To fix this, you can do either of the two possible solutions
1. Copy the liblib.so into any folder listed in the system's LD_LIBRARY_PATH environment variable. This is a more consistent solution because you only do this once.
2. add ~/demo/lib folder into LD_LIBRARY_PATH environment variable. You have to keep setting this every time you try to execute your program in a new terminal. To do this, follow the command below:
~/setenv LD_LIBRARY_PATH ~/demo/lib:${LD_LIBRARY_PATH}
Now try to run the program again.
Using Makefile
You can create a makefile to simplify this process. Copy the code below into ~/demo/makefile
all: so main
so : ./lib/print.cpp ./lib/loop.cpp
g++ -o ./lib/liblib.so -shared -fpic ./lib/print.cpp ./lib/loop.cpp -I./lib
main : ./lib/liblib.so
g++ -o run main.cpp -L./lib -llib -I./lib -I ./
so : ./lib/print.cpp ./lib/loop.cpp
g++ -o ./lib/liblib.so -shared -fpic ./lib/print.cpp ./lib/loop.cpp -I./lib
main : ./lib/liblib.so
g++ -o run main.cpp -L./lib -llib -I./lib -I ./
Then just call 'make' and the whole compiling process will be done.
No comments:
Post a Comment