4

Porting my project from Qt4 to Qt5.1, I get this error from a Qt file:

C:\Qt\Qt5.1.1\5.1.1\mingw48_32\include\QtGui\qopenglversionfunctions.h:785: error: expected unqualified-id before ')' token
     void (QOPENGLF_APIENTRYP MemoryBarrier)(GLbitfield barriers);
                                           ^

This is the chain of defines:

#define QOPENGLF_APIENTRYP QOPENGLF_APIENTRY *
#define QOPENGLF_APIENTRY APIENTRY
#define APIENTRY WINAPI
#define WINAPI __stdcall

I noticed that the "MemoryBarrier" token is present in the libQt5OpenGLExtensionsd.a library. Should I include it, even if in the original Qt4 project nothing related to OpenGL was used?

Platform:
Windows 7
MinGW 4.8
Qt 4.8 --> Qt 5.1

László Papp
  • 51,870
  • 39
  • 111
  • 135
Pietro
  • 12,086
  • 26
  • 100
  • 193

4 Answers4

7

Besides the bug in MinGW 4.8.1 with uint64_t in io.h, there is also this one in QT 5.2.1 still. I came across this today when trying to compile QT 5.2.1 with MinGW 4.8.1, so I thought I would post my solution as well.

I don't know what the official fix will be for QT, but for my needs I did it like this:

in src/gui/opengl/qopengl.h line 49:

// Windows always needs this to ensure that APIENTRY gets defined
#if defined(Q_OS_WIN)
# include <QtCore/qt_windows.h>
#endif

I just undefined the windows MemoryBarrier macro there:

// Windows always needs this to ensure that APIENTRY gets defined
#if defined(Q_OS_WIN)
# include <QtCore/qt_windows.h>
# undef MemoryBarrier
#endif
Brian Onn
  • 1,026
  • 11
  • 18
  • This is not the correct way to fix it - in fact, it could potentially break other cases -, and `QT` is a different project. Please read the tag for details about that. Also, it is better worked around in user application code without the need to rebuild Qt itself because it is a long procedure. – László Papp Mar 26 '14 at 16:54
  • Unfortunately you often do need to rebuild QT if your application project is using a different version of MingGW that QT was built with, or you want different threads (posix vs. win32 threads). This was why I had to rebuild it. – Brian Onn Mar 29 '14 at 04:06
  • @LaszloPapp agreed though, it's better if it can be worked around in the user app rather than changing the QT source, but my posted solution works for all version of MinGW. There really needs to be a better fix in QT for this for all versions of MinGW. – Brian Onn Mar 29 '14 at 04:14
5

I noticed that the "MemoryBarrier" token is present in the libQt5OpenGLExtensionsd.a library. Should I include it, even if in the original Qt4 project nothing related to OpenGL was used?

No, those are not related. OpenGLExtension is compiled after QtGui.

What you are hitting unfortunately is that there is a MemoryBarrier() already defined on Windows, and hence there is a clash for that and what qt is having. You can find the official Windows documentation for that:

http://msdn.microsoft.com/en-us/library/windows/apps/ms684208(v=vs.85).aspx

I have just discussed this with Gunnar, the QtGui maintainer, and I am planning to submit a change to Gerrit to address your issue.

We had used something like this in our project a couple of years ago when we were writing thread-safe singletons based on QtCore:

#if defined __GNUC__ && __GNUC__ >= 4 && __GNUC_MINOR__ >= 4    
#define __MEMBARRIER __sync_synchronize();  
#elif defined _MSC_VER && defined _WIN64    
#define __MEMBARRIER MemoryBarrier();   
#else   
#define __MEMBARRIER
#endif

Qt may need to check ifdef MINGW/GCC/VERSION and undef the MemoryBarrier define.

EDIT: This was fixed about half a year ago. See the following Gerrit review and the corresponding bug report for details:

https://codereview.qt-project.org/#change,68156

and

https://bugreports.qt.io/browse/QTBUG-34080

So, update to Qt 5.2.0 and it will work. Failing that, you can try to backport it.

MBach
  • 1,647
  • 16
  • 30
László Papp
  • 51,870
  • 39
  • 111
  • 135
  • 1
    Just for the record, the issue is still there on version 5.2.0, released today. – Massimo Callegari Dec 12 '13 at 22:36
  • @MassimoCallegari: yes, we did not have time to fix it upstream, apparently. – László Papp Dec 13 '13 at 03:07
  • While this answer may be intersting, it doesn't really help because nobody knows where this woul dhave to be applied. – Devolus Mar 26 '14 at 16:06
  • @LaszloPapp, as I said, not really helpful because "anywhere in my code" doesn't seem to work. – Devolus Mar 27 '14 at 07:08
  • 1
    @LaszloPapp, "unseen code"? It's the official QT 5.2 source download, that shouldn't be some "unknown code". Considering that this is already known for months https://bugreports.qt-project.org/browse/QTBUG-34044 I would have expected that a proper fix description should be possible even if the latest build may not have a fix included. – Devolus Mar 27 '14 at 07:25
  • I don't have any application code at the moment, I'm trying to build the regular QT 5.2 source code and of course I want to have it correctly fixed. I would expect that a library builds out of the box so I wonder how to properly fix this to get QT compiled. I mean, QT itself must have been built at some time otherwise where are the precompiled builds coming from? – Devolus Mar 27 '14 at 07:47
  • I want to get started with QT and my usualy approach is to first build the neccessary library. That's the point of using an Open Source project. ;) To have the code available and be able to build it. – Devolus Mar 27 '14 at 08:03
  • Well, if I assess a library for my company and one requirement is full access to the source, then being able to build is the first step. I've been using wxWidgets so far but I'm considering to switch to QT but no build, no QT ;). – Devolus Mar 27 '14 at 08:08
  • @LaszloPapp, I posted another fix, which at least compiles but doesn't just undefine `MemoryBarrier` can you tell me if this is a proper solution? – Devolus Mar 27 '14 at 08:20
  • @MassimoCallegari: it seems to be fixed in 5.2.0. Please check 5.2.1 out, too. It oughta work. – László Papp Mar 27 '14 at 08:26
  • I'v been using this link http://download.qt-project.org/archive/qt/5.2/5.2.1/single/qt-everywhere-opensource-src-5.2.1.zip which would seem to me that it should be the latest version. That's why I'm a bit surprised that this fix wouldn't be in there. I'm building with MingW. – Devolus Mar 27 '14 at 08:27
  • Is it possible that this fix doesn't work when you don't use ANGLE? I've had another problem here http://stackoverflow.com/questions/22682406/building-qt-5-2-1-with-mingw-recipe-failed-for-target but this posting shows the configure parameters that I use to compile 5.2.1 where I have exactly this problem as well. – Devolus Mar 27 '14 at 10:59
  • 1
    @LaszloPapp Nope, it's not fixed. Remember I tried to build 5.3.0 to make serial device serial number tests ? I got crazy with this MemoryBarrier thing. I'm afraid it's still there even on 5.3.0 – Massimo Callegari Mar 28 '14 at 09:22
  • @MassimoCallegari: hmm, ok, it is probably worth noting it in the corresponding bugreport. I think it is difficult to support every mingw variant. – László Papp Mar 28 '14 at 09:28
1

I run into the same problem. I could compile and run with just commenting out the problematic line:

// void (QOPENGLF_APIENTRYP MemoryBarrier)(GLbitfield barriers);

In file C:/Qt/Qt5.1.1/5.1.1/mingw48_32/include/QtGui/qopenglversionfunctions.h:785

My application does not use any OpenGL stuff. Let's hope they fix it soon ;-)

adler
  • 949
  • 1
  • 9
  • 10
1

Since the accepted answer doesn't seem to help when one tries to build the QT library on it's own and Laszlo Pap claims that thie other solution is not a proper fix, I tried to find a way to fix it correctly. On Google I found a posting where it was said that MemoryBarrier is not implemented in MingW and there was a patch for it.

So I tried to incorporate the fix into opengl.h and hope that this is the correct way as simply commenting out the lines may cause problems later on.

#ifndef QT_NO_OPENGL

// Windows always needs this to ensure that APIENTRY gets defined
#if defined(Q_OS_WIN)

# include <QtCore/qt_windows.h>

#if defined(__MINGW32__) && defined(MemoryBarrier)
#undef MemoryBarrier

__CRT_INLINE void MemoryBarrier(void)
{
    long Barrier = 0;
    __asm__ __volatile__("xchgl %%eax,%0 "
        :"=r" (Barrier));
}
#endif

#endif
Devolus
  • 21,661
  • 13
  • 66
  • 113