How to deploy and link a shared library on Harmattan
This article explains how to include a shared library into a .deb distribution to comply with Nokia Store requirements; and let an application dynamically link against the deployed shared library.
The use of shared libraries other than already available on the system, or third party shared libraries, is a rather essential part of the development process. However, the Nokia Store policy expressly prohibits a developer to install shared libraries system-wide (e.g. to /usr/lib) since this may lead to overwriting the libraries deployed with other applications and thus rendering the latter inoperative. This results in a situation when your application is unable to resolve the location of the shared library you deployed because the LD_LIBRARY_PATH environment variable does not contain the path to your library.
The Nokia Store policy suggests you deploy shared libraries somewhere in /opt partition, ideally inside your application's directory. Hereinafter we shall imply the target path for deploying the library to be /opt/myapp/lib and the library file itself is called libcool.so.
To deploy a library you need to insert the following into your .pro file:
coollib.files = /local/path/to/libcool.so
coollib.path = /opt/myapp/lib
INSTALLS += coollib
If you are developing under Windows environment, your local path will use DOS notation with backslashes substituted with forward slashes, e.g. something like c:/local/path/to/libcool.so.
You may also consider using the $$PWD variable to specify the path which is relative to the location of your .pro file, for example:
coollib.files = $$PWD/../coollib/libcool.so
There are two stages needed for linking against a shared library: compile-time and runtime. At compile-time the shared library is being searched for the functions it exports to build dependencies inside your application's binary. At runtime these dependencies are followed and the code of the shared library is actually executed.
To allow a compile-time stage in your .pro file:
LIBS += -L/local/path/to -lcool
INCLUDEPATH = /local/headers-path
where cool is the library filename with stripped extension and leading lib, and /local/headers-path is the directory (or directories separated with space) where the library's .h files reside. You may use $$PWD variable here too, if you wish.
To successfully compile your project you have to make one more change, this time rather weird. In your rules file find the following line:
# dh_shlibdeps # Uncomment this line for use without Qt Creator
and comment it twice:
## dh_shlibdeps # Uncomment this line for use without Qt Creator
or simply delete it at all.
For currently unknown reasons (as of QT 4.8.0) dh_shlibdeps command, commented once, is still being executed, though it will prevent your project from compiling with a shared library.
Now, to allow runtime stage you need to tell your application binary the location you've deployed the library file to. This path cannot be resolved automatically because the LD_LIBRARY_PATH environment variable does not contain the path to your library.
To resolve this problem you have to link your application with --rpath option. This is done by adding the following line to your .pro file:
QMAKE_LFLAGS += -Wl,--rpath=/opt/myapp/lib
and you're done.
The described approach works well for Meego 1.2 Harmattan as you can exactly predict the installation path for your application. However, on some other systems the --rpath option cannot be used because you cannot know the exact path your library will be installed to. For such systems you should consider other approaches like installing the library to a system-wide location or modifying environment variables.