Build custom library without header dependency - c++

I made a small application in Qt, for sending and receiving messages from/to a RabbitMQ broker.
I made a library containing a RabbitMQ publisher and consumer, which in turn uses the AMQP library here.
Now everytime I need to use this library in an application, I need to copy the two .lib files (qamqp, RabbitMQLib), plus about 10 header files, and then add them in my .pro file (through LIBS and INCLUDEPATH).
I made a similar project in C#, but there I only needed two .dlls, and that was it.
My question is : how can I make the same with Qt? Just one or two .lib files, which will be included in the application that needs them, and that's it, no need for 10 additional header files.

You can totally do this. You do not actually need these headers (using them is just usefull) - all you really need is to declare all objects (types, functions, variables) you are actually using. So, if you have a lot of headers, but use, say, only one function, all you need is to add this function declaration before you actually use it (may be, adding something like __declspec(dllimport), or, if using Qt - Q_DECL_IMPORT).
But, if the only problem you are facing, is adding all these files to your pro-file, a better solution here would be to write a pri-file, like this:
mylib.pri
INCLUDEPATH += $$PWD/headers
DEPENDPATH += $$PWD/headers
HEADERS += \
$$PWD/headers/header1.h \
...
$$PWD/headers/header10.h
LIBS += -L$$PWD/libs -lqamqp -lRabbitMQLib
and include it to your pro-file:
include($$PATH_TO_COMMON_LIBS/mylib/mylib.pri)

Related

How to choose only the needed Qt headers?

In a large Qt project in which a lot of Qt and project headers are included in every file, it is easy to:
include extra Qt files that don't need to be included because they are already included in another Qt file (for example, qbytearray.h is included in qstring.h).
forget to include needed Qt files because they are already included in other included project files (for example, the compiler finds qstring.h included in another of your files and doesn't complain).
left included extra Qt files that are not needed anymore after a modification.
I have been also reading that, even with modern compilers, it is better to include the files needed, and only those, instead of the easy way of including more generic headers like QtCore and QtGui.
The rule seems easy: include only everything you need and don't depend on other included files in case they change in the future (for example, qstring.h could not use qbytearray.h anymore, which is also true for project files), but it's not so easy to achieve. And Qt Creator doesn't help much with that, because when you begin to write QStr... it auto-completes with QString and compiles, and you don't even wonder why nor think of including the header.
Is there a list of Qt headers dependencies or an automatic Qt tool or a rule or something to make sure I have chosen all the headers I need and nothing else? The question is general to C/C++, a way to get the optimum header dependency.
The rules of thumb to minimize the number of include files read:
A .cpp file usually has an associated header. That header must be included first - it ensures that the header will compile by itself and is not missing any dependencies.
For any class hierarchy, include only the most derived class's headers. E.g. if you include <QLabel>, you won't need <QFrame>, nor <QWidget>, nor <QObject>. If you include <QGraphicsView> and <QLabel>, you won't need <QAbstractScrollArea>, nor <QFrame>, nor <QWidget>, nor <QObject>. And so on.
Other than in the preceding rule, do not depend on "files included by other files". I.e. QString including QByteArray is an implementation detail and the API of QString does not warrant such inclusion.
The rules of thumb to minimize the number of compiled source files:
Cut the number of compiled files by two (!!) by adding #include "foo.moc" at the end of every foo.cpp that implements new QObject types.
Short classes (<250 lines total) belong in a single .h file, there's no need to separate them between .h and .cpp.

MACRO depending on its folder location

In the following files:
app/main.cpp
app/config.hpp
app/show.hpp
app/file.hpp
lib/append.hpp
lib/clear.hpp
lib/reopen.hpp
lib/crypt.hpp
I have a problem. Imagine a few of my files use lib/crypt.hpp. For example in app/file.hpp I should write:
#include "../lib/crypt.hpp"
If I take this file to lib folder it does not work anymore. So I need a something like:
#include "LIB/crypt.hpp"
So, this LIB/ has meaning of (empty) in lib directory while it has meaning of "../lib/" in app directory.
Then I will have no worry about moving file.hpp from app to lib. I just need to fix the callers of it. But not what it calls.
Similar to concept of web programming frameworks. Is it possible in C/C++?
According to what you wrote you're searching for a way to move your sources around without worrying for hard-coded paths to your headers.
You didn't specify the compiler you're using so I'm not focusing on a specific one, anyway most C++ compilers have an option to specify one or more header search paths (on gcc you would just use something like -Ilib_parent_dir).
Once you've included your lib's parent path to the search list, you can move your sources around (as long as you don't move lib's headers) and have them include the right headers with something like #include <lib/crypt.hpp> (and keep include paths priority in mind)
This should be a cleaner and simpler way to achieve what you asked rather than using a macro.

C++ #include for a third-party API - Can never find some headers

I am having a lot of trouble figuring out how to use third party API.
I'm using QT 5.3.1 / QT Creator 3.1.2
And I want to include the necessary headers for Nvidia's SceniX which can be found here: https://developer.nvidia.com/scenix
I have Bjarne Stroustrup's fourth edition the C++ programming language and looked up include in the index and all 4 entries gave worthless information, and if looking up what I want by the index doesn't get the right answer then I have no idea how to use the book and google isn't giving anything useful either. I have also tried reading heaps of answers here but are all ultimately irrelevant and just end up in spending time for nothing.
The directory structure is something like the following but is trimmed.. a lot:
-root
-inc
-nvsg
-nvsg
-nvsg.h
-nvgl
-nvgl.h
Showing my code doesn't mean much because I've tried a hundred different iterations, but currently it goes like this..
HEADERS += mainwindow.h \
inc/nvsg/nvsg/nvsg.h \
But no matter what I do, it will NOT find the header when I try to include it, it's as if it isn't even there. Auto-complete doesn't even see it.
But sometimes when I include things from other folders they work. It simply doesn't follow any form of logic.
Do not add the third-party .h files in HEADERS. These files are YOUR headerfiles. Add the includepath for these .h files to INCLUDEPATH += inc/nvsg and use in your cpp code:
#include <nvgl/nvgl.h>
#include <nvsg/nvsg.h>

Proper structure for C++ project & libs

I'm starting to write a data processing library of mine and quite confused about building the proper structure of project and libraries.
Say, I'd like to have a set of functions stored in myfunclib library. My current set up (taken from multiple recommendations online) looks like this:
myproj/include/myfunclib.h - class declaration
myproj/include/myfunclib.cpp - class functionality
myproj/src/functest.cpp - test file to check functions
Firstly, it feels like this is a proper set up in case I use myfunc only for myproj project, but say I want to reuse it - then I'd need to specify it's path in each of cpp files using it or store multiple copies of it.
Secondly, compilation is a bit bulky in such case:
g++ -I include include/myfunclib.cpp src/functest.cpp
Is it a normal practice to type all that stuff every time? What if I have many custom libraries I need? Is there a way to store them all separately, simply include as 'myfunclib.h' and not worry about recompiling etc?
Use a makefile to handle all of your dependencies and building your code. Google the syntax it's pretty simple. then you can just say "make" on the command line and it will build everything for you.
here's a good tutorial
http://mrbook.org/tutorials/make/
some things that bit me originally,
remember that templated classes should only be included, what is generally the source implementation should not be built like normal class implementations into object files, so generally i put my whole template implementation within the include directory
i keep include and source files separate, by source files i mean code (definitions) that needs to be compiled into object files for linking, and includes are all the declarations, inline functions, etc it just seems to make more sense to me
sometimes i'll have a header file that includes all relevant headers for a specific module, and in turn perhaps a header file higher up that includes all main headers for modules i am using
also as said in the comments, you need to introduce yourself to some build tools, and get comfortable with them, these will help you track dependencies within your project, and in most cases avoid rebuilding an entire project when only a subset of dependencies have changed (this can be a pain to get right in the beginning but is worthwhile learning, if you use make and g++ there is a way to get this working with g++ -MM ... not sure how well it works for all cases ), i know that the way i organized my projects changed drastically the more i learnt about the build process, and the more complex my projects became (and the more flaws i had to fix )
this is how i generally keep my a project directory structure when starting
build - where all the built files will be stored
app - these are the main apps (can also be split into include/src)
include - includes files
src - src files (compiled into objects and then linked with main compiled app)
lib - any libs (usually 3rdparty libs , if any my src is compiled into a library it usually ends up in build/lib/target/... )
hope some of this helps

Header files dependencies between C++ modules

In my place we have a big C++ code base and I think there's a problem how header files are used.
There're many Visual Studio project, but the problem is in concept and is not related to VS. Each project is a module, performing particular functionality. Each project/module is compiled to library or binary. Each project has a directory containing all source files - *.cpp and *.h. Some header files are API of the module (I mean the to the subset of header files declaring API of the created library), some are internal to it.
Now to the problem - when module A needs to work with module B, than A adds B's source directory to include search path. Therefore all B's module internal headers are seen by A at compilation time.
As a side effect, developer is not forced to concentrate what is the exact API of each module, which I consider a bad habit anyway.
I consider an options how it should be on the first place. I thought about creating in
each project a dedicated directory containing interface header files only. A client module wishing to use the module is permitted to include the interface directory only.
Is this approach ok? How the problem is solved in your place?
UPD On my previous place, the development was done on Linux with g++/gmake and we indeed used to install API header files to a common directory is some of answers propose. Now we have Windows (Visual Studio)/Linux (g++) project using cmake to generate project files. How I force the prebuild install of API header files in Visual Studio?
Thanks
Dmitry
It sounds like your on the right track. Many third party libraries do this same sort of thing. For example:
3rdParty/myLib/src/ -contains the headers and source files needed to compile the library
3rdParty/myLib/include/myLib/ - contains the headers needed for external applications to include
Some people/projects just put the headers to be included by external apps in /3rdParty/myLib/include, but adding the additional myLib directory can help to avoid name collisions.
Assuming your using the structure: 3rdParty/myLib/include/myLib/
In Makefile of external app:
---------------
INCLUDE =-I$(3RD_PARTY_PATH)/myLib/include
INCLUDE+=-I$(3RD_PARTY_PATH)/myLib2/include
...
...
In Source/Headers of the external app
#include "myLib/base.h"
#include "myLib/object.h"
#include "myLib2/base.h"
Wouldn't it be more intuitive to put the interface headers in the root of the project, and make a subfolder (call it 'internal' or 'helper' or something like that) for the non-API headers?
Where I work we have a delivery folder structure created at build time. Header files that define libraries are copied out to a include folder. We use custom build scripts that let the developer denote which header files should be exported.
Our build is then rooted at a substed drive this allows us to use absolute paths for include directories.
We also have a network based reference build that allows us to use a mapped drive for include and lib references.
UPDATE: Our reference build is a network share on our build server. We use a reference build script that sets up the build environment and maps(using net use) the named share on the build server(i.e. \BLD_SRV\REFERENCE_BUILD_SHARE). Then during a weekly build(or manually) we set the share(using net share) to point to the new build.
Our projects then a list of absolute paths for include and lib references.
For example:
subst'ed local build drive j:\
mapped drive to reference build: p:\
path to headers: root:\build\headers
path to libs: root:\build\release\lib
include path in project settings j:\build\headers; p:\build\headers
lib path in project settings j:\build\release\lib;p:\build\release\lib
This will take you local changes first, then if you have not made any local changes(or at least you haven't built them) it will use the headers and libs from you last build on the build server.
I've seen problems like this addressed by having a set of headers in module B that get copied over to the release directory along with the lib as part of the build process. Module A then only sees those headers and never has access to the internals of B. Usually I've only seen this in a large project that was released publicly.
For internal projects it just doesn't happen. What usually happens is that when they are small it doesn't matter. And when they grow up it's so messy to separate it out no one wants to do it.
Typically I just see an include directory that all the interface headers get piled into. It certainly makes it easy to include headers. People still have to think about which modules they're taking dependencies on when they specify the modules for the linker.
That said, I kinda like your approach better. You could even avoid adding these directories to the include path, so that people can tell what modules a source file depends on just by the relative paths in the #includes at the top.
Depending on how your project is laid out, this can be problematic when including them from headers, though, since the relative path to a header is from the .cpp file, not from the .h file, so the .h file doesn't necessarily know where its .cpp files are.
If your projects have a flat hierarchy, however, this will work. Say you have
base\foo\foo.cpp
base\bar\bar.cpp
base\baz\baz.cpp
base\baz\inc\baz.h
Now any header file can include
#include "..\baz\inc\baz.h
and it will work since all the cpp files are one level deeper than base.
In a group I had been working, everything public was kept in a module-specific folder, while private stuff (private header, cpp file etc.) were kept in an _imp folder within this:
base\foo\foo.h
base\foo\_imp\foo_private.h
base\foo\_imp\foo.cpp
This way you could just grab around within your projects folder structure and get the header you want. You could grep for #include directives containing _imp and have a good look at them. You could also grab the whole folder, copy it somewhere, and delete all _imp sub folders, knowing you'd have everything ready to release an API.
Within projects headers where usually included as
#include "foo/foo.h"
However, if the project had to use some API, then API headers would be copied/installed by the API's build wherever they were supposed to go on that platform by the build system and then be installed as system headers:
#include <foo/foo.h>