代码之家  ›  专栏  ›  技术社区  ›  Uflex

将Mac OSX 10.8上的GraphicsMagick与clang和libc链接++

  •  0
  • Uflex  · 技术社区  · 11 年前

    我一直在努力包括 GraphicsMagick 在过去的几天里,我一直在参与我的项目,但如果没有运气的话,希望这里有人能够帮助我(如果时间太长,请在最后查看TL/DR)。

    因为我需要JPEG、PNG和 lcms 支持,我以前使用configure和make工具下载并构建了它们:

    ./configure CC=clang
    make
    sudo make install
    

    所有这些似乎都很好,所以在下载GraphicsMagick之后,我再次运行configure:

    CC=clang CXX="clang++ -stdlib=libc++" CXXFLAGS="-stdlib=libc++" LDFLAGS="-stdlib=libc++" ./configure --enable-shared --disable-static --disable-openmp --without-xml --without-zlib --without-bzlib

    然后 make 创建动态库: libGraphicsMagick.3.dylib libGraphicsMagick++.3.dylib 。当我使用 MacDependency 或与 otool ,我看到它正在链接/usr/lib/libc++.1.dylib(而不是libstdc++)

    现在,如果我使用GraphicsMagick创建一个新项目,请添加 #include <Magick++.h> (通过/usr/local/include/GraphicsMagick中的上一步安装),只是这样,实际上没有使用任何功能,我得到了一个链接错误:

    clang++ -headerpad_max_install_names -stdlib=libc++ -arch x86_64 -o TestMagickApp.app/Contents/MacOS/TestMagickApp main.o widget.o moc_widget.o   -F/Library/Frameworks -L/Library/Frameworks -framework QtGui -framework QtCore 
    Undefined symbols for architecture x86_64:
      "std::__1::basic_streambuf<char, std::__1::char_traits<char> >::gptr() const", referenced from:
          std::__1::basic_stringbuf<char, std::__1::char_traits<char>, std::__1::allocator<char> >::seekoff(long long, std::__1::ios_base::seekdir, unsigned int) in widget.o
          std::__1::basic_stringbuf<char, std::__1::char_traits<char>, std::__1::allocator<char> >::underflow() in widget.o
          std::__1::basic_stringbuf<char, std::__1::char_traits<char>, std::__1::allocator<char> >::pbackfail(int) in widget.o
          std::__1::basic_stringbuf<char, std::__1::char_traits<char>, std::__1::allocator<char> >::overflow(int) in widget.o
      "std::__1::basic_streambuf<char, std::__1::char_traits<char> >::pptr() const", referenced from:
          std::__1::basic_stringbuf<char, std::__1::char_traits<char>, std::__1::allocator<char> >::seekoff(long long, std::__1::ios_base::seekdir, unsigned int) in widget.o
          std::__1::basic_stringbuf<char, std::__1::char_traits<char>, std::__1::allocator<char> >::underflow() in widget.o
          std::__1::basic_stringbuf<char, std::__1::char_traits<char>, std::__1::allocator<char> >::pbackfail(int) in widget.o
          std::__1::basic_stringbuf<char, std::__1::char_traits<char>, std::__1::allocator<char> >::overflow(int) in widget.o
      "std::__1::basic_streambuf<char, std::__1::char_traits<char> >::eback() const", referenced from:
          std::__1::basic_stringbuf<char, std::__1::char_traits<char>, std::__1::allocator<char> >::seekoff(long long, std::__1::ios_base::seekdir, unsigned int) in widget.o
          std::__1::basic_stringbuf<char, std::__1::char_traits<char>, std::__1::allocator<char> >::underflow() in widget.o
          std::__1::basic_stringbuf<char, std::__1::char_traits<char>, std::__1::allocator<char> >::pbackfail(int) in widget.o
          std::__1::basic_stringbuf<char, std::__1::char_traits<char>, std::__1::allocator<char> >::overflow(int) in widget.o
      "std::__1::basic_streambuf<char, std::__1::char_traits<char> >::egptr() const", referenced from:
          std::__1::basic_stringbuf<char, std::__1::char_traits<char>, std::__1::allocator<char> >::underflow() in widget.o
      "std::__1::basic_streambuf<char, std::__1::char_traits<char> >::epptr() const", referenced from:
          std::__1::basic_stringbuf<char, std::__1::char_traits<char>, std::__1::allocator<char> >::seekoff(long long, std::__1::ios_base::seekdir, unsigned int) in widget.o
          std::__1::basic_stringbuf<char, std::__1::char_traits<char>, std::__1::allocator<char> >::overflow(int) in widget.o
      "std::__1::basic_streambuf<char, std::__1::char_traits<char> >::pbase() const", referenced from:
          std::__1::basic_stringbuf<char, std::__1::char_traits<char>, std::__1::allocator<char> >::seekoff(long long, std::__1::ios_base::seekdir, unsigned int) in widget.o
          std::__1::basic_stringbuf<char, std::__1::char_traits<char>, std::__1::allocator<char> >::overflow(int) in widget.o
      "std::__1::basic_iostream<char, std::__1::char_traits<char> >::basic_iostream(std::__1::basic_streambuf<char, std::__1::char_traits<char> >*)", referenced from:
          std::__1::basic_stringstream<char, std::__1::char_traits<char>, std::__1::allocator<char> >::basic_stringstream(unsigned int) in widget.o
      "std::__1::basic_streambuf<char, std::__1::char_traits<char> >::setg(char*, char*, char*)", referenced from:
          std::__1::basic_stringbuf<char, std::__1::char_traits<char>, std::__1::allocator<char> >::seekoff(long long, std::__1::ios_base::seekdir, unsigned int) in widget.o
          std::__1::basic_stringbuf<char, std::__1::char_traits<char>, std::__1::allocator<char> >::underflow() in widget.o
          std::__1::basic_stringbuf<char, std::__1::char_traits<char>, std::__1::allocator<char> >::pbackfail(int) in widget.o
          std::__1::basic_stringbuf<char, std::__1::char_traits<char>, std::__1::allocator<char> >::overflow(int) in widget.o
          std::__1::basic_stringbuf<char, std::__1::char_traits<char>, std::__1::allocator<char> >::str(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) in widget.o
      "std::__1::basic_streambuf<char, std::__1::char_traits<char> >::setp(char*, char*)", referenced from:
          std::__1::basic_stringbuf<char, std::__1::char_traits<char>, std::__1::allocator<char> >::seekoff(long long, std::__1::ios_base::seekdir, unsigned int) in widget.o
          std::__1::basic_stringbuf<char, std::__1::char_traits<char>, std::__1::allocator<char> >::overflow(int) in widget.o
          std::__1::basic_stringbuf<char, std::__1::char_traits<char>, std::__1::allocator<char> >::str(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) in widget.o
      "std::__1::basic_streambuf<char, std::__1::char_traits<char> >::pbump(int)", referenced from:
          std::__1::basic_stringbuf<char, std::__1::char_traits<char>, std::__1::allocator<char> >::seekoff(long long, std::__1::ios_base::seekdir, unsigned int) in widget.o
          std::__1::basic_stringbuf<char, std::__1::char_traits<char>, std::__1::allocator<char> >::overflow(int) in widget.o
          std::__1::basic_stringbuf<char, std::__1::char_traits<char>, std::__1::allocator<char> >::str(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) in widget.o
      "std::__1::basic_streambuf<char, std::__1::char_traits<char> >::sputc(char)", referenced from:
          std::__1::basic_stringbuf<char, std::__1::char_traits<char>, std::__1::allocator<char> >::overflow(int) in widget.o
      "std::__1::basic_ios<char, std::__1::char_traits<char> >::basic_ios()", referenced from:
          std::__1::basic_stringstream<char, std::__1::char_traits<char>, std::__1::allocator<char> >::basic_stringstream(unsigned int) in widget.o
    ld: symbol(s) not found for architecture x86_64
    clang: error: linker command failed with exit code 1 (use -v to see invocation)
    make: *** [TestMagickApp.app/Contents/MacOS/TestMagickApp] Error 1
    19:43:22: The process "/usr/bin/make" exited with code 2.
    Error while building/deploying project TestMagickApp (kit: 4.8.5)
    When executing step 'Make'
    

    但只有当我尝试使用libc++时才会发生这种情况,如果我尝试改用libstdc++,它链接起来没有任何问题(但如果我仍在思考问题,那么只要我尝试使用任何功能,它就会出错)。

    我试图只包含某些文件来缩小问题,似乎是由内部的这段代码引起的 /usr/local/include/GraphicsMagick/magick/common.h :

    /*
      Support for __attribute__ was added in GCC 2.0.  It is not supported
      in strict ANSI mode which is indicated by __STRICT_ANSI__ being
      defined.
    
      http://www.ohse.de/uwe/articles/gcc-attributes.html
    
      Note that GCC 3.2 on MinGW does not define __GNUC__ or __GNUC_MINOR__.
    
    */
    #if !defined(__attribute__)
    #  if (!defined(__GNUC__) || (__GNUC__ < 2 || __STRICT_ANSI__))
    #    define __attribute__(x) /*nothing*/
    #  else
    #    if (((__GNUC__) > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1))) /* 3.1+ */
    #      define MAGICK_FUNC_DEPRECATED __attribute__((__deprecated__))
    #    endif
    #    if (__GNUC__ >= 3)  /* 3.0+ */
    #      define MAGICK_FUNC_MALLOC __attribute__((__malloc__))
    #    endif
    #    if (((__GNUC__) > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)))  /* 3.3+ */
      /* Supports argument syntax like __attribute__((nonnull (1, 2))) but
         don't know how to support non-GCC fallback. */
    #      define MAGICK_FUNC_NONNULL __attribute__((__nonnull__))
    #    endif
    #    if (((__GNUC__) > 3) || ((__GNUC__ == 2) && (__GNUC_MINOR__ >= 5))) /* 2.5+ */
    #      define MAGICK_FUNC_NORETURN __attribute__((__noreturn__))
    #    endif
    #    if ((__GNUC__) >= 3) /* 2.96+ */
    #      define MAGICK_FUNC_PURE __attribute__((__pure__))
    #    endif
    #    if (((__GNUC__) > 3) || ((__GNUC__ == 2) && (__GNUC_MINOR__ >= 7))) /* 2.7+ */
    #      define MAGICK_FUNC_UNUSED __attribute__((__unused__))
    #    endif
    #    if (((__GNUC__) > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)))  /* 3.3+ */
    #      define MAGICK_FUNC_WARN_UNUSED_RESULT __attribute__((__warn_unused_result__))
    #    endif
    #    if (((__GNUC__) > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 3)))  /* 4.3+ */
    #      define MAGICK_FUNC_ALLOC_SIZE_1ARG(arg_num) __attribute__((__alloc_size__(arg_num)))
    #      define MAGICK_FUNC_ALLOC_SIZE_2ARG(arg_num1,arg_num2) __attribute__((__alloc_size__(arg_num1,arg_num2)))
    #      define MAGICK_FUNC_HOT __attribute__((__hot__))
    #      define MAGICK_FUNC_COLD __attribute__((__cold__))
    #      define MAGICK_OPTIMIZE_FUNC(opt) __attribute__((__optimize__ (opt)))
    #    endif
    #    if (((__GNUC__) > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)))  /* 4.7+ */
    #      define MAGICK_ASSUME_ALIGNED(exp,align) __builtin_assume_aligned(exp,align)
    #      define MAGICK_ASSUME_ALIGNED_OFFSET(exp,align,offset) __builtin_assume_aligned(exp,align,offset)
    #    endif
    #  endif
    #endif
    

    现在我不太理解这段代码,但它似乎支持真正的旧编译器(GCC版本<2!!)。如果我将整个部分注释掉,它似乎编译得很好,但由于我不知道它在做什么,注释掉感觉有点冒险/奇怪,因为它是一个只读文件,这表明我无论如何都不应该真的弄乱它。

    值得一提的是,使用GraphicsMagick的应用程序也使用了Qt 4.8.5,我使用的是QtCreator和QMake,但我认为这在这里并不相关。我也尝试过Qt 5.1和5.2,但没有运气。

    clang++ --version 回报 Apple LLVM version 5.0 (clang-500.2.79) (based on LLVM 3.3svn) (我知道这不是最新版本,但我宁愿不更改它)。

    目标/目标:

    有人对用libc++编译GraphicsMicck有任何经验/反馈吗?

    有人能给我解释一下上面最后一段代码在做什么吗?当我评论它时,为什么它会起作用?

    你能发现我做的有什么不对吗?整个过程我做了几次,但可能我忘记了一些明显的事情。。。

    欢迎任何帮助。

    1 回复  |  直到 11 年前
        1
  •  0
  •   Uflex    11 年前

    自上一个稳定版本(截至今天的1.3.19)以来,clang的配置已添加。正在从生成 Mercurial 解决了这个问题。