tech-toolchain archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: CVS commit: pkgsrc/x11/gtk

On Sun, Nov 16, 2008 at 08:06:01PM +0000, David Holland wrote:
>  > I'll try and look at it.   I didn't really understand what was going
>  > on, but then I found this discussion on gcc inline and c99:
>  >

> My understanding from reading comp.std.c is that the message is wrong.
> I will look for C&V though, because my understanding is by no means
> authoritative.
> (Adding tech-toolchain for obvious reasons.)

OK, more debugging shows that the source of the problem is in the file 
/usr/pkg/include/glib/glib-1.2/glib.h from the glib package.   That
is causing the compile failure for x11/gtk.   

The critical bit is below (quoting from glib-1.2/glib.h).  Note that
when compiling:

 G_INLINE_FUNC is not initially defined (but gets defined in this file)
 G_CAN_INLINE gets defined to 1
 __GNUC__ is defined
 __STRICT_ANSI__ is NOT defined
 __OPTIMIZE__ is defined

so that basically results in this line getting run:

#      define G_INLINE_FUNC extern inline

and on Darwin if you do "extern inline" it generates a "T" symbol,
so if you put that in a .h file and include it more than once you are
going to get a duplicate symbol compile time error [e.g. on functions 
like g_bit_nth_lsf() ... also included below, as an example].

We could modify the glib.h (via a pkgsrc patch file) to do "static inline"
rather than "extern inline" when __GNUC__ and __OPTIMIZE__ are set?


/* inlining hassle. for compilers that don't allow the `inline' keyword,
 * mostly because of strict ANSI C compliance or dumbness, we try to fall
 * back to either `__inline__' or `__inline'.
 * we define G_CAN_INLINE, if the compiler seems to be actually
 * *capable* to do function inlining, in which case inline function bodys
 * do make sense. we also define G_INLINE_FUNC to properly export the
 * function prototypes if no inlining can be performed.
 * we special case most of the stuff, so inline functions can have a normal
 * implementation by defining G_INLINE_FUNC to extern and G_CAN_INLINE to 1.
#  define G_CAN_INLINE 1
#  if defined (__GNUC__) && defined (__STRICT_ANSI__)
#    undef inline
#    define inline __inline__
#  endif
#else /* !G_HAVE_INLINE */
#  undef inline
#  if defined (G_HAVE___INLINE__)
#    define inline __inline__
#  else /* !inline && !__inline__ */
#    if defined (G_HAVE___INLINE)
#      define inline __inline
#    else /* !inline && !__inline__ && !__inline */
#      define inline /* don't inline, then */
#      ifndef G_INLINE_FUNC
#        undef G_CAN_INLINE
#      endif
#    endif
#  endif
#  ifdef __GNUC__
#    ifdef __OPTIMIZE__
#      define G_INLINE_FUNC extern inline
#    else
#      undef G_CAN_INLINE
#      define G_INLINE_FUNC extern
#    endif
#  else /* !__GNUC__ */
#    ifdef G_CAN_INLINE
#      define G_INLINE_FUNC static inline
#    else
#      define G_INLINE_FUNC extern
#    endif
#  endif /* !__GNUC__ */

/* ... */

/* Bit tests
G_INLINE_FUNC gint      g_bit_nth_lsf (guint32 mask,
                                       gint    nth_bit);
#ifdef  G_CAN_INLINE
g_bit_nth_lsf (guint32 mask,
               gint    nth_bit)
      if (mask & (1 << (guint) nth_bit))
        return nth_bit;
  while (nth_bit < 32);
  return -1;
#endif  /* G_CAN_INLINE */

Home | Main Index | Thread Index | Old Index