I couldn't find anything similar.
I found that boost library has an implementation, but I'm not sure I want to insert the whole library just for cyclic buffer implementation.
There are no such types in Qt's public API. If you're willing to use Qt's internals, there are two classes of note:
QRingBuffer
Stores bytes and is tailored for I/O buffering. Used by QSerialPort etc.
QT += core-private # In the .pro file
#include <private/qringbuffer_p.h>
https://github.com/qt/qtbase/blob/5.9/src/corelib/tools/qringbuffer_p.h
QCircularBuffer
Stores arbitrary types and is of general use. Provides sensible STL-style API.
QT += 3dcore-private # In the .pro file
#include <private/qcircularbuffer_p.h>
https://github.com/qt/qt3d/blob/5.9/src/core/resources/qcircularbuffer_p.h
Note: After adding the private modules to the project file, you have to re-run qmake, or ideally delete the build folder. A mere rebuild of the project won't get the code to compile!
There is one called QCircularBuffer.
http://doc.qt.io/archives/qt-5.5/qt3d-qcircularbuffer.html#details
QCircularBuffer<T> is one of Qt's generic container classes (from documentation). So this class will fulfill all basic requirements of a container class.
Need to include 3dcore library (Qt3D header).
Check your version of Qt can support it or not. I saw this in Qt5.5.
Related
I have a Qt project which requires a library (gphoto2) to enable some features that are not essential. I'd like to add some sort of configuration option to my qmake or make call to enable features using this library, so I can compile without it being installed.
What is the best way to configure something like this?
I guess I need some way to add a define based on a compiler parameter, which I can query in my code using #ifdef ...
I assume you use make (without qmake). It is reasonable and quite easy to use GNU make (alone) on Qt projects. You could use some other build automation tool like ninja.
Then you could decide to enable that Gphoto feature by compiling your code with -DWITH_GPHOTO and using #if WITH_GPHOTO in your C++ code.
You would compile by adding
CXXFLAGS+= -DWITH_GPHOTO
in your Makefile
I won't call that a "custom compiler flag" (e.g. like GCC plugins can provide) but a preprocessor flag. It is pretty standard practice.
Maybe you also want to pass such flags to moc. Then your Makefile is running moc thru some rule and command, which you could tailor too.
BTW, you might consider GNU autoconf or some other Makefile generator like cmake. I don't think you should spend too much time on these...
PS. I don't know how that idea translates into qmake and leave you to find out.
Assuming, you are using qmake, you can add a preprocessor definition depending on the existence of a file or an environment variable.
You could add a qmake project for compiling your external library and place it relative to your own project by default.
LIBGPHOTO2_PATH = $$getenv(LIBGPHOTO2PATH)
isEmpty(LIBGPHOTO2_PATH): LIBGPHOTO2_PATH = ../../libgphoto2
exists($$LIBGPHOTO2_PATH/libgphoto2.pri): include($$LIBGPHOTO2_PATH/libgphoto2.pri)
In libgphoto2.pri you add a preprocessor definition to indicate the presence of libgphoto2, add include and linker paths etc.:
DEFINES += WITH_LIBGPHOTO2
In the code of your dependent project, you check for the presence using #ifdef.
Instead of creating a qmake-project to compile, you could also check for the presence of the compiled library at a given path and set values directly (I don't know how libgphoto compiles, so I assume a default directory structure with include/, lib/ etc):
LIBGPHOTO2_PATH=$$getenv(LIBGPHOTO2PATH)
isEmpty(LIBGPHOTO2_PATH): LIBGPHOTO2_PATH = ../../libgphoto2
exists($$LIBGPHOTO2_PATH/include) {
DEFINES += WITH_LIBGPHOTO2
INCLUDEPATH += $$LIBGPHOTO2_PATH/include
LIBS += -L$$LIBGPHOTO2_PATH/lib -lgphoto2
}
You should however consider to move to something more modern like qbs, which is a lot faster, more flexible and easier to read.
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)
What is the purpose or meaning behind the aux_ subdirectory in the boost libraries?
For example:
boost/parameter/aux_/
boost/mpl/aux_/
boost/local_function/aux_/
What #DevSolar wrote:
Lots of Boost functionality is implemented in templates, which -- as
we know -- need their definition to be included in the header file.
You cannot hide it in a linker library. But because portions of that
template code are auxiliary to the actual API functionality, they are
put into a subdirectory so they do not confuse the user.
It looks like several similar directory naming schemes are used in boost:
detail
impl
aux_
From what I can see all 3 of these subdirectories serve the same purpose. The naming just depends on the specific boost library. If there is a more specific purpose to the different naming convention, please edit or submit another answer...I'm only guessing here!
Thanks for the hints. I eventually did find a page on www.boost.org that mentions (just in passing!) the directory structure, and why there are different conventions. Here is what it says:
The organization of Boost library headers isn't entirely uniform, but most libraries follow a few patterns:
Some older libraries and most very small libraries place all public headers directly into boost/.
Most libraries' public headers live in a subdirectory of boost/, named after the library. For example, you'll find the Python library's def.hpp header in
boost\python\def.hpp.
Some libraries have an “aggregate header” in boost/ that #includes all of the library's other headers. For example, Boost.Python's aggregate header is
boost\python.hpp.
Most libraries place private headers in a subdirectory called detail/, or aux_/. Don't expect to find anything you can use in these directories.
Source: http://www.boost.org/doc/libs/1_56_0/more/getting_started/unix-variants.html
I am developing C++ headers only library, lets call it PROJ. When a library header is including another, it uses:
#include <proj/foo.h>
And compiler (gcc and clang) have -I path-to-proj-parent. Users of the library should also have parent of PROJ in their include search path.
My rationally for using this scheme is that after installing this library into proj subdirectory of default-seachable parent (/usr/include/proj or /usr/local/include/proj), library user do not need to specify -I option.
Is there cons to this scheme? Is using <foo.h> without proj/ prefix is more conventional and recommended way?
Question is not about if installing in subdir or not (there will be proj subdir), but rather how to refer to include-files.
If you look at boost, you will note that they use a similar scheme:
#include <boost/shared_ptr.hpp>
It has the advantage of preventing clashes with another similarly named file from another dependency.
However, in the case of boost, they take it one step further. If you include <x/y/z.hpp>, then you are likely to be dealing with an entity named ::x::y::z (be it function or class). That is, the way the directories in the project are laid out mimic the namespace organization. It's quite neat really to orient oneself.
Normally, most projects are stashed in subdirectories (and subnamespaces), but the most used ones are pulled into the boost namespace for convenience, and thus they have headers living directly in the boost folder. There are also some convenience headers (whose job is just to gather a smattering of other headers to pull them in all at once).
You may finally note, if you open a header file, than the include guards they use follow the exact same hierarchy:
#ifndef BOOST_SHARED_PTR_HPP_INCLUDED
once again because it helps avoiding clashes since it's named after the very file it's in and there can be only one at that place in the whole Boost project (on case sensitive filesystems).
It is ok to have proj in the path if you create the proj directory when you install. In fact its a good way to prevent name collisions with other include files.
The name should not be something generic like "proj' though. It should be specific to the project.
I currently have a c++ setup like the following
class FlowController
{
public:
//...
private:
cntrl::OneWayValve _intake;
}
As you can see i'm using a cntrl::OneWayValve instance within my class. The Valve class resides in another library which i link with at compile time. The cntrl::OneWayValve has a cntrl::Value within its implementation like so.
class OneWayValve
{
public:
//...
private:
cntrl::Valve _valve;
}
And as before the cntrl::Valve resides in a different library for reasons you'll have to ask the previous developer about.
Now when i compile my FlowController class i'm required to link with the OneWayValve library and the cntrl::Valve library as well.
My question:
Is it possible to only link with the cntrl::OneWayValve library at compile time?
Forward declaration?
Static libraries (really don't want to do this tho)?
Another alternative?
Basically i don't want to know that its using a cntrl::Valve internally, its none of my business.
Note: apologies the OS is Unix.
Cheers,
Ben
What you could do is make your Valve library part of your OneWayValve library using a tool called a librarian. I don't know what OS/compiler you are using so I'm going to describe how do it using Visual Studio since that's the only system I've actually done this with (unless you want to count CP/M + LIB-80 :-)
If you bring up the Tools|Options dialog for you OneWayValve project and select Configuration Properties|Librarian|Additional Dependencies, you can put a reference to your Valve library in the Additional Dependencies setting. This will cause OneWayValve.lib to contain any objects that it references from Valve.lib.
Unfortunately for you, the OneWayValve isn't very well designed. Not only you need to link to both libraries, but you will also have to recompile both the OneWayValve library and your code if the Valve class changes.
You can do it by defining all methods of OneWayValve and Valve in their headers as inline. Then you don't need to link to the library.
But if it was designed that way, then what problems are linking to this library causing? Nothing wrong with dynamically linking a library.