Intel® C++ Compiler
Community support and assistance for creating C++ code that runs on platforms based on Intel® processors.

OS X, QT 4.8.7 and Intel 16.0.3 Issues

Cole_R_
Beginner
943 Views

Compiler: Intel 16.0.3

OS: OS X 10.10.5

Qt Version: 4.8.7

Clang Version: Apple LLVM version 7.0.2 (Clang-700.1.81)

Hello,

We are having some issues with the Intel compiler and Qt 4.8.7, we use the Intel compiler 16.0.3 across Windows, Linux and Mac, and the problem only arises on Mac. We cannot even compile a small test Qt program that shows a a simple window. Qt was compiled with clang (we can also compile the simple program with clang) since we could not get Qt to compile with the Intel compiler. The intel flags used to compile are as follows:

icpc -c -wd858,1572,1569,279 -O3 -inline-level=2 -falign-functions=16 -ansi-alias -xSSSE3 -w -m64 -std=c++11 -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED -I/opt/qt-4.8.7/mkspecs/macx-icc -I../test2 -I/opt/qt-4.8.7/lib/QtCore.framework/Headers -I/opt/qt-4.8.7/include/QtCore -I/opt/qt-4.8.7/lib/QtGui.framework/Headers -I/opt/qt-4.8.7/include/QtGui -I/opt/qt-4.8.7/include -I. -I. -I../test2 -I. -F/opt/qt-4.8.7//lib -o main.o ../test2/main.cpp

The error we get is as follows:

In file included from /opt/qt-4.8.7/include/QtGui/qpalette.h(47),
                 from /opt/qt-4.8.7/include/QtGui/qwidget.h(50),
                 from /opt/qt-4.8.7/lib/QtGui.framework/Headers/qmainwindow.h(45),
                 from /opt/qt-4.8.7/lib/QtGui.framework/Headers/QMainWindow(1),
                 from ../test2/mainwindow.h(4),
                 from ../test2/main.cpp(1):
/opt/qt-4.8.7/include/QtGui/qbrush.h(150): error: no instance of overloaded function "std::__1::swap" matches the argument list
In file included from /opt/qt-4.8.7/include/QtGui/qpalette.h(47),
                 from /opt/qt-4.8.7/include/QtGui/qwidget.h(50),
                 from /opt/qt-4.8.7/lib/QtGui.framework/Headers/qmainwindow.h(45),
                 from /opt/qt-4.8.7/lib/QtGui.framework/Headers/QMainWindow(1),
                 from ../test2/mainwindow.h(4),
                 from ../test2/main.cpp(1):
            argument types are: (QBrush::DataPtr, QBrush::DataPtr)
In file included from /opt/qt-4.8.7/include/QtGui/qpalette.h(47),
                 from /opt/qt-4.8.7/include/QtGui/qwidget.h(50),
                 from /opt/qt-4.8.7/lib/QtGui.framework/Headers/qmainwindow.h(45),
                 from /opt/qt-4.8.7/lib/QtGui.framework/Headers/QMainWindow(1),
                 from ../test2/mainwindow.h(4),
                 from ../test2/main.cpp(1):
  Q_DECLARE_SHARED(QBrush)
  ^

/opt/qt-4.8.7/include/QtCore/qshareddata.h(166): error: pointer to incomplete class type is not allowed
      inline ~QExplicitlySharedDataPointer() { if (d && !d->ref.deref()) delete d; }
                                                         ^
          detected during:
            instantiation of "QExplicitlySharedDataPointer<T>::~QExplicitlySharedDataPointer() [with T=QPixmapData]" at line 3561 of "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/type_traits"
            instantiation of "std::__1::enable_if<<expression>, void>::type std::__1::swap(_Tp &, _Tp &) [with _Tp=QPixmap::DataPtr]" at line 300 of "/opt/qt-4.8.7/include/QtGui/qpixmap.h

 

One thing to note is I have made sure that Qt has been compiled using the default library libc++. Is the a set of flags that I would be able to use to get this to build? I wanted to try and use icl++,  but as far as I can tell that does not come with the Mac Intel compiler in 2016 (I found it on the Windows one).

Thank you,

Cole

0 Kudos
13 Replies
Yuan_C_Intel
Employee
943 Views

Hi, Cole

Yes, libc++ is not provided by Intel compiler. It's a C++ standard library provide by LLVM or gcc.

Your LLVM version is compatible icc 16.0.3. I am now trying to reproduce your issue, but it takes quite a long time in building QT with clang. I will let you know if I have an update.

Thanks.

 

0 Kudos
Yuan_C_Intel
Employee
943 Views

Hi, Cole

I have reproduced the issue you reported.

You need to add option "-mmacosx-version-min=10.5".  This option will be used by the various availability macros placed into the headers, which makes a difference in Apple's API headers.

This option is set by default in the Makefile of QT 4.8.7 tutorial examples, which I can compile without a problem by icc.

This is not necessary for Clang though, most likely because it is already set to align with different Clang version. 

Hope this helps.

Thanks.

0 Kudos
Cole_R_
Beginner
943 Views

Thank you for your reply, and yes that will work, however that will compile QT using the old C++ libraries. On OS X pre 10.7, c++ was compiled using libstdc++, anything after uses libc++. There is a lot of C++ 11 functionality that is missing in the libstdc++ library so it would be nice to be able to compile it using the new library. Clang is able to to compile it using libc++ however Intel 2016 Update 3 cannot. If you run otool -L on your qmake binary if it was compiled using -mmacosx-version-min=10.10 you will see that clang was able to compile it with libc++. I have attached a picture showing my qmake binary.

qt_clang_libc.PNG

If clang can compile it using the libc++ libraries, shouldn't Intel be able to as well?

Cole

0 Kudos
David_K_5
Novice
943 Views

Hi,

I just want to chime in here to indicate that have the same problem.  It is a problem for us on the Mac platform as well, and it is preventing us from moving to the Intel C++ compiler to support our QT-based software.  (We are too invested in Qt 4.8 to switch to anything else.)

David

 

0 Kudos
Yuan_C_Intel
Employee
943 Views

Hi, Cole

Previously I configured QT with -platform macx-llvm which by default set "-mmacosx-version-min=10.5". 

Intel compiler also set default to use libc++ after OS X* v10.8, please see note of CLANG compatibility from here:

https://software.intel.com/en-us/node/583824

However the Clang support seems still requires the Intel Clang-based compiler, which you mentioned as icl or icl++ before. But this is not included in the C++ composer edition now. I have escalated this issue and will let you know for an update.

I am also trying to build llvm-g++ with QT and see if it can be used to build QT examples with icc. Will this be an option to you?

Thanks.

 

0 Kudos
Yuan_C_Intel
Employee
943 Views

Hi, Cole

I tried llvm-g++ built QT and will see the same error. So it does not look like an issue relating to Clang support with Intel Clang-based compiler.

I am still trying to create a reproducible test case with similar template declarations of Q_DECLARE_SHARED but without a success yet.

Another founding is that if I add -DQT_NO_STL it compiles, though I think it's not a choice since std library function will not be called.

As Kevin indicated, the issue might not be mac specific. I will try to root cause it and let you know for an update.

Thanks

0 Kudos
Cole_R_
Beginner
943 Views

Yes, compiling it with no-stl would not really be an option. As for it being Mac specific, we use the Intel 2016 Update 3 C++ compiler on both Windows and Linux as well. On Windows we compile Qt with MSVC and on Linux we compile with GCC, both do not have any issues. We compile our software using the Intel compiler on all 3 platforms with only issues compiling our software on Mac (our software uses a few Qt headers which is how we found the issue).

Cole

0 Kudos
Yuan_C_Intel
Employee
943 Views

Hi, Cole

Thank you for the update.

Finally I have created a reproducible test case and root-caused the problem.

It relates to below lines in src/corelib/global/qglobal.h. When I comment out the first template specialization on qIsDetached, icc compiles the code successfully, though this declaration looks not quite related to instantiation of qSwap.

 

#define Q_DECLARE_SHARED(TYPE)                                          \
//template <> inline bool qIsDetached<TYPE>(TYPE &t) { return t.isDetached(); } \
template <> inline void qSwap<TYPE>(TYPE &value1, TYPE &value2) \
{ qSwap(value1.data_ptr(), value2.data_ptr());} \
Q_DECLARE_SHARED_STL(TYPE)

I will escalate this to engineer for resolution. I will let you know when I have an update.

Hope this helps.

Thanks.

0 Kudos
Judith_W_Intel
Employee
943 Views

 

It looks like the Clang has a different lookup of names inside inline namespaces than GNU and their headers rely on this lookup and we haven't emulated the Clang specific behavior yet.

In the meantime I think you can workaround this problem by qualifying the lookup of swap with std::swap here:

sptem26-752> diff -c qglobal.h.save qglobal.h
*** qglobal.h.save      Thu Sep  8 17:57:47 2016
--- qglobal.h   Thu Sep  8 17:58:00 2016
***************
*** 16,22 ****
  }\
  namespace std { \
      template <> inline void swap<qt::TYPE>(qt::TYPE &value1, qt::TYPE &value2) \
!     { swap(value1.data_ptr(), value2.data_ptr()); } \
  } \
  namespace qt{

--- 16,22 ----
  }\
  namespace std { \
      template <> inline void swap<qt::TYPE>(qt::TYPE &value1, qt::TYPE &value2) \
!     { std::swap(value1.data_ptr(), value2.data_ptr()); } \
  } \
  namespace qt{

sptem26-753>

0 Kudos
Yuan_C_Intel
Employee
943 Views

Thank you Judith.

I made the change on Qt 4.8.7 src, and it compiles the Qt example with icpc

$ diff src/corelib/global/qglobal.h src/corelib/global/qglobal_new.h
2324c2324
<     { swap(value1.data_ptr(), value2.data_ptr()); } \
---
>     { std::swap(value1.data_ptr(), value2.data_ptr()); } \

 

Hope this helps.

Thanks.

0 Kudos
Cole_R_
Beginner
943 Views

Thank you for your help, I will try this out and see how it goes. Do you know when this functionality will be implemented? Would it be in update 4 or is this something that is longer term?

Cole

0 Kudos
Judith_W_Intel
Employee
943 Views

 

Cole,

16.0 update 4 had a code freeze date of August 4th -- so it's much too late for that update.The best we can do at this point is fix it in a 17.0 update.

I'm not sure how difficult it will be to fix - here is a reduced example which shows the problem is with the template name lookup from a specialization to a generic definition inside an inline namespace. Note that this code compiles with clang  -- but not with Gnu on Linux or Intel on Linux or Mac. Our goal would be to make it to compile with our compiler on Mac to be clang-compatible. I'm not sure who's right according to the C++ standard.

namespace std {

inline namespace __1 {

  template <class T>
  void swap(T x)
  {
    x->ref;
  }
}

template <class T> void swap(T*);

template <>
void swap<int>(int)
{
  void* data;
  swap(data); // which version of swap should be called? GNU and Intel choose std::__1::swap, clang chooses std::swap
}

}

Very sorry for the inconvenience. I hope you can workaround it as shown in the notes above...

Judy

0 Kudos
Cole_R_
Beginner
943 Views

Hi Judith,

I tried your workaround today and it worked great! We were able to build. Thank you so much for your help.

Cole

0 Kudos
Reply