QT Creator - Using External Libraries Within My Own Library - c++

I am developing an application in QT Creator in c++ on Linux
I have created my own library so that I can use some common classes throughout a set of applications.
In the library I have created I have used another external static library (libSDL.a).
I have configured my library to a static library (*.a) and it compiles with no problems.
I then added my library to another application and used some of the classes. When trying to compile my application I am getting undefined references from within my library to function calls to the other library.
From my understanding, static libraries are suppose to be copied in during compilation. Why am I getting the undefined references to a library that should be copied into my library?
Here is how the library project is configured in the *.pro file:
QT -= gui
TARGET = FoobarTools
TEMPLATE = lib
CONFIG += staticlib
CONFIG -= shared
DEFINES += FOOBARTOOLS_LIBRARY
INCLUDEPATH += ./include/SDL_Headers/
LIBS += -L./bin/ -lSDL
SOURCES += ...
HEADERS += ...
Here is how my application *.pro file is using my library:
QT -= gui
TARGET = FoobarApp
CONFIG += console
CONFIG -= app_bundle
TEMPLATE = app
INCLUDEPATH += ./include/
LIBS += -L./bin/ -lFoobarTools
SOURCES += ...
HEADERS += ...

In the application's .pro you need:
INCLUDEPATH += LibraryPath (This points to the header-file's directory.)
DEPENDPATH += LibraryPath (This also points to the header-file's directory.)
LIBS += -LDebugOrReleasePath -lLibraryName (This is the lib-filename minus 'lib' at the beginning and '.a' at the end.)
Once that's done check if the #includes to your custom library are still working.
In the static libary's .pro file you dont need to touch anything, maybe add 'CONFIG += release'.

Both your library and the library it's using should be linked in the application.
INCLUDEPATH += ./include/SDL_Headers/
INCLUDEPATH += ./include/
LIBS += -L./bin/ -lFoobarTools
LIBS += -L./bin/ -lSDL
//And dont forget the Target dependencies.
PRE_TARGETDEPS += ./libFoobarTools.a
PRE_TARGETDEPS ./libSDL.a
If you want to find out more about the reason the library compiles but not the application check out this question.

I think you can find the answer here:
http://gcc.gnu.org/ml/gcc-help/2004-04/msg00104.html
and, more precisely in this follow-up:
http://gcc.gnu.org/ml/gcc-help/2004-04/msg00106.html
I cannot test it right now, but I think the probable cause might be resumed by this:
"linker will "throw away" a library if it comes across it but none of the symbols it defines are needed"
As a first-aid help, add the -lSDL to your second .pro file.
Edit: are you sure that your static library (the first .pro file) really uses some symbols from libSDL? If not, then the compiler will simply ignore the libSDL.a file and will not include it in your static library. Even if you use some symbols from libSDL.a, only those functions will be copied into the executable, while the other symbols would be not (at least, this is what I think). "Static libraries have special rules when it comes to linking. An object from the static library will only added to the binary if the object provides an unresolved symbol." (see: https://stackoverflow.com/a/2649792/1284631). Then, if your executable (the second .pro file) makes use of some not-copied symbols from libSDL, you will have the errors. Quoting the same source: "On Linux, you can change that behavior with the --whole-archive linker option: g++ -Wl,--whole-archive some_static_lib.a -Wl,--no-whole-archive". This way you make sure that you carry the whole static libSDL.a archive within yours.

Related

Qt can't find my shared library - no really it cant

I'm new to Qt and I'm trying to implement a simple shared library for use in another application. I've read the wiki and other docs, but even after carefully following the steps, the compiler will always throw an error saying it can't find my header files.
I'm using Qt MinGW on Windows 10. Here's what I did:
Created and compiled a shared library called libgx
In another project (hello), added the generated liblibgx.a file, using the "Add Library" wizard.
Pulled my hair over this error I get when I try to include the library's header into hello's main.cpp
The wiki is not helpful here at all. It tells me, "MinGW compiled linking libraries are in .a, but you will need to add it manually (as of Qt Creator 2.7). You could also try simply linking the .dll directly cause it would probably work." I'm like WHAT?
hello's .pro file
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = hello
TEMPLATE = app
SOURCES += main.cpp\
mainwindow.cpp\
C:/Users/sagar.JARVISAIO/Documents/libgx/libgx.cpp
HEADERS += mainwindow.h\
C:/Users/sagar.JARVISAIO/Documents/libgx/libgx.h
FORMS += mainwindow.ui
win32:CONFIG(release, debug|release): LIBS += -L$$PWD/../build-libgx-Desktop_Qt_5_5_0_MinGW_32bit-Release/release/ -llibgx
else:win32:CONFIG(debug, debug|release): LIBS += -L$$PWD/../build-libgx-Desktop_Qt_5_5_0_MinGW_32bit-Release/debug/ -llibgx
else:unix: LIBS += -L$$PWD/../build-libgx-Desktop_Qt_5_5_0_MinGW_32bit-Release/ -llibgx
INCLUDEPATH += $$PWD/../build-libgx-Desktop_Qt_5_5_0_MinGW_32bit-Release/release
DEPENDPATH += $$PWD/../build-libgx-Desktop_Qt_5_5_0_MinGW_32bit-Release/release
I manually added the headers and the library files in the .pro file using the procedure here. Never going to bother with that "wizard" again. It was unnecessarily adding a $$PWD variable in all my paths which I think was causing my problem.

Using libraries in Qt

My questions may seems like it is a real duplicate, but however I checked many related questions, my problem still remains.
I found and compiled a project called SMTPEmail, so I have my .dll and .lib files under the directories Libraries/SMTPClient/debug and Libraries/SMTPClient/release.
When I try to include the header files in example in case of emailadress.h: #include <emailaddress.h> or #include <SMTPEmail/emailaddress.h>, I got the error Cannot open include file 'emailaddress.h'. The Q_DECL_EXPORT modifier is used in the header files.
SMTPEmail.pro:
...
QT += core network
TARGET = SMTPEmail
TEMPLATE = lib
DEFINES += SMTP_BUILD
win32:CONFIG += dll
QMAKE_CXXFLAGS += -fPIC
...
MyProject.pro:
...
INCLUDEPATH += ./Libraries/SMTPClient/debug
DEPENDPATH += ./Libraries/SMTPClient/debug
win32:LIBS += ./Libraries/SMTPClient/debug/SMTPEmail.lib
...
I also tried:
LIBS += -L./Libraries/SMTPClient/debug/ -lSMTPEmail
and
LIBS += -L$$_PRO_FILE_PWD_/Libraries/SMTPClient/debug/ -lSMTPEmail
and
LIBS += -L$$PWD_/Libraries/SMTPClient/debug/ -lSMTPEmail
and
LIBS += -L./MyProject/Libraries/SMTPClient/release/ -lSMTPEmail
The only thing that I didn't do is copying or linking the header files which are inside the library to my app?
I have the strong feeling that I missed a small step somewhere, can you help me pointing out what I am doing wrong?
I think your problem is (at least) this line:
INCLUDEPATH += ./Libraries/SMTPClient/debug
I am almost certain that this is not the right path to the include path where the headers can be found including emailadress.h.
You have explained the LIBS values that you have tried as well as the lib path in great length, but you are getting an include error from the compiler rather than a linkage problem with the libraries from the linker. I would suggest to figure out where the headers are located and add it to the include path as follows:
# This is just pseudo code, but you need something like this
INCLUDEPATH += $$PWD/Includes/SMTPClient
Answering your question of:
The only thing that I didn't to is copying the header files which should be inside the library, is that right?
It depends on what you mean. If you mean whether the library should be self-contained, then the answer is no, unless you are using dynamic library loading with manual symbol resolution and the like, which I do not recommend for simple cases.
If you mean, it is shipped with the project that you are trying to reuse, then sure, and that is why you would need to specify the includepath in your project to that path.

Using SOCI with Qt = how to write a good *.pro file?

I would like to write a GUI app using Qt and SOCI. How to write a good *.pro file to compile a project with no errors? I wrote this:
QT += core gui
TARGET = example-project
TEMPLATE = app
SOURCES += main.cpp\
mainwindow.cpp
HEADERS += mainwindow.h
FORMS += mainwindow.ui
INCLUDEPATH += /usr/local/include/soci\
/usr/include/postgresql/
LIBS += -lsoci_core -lsoci_postgresql -ldl -lpq
and it works but I don't know if it's correct.
The .pro file you wrote looks good, the INCLUDEPATH /usr/include/postgresql/ may not need a trailing slash, however, the way to tell if it will produce "no errors" is to try it. The INCLUDEPATH definition will let you use headers from those directories like this:
#include <header.h>
instead of:
#include "/usr/include/postgresql/header.h"
The LIBS+= section should only contain the libraries from SOCI that contain symbols that you reference in your code. If you are statically compiling your program it will bundle these libraries into your binary, increasing its size.
There are a lot of features you can easily add with the .pro file, and it's helpful to know how to write one, for example you can add an application icon for Mac OS programs by adding the line:
ICON = Icon.icns
Have a look at the Qt 4.7 .pro file reference.
You can always use an auto-generated .pro file by navigating to the directory that your source is in (in a terminal), and using the command:
qmake -project
In my experience, the auto generated .pro file is usually incomplete, but it gives you a standard of comparison and sometimes includes stuff that you would otherwise forget.
A final method of .pro file authoring is from the QtCreator IDE. It automatically adds and subtracts things from your pro file as you add/subtract them from your project, it's especially simple to add forms and resources in this environment.

Using DLLs Qt - Undefined Reference

I am trying to use and make a DLL in Qt. The DLL, does not use any Qt frameworks. Here is my library's .pro file:
TARGET = MyLib
TEMPLATE = lib
include(Botan.pri)
win32:INCLUDEPATH += "C:/botan/include"
win32:LIBS += "C:/botan/libBotan.a"
unix:INCLUDEPATH += "/usr/local/include/botan-1.10"
unix:LIBS += "/usr/local/lib/libbotan-1.10.a"
HEADERS += \
HEADERS HERE
SOURCES += \
SOUCRES HERE
My library is compiled successfully, and I get a MyLib.dll in my debug/release folder. I then copied my library sources completely, and removed everything besides the header files for the 'includes' folder.
I then created a new project to use my library.
I added this to my project file:
INCLUDEPATH += "C:/Users/Stevie/Desktop/MyLib/include"
LIBS += "C:/Users/Stevie/Desktop/MyLib/MyLib.dll"
The headers have no problem, and it finds my DLL fine (if I change it to a non-existing path, it throw an error. It doesn't as of now.)
Now when I go into my '.cpp' file, I include my header file, and try and use my library and it throws 'undefined reference to MyLib::...'. I have no idea why, as I am including the DLL and I believe it should be found perfectly fine.
Also, I am 99% sure it isn't with Botan, as I use Botan often like this, and it works fine. Anyway, I include the 'Botan.dll' with it anyway just to be sure, but it's not throwing the undefined errors on Botan.
Thanks.
Replace
LIBS += "C:/Users/Stevie/Desktop/MyLib/MyLib.dll"
with
LIBS += -L$$quote(C:/Users/Stevie/Desktop/MyLib)
LIBS += -l$$quote(MyLib)
Does your library have Q_DECL_EXPORT / Q_DECL_IMPORT macros?
After all that clean and rebuild your project, which use library.

Qt Creator and static libraries

I'm quite a newbie with C++ and maybe that's a very stupid question, but how do one include a header from a static linked library?
I've created a static library in Qt Creator with the following .pro file:
QT -= gui
TARGET = Foobar
TEMPLATE = lib
CONFIG += staticlib
SOURCES += thefoobar.cpp \
sub/subbar.cpp
HEADERS += thefoobar.h \
sub/subbar.h
compiled it and put the resulting libFoobar.a into the "extstaticlibs" folder of my target project.
In my target projects .pro file i've added the following lines:
LIBS += -L$$PWD/extstaticlibs/ -lFoobar
INCLUDEPATH += $$PWD/extstaticlibs
The target project compiles without problems. But when I try to include the header thefoobar.h in one of my code files:
#include "thefoobar.h"
it always results in an error:
error: thefoobar.h: No such file or directory
Any suggestions for the correct syntax would be very much appreciated.
Kristoffer
Check where you have placed your "thefoobar.h" header file . Place it in the "extstaticlibs/" folder .
If I follow your description correctly, you ONLY put the static library into your extstaticlibs directory.
You need to carry over your thefoobar.h file too. If you follow the common structure you could make:
extstaticlibs/include <- thefoobar.h goes here
extstaticlibs/lib <- libFoobar.a goes here
You then need to modify your project file like this:
LIBS += -L$$PWD/extstaticlibs/lib -lFoobar
INCLUDEPATH += $$PWD/extstaticlibs/include
Of course you can all throw it in one directory, if you want, but it may be helpful to sort things out in the beginning.