Wednesday, February 29, 2012

Shared Libraries with Eclipse


Hello there! So here we go with another tutorial, this time explaining how to develop shared libraries using Eclipse-CDT as IDE. If you are wondering what is Eclipse-CDT, or what is and IDE that means that you did not read my previous post explaining these topics: http://linuxtortures.blogspot.com/2011/01/c-development-tools.html

A. Installing Eclipse-CDT on Debian Squeeze

Now that you know that and you feel anxious about start developing let me tell you that I have migrated recently to Debian and the installation process is a bit more complicated:

First you have to add the following line (you are actually adding the debian backports repository) in your /etc/apt/sources.list

deb http://backports.debian.org/debian-backports squeeze-backports main

Afterward just run apt-get update and now you should see Eclipse-CDT in your Synaptic, just install among all its depencencies.




B. Creating our 'Client' project and our Shared Library

Once you have selected your workspace you should be into a screen like the following one (Close the welcome tab it is not the case)




Click on File –> New → Project and select C++ Project


Now Select 'Hello world C++ project', set a name for your project (MyClientProject in my case) and click on finish (If you receive a prompt asking for a change of perspective just click on yes):


A brand new project is now on your workspace ready to be compiled:


Repeat the first step File → new –> C++ Project but select this time shared library as project type:



By clicking of Finish you will get back the project perspective with the client and the shared library projects included.



C. Adding some logic to our Shared Library and compiling it

Let's add a class to our shared library (Right click over the shared library project → new → class)





Give it a name and click on Finish.

Let's now implement a little public method 'saySomething()' in our class that returns a string saying 'Im a class'

 



Now compile your shared class (Ctrl + b)

You should see that the Debug Folder contains now the compiled library (libmytestsharedlibrary.so)

 



D. Link our 'Client' to the shared library use it and compile it

We have basically two different ways to do this, the 'Eclipse' way, where we specify the folder where the .h is and the folder where the library is or the 'Linux' way where we copy the shared library and the header to the default folders (/usr/local/include/ or /usr/include/ in the case of the header and /usr/local/lib/ or /usr/lib/ in the case of the libraries).

We are going to do it in the 'Eclipse' way so right click on your client project (MyClientProject in my case) and click on 'Properties'. Unfold C/C++ General, select 'GNU C++' and under the tab 'Includes' select Add:
 




Click on workspace and select the shared library (mytestsharedlibrary in my case).
 



Click on ok and the reference should be included:
 



Now go to the tab 'Library Paths' and add the debug folder of our shared library (the one that contains the .so file)
 



The final result should be something like this:
 

 
Finally we need to include the name of our library. Go to C++ Build → Settings and under GCC C++ Linker click on add on the library window:



Put the name of our library (without the initial 'lib' and the final '.so', in our case that would be mytestsharedlibrary


Click on OK and let it rebuilt if you get a prompt asking for it.


E. Using the library and compiling the client

Modify the client source code to include the header file, instantiate an object of our class and print out the result of calling its method 'saySomething()', then Build the project (Ctrl + b):





D. Running the project

You are now excited about clicking on play and see what happens right? Ok you can try but I bet you get an error like:



First of all we have to create a run configuration, click on the right side of the Play buttom and select 'Run Configurations …' Double click over C/C++ Applicaton and click on 'Run'

 



/home/javier/workspacetest/MyClientProject/Debug/MyClientProject: error while loading shared libraries: libmytestsharedlibrary.so: cannot open shared object file: No such file or directory


What happened?? Well, basically the executable did not found the shared library at execution time. You might think that we already configured the  path where the library is on previous steps. Indeed we did but what we configured was the 'compilation path', meaning that we let the compiler know where the shared library is. Now we need to let the operative system know where the shared library and that could be done in 2 ways.

1. By exporting the path on the environment variable LD_LIBRARY_PATH
This way is not very recommended but on Eclipse is quite convenient, you can do that by opening again the 'Run configurations' and under the tab 'Enviroment' create a new entry with LD_LIBRARY_PATH as name and ${workspace_loc:/mytestsharedlibrary/Debug} as value. The result should looke like this:


Click on 'Run' and …


2. The second way is a bit more exotic, but is the recommended one. You have to include your shared library path in the file /etc/ld.so.conf or create a file ending on .conf on the directory /etc/ld.so.conf.d that includes the path. Once you have done it run the config ldconfig as superuser.

If you have performed this second way correctly you should be able to execute your your program from the terminal