How to specify Libs variable of pkgconfig during its generation by qmake? - qt

I want to set Libs: line via qmake .pro file and I try doing it like this:
LIBS += -ldl
to make my target executable be also linked with dl library because my library I am trying to link it with uses dl inside. However, this does not work, and qmake puts this string into Libs.private section instead which is not passed to gcc command line during compilation and so I am unable to produce an executable:
Libs.private: -ldl
while I want it to be in Libs: line like that:
Libs: -lmylibrary -ldl
I also can't find any references to QMAKE_PKGCONFIG_* variables anywhere in the web, is there any?

Is used for generating .pc files:
CONFIG += create_pc create_prl no_install_prl
By greping for QMAKE_PKGCONFIG_ I found the following in ~/5.12.0/clang_64/mkspecs/features/qt_module.prf
QMAKE_PKGCONFIG_DESTDIR
QMAKE_PKGCONFIG_LIBDIR
QMAKE_PKGCONFIG_INCDIR
QMAKE_PKGCONFIG_CFLAGS
QMAKE_PKGCONFIG_NAME
QMAKE_PKGCONFIG_FILE
QMAKE_PKGCONFIG_REQUIRES
QMAKE_PKGCONFIG_DESCRIPTION
QMAKE_PKGCONFIG_INSTALL_REPLACE
From the man page for pkg-config:
Libs.private:
This line should list any private libraries in use.
Private libraries are libraries which are not exposed through your library,
but are needed in the case of static linking.
This differs from Requires.private in that it references
libraries that do not have package files installed.
So i guess as long as you don't export them through your lib they will end up in Libs.private.

Related

How can I tell Qt where it should look for openssl?

Qt seems to load openssl dynamically at runtime, as seen in this question.
And apparently, it gets the system openssl. For instance, on macOS, I would rather use the homebrew-installed openssl, and package it into my dmg, so that the users don't need to install it themselves.
How can I tell Qt where to look for the libraries it links? Is there something to do with the qt.conf file?
you can do something like that in your .pro file:
win32-msvc* {
LIBS += -LC:/openssl/lib/ -llibeay32
LIBS += -LC:/openssl/lib/ -lssleay32
INCLUDEPATH += C:/openssl/include
}
left click on your project -> add library -> external library -> choose the .lib file and the include folder for the library. check for which platform it is.
It will put the specific platform dependend commands to your project .pro filefile.

Using FFMPEG with QT

I'm having a problem with linking FFmpeg libraries to Qt 5.10 Projects.
I downloaded the source code from the official website and successfully compiled and installed to my Ubuntu. I used: ./configure --enable-libvpx --disable-x86asm them: make && make install
I'm able to find the installed libraries in /usr/local/lib (which are .a libs).
my .pro looks like this:
INCLUDEPATH += /usr/local/include
LIBS += -L/usr/local/lib -lavformat -lavcodec -lavutil
but i get the output:
/usr/bin/x86_64-linux-gnu-ld:
/usr/loca/lib/libavformat.a(http.o):undefined reference to symbol 'inflateEnd'
//lib/x86_64-linux-gnu/libz.so.1: error adding symbols: DSO missing from command line
Does anyone know how to solve it? Thanks for the attention!
Note: I would like to static link it to my project

Can you specify the path to exe in qmake?

Let's talk about it in linux terms. I have a ".so" file. I want to make the executable dependent on it, look for it in the same directory. How do you do it through qmake? Or can this only be achieved through the use of QLibrary?
For example, when you have a ".so" file and want to use it in your project, in qmake you write:
LIBS += -L"path to the folder that contains your .so" -lSoName
But the path is hardcoded, as you can see, and I'm wondering what to write there to make the executable look for the ".so" in the same directory.
You use RPATH
You can configure your binary or library to find shared library (or dll) in current directory using RPATH directive that is emedded in the binary itself which the loader respects at runtime
1- Add the following in your .pro file
unix {
message("Adding RPATH to the app")
QMAKE_LFLAGS += -Wl,-rpath=\'\$$ORIGIN/\'
QMAKE_RPATH =
}
This will set RPATH of executable to current directory and your executable will first try to look for that .so in your current directory and then in standard directory (this process is explained here)
2- After you compile and create binary VERIFY that RPATH is set correctly
objdump -x <path/to/binary> |grep RPATH
it should say $ORIGIN
Compile time configuration:
CXXFLAGS += -L"/path/to/libmarylin.so/file" -lmarylin
There are a few ways to do it.
If the executable is going in the current directory, just do LIBS += -L$$(PWD) -lSoName.
If you're putting the executable into some other sub-directory, specified by some qmake variable like DESTDIR, use LIBS += -L$$(DESTDIR) (or whatever variable holds that directory).
Alternatively, you can add the directory with the executable to the runtime path of the executable, which gives the dynamic linker a list of directories to search for any unresolved libraries at runtime. This can be done with QMAKE_RPATHDIR += -L$$(PWD) and LIBS += -lSoName, which will tell the linker to look for unresolved libraries in the current directory where qmake is run.
Some operating systems may also include the current directory in the runtime search path for libraries by default, in which case just doing LIBS += -lSoName should be sufficient. That is platform-dependent, though, while the above solutions are not.

Replacing RPATH when Deploying Qt Shared Libraries

Setup
I have a local installation of Qt located in my home directory: /home/user/Qt/... (from now on, devdir).
The Qt application that I'm trying to package installs the relevant Qt shared libraries to /usr/lib/myapplication (from now on, installdir).
My packaging process is currently set up like this:
qmake > dh_make -s --createorig > debuild
Problem
I am trying to set RPATH in myapplication.pro to only link to libraries in installdir, but it is currently linking to both installdir and devdir.
I think it has to do with qmake creating dependencies to the installation libraries automatically. To try to stop it, I have run the build process with qmake -nodepend, but that hasn't stopped the link to devdir from happening.
How do I force qmake to link only to libraries in installdir?
Code
In myapplication.pro:
QMAKE_LFLAGS = -Wl,-rpath,/usr/lib/myapplication
The resulting link flags in the Makefile are:
LFLAGS = -Wl,-rpath,/usr/lib/myapplication -Wl,-Bsymbolic-functions -Wl,-z,relro -Wl,-rpath,/home/user/Qt/5.3/gcc_64 -Wl,-rpath,/home/user/Qt/5.3/gcc_64/lib
The path to /home/user/Qt/5.3/gcc_64 can be removed by overwriting QMAKE_RPATHDIR. To suppress both paths the variable QMAKE_LFLAGS_RPATH should be empty as in Setting RPATH order in QMake
# rpath variables for unix
unix: {
# suppress the default RPATH
QMAKE_LFLAGS_RPATH =
# add custom path
QMAKE_LFLAGS = -Wl,-rpath,/usr/lib/myapplication
}

How to solve undefined reference errors when linking log4cxx in qmake project

It's the second day I'm trying to marry Qt5, MinGW and log4cxx.
Even after I've compiled everything successfully, linked apr, apr-util and log4cxx libraries, ld gives me a bunch of "undefined reference" problems.
It looks like different settings were specified during log4cxx compilation (I'm using ant).
Was anyone able to successfully compile and use log4cxx with MinGW?
Environment:
log4cxx trunk
apr 1.4.6
apr-util 1.5.2
latest MinGW
I'm using Qt 5 with latest MinGW as a compiler
What I've done:
compiled log4cxx using ant with the following command: "ant
-Dcompiler=gcc -Dfind=false -DLOG4CXX_STATIC=1 -Dlib.type=static"
added result libraries to my project in pro file: "LIBS +=
-L../log4cxx/lib LIBS += -llibapr-1 -llibaprutil-1 -lliblog4cxx"
And now, as I try to link my project, I'm getting the next:
*C:/mingw/bin/mingw32-make -f Makefile.Debug
mingw32-make[1]: Entering directory 'C:/Work/SPP_Development/AutoHaul/Sub-systems/TCS/Source/build-SimulatorEngine-Standalone_MinGW-Debug'
g++ -Wl,-subsystem,windows -mthreads -o debug\SimulatorEngine.exe object_script.SimulatorEngine.Debug -lmingw32 -lqtmaind -L../log4cxx/lib -llibapr-1 -llibaprutil-1 -lliblog4cxx -LC:\Qt\Qt5.0.1\5.0.1\mingw47_32\lib -lQt5XmlPatternsd -lQt5Widgetsd -lQt5Networkd -lQt5Xmld -lQt5Guid -lQt5Cored -llibEGLd -llibGLESv2d -lgdi32 -luser32
Makefile.Debug:200: recipe for target 'debug\SimulatorEngine.exe' failed
mingw32-make[1]: Leaving directory 'C:/Work/SPP_Development/AutoHaul/Sub-systems/TCS/Source/build-SimulatorEngine-Standalone_MinGW-Debug'
Makefile:34: recipe for target 'debug' failed
../log4cxx/lib/liblog4cxx.lib(mutex.o): In function `ZN7log4cxx7helpers5MutexC2ERNS0_4PoolE':
c:/Work/log4cxx/apache-log4cxx-trunc/src/main/cpp/mutex.cpp:35: undefined reference to `apr_thread_mutex_create#12'
../log4cxx/lib/liblog4cxx.lib(mutex.o): In function `ZN7log4cxx7helpers5MutexC2EP10apr_pool_t':
c:/Work/log4cxx/apache-log4cxx-trunc/src/main/cpp/mutex.cpp:45: undefined reference to `apr_thread_mutex_create#12'
../log4cxx/lib/liblog4cxx.lib(mutex.o): In function `ZN7log4cxx7helpers5MutexD2Ev':
c:/Work/log4cxx/apache-log4cxx-trunc/src/main/cpp/mutex.cpp:55: undefined reference to `apr_thread_mutex_destroy#4'*
It looks like log4cxx library cannot findfunctions declared and defined in the apr library by whatever reason.
Is there any way to analyze the problem further to see why is this happening?
I will describe the 1st problem you have and give the solution for it. If it does not solve your problem, do not revert back because that would be just the 1st step of fixing process, and I will gradually expand the answer to solve more incoming issues as long as you provide relevant feedback on each fix until we finally nail it down. So, lets begin.
First of all, you add libraries into LIBS variable in a wrong way. You have 2 options to do it right:
#1
LIBS += $${PWD}/../log4cxx/lib/libapr-1.a
LIBS += $${PWD}/../log4cxx/lib/libaprutil-1.a
LIBS += $${PWD}/../log4cxx/lib/liblog4cxx-1.a
#2
LIBS += -L$${PWD}/../log4cxx/lib
LIBS += -lapr-1
LIBS += -laprutil-1
LIBS += -llog4cxx-1
NOTE: Of course one liner is possible too:
LIBS += -L$${PWD}/../log4cxx/lib -lapr-1 -laprutil-1 -llog4cxx-1
NOTE: Using line continuation (\) for readability is possible too:
LIBS += -L$${PWD}/../log4cxx/lib \
-lapr-1 \
-laprutil-1 \
-llog4cxx-1
You need to take care of the proper link order: liblog4cxx depends on libapr*, so the libapr entries need to come after liblog4cxx:
LIBS += -L../log4cxx/lib \
-llog4cxx-1 \
-lapr-1 \
-laprutil-1
The reason is that dependencies are resolved left to right, so that in your case the apr libraries have been read, and forgotten, when log4cxx comes along that has some external symbols that need resolving. ld won't read the apr libraries again (has to do with cyclic dependency issues, and historical reasons).
To test if this works, you can try running the command
g++ -Wl,-subsystem,windows -mthreads -o debug\SimulatorEngine.exe object_script.SimulatorEngine.Debug -lmingw32 -lqtmaind -L../log4cxx/lib -lliblog4cxx -llibapr-1 -llibaprutil-1 -LC:\Qt\Qt5.0.1\5.0.1\mingw47_32\lib -lQt5XmlPatternsd -lQt5Widgetsd -lQt5Networkd -lQt5Xmld -lQt5Guid -lQt5Cored -llibEGLd -llibGLESv2d -lgdi32 -luser32
from the directory
C:/Work/SPP_Development/AutoHaul/Sub-systems/TCS/Source/build-SimulatorEngine-Standalone_MinGW-Debug
yourself first. But perhaps just modifying the .pro file is simplest.

Resources