Opened 6 years ago

Last modified 23 months ago

#46951 new enhancement

finance/bitcoin: Problems compiling against Qt4

Reported by: easye Owned by: easye
Priority: Normal Milestone:
Component: ports Version:
Keywords: Cc:
Port: bitcoin

Description

After updating the checksums to the bitcoin-0.10.0, the compilation fails in linking bitcoin-qt as follows

 GEN      qt/locale/bitcoin_zh_TW.qm                                                                       
  GEN      qt/qrc_bitcoin_locale.cpp                                                                        
  CXX      qt/qt_libbitcoinqt_a-qrc_bitcoin_locale.o                                                        
  AR       qt/libbitcoinqt.a                                                                                
/opt/local/bin/ranlib: file: qt/libbitcoinqt.a(qt_libbitcoinqt_a-winshutdownmonitor.o) has no symbols       
/opt/local/bin/ranlib: file: qt/libbitcoinqt.a(qt_libbitcoinqt_a-moc_peertablemodel.o) has no symbols       
/opt/local/bin/ranlib: file: qt/libbitcoinqt.a(qt_libbitcoinqt_a-moc_rpcconsole.o) has no symbols           
/opt/local/bin/ranlib: file: qt/libbitcoinqt.a(qt_libbitcoinqt_a-winshutdownmonitor.o) has no symbols       
/opt/local/bin/ranlib: file: qt/libbitcoinqt.a(qt_libbitcoinqt_a-moc_peertablemodel.o) has no symbols       
/opt/local/bin/ranlib: file: qt/libbitcoinqt.a(qt_libbitcoinqt_a-moc_rpcconsole.o) has no symbols           
  OBJCXXLD qt/bitcoin-qt                                                                                    
clang: warning: argument unused during compilation: '-pthread'                                              
clang: warning: argument unused during compilation: '-pie'                                                  
clang: warning: argument unused during compilation: '-pthread'                                              
Undefined symbols for architecture x86_64:                                                                  
  "vtable for RPCExecutor", referenced from:                                                                
      RPCConsole::startExecutor() in libbitcoinqt.a(qt_libbitcoinqt_a-rpcconsole.o)                         
  NOTE: a missing vtable usually means the first non-inline virtual member function has no definition.      
  "vtable for RPCConsole", referenced from:                                                                 
      RPCConsole::RPCConsole(QWidget*) in libbitcoinqt.a(qt_libbitcoinqt_a-rpcconsole.o)                    
  NOTE: a missing vtable usually means the first non-inline virtual member function has no definition.      
  "RPCConsole::staticMetaObject", referenced from:                                                          
      RPCConsole::RPCConsole(QWidget*) in libbitcoinqt.a(qt_libbitcoinqt_a-rpcconsole.o)                    
      RPCConsole::clear() in libbitcoinqt.a(qt_libbitcoinqt_a-rpcconsole.o)                                 
      RPCConsole::setNumConnections(int) in libbitcoinqt.a(qt_libbitcoinqt_a-rpcconsole.o)                  
      RPCConsole::FormatBytes(unsigned long long) in libbitcoinqt.a(qt_libbitcoinqt_a-rpcconsole.o)         
  "BitcoinApplication::requestedShutdown()", referenced from:                                               
      BitcoinApplication::requestShutdown() in qt_bitcoin_qt-bitcoin.o                                      
  "BitcoinApplication::requestedInitialize()", referenced from:                                             
      BitcoinApplication::requestInitialize() in qt_bitcoin_qt-bitcoin.o                                    
  "vtable for BitcoinCore", referenced from:                                                                
      BitcoinCore::BitcoinCore() in qt_bitcoin_qt-bitcoin.o                                                 
  NOTE: a missing vtable usually means the first non-inline virtual member function has no definition.      
  "vtable for BitcoinApplication", referenced from:                                                         
      BitcoinApplication::BitcoinApplication(int&, char**) in qt_bitcoin_qt-bitcoin.o                       
      BitcoinApplication::~BitcoinApplication() in qt_bitcoin_qt-bitcoin.o                                  
  NOTE: a missing vtable usually means the first non-inline virtual member function has no definition.      
  "BitcoinApplication::stopThread()", referenced from:                                                      
      BitcoinApplication::~BitcoinApplication() in qt_bitcoin_qt-bitcoin.o                                  
ld: symbol(s) not found for architecture x86_64                                                             
clang: error: linker command failed with exit code 1 (use -v to see invocation)                 

Change History (8)

comment:1 Changed 6 years ago by easye

The build process is failing to generate a proper src/qt/moc_rpcconsole.cpp file with the following error

opt/local/include/boost/type_traits/detail/has_binary_operator.hp:50: Parse error at "BOOST_JOIN" 

comment:2 Changed 6 years ago by easye

Seems to be due to the issues outlined in https://trac.macports.org/ticket/46441.

Recommendation would seem to be patch bitcoin to add

-DWITH_QT4=OFF

to the Portfile configure.args variable.

See also https://bugreports.qt.io/browse/QTBUG-22829

Last edited 6 years ago by easye (previous) (diff)

comment:3 in reply to:  2 Changed 6 years ago by easye

Replying to easieste@…:

Recommendation would seem to be patch bitcoin to add

-DWITH_QT4=OFF

to the Portfile configure.args variable.

This fails, understandably as reading the patch to bob shows that they fixed the problem by removing Qt4.

One will have to go through the Qt bug report to figure out the more appropriate stategy for fixing Qt for the bitcoin link.

N.b. the other bitcoin binaries appear to build successfully.

comment:4 Changed 6 years ago by mf2k (Frank Schima)

Milestone: MacPorts Future
Owner: changed from easieste to easieste@…
Version: 2.3.3

Trac requires complete email addresses. Please do not set the Milestone field for a normal "ports" ticket, that is only used for base updates.

comment:5 Changed 6 years ago by easye

An example of how to solve this by providing guards around all inclusion of Boost headers.

https://gist.githubusercontent.com/jkseppan/ccf72d14f8b0efee6c7d/raw/dc97fbeb6b086a44c75b857a0f31e7a4f2adcdda/scantailor-0.9.11.1-moc-boost.patch

Note that bitcoin-0.9.3 now fails to build as well due to this problem.

comment:6 Changed 6 years ago by easye

I wasn't able to easily come up with a manner to get Bitcoin Core 0.10.0 to build under Macports with the qt4 GUI.

The default variant of "daemon" has been committed r134705, so our Bitcoin Core port goes sans GUI for a while.

It doesn't look like the source of this problem, namely the qt4 moc generator, is going to get fixed anytime soon.

Configuring the port via "--with-gui=qt5" leads to QT include header problems, seemingly indicating that Bitcoin Core has not been ported to QT5.

comment:7 Changed 6 years ago by easye

Summary: finance/bitcoin: Problems updating to bitcoin-0.10.0finance/bitcoin: Problems compiling against Qt4

bitcoin-0.10.1 as daemon-only has been committed to MacPorts, so renaming ticket to more accurately reflect that building the Qt GUI via MacPorts is currently hosed.

comment:8 Changed 23 months ago by kencu (Ken)

This error occurs because the older moc program in qt4, which is essentially a preprocessor, does not understand the more complicated macro substitution that is being used in certain parts of newer versions of boost.

boost has decided this is not their error to fix. qt5 has an upgrade moc program and it understands the fancy business going on in the boost headers. It is reported that this improved moc will never be backported to qt4.

The only solution is to block the problematic boost header from being preprocessed by qt4's moc. If there are not too many instances of #include <boost/xyz> then you can wrap the header with

#ifndef Q_MOC_RUN
#include <boost/myfailingheader.h>
#endif

and that basically makes moc skip over the header, but somehow it still works out in the end that the header is used.

If you have a lot of these #include <boost/xyx.h> then that approach can get mighty tedious quickly.

This discussion suggests you can wrap moc and add a define to it's implementation to make moc skip the problematic header series:

QMAKE_MOC = /path/to/moc -DBOOST_TT_HAS_OPERATOR_HPP_INCLUDED

For my purposes, I just hacked the boost header directly for the duration of the problem build. This header that was causing all the errors for me was this one:

/opt/local/include/boost/type_traits/detail/has_binary_operator.hpp

so I added this at the top:

#ifndef Q_MOC_RUN

and this at the bottom

#endif

and the build completed without a hiccup.

Now -- clearly I should remove that guard after the qt4 build has completed, to get back to stock boost headers. But I will admit I'm rather tempted to just leave it there, because it looks like it can do no harm (what else is ever going to define Q_MOC_RUN other than moc)... but I guess qt5's moc might, so there's a reason to remove it.

I have been trying to come up with a fancy method to wrap that header in a block automatically, and so far, I can't.

But anyway, there are several workarounds for the BOOST_JOIN problem with qt4.

Note: See TracTickets for help on using tickets.