Mailing List Archive


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

Re: [tlug] Compile/load problem with graphics library



Brian Chandler writes:

 > I may not have mentioned: this program has been compiled several
 > times, 

Like Joe F, I do not understand how this could be possible with that
Makefile.  Are you sure the application source code (specifically the
Makefile) hasn't been refactored in the meantime?

Linking is order-sensitive, and one-pass (the linker does not go back
over the list to try to resolve unresolved references using libraries
or objects it has already processed, unless they're actually listed
more than once in the command arguments[1]).  So both the command line
in the error message and the Makefile snippet are in the wrong order.

‾\_(ツ)_/‾

 > and was running for more than 3 years. So it seems unlikely that I
 > made a fundamental mistake.  I got the response about object order
 > on the magick forum too; I have tried putting the configure script
 > which generates the library references after the .o files, but it
 > makes no difference.
 > 
 > One big problem is that I simply cannot understand the mass of subtly 
 > different library names involved. The configure script generates the 
 > following for the libraries to be searched:
 > 
 > -L/usr/local/lib -lMagick++-6.Q16 -lMagickWand-6.Q16 -lMagickCore-6.Q16

If you think this is a "big problem" (it's really very basic Unix
programming), perhaps you're out of your depth?  I have a few
suggestions below.  (0) and (1) are easy to implement and may or may
not be helpful, but (2) and (3) I can't explain in detail without
hands on, although there may be a few people around who know how to
get the needed information out of your system.  And of course I can't
help you if it's something else without more information.  If the easy
fixes don't work, you should probably give somebody who knows how this
all fits together access to the system.

FYI: The library actually linked has a name generated by prepending
"lib" and appending ".so" (and possibly some version numbers).[2]  These
are the relevant files:

 > libMagick++-6.Q16.a            # This is for "static" linking
 > libMagick++-6.Q16.la           # This is for creating more libraries
 > libMagick++-6.Q16.so           # This is a link to the "real" file
 > libMagick++-6.Q16.so.6         # This is a link to the "real" file
 > libMagick++-6.Q16.so.6.0.0     # This is the "real" file
 > libMagickCore-6.Q16.a          # And similar for each group of five
 > libMagickCore-6.Q16.la
 > libMagickCore-6.Q16.so
 > libMagickCore-6.Q16.so.2
 > libMagickCore-6.Q16.so.2.0.0
 > libMagickWand-6.Q16.a
 > libMagickWand-6.Q16.la
 > libMagickWand-6.Q16.so
 > libMagickWand-6.Q16.so.2
 > libMagickWand-6.Q16.so.2.0.0

Darren said you have a lot of versions installed, but that's only true
for GraphicsMagick, which you aren't linking to.  As you can see
above, the libMagick libraries all contain the string "-6.Q16", which
probably corresponds the version number or string in the ImageMagick
include file(s).  The .so versions differ (.6 for libMagick vs. .2 for
Core and Wand), but this is common.  The question of when to bump the
.so numbers is very technical (ie, I haven't a clue :-).  Bottom line:
all your ImageMagick libraries are the same version.

 > ---- Latest error: with the library files after the .o files ----
 > horigome@kulle% make imagetrim
 > g++ imagetrim.o boundingbox.o `Magick++-config --ldflags --libs` -o imagetrim
 > imagetrim.o: In function `main': imagetrim.cpp:(.text+0x3c1):
 > undefined reference to
 > `Magick::Image::read(std::__cxx11::basic_string<char,
 >                                                 std::char_traits<char>,
 >                                                 std::allocator<char>
 >                                                 > const&)'

So I told a fib above.  C++ is extremely finicky about function names,
and pretty much everything in the `...' quoted part of the "Latest
error" above is encoded in the name the linker sees.  There are four
issues I can think of that would cause that error in the presence of
successfully compiled .o files and the appropriate library files.

(0) You still have old .o files lying around that refer to an earlier
    version of ImageMagick.  With that Makefile, "make" will *not*
    recompile them unless the sources have changed.  Does "make clean;
    make" help?

(1) The version of the ImageMagick headers used to compile the .o
    files is out of sync with the version of the libraries, and the
    prototypes are just plain wrong.  This would be especially likely
    if there are many calls to ImageMagick in the program but only
    these three functions are undefined at link time.

    (a) This typically happens at upgrades when the admin upgrades the
        runtime package (probably something like "imagemagick" +
        version information and package manager stuff), but not the
        corresponding developer package (typically something like
        "imagemagick-dev" + corresponding stuff).  If so, you're in
        luck: the trivial solution is to upgrade the -dev package to
        the same version as the runtime package.

    (b) It also happens if somebody has installed a local build and
        cleaned up /usr/local/lib but not /usr/local/include.  This
        seems very unlikely here, though, since you're getting the
        location of ImageMagick includes from Magick++-config
        according to the Makefile.

    I think (0) or (1a) is most likely, as the other possibilities
    shouldn't happen with a modern package management system.  If they
    were common, nobody would ever be able to compile C++ programs!

(2) As Jim T suggests, it's possible that the issue is in the version
    or options of G++ being used.  Specifically, the application
    program is requesting C++11 conformance (ie, to 2011 standard
    C++), it seems (just guessing, but the __cxx11 seems indicative).
    If the library was compiled to a different standard (perhaps
    because the default conformance level changed between G++
    versions), it won't link.  For this you need to figure out what
    the conformance level of the libraries is and how to get G++ to
    conform to that level.  (Sorry, I don't recall how to do this
    offhand; last time I programmed C++ in anger cfront was still the
    reference implementation!)

(3) The method used for encoding function prototypes into linker names
    and the calling convention for functions occasionally change
    across compiler versions, and this will change the linker names
    mangled up from the prototypes.  You need to figure out what
    version of the compiler was used for the libraries, and use that
    one.  (Again, not something I've done in a very long time.)

The reason that the people on the ImageMagick channel don't seem to
understand what's going on is that they don't.  They offered several
really plausible guesses, but in the end the problem is in the build
environment of the system (eg, include/lib version skew) or the build
process for your application, not in ImageMagick.  They clearly also
assumed you have more knowledge of how to build applications on
Unix-like systems than you show here.


Footnotes: 
[1]  Yes, this is actually useful in particularly complex cases.
There is one exception: if the static .a library is linked instead of
the dynamic .so, GNU ld will repeatedly search it to resolve
references in an object linked later.  But if the application were
statically linked, it should still work because the library is
actually incorporated in the executable.  And of course there's no
-static flag in the link command.

[2]  Static linking, mentioned above, is an exception.  Those libraries
will use .a extension without a version number extension, and the link
line will have a "-static" flag.


Home | Main Index | Thread Index

Home Page Mailing List Linux and Japan TLUG Members Links