4

I need to include the following header in my code:

#include <5.4.1/QtGui/private/qzipwriter_p.h>

The problem is, we are compiling this on other Qt versions, such as 5.4.2 or 5.5.x

I know I should not use these "private" headers since they are unsupported, but we need them at least until we have a durable replacement.

How can I concatenate the QT_VERSION_STR variable in the path so that this works with all versions?

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
galinette
  • 8,896
  • 2
  • 36
  • 87
  • Did you try ``#include ``? Wouldn't that just include the once required of your current Qt installation? If you need it to be just this one file just include the constant path (set in environment variable for example) – Sebastian Lange Oct 28 '15 at 13:01

4 Answers4

4

Use QT_VERSION instead:

QT_VERSION This macro expands a numeric value of the form 0xMMNNPP (MM = major, NN = minor, PP = patch) that specifies Qt's version number.

#if QT_VERSION == 0x050401
  #include <5.4.1/QtGui/private/qzipwriter_p.h>
#endif

Edit:

No idea for concatenating the version string in the path?

The standard doesn't allow that (16.3.4/3):

The resulting completely macro-replaced preprocessing token sequence is not processed as a preprocessing directive even if it resembles one

So you can't make a macro that will be expanded into an #include directive. You also can't use a macro inside the brackets of include (#include <like this>) because everything inside the brackets is just a string.

SingerOfTheFall
  • 29,228
  • 8
  • 68
  • 105
3

You can compare numeric QT_VERSION macro using human readable helper QT_VERSION_CHECK that combines major, minor and patch numbers into QT_VERSION format:

#if QT_VERSION == QT_VERSION_CHECK(5, 4, 1)
//...
#endif

The idea for concatenation taken from GCC headers C Macro - Dynamic #include

The problem is that we do not have macro tokens with Qt major, minor and patch versions. There is only numeric QT_VERSION. So, it is tricky to get required numbers. It is possible to transfer them as macro definitions from .pro file using qmake variables QT_*_VERSION:

DEFINES += QT_MAJOR_VERSION=$$QT_MAJOR_VERSION
DEFINES += QT_MINOR_VERSION=$$QT_MINOR_VERSION
DEFINES += QT_PATCH_VERSION=$$QT_PATCH_VERSION

Now those macro versions can be used in source files:

// To return as a string: "5.4.1/QtGui/private/qzipwriter_p.h"
#define qt_header__(x) #x
#define qt_header_(major,minor,patch) qt_header__(major.minor.patch/QtGui/private/qzipwriter_p.h)
#define qt_header(major,minor,patch) qt_header_(major,minor,patch)

// Simpler without stringification, however Qt Creator cannot follow
// that header
#define qt_header(major,minor,patch) <major.minor.patch/QtGui/private/qzipwriter_p.h>

#include qt_header(QT_MAJOR_VERSION, QT_MINOR_VERSION, QT_PATCH_VERSION)

It is better to use stringified variant ("5.4.1/QtGui/private/qzipwriter_p.h"). In that case the latest versions of Qt Creator can follow such qt_header() macro and highlight text accordingly.

Community
  • 1
  • 1
Orest Hera
  • 6,706
  • 2
  • 21
  • 35
  • No idea for concatenating the version string in the path? – galinette Oct 28 '15 at 11:11
  • @galinette No, it is possible to concatenate macro tokens but not strings http://stackoverflow.com/a/20551609/4023446 To use that you need to have not a string but something like `#define VER 5.4.1`. Then it is possible to generate include path from such `VER` macro. – Orest Hera Oct 28 '15 at 11:18
  • @galinette I updated the answer with possible concatenation. – Orest Hera Oct 28 '15 at 14:39
  • There is a version string in Qt, it is `QT_VERSION_STR`, as in the question. It is exactly equal to "major.minor.patch", at least in Qt 4 and 5 – galinette Oct 28 '15 at 17:34
  • @galinette `QT_VERSION_STR` is a string. It is defined as `#define QT_VERSION_STR "5.4.1"`, but you need it without quotation. – Orest Hera Oct 28 '15 at 17:50
  • Ah, that's the reason why I could not use it for this purpose – galinette Oct 29 '15 at 12:07
0

With cmake it would be like this:

CMakeLists.txt:

find_package(Qt5 COMPONENTS Core Qml)
add_definitions(-DQT_VERSION_MAJOR=${Qt5_VERSION_MAJOR})
add_definitions(-DQT_VERSION_MINOR=${Qt5_VERSION_MINOR})
add_definitions(-DQT_VERSION_PATCH=${Qt5_VERSION_PATCH})

yourcode.cpp:

#define p_qqmljslexer(major,minor,patch)  <major.minor.patch/QtQml/private/qqmljslexer_p.h>

#include p_qqmljslexer(QT_VERSION_MAJOR, QT_VERSION_MINOR, QT_VERSION_PATCH)  
0

With two letter minor_version e.g. 5.11 not works but it does

#if QT_VERSION >= QT_VERSION_CHECK(5, 11, 0)
    auto isok = f.open(QIODevice::NewOnly| QIODevice::Text);
#else
    auto isok = !QFileInfo::exists(newfile) && f.open(QIODevice::Text);
#endif