Terminology

The first hurdle to take was terminology. Apparently I was the only one in the world building DLLs on Linux as Google didn't give me any hope. But are Linux applications all statically built? No. I was wrong to make the assumption that terminology was the same across the OSs.

While in Windows world it's called DLLs, in Unix/Linux world the same thing is called 'shared libraries' and they usually have the .so file extension. That was an important breakthrough as that really helped me finding useful results on Google.

Note

In Windows we have DLLs, in Linux/Unix we have shared libraries. It's the same!

Creating the projects

Step 1: Using the wizard

We'll need at least two projects in Qt Creator; one will be the shared library, the other one the main() and maybe some other classes. This, of course, depends on the model you're trying to put life to.

  1. Create a new project.
  2. Choose 'Other Project' on the left and select C++ Libary.
  3. A wizard will open and select 'Shared Library' as the type. Fill in the name of your library and the (base) path to create it in.
  4. Select 'QtCore' as only required Qt module. (Don't know if this is really needed.)
  5. Create your first class from the wizard.
  6. Finish the wizard.
  7. Open the .pro file with the editor and notice the following: TEMPLATE (should be LIB).

Build (don't run) the project.

Now you should get .dll along with .a files on Windows (G++/MinGW setup) or .so files on Linux (with a lot of symlinks) in the build directory (probably some shadow build folder—this is fine).

Step 2: Moving the shared libraries to a common folder

It's quite common to build libraries yourself and actually use them in another project at the same time. One would need to make install all of the libraries in order to use them. For developing your libraries and their uses at the same time, this is unwanted. In order to move the shared libraries (and the needed header files to interface with it) we'll use some QMake magic.

Open the .pro file and append on the end of the file the following (example, customize to your own needs):

# Set the destination directory of the shared libraries
# MYDLLDIR is a name something I made up myself, DESTDIR is a QMake variable.
# $$IN_PWD expands to the directory your .pro file is in.
# This example copies the final build output to ../dlls (one level above your project).
MYDLLDIR = $$IN_PWD/../dlls

# We need quotes around the path in order to support whitespaces in the path
# for Windows. e.g. (''C:\Users\Gert van Dijk\...'').
# For some strange reason $$quote(...) does not seem to work for Windows here.
DESTDIR = \"$$MYDLLDIR\"

#
# Here's some magic to move all of the project's header files to the same DLL directory.
#

DDIR = \"$$MYDLLDIR/\"
SDIR = \"$$IN_PWD/\"
# Replace slashes in paths with backslashes for Windows
win32:file ~= s,/,\\,g
win32:DDIR ~= s,/,\\,g
win32:SDIR ~= s,/,\\,g
# For-loop to copy all header files to DDIR.
for(file, HEADERS) {
    QMAKE_POST_LINK += $$QMAKE_COPY $$quote($${SDIR}$${file}) $$quote($$DDIR) $$escape_expand(\\n\\t)
}

In the directory dlls (located one level above your project) you should now find the library along with the header files.

Hint

If you don't want to expose all of the HEADERS, just specify your on list of headers and let the for-loop run on that. This can be useful in cases that you want your internal library method calls to be completely closed and only expose some classes to interface with others.

Note

This whole magic could also be done using the 'Build Settings' and specifying custom build steps of your project, but this ends up in the .pro.user file and this is not desiged to be shared with other developers.

Step 3: Creating a project using the shared library

Now that we output the library and their headers to some common folder, we can use that as the path for QMake to depend on when linking against the libraries in there.

You can leave the project of the shared library open or close it, it doesn't matter.

  1. Create a new project.
  2. Choose 'Other Project' on the left and select 'Qt Console application' (just an example).
  3. Fill in the name of your library and the (base) path to create it in.
  4. Use default build set up (both Release and Debug, enable shadow building).
  5. Create your first class from the wizard.
  6. Finish the wizard.
  7. Open the .pro file with the editor and notice the following: TEMPLATE (should be app).

Now in order to make it dependent on the library, append the following to the .pro file:

MYDLLDIR = $$IN_PWD/../dlls

# As our header files are in the same directory, we can make Qt Creator find it
# by specifying it as INCLUDEPATH.
INCLUDEPATH += $$MYDLLDIR

# Dependency to library domain (libdomain.so for Unices or domain.dll on Win32)
# Repeat this for more libraries if needed.
win32:LIBS += $$quote($$MYDLLDIR/domain.dll)
 unix:LIBS += $$quote(-L$$MYDLLDIR) -ldomain

Now you should be able to build (not yet run) your project.

Note

To create libraries depending on other libraries, you simply specify the QMake LIBS also in you shared library project. If you fail to do so, you'll get runtime errors.

Step 4: Set up runtime linker paths

While it now builds, it needs to be able to find your shared libraries at runtime. To make it search in the specified directory we will need to append it to the PATH environment variable (Windows) or LD_LIBRARY_PATH environment variable (Unices).

  1. Click on 'Projects' in the left toolbar in Qt Creator.
  2. Select the leaf project (the one that builds to the executable to run) at the top.
  3. Click on 'Run Settings'
  4. Somewhat below, you'll find 'Run Environment'. Expand it (click on 'Details').
  5. For Unices:
    • Click on the button 'Add' to the right.
    • Enter LD_LIBRARY_PATH as 'Variable' and ../dlls as Value.
  6. For Windows:
    • Find PATH In the list of Variables.
    • Click 'Edit'.
    • Add our path relative by appending ;..\dlls.

Now you should be able to build and run your leaf project depending on a library!

Warning

Build order does matter. While you can specify build dependencies in Qt Creator in order to just hit "Build All", this didn't work out for me. Just build the libraries in the order it works for their dependencies, and your leaf project as the last one.

Share on: TwitterHacker NewsFacebookLinkedInRedditEmail

Comments

comments powered by Disqus

Related Posts


Published

Last Updated

Category

Programming

Tags

Connect with me on...