PDA

View Full Version : How to include library using config+=mylibrary



marcvanriet
19th August 2011, 02:35
Hi,
If you use wwWidgets, you just need to build wwWidgets, put CONFIG+=wwwidgets in your .pro file, and you're ready to go.

I'd like to do the same for libraries that I often use, like QExtSerialport and QJson, and later on for a library of my own. I've read about "Adding New Configuration Features" in the qmake manual.

Now I seek advice about :
- when I build my output, where should the output go (the binaries). Not just anywhere among the Qt binaries I suppose.
- should I copy an include file for my stuff, or just have the user include the 'include' directory of my project ?
- what to put in this .prf file ?
- where to put this .prf file ?

Any help would be appreciated. An example project for dummies even more :)

Best regards,
Marc

high_flyer
22nd August 2011, 09:00
If you use wwWidgets, you just need to build wwWidgets, put CONFIG+=wwwidgets in your .pro file, and you're ready to go.
Not entirely.
You also need to provide the location of the lib and its headers.
Then, its exactly the same as in Qt qmake/pro files.


Now I seek advice about :
- when I build my output, where should the output go (the binaries). Not just anywhere among the Qt binaries I suppose.
Where ever you want.
Usually people put binaries under ./debug or ./release, *.obj under ./obj etc...
But its fully up to you.


- should I copy an include file for my stuff, or just have the user include the 'include' directory of my project ?
What kind of user?
A user that runs you executable - then no, he only needs to run the exe. Your setup should take care of putting the libs and dependencies where the exe can find them.
A user for a lib you are writing, will have to get all the symbols files and header at least, and code if its not closed source.



- what to put in this .prf file ?
- where to put this .prf file ?
http://doc.qt.nokia.com/latest/qmake-advanced-usage.html#adding-new-configuration-features

marcvanriet
24th August 2011, 02:29
Hi High_flyer,

To be clear : I'm talking about creating your own set of widgets (or other classes), and providing a library to other programmers that is easy to integrate.

When you use wwWidgets and when you put CONFIG+=wwwidgets in your .pro file, you don't have to provide any paths. Libraries and header files are installed in the appropriate directories when you (n)make install wwWidgets.

Where should the output go ? I mean the final .lib or .dll, and I mean where in the Qt directory. wwWidgets make install puts its binaries directly under /lib, and creates a wwWidgets subdirectory in the /include directory. Personally, I prefer a solution where 3rd party files are not mixed with Qt's own files.

Then my question about copying or not... you ask "what user". As clarified before, I mean a programmer using my library. Of course he needs the header files and so on. But the question was : do I copy the include files of my library to e.g. the "include" directory of Qt, or instead add (the includes of) my source directory to the Qt include path ?

wwWidgets uses the 'copy' approach. However in Qt's prf files I see something like QMAKE_PRL_BUILD_DIR = xxxxx which says from what source directory the library was built, indicating more of a 'referencing' approach. However I think this is more for debugging (so you can trace the source) and not for building, since all headers and binaries of Qt are always in /include and /lib.

http://doc.qt.nokia.com/...adding-new-configuration-features (http://doc.qt.nokia.com/latest/qmake-advanced-usage.html#adding-new-configuration-features)

Well... this doesn't say anything about the keywords like QMAKE_PRL_BUILD_DIR that you see in most files. And wwWidgets uses a keyword qtAddLibrary() that seems to be undocumented :(


Then, its exactly the same as in Qt qmake/pro files.

Do you mean you can put anything in a prf like you would put in a pro or pri file ?

Regards,
Marc

high_flyer
24th August 2011, 09:22
When you use wwWidgets and when you put CONFIG+=wwwidgets in your .pro file, you don't have to provide any paths.
That is NOT true!
What is probably happening, is that wwWidgets install process also sets PATH, so the make file finds the libs without you needing to explicitly specify the lib and header locations.
But these paths ARE set, and ARE needed.
If you just copy the libs and headers, and not use the install program, you will have to explicitly specify the path of the lib and headers.


Libraries and header files are installed in the appropriate directories when you (n)make install wwWidgets.
Again, "appropriate" is what the author of the lib thought to be appropriate.
Usually however, make install can also take comand line paremters, where you, the user can tell make install where you would like the libs.
So, it fully up to you to think where your header and lib should be located, and it will be very user friendly if you offer the user the ability to specify his own location should your default location is not good for him.


Well... this doesn't say anything about the keywords like QMAKE_PRL_BUILD_DIR that you see in most files. And wwWidgets uses a keyword qtAddLibrary() that seems to be undocumented
Well, a short google search brings this up:
http://initek.net.au/mediawiki/index.php/Inside_Qmake


And wwWidgets uses a keyword qtAddLibrary() that seems to be undocumented
I don't know if qtAddLibrary() is documented or not, but as wwWidgets is written by wysota, it just might be! :-)

@wysota - does your install actually sets PATH?

marcvanriet
24th August 2011, 17:43
About the path : wwwidgets.prf contains :

INCLUDEPATH += $$[QT_INSTALL_HEADERS]/wwWidgets
So the path is set automatically when you say CONFIG += wwwidgets in your .pro file. But this is what I mean : as a programmer using the library, you don't have to set it in your own .pro file.

Anyway, I think I can make some simple library that is easy to use by :
- making a subdirectory in the Qt include directory for my header files, and add it to the include path in the .prf file
- putting the binaries in the Qt lib directory
- making a mylibrary.prf file that is included when CONFIG += mylibrary is put in the .pro file

Once I get this to work, I can look into the possibilities of make install for specifying custom locations.

Regards, and thanks,
Marc

wysota
24th August 2011, 18:31
When you use wwWidgets and when you put CONFIG+=wwwidgets in your .pro file, you don't have to provide any paths. Libraries and header files are installed in the appropriate directories when you (n)make install wwWidgets.
The paths are provided in the feature file.


Where should the output go ?
Wherever you want as long as you provide appropriate paths to all the projects using your library. I'm not sure putting wwWidgets in Qt dir was the proper approach but at the time I didn't know any other good solution. I guess now I could install it anywhere and patch the prf file.


wwWidgets uses the 'copy' approach.
Not really. It installs the headers in its own directory. And it's just an apriori decision that this directory is inside Qt's tree. It doesn't matter where you put the files as long as you provide proper paths for all the projects.


Well... this doesn't say anything about the keywords like QMAKE_PRL_BUILD_DIR that you see in most files.
Unless you're using prl files, this directive is of no use to you.


Do you mean you can put anything in a prf like you would put in a pro or pri file ?
Yes, as long as you understand the execution order of entries.



But these paths ARE set, and ARE needed.
Agreed.


I don't know if qtAddLibrary() is documented or not, but as wwWidgets is written by wysota, it just might be! :-)
qtAddLibrary() is not documented. I found it while roaming Qt source code.


@wysota - does your install actually sets PATH?
No. The important part is that it dumps a feature (prf) file inside $QTDIR/mkspecs/features. The file contains all the paths that are required for linking the library. You could as well have a pri file that you would include in all project files using the library. And I suggest one does that if he doesn't feel comfortable with prf files, those are tricky. At our company we use prf files for all libraries and projects we have but we don't store them in Qt tree. Instead we have our own directory that is passed to QMake using qmake -set or by setting environment variables. Sadly, recent versions of Qt Creator have trouble discovering those files in certain cases. We even provided a patch to one of previous versions of Creator so it used to work for a while, but now the Trolls have broken it again :)

Here is an example of a project file we use:
# qcms.pro
load(arise)
CONFIG += no_link_qcms qcms

TARGET = $$shlibname(qcms)
HEADERS += ...
SOURCES += ...
DEFINES += BUILD_QCMS

win32:installLib($$TARGET)
with qcms.prf:
load(arise)
createLibrary(qcms, qcms, qcms)
CONFIG += activemq installlib
and arise.prf:
load(arisefunctions)
#CONFIG += personal
ARISEDIR = $${PWD}/../..
ARISESRC = $$ARISEDIR/trunk
ARISEBIN = $$ARISEDIR/bin
ARISELIB = $$ARISEDIR/lib
ARISECONFIG = $$ARISEDIR/config
ARISELIBSCONFIG = $$ARISECONFIG/common
ARISE3RDPARTY = $$ARISEDIR/3rdparty
load(personal)


QMAKE_LIBDIR += $${ARISELIB}
LIBS += -L$$ARISELIB

CONFIG += arisehelp

We can even override (per developer or rather per machine) most variables by dumping a .pri file in a certain directory (handled by load(personal)), for instance I store sources in $$ARISEDIR/src and not $$ARISEDIR/trunk, thus witek.pri looks like this:
ARISESRC=$$ARISEDIR/src
QTPROPERTYBROWSERDIR=/home/wysota/Dokumenty/praca/arise/3rdparty/qtpropertybrowser
unset(OQDL)

# do QCms:
LIBS += -L/usr/local/libs
INCLUDEPATH += /usr/local/include/activemq-cpp-3.2.3

CONFIG += rpath_libdirs

QUICKFIX_INCLUDES_DIR = $$ARISEDIR/3rdparty/quickfix/include

Line #1 effectively overrides an entry from arise.prf (ARISESRC) while retaining all other values relative to this variable defined in statements that are executed after load(arise). Line #6 adds a library search path for every project I (and only I) build.

But as I said, this IS complicated. For simple projects I would strongly advise against using such things. If you want a simpler setup, make a .pri file for every library you use, dump them in a well known directory and include them in your projects.

travlr
9th September 2011, 15:22
To early in the morning me to fully describe why everything mentioned in this thread is poor programming practice and should be discouraged not encouraged.

Qt and Qmake (as well as certified developers) should know better!!

Installing user generated libraries and other dependencies directly into the Qt install directories is fragile and will break when for instance the Qt library is upgraded or deleted and re-installed.

Also, on Linux for instance, distribution based installs are installed with permission filters to the 'admin' of the system. Developers using the 3rd party library, may very well not want to be forced by the provider of a 3rd party, Qt based library, to have to install in this area, but instead in the less restricted 'user' space.

Another peeve I'll mention is that Qmake relies on hard coded Qt environment variables that are not available to the build environment outside of using Qmake itself. I constantly come across projects using qmake build configurations that I have to completely rewrite to make for a more flexible environment.

Qtcreator is a fine example of a crappy qmake build file. On Linux the install is in-flexible and has to be patched or deviated from. Qtcreator installs itself not in the 'admin' restricted area, but where only system related files belong.. /lib /include /bin ...etc!

Please consider this when you distribute your 3rd party projects using the very poorly created (and documented) qmake build system.

Please use system wide ENVIRONMENT variables and not hard coded Qt variables for others to rely on.

Thank you!

// rant over :-)

marcvanriet
10th September 2011, 13:07
@travlr. Thanks for your comment. However, you don't say how the 'right' way to do is in your opinion if you would write your own library. Or how 3d party libraries should do it.

As a sidenote : I have different builds of Qt on my systen (4.6.3 and 4.7.3). I build each 3rd party library I use with both versions. Therefore I think it is a GOOD idea to put the Qt build and the libraries in a common place. So that when you delete a Qt version you don't have to look for all the old libraries to delete. However I agree putting the binaries and include files of the 3rd party library together with the Qt ones is a bad idea. There may be a conflict between different 3rd party libraries, and cleaning this up when rebuilding or removing a library is cumbersome. Also, you may want to evaluate newer versions of a library without deleting the old one.

I am thinking of keeping a directory 'addons' in the Qt directory in which I put the includes and binaries of all libraries, each in their own subdirectory. The include and library paths can then easily be specified in your own .pro or in a pri or prl file.

Maybe the Trolls could specify some conventions regarding this, so that all 3rd party libraries can be installed in the same way without conflict.

Regards,
Marc

wysota
11th September 2011, 20:17
To early in the morning me to fully describe why everything mentioned in this thread is poor programming practice and should be discouraged not encouraged.
Please explain what exactly from this "everything" you consider poor programming practice otherwise following your approach everything you say is just trolling. So far I have only seen you touch the problem of installing addons inside Qt install directory. There is more to this thread than that.


Installing user generated libraries and other dependencies directly into the Qt install directories is fragile and will break when for instance the Qt library is upgraded or deleted and re-installed.
Considering the fact that Qt manual tells us to install Designer plugin to Qt's install tree by default, I don't care. If you upgrade/reinstall/modify Qt, you'll need to reinstall the 3rd party plugin anyway. If you choose to install the plugin in a self-contained environment, you are very welcome to do that, Qt/QMake give you such possibilities (also described in the manual). Considering the fact that 99% of the users will want the default behaviour, I think it is a sane decision to make it my default behaviour too. The remaining 1% of people is clever enough to alter the installation path using a simple call to qmake or make with proper arguments.


Also, on Linux for instance, distribution based installs are installed with permission filters to the 'admin' of the system. Developers using the 3rd party library, may very well not want to be forced by the provider of a 3rd party, Qt based library, to have to install in this area, but instead in the less restricted 'user' space.
True, however you could say the same about every library or other piece of software that installs itself into /usr or /usr/local subtree which also require superuser privileges. Considering the fact that all Linux distributions I know of install packages to /usr, /usr/local and /opt by default and most build environments are preconfigured to install the build in /usr/local, I really don't care that my software follows the same pattern and requires superuser rights to install by default. Please take a standard deb or rpm package containing glibc and have it install itself to /home/something keeping the functionality of the system without any need for manual tweaking. And to make things even more funny let's assume my home directory is encrypted and mounted/decrypted only when I log in.


Qtcreator is a fine example of a crappy qmake build file. On Linux the install is in-flexible and has to be patched or deviated from. Qtcreator installs itself not in the 'admin' restricted area, but where only system related files belong.. /lib /include /bin ...etc!
Funny, I can install Qt Creator wherever I want. It's as easy as calling "INSTALL_ROOT=/home/wysota/QtC make install".

By the way, not every developer is a Linux user. Don't require people to have knowledge about layout and policies of a Linux system just because you yourself use Linux. I'm sure you'd want Windows people to have a similar approach. If you can't satisfy everyone, find a largest common denominator. I think Qt does that pretty well.