Linking Libraries in C++ (Linux)
(Disclaimer: I am not an experienced C++ developer, there might be inaccuracies in the following text. I will correct any mistakes I’ll find as I progress. This article is mainly targeting myself for future references).
For the last two years-or-so I’ve been reading up on C++. I’ve read books, done courses, watched about 20 hours of handmade hero and built a few small games/prototypes using open frameworks. Still the thing is that no one is talking about is how to include and use libraries into your project. Trying to figure out the project settings in Visual Studio by yourself is a complete nightmare, and most tutorials will just totally skip this step.
So a couple of nights ago I decided I wanted to try some C++ coding. I wanted to try something that would cross compile so I could develop on both my Linux and my Windows partition. I decided I wanted to use glfw to create a window with an OpenGL context in a cross platform manner. And I wanted to do it from code::blocks (since on Linux). It took two days until I got it running, so I decided to write down the steps I took to get it to work….
I was using Code::blocks 13.12, and Linux Mint 17.1 “Rebecca” at this time.
First of all, download the source files from the glfw homepage (I downloaded Source Package).
Second, find out the dependencies you need from this page. In my case I needed the X11 and openGL header packages, so open up a terminal and enter:
sudo apt-get install xorg-dev libglu1-mesa-dev
Now unzip the glfw sources into a folder and navigate to that folder with your terminal (you might have to install cmake as well with the same apt-get as above), and just write
cmake .
After this the documentation leaves you on your own, with the friendly hint “Go ahead and compile the actual GLFW library with these files, as you would with any other project”. Thanks a lot.
So, after a lot of searching and trial-and-error I found you can write the following (still in the glfw-folder):
make
sudo make install
It might be enough with the second command, but I did both of them. Now you see a lot of good stuff going on, and at the end the terminal will output where it has installed the compiled output and headers. It also creates a text file in the same folder install_manifest.txt which lists the paths to the installed libraries. Mine went into the /usr/local/include/GLFW for the headers and /usr/local/lib for the libraries.
Static vs. Runtime/dynamic libraries
Next tricky part is to get code::blocks to find these libraries. Start with creating a new empty console project, then copy-paste this code into the main.cpp so we have something to test.
Next we need to read up a bit on the difference between static and runtime libraries. It’s even more tricky as the extension differs between Windows and Linux.
After this we need to tell the compiler where to look for the header files, and the linker where to find the actual libraries. This page (again from the excellent learncpp.com guide) is a bit outdated bit makes it pretty straight forward to figure out how to proceed.
Note: after a few days of frustration I have come to the conclusion that setting the search directories in settings > compiler does not make any difference for me. If I remove all entries the project still builds just fine… I still added the step just in case, but marked in blue.
And under the tab Linker, add the following directories: /usr/lib /usr/local/lib /usr/lib/x86_64-linux-gnu
You can probably skip the step above for now and proceed instead by right clicking your project and select “Build options…”. Make sure you always select the global profile and not the debug build, which is selected by default! So now you need to add the library files you want to link against. For me I had to add each in two places. First by entering the folder containing the lib under Seach Directories > Linker, and then add the full path (again…?!?) under Linker Settings > Link Libraries. Looks like this for me:
Search Directories > Linker /usr/local/lib /usr/lib/x86_64-linux-gnu
Linker Settings > Link Libraries /usr/local/lib/libglfw.so /usr/lib/x86_64-linux-gnu/libGL.so
For some reason the global compiler setting doesn’t seem to work, and you need to enter both the path in search directories, AND full path for the library… seems fishy to me.
For me the window appeared without errors after this step. Actually, it did work without linking to libGL.so, however it did not compile if I replaced the test code with this sample for a spinning triangle (scroll to the bottom)
Ok, so it works… here’s a few tricks I also used while struggling with setting this up. Searching for libraries. Haven’t got any good ways of doing this except the old terminal find command (requires you to know the name of the library)
find / -name "libGL.so" 2>/dev/null
Another thing is that you can inspect a file that you built to get the library dependencies in it. However it only works after you have compiled a binary…
ldd ./[outputfile]
When things looked the darkest, when I was just about to give up, I found this link that managed to help me locating the GL-library. I thought I should save it here for future reference.