rakshasa / libtorrent

libTorrent BitTorrent library
http://rtorrent.net/downloads/
GNU General Public License v2.0
895 stars 209 forks source link

newer gcc versions or clang give build errors [with patch] #159

Open Rhialto opened 7 years ago

Rhialto commented 7 years ago

Gcc versions such as gcc7, and clang, complain like this when compiling on NetBSD 7:

In file included from poll_kqueue.cc:50:0:                                      
../../rak/functional.h: In instantiation of 'bool rak::equal_t<Type,            
Ftor>::operator()(Arg&) [with Arg = kevent; Type = torrent::Event*; Ftor =      
rak::mem_ref_t<kevent, long int>]':                                             
/usr/include/g++/bits/predefined_ops.h:234:30:   required from 'bool            
__gnu_cxx::__ops::_Iter_pred<_Predicate>::operator()(_Iterator) [with           
_Iterator = kevent*; _Predicate = rak::equal_t<torrent::Event*,                 
rak::mem_ref_t<kevent, long int> >]'                                            
/usr/include/g++/bits/stl_algo.h:866:20:   required from '_ForwardIterator      
std::__remove_if(_ForwardIterator, _ForwardIterator, _Predicate) [with          
_ForwardIterator = kevent*; _Predicate =                                        
__gnu_cxx::__ops::_Iter_pred<rak::equal_t<torrent::Event*,                      
rak::mem_ref_t<kevent, l                                                        
ong int> > >]'                                                                  
/usr/include/g++/bits/stl_algo.h:936:30:   required from '_FIter                
std::remove_if(_FIter, _FIter, _Predicate) [with _FIter = kevent*;              
_Predicate = rak::equal_t<torrent::Event*, rak::mem_ref_t<kevent, long int>     
>]'                                                                             
poll_kqueue.cc:316:83:   required from here                                     
../../rak/functional.h:97:16: warning: ISO C++ forbids comparison between       
pointer and integer [-fpermissive]                                              
     return m_t == m_f(a);                                                      
                ^                                                               
Makefile:584: recipe for target 'poll_kqueue.lo' failed                         
gmake[4]: *** [poll_kqueue.lo] Error 1                                          
gmake[4]: Leaving directory                                                     
'/usr/pkgsrc/net/libtorrent/work/libtorrent-0.13.6/src/torrent'                 
Makefile:624: recipe for target 'all-recursive' failed                          
gmake[3]: *** [all-recursive] Error 1                                           
gmake[3]: Leaving directory                                                     
'/usr/pkgsrc/net/libtorrent/work/libtorrent-0.13.6/src/torrent'                 
Makefile:562: recipe for target 'all-recursive' failed                          

Different compiler versions may have different exact complaints, but the ones I saw with the ones at my disposal get fixed by adding the following casts. kevent.udata is of type intptr_t (or close enough).

--- src/torrent/poll_kqueue.cc.orig     2015-08-08 15:01:32.000000000 +0000     
+++ src/torrent/poll_kqueue.cc                                                  
@@ -111,7 +111,7 @@ PollKQueue::modify(Event* event, unsigne                    
   struct kevent* itr = m_changes + (m_changedEvents++);                        

   assert(event == m_table[event->file_descriptor()].second);                   
-  EV_SET(itr, event->file_descriptor(), mask, op, 0, 0, event);                
+  EV_SET(itr, event->file_descriptor(), mask, op, 0, 0, (intptr_t)event);      
 }                                                                              

 PollKQueue*                                                                    
@@ -309,11 +309,11 @@ PollKQueue::close(Event* event) {                         

   // Shouldn't be needed anymore.                                              
   for (struct kevent *itr = m_events, *last = m_events + m_waitingEvents; itr !
= last; ++itr)                                                                  
-    if (itr->udata == event)                                                   
+    if (itr->udata == (intptr_t)event)                                         
       itr->udata = NULL;                                                       

   m_changedEvents = std::remove_if(m_changes, m_changes + m_changedEvents,     
-                                   rak::equal(event,                           
rak::mem_ref(&kevent::udata))) - m_changes;                                     
+                                   rak::equal((intptr_t)event,                 
rak::mem_ref(&kevent::udata))) - m_changes;                                     
 }                                                                              

 void                                                                           
@@ -335,11 +335,11 @@ PollKQueue::closed(Event* event) {                        

   // Shouldn't be needed anymore.                                              
   for (struct kevent *itr = m_events, *last = m_events + m_waitingEvents; itr !
= last; ++itr)                                                                  
-    if (itr->udata == event)                                                   
+    if (itr->udata == (intptr_t)event)                                         
       itr->udata = NULL;                                                       

   m_changedEvents = std::remove_if(m_changes, m_changes + m_changedEvents,     
-                                   rak::equal(event,                           
rak::mem_ref(&kevent::udata))) - m_changes;                                     
+                                   rak::equal((intptr_t)event,                 
rak::mem_ref(&kevent::udata))) - m_changes;                                     
 }                                                                              

 // Use custom defines for EPOLL* to make the below code compile with           
krytarowski commented 7 years ago

This has been improved in NetBSD 8.0 and HEAD so cast should be no longer needed.

And option is to use:

#if defined(__NetBSD__) /* NetBSD version < 8.0 */
#define LIBEV_UDATA(a) __CAST(intptr_t, (a))
#else
#define LIBEV_UDATA(a) (a)
#endif

and use in the code:

EV_SET(itr, event->file_descriptor(), mask, op, 0, 0, LIBEV_UDATA(event));