Search code examples
c++cpthreadsimagemagickglibc

ImageMagick pthread.h multiple definition


When trying to compile more recent versions of ImageMagick (v6.8.7-2 or later, v6.8.7-1 is fine), I get a bunch of:

CCLD     magick/libMagickCore-6.Q16.la
magick/.libs/magick_libMagickCore_6_Q16_la-animate.o: In function `__pthread_cleanup_routine':
/usr/include/pthread.h:581: multiple definition of `__pthread_cleanup_routine'
magick/.libs/magick_libMagickCore_6_Q16_la-accelerate.o:/usr/include/pthread.h:581: first defined here
magick/.libs/magick_libMagickCore_6_Q16_la-annotate.o: In function `__pthread_cleanup_routine':
/usr/include/pthread.h:581: multiple definition of `__pthread_cleanup_routine'
magick/.libs/magick_libMagickCore_6_Q16_la-accelerate.o:/usr/include/pthread.h:581: first defined here
magick/.libs/magick_libMagickCore_6_Q16_la-artifact.o: In function `__pthread_cleanup_routine':
/usr/include/pthread.h:581: multiple definition of `__pthread_cleanup_routine'
magick/.libs/magick_libMagickCore_6_Q16_la-accelerate.o:/usr/include/pthread.h:581: first defined here
magick/.libs/magick_libMagickCore_6_Q16_la-attribute.o: In function `__pthread_cleanup_routine':
/usr/include/pthread.h:581: multiple definition of `__pthread_cleanup_routine'
magick/.libs/magick_libMagickCore_6_Q16_la-accelerate.o:/usr/include/pthread.h:581: first defined here
... goes on for quite a bit longer, all the same.

The pertinent area of /usr/include/pthread.h (from glibc-headers 2.5-118.el5_10.2) is:

/* Function called to call the cleanup handler.  As an extern inline
function the compiler is free to decide inlining the change when
needed or fall back on the copy which must exist somewhere else.  */

extern __inline void
__pthread_cleanup_routine (struct __pthread_cleanup_frame *__frame)
{
  if (__frame->__do_it) // <======= this is :581
    __frame->__cancel_routine (__frame->__cancel_arg);
}

I've been posting on ImageMagick's forum without response.

Even if you can't say exactly what's happening, how do I start figuring out whether the issue is with ImageMagick or pthread.h? Where do I go from there?

grep pthread_cleanup_routine -r * only shows matches against the binary object files -- none of ImageMagick's source code has pthread_cleanup_routine in it. A few of the sources include "pthread.h" of course.

That's leading me to believe that this is a glibc issue, not an ImageMagick issue... but, again, previous versions of ImageMagick compile just fine. (I have diff'ed the svn sources between versions where it broke. Lots of configuration/makefile changes, but nothing sticks out to me as to why it would cause this.)

I'm on CentOS 5, kernel 2.6.18-308.24.1.el5, gcc v4.9.0, ld v2.24, glibc-headers 2.5-118.el5_10.2


Solution

  • I've seen a lot of people posting similar issues with other packages than ImageMagick. Hopefully others will find this useful.

    Changing pthread.h, just before __pthread_cleanup_routine :

    extern __inline void
    

    to

    if __STDC__VERSION__ < 199901L
    extern
    #endif
    __inline void
    

    Fixes the issue. Older versions of glibc had an issue when -fexceptions was used, and inline non-C99 conformance (see http://gcc.gnu.org/ml/gcc-patches/2006-11/msg01030.html.) More recent glibc's would fix the issue too, but this should be a temp fix for those who don't want to / shouldn't upgrade it.

    ImageMagick svn 13539 (which later became v6.8.7-2) began using -fexceptions.