Qt
  1. Qt
  2. QTBUG-22829

boost 1.48, Qt and [Parse error at "BOOST_JOIN"] error

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: P2: Important P2: Important
    • Resolution: Done
    • Affects Version/s: 4.7.3, 4.7.4, 4.8.0, 4.8.1
    • Fix Version/s: 5.0.0
    • Component/s: Build tools: moc
    • Labels:
      None

      Description

      I have large project with the mix of Qt and boost. I keep upgrading both Qt and boost to the latest available production releases. Currently I am on Qt 4.7.3 and boost 1.47. Recently a new boost build, 1.48 was released. When I compiled my project with this new boost release I started to get multiple errors "Parse error at "BOOST_JOIN", pointing to boost/type_traits/detail/has_binary_operator.hp(50)

      Naturally I thought that this is the boost problem, switched back to 1.47 and problem dissappeared. I posted the report on boost. I also found out that that this issue was already discussed in another boost thread and the conclusion was that it is MOCC bug. I received responses to my boost report where it was stated that the maintainer of the boost library definitely points out to a bug in Qt MOC compiler.

      Following are the links to the discussion:

      http://groups.google.com/group/boost-list/browse_thread/thread/212fa3fa2f712206
      http://groups.google.com/group/boost-list/browse_thread/thread/1642b52217e30ff7/313695d3024a0234?show_docid=313695d3024a0234

      Last link suggests workaround for Qt, but it looks to be specific to the software they discuss.

      I believe that it might affect quite a large number of people/projects. I will appreciate if you can suggest a generic workaround to fix this issue.

      Please let me know if I can be of any assistance.

        Issue Links

          Activity

          Hide
          Panagiotis Foteinos added a comment -

          Qt version 4.6.2 has also the same problem with boost 1.48

          Show
          Panagiotis Foteinos added a comment - Qt version 4.6.2 has also the same problem with boost 1.48
          Hide
          Zac added a comment - - edited

          <HACK>
          Its possible to abuse the header guard for a portion of boost to work around this issue with moc.

          Its the lease evil of several possible hack solutions that I came up with. It wasn't an option to go to all the places in our code that include boost and put #ifdef QT_MOC around them.

          Passing the following to moc will prevent it from parsing through the portion of boost that it is having problems with:
          -DBOOST_TT_HAS_OPERATOR_HPP_INCLUDED

          </HACK>

          If I can find some time I'll see about patching moc - so I'm not just a consumer of this great project..

          Show
          Zac added a comment - - edited <HACK> Its possible to abuse the header guard for a portion of boost to work around this issue with moc. Its the lease evil of several possible hack solutions that I came up with. It wasn't an option to go to all the places in our code that include boost and put #ifdef QT_MOC around them. Passing the following to moc will prevent it from parsing through the portion of boost that it is having problems with: -DBOOST_TT_HAS_OPERATOR_HPP_INCLUDED </HACK> If I can find some time I'll see about patching moc - so I'm not just a consumer of this great project..
          Hide
          Michael B added a comment -

          Zac,

          I will appreciate it if you can provide more information about the solution. I searched Qt sources and also googled for DBOOST_TT_HAS_OPERATOR_HPP_INCLUDED switch and search came out empty. Is that perhaps the undocumented feature of MOC or I missed something in the search?

          Thanks.

          Show
          Michael B added a comment - Zac, I will appreciate it if you can provide more information about the solution. I searched Qt sources and also googled for DBOOST_TT_HAS_OPERATOR_HPP_INCLUDED switch and search came out empty. Is that perhaps the undocumented feature of MOC or I missed something in the search? Thanks.
          Hide
          Andrea Scarpino added a comment -

          Thanks Zac! Your workaround works. I used it in the QT4_WRAP_CPP() macro.

          Show
          Andrea Scarpino added a comment - Thanks Zac! Your workaround works. I used it in the QT4_WRAP_CPP() macro.
          Hide
          Zac added a comment -

          @Michael B

          More detail on my hack:

          Passing a -D parameter to moc.exe "-D<macro>[=<def>] define macro, with optional definition" from moc's help.

          The BOOST_JOIN macro in the following files are crashing moc:

          • boost\type_traits\detail\has_binary_operator.hpp
          • boost\type_traits\detail\has_postfix_operator.hpp
          • boost\type_traits\detail\has_prefix_operator.hpp

          They are all eventually ( I believe exclusively ) included by:

          • boost\type_traits\has_operator.hpp

          has_operator.hpp uses header guards "BOOST_TT_HAS_OPERATOR_HPP_INCLUDED", so defining that macro on moc's command line prevents it from parsing through the portion of boost that it is having issues with.

          Show
          Zac added a comment - @Michael B More detail on my hack: Passing a -D parameter to moc.exe "-D<macro> [=<def>] define macro, with optional definition" from moc's help. The BOOST_JOIN macro in the following files are crashing moc: boost\type_traits\detail\has_binary_operator.hpp boost\type_traits\detail\has_postfix_operator.hpp boost\type_traits\detail\has_prefix_operator.hpp They are all eventually ( I believe exclusively ) included by: boost\type_traits\has_operator.hpp has_operator.hpp uses header guards "BOOST_TT_HAS_OPERATOR_HPP_INCLUDED", so defining that macro on moc's command line prevents it from parsing through the portion of boost that it is having issues with.
          Show
          Kevin Kofler added a comment - 1-line workaround: http://pkgs.fedoraproject.org/gitweb/?p=qt.git;a=blob;f=qt-everywhere-opensource-src-4.8.0-rc1-moc-boost148.patch;h=f0ce6564e29e22eac504c538698517bdcef80061;hb=060db3c767b670dc1e168252644c937abc9fe607
          Hide
          Vincenzo Comito added a comment -

          For the ones that use cmake:
          QT4_WRAP_CPP(sources $

          {moc-sources}

          OPTIONS -DBOOST_TT_HAS_OPERATOR_HPP_INCLUDED)

          Show
          Vincenzo Comito added a comment - For the ones that use cmake: QT4_WRAP_CPP(sources $ {moc-sources} OPTIONS -DBOOST_TT_HAS_OPERATOR_HPP_INCLUDED)
          Hide
          Martin Franzke added a comment - - edited

          For the ones that use qmake:
          You may just edit the variable assignment for QMAKE_MOC in the file $QTDIR/mkspecs\<your_platform>/qmake.conf; e.g. for win32-msvc2008
          QMAKE_MOC = $$[QT_INSTALL_BINS]\\moc.exe -DBOOST_TT_HAS_OPERATOR_HPP_INCLUDED

          Show
          Martin Franzke added a comment - - edited For the ones that use qmake: You may just edit the variable assignment for QMAKE_MOC in the file $QTDIR/mkspecs\<your_platform>/qmake.conf; e.g. for win32-msvc2008 QMAKE_MOC = $$ [QT_INSTALL_BINS] \\moc.exe -DBOOST_TT_HAS_OPERATOR_HPP_INCLUDED
          Hide
          Zac added a comment -

          I have boiled it down to this repro:

          test.h:

          #define MAC( X ) X
          
          namespace MAC(broken) 
          {
          }
          

          #>moc test.h
          test.h(3): Parse error at "MAC"

          If I find some more time I'll try to debug moc.

          Show
          Zac added a comment - I have boiled it down to this repro: test.h: #define MAC( X ) X namespace MAC(broken) { } #>moc test.h test.h(3): Parse error at "MAC" If I find some more time I'll try to debug moc.
          Hide
          Dirk Kraft added a comment -

          I can reproduce this using qt 4.8.0. Both cases (related to boost and the above testcase) produce an error message.

          Show
          Dirk Kraft added a comment - I can reproduce this using qt 4.8.0. Both cases (related to boost and the above testcase) produce an error message.
          Hide
          Olivier Goffart (Woboq GmbH) added a comment -

          Another workaround: make sure problematic boost header are not seen by moc by putting them in a relevent #ifndef Q_MOC_RUN

          #ifndef Q_MOC_RUN
          #include <boost/python.hpp>
          #endif
          
          Show
          Olivier Goffart (Woboq GmbH) added a comment - Another workaround: make sure problematic boost header are not seen by moc by putting them in a relevent #ifndef Q_MOC_RUN #ifndef Q_MOC_RUN #include <boost/python.hpp> #endif
          Hide
          Olivier Goffart (Woboq GmbH) added a comment -

          This is related to the fact that moc do not expend macro properly.

          One could have a workaround to ignore that kind of namespace definition, but the proper fix would be proper macro support.

          Show
          Olivier Goffart (Woboq GmbH) added a comment - This is related to the fact that moc do not expend macro properly. One could have a workaround to ignore that kind of namespace definition, but the proper fix would be proper macro support.
          Hide
          Olivier Goffart (Woboq GmbH) added a comment -

          Moc in Qt 5.0 has proper macro substitutions

          Show
          Olivier Goffart (Woboq GmbH) added a comment - Moc in Qt 5.0 has proper macro substitutions
          Hide
          Andrea Tagliasacchi added a comment -

          Q_MOC_RUN worked perfectly for me
          Still.. shouldn't be happening (Qt4.8.3)

          Show
          Andrea Tagliasacchi added a comment - Q_MOC_RUN worked perfectly for me Still.. shouldn't be happening (Qt4.8.3)
          Hide
          John-Michael Fischer added a comment -

          Getting this with QT 4.8.4 and boost 1.52.0. VS2010 x64.

          Show
          John-Michael Fischer added a comment - Getting this with QT 4.8.4 and boost 1.52.0. VS2010 x64.
          Hide
          Steven Peters added a comment -

          The BOOST_TT_HAS_OPERATOR_HPP_INCLUDED workaround isn't always working with boost 1.53 because some of the type_traits headers are being included outside of has_operator.hpp, for example lexical_cast.hpp includes has_left_shift.hpp, which includes has_binary_operator.hpp

          http://www.boost.org/doc/libs/1_53_0/boost/lexical_cast.hpp
          http://www.boost.org/doc/libs/1_53_0/boost/type_traits/has_left_shift.hpp

          An alternative workaround is -DBOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION

          Show
          Steven Peters added a comment - The BOOST_TT_HAS_OPERATOR_HPP_INCLUDED workaround isn't always working with boost 1.53 because some of the type_traits headers are being included outside of has_operator.hpp, for example lexical_cast.hpp includes has_left_shift.hpp, which includes has_binary_operator.hpp http://www.boost.org/doc/libs/1_53_0/boost/lexical_cast.hpp http://www.boost.org/doc/libs/1_53_0/boost/type_traits/has_left_shift.hpp An alternative workaround is -DBOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
          Hide
          Vivek Ayer added a comment -

          I'm seeing this issue using Qt 4.8.5, Boost 1.54.0, GCC 4.8.1 on CentOS 6.4. So what's the workaround? Thanks

          Show
          Vivek Ayer added a comment - I'm seeing this issue using Qt 4.8.5, Boost 1.54.0, GCC 4.8.1 on CentOS 6.4. So what's the workaround? Thanks
          Hide
          Steven Peters added a comment -

          The workaround that we use is to wrap boost headers in an ifdef directive. See the following pull request for an example:
          https://bitbucket.org/osrf/sdformat/pull-request/14/fix-for-qt-bug-22829/diff

          Show
          Steven Peters added a comment - The workaround that we use is to wrap boost headers in an ifdef directive. See the following pull request for an example: https://bitbucket.org/osrf/sdformat/pull-request/14/fix-for-qt-bug-22829/diff
          Hide
          mar-na added a comment -

          Only for info: See also with Qt 4.8.6 + boost 1.57.0 + include <boost/signals2.hpp>

          Show
          mar-na added a comment - Only for info: See also with Qt 4.8.6 + boost 1.57.0 + include <boost/signals2.hpp>
          Hide
          Uwe Kindler added a comment -

          Only for info: See also with Qt 4.8.6 + boost 1.57.0 + include <boost/property_tree/ptree.hpp>

          Show
          Uwe Kindler added a comment - Only for info: See also with Qt 4.8.6 + boost 1.57.0 + include <boost/property_tree/ptree.hpp>
          Hide
          Jan Niklas Hasse added a comment -

          As this seems to be fixed in 5.0.0, can the fix be backported to Qt 4.8.x?

          Show
          Jan Niklas Hasse added a comment - As this seems to be fixed in 5.0.0, can the fix be backported to Qt 4.8.x?
          Hide
          Olivier Goffart (Woboq GmbH) added a comment -

          This is a major change and will never be backported to Qt4

          Until you port your code to Qt5, you can use this work around of wrapping any problematic include within #ifndef Q_MOC_RUN:

          #ifndef Q_MOC_RUN
          #include <boost/python.hpp>
          #endif
          
          Show
          Olivier Goffart (Woboq GmbH) added a comment - This is a major change and will never be backported to Qt4 Until you port your code to Qt5, you can use this work around of wrapping any problematic include within #ifndef Q_MOC_RUN: #ifndef Q_MOC_RUN #include <boost/python.hpp> #endif
          Hide
          Jan Niklas Hasse added a comment -

          I see, thanks for the info. The workaround does the trick

          Show
          Jan Niklas Hasse added a comment - I see, thanks for the info. The workaround does the trick

            People

            • Assignee:
              Olivier Goffart (Woboq GmbH)
              Reporter:
              Michael B
            • Votes:
              16 Vote for this issue
              Watchers:
              28 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: