C++ 将Mac OSX 10.8上的GraphicsMagick与clang和libc+链接+;
在过去的几天里,我一直在尝试将其加入到我的项目中,但运气不好,希望这里有人能够帮助我(如果时间太长,请参阅最后的TL/DR) 由于我需要JPEG、PNG和支持,我以前使用配置和制作工具下载并构建了它们:C++ 将Mac OSX 10.8上的GraphicsMagick与clang和libc+链接+;,c++,macos,clang,graphicsmagick,libc++,C++,Macos,Clang,Graphicsmagick,Libc++,在过去的几天里,我一直在尝试将其加入到我的项目中,但运气不好,希望这里有人能够帮助我(如果时间太长,请参阅最后的TL/DR) 由于我需要JPEG、PNG和支持,我以前使用配置和制作工具下载并构建了它们: ./configure CC=clang make sudo make install 所有这些似乎都工作正常,因此在下载GraphicsMagick后,我再次运行配置: CC=clang CXX=“clang++-stdlib=libc++”cxflags=“-stdlib=libc++”L
./configure CC=clang
make
sudo make install
所有这些似乎都工作正常,因此在下载GraphicsMagick后,我再次运行配置:
CC=clang CXX=“clang++-stdlib=libc++”cxflags=“-stdlib=libc++”LDFLAGS=“-stdlib=libc++”/configure--enable shared--disable static--disable openmp--un带xml--un带zlib--un带bzlib
然后make
创建我的动态库:libGraphicsMagick.3.dylib
和libGraphicsMagick++.3.dylib
。当我使用或使用otool
检查libGraphicsMagick++时,我看到它链接到/usr/lib/libc++.1.dylib(而不是libstdc++)
现在,如果我使用GraphicsMagick创建一个新项目,添加#include
(由/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'
现在我不太理解这段代码,但它似乎支持非常旧的编译器(GCC版本<2!!)。如果我注释掉整个部分,它看起来编译得很好,但是我不知道它在做什么,注释掉它感觉有点危险/奇怪,因为它是一个只读文件,这表明我无论如何都不应该弄乱它
值得一提的是,使用GraphicsMagick的应用程序也使用Qt4.8.5,我使用的是QtCreator和QMake,但我认为这与此无关。我也试过Qt5.1和5.2,但运气不好
clang++--version
返回Apple LLVM版本5.0(clang-500.2.79)(基于LLVM 3.3svn)
(我知道它不是最新版本,但我不想更改它)
TL/DR:
是否有人对使用libc++编译GraphicsMagick有任何经验/反馈
有人能给我解释一下上面最后一段代码在做什么吗?为什么我在评论它的时候它会起作用
你能看出我所做的有什么不对吗?整个过程我做了几次,但可能我忘记了一些明显的事情
非常欢迎任何帮助。自上一个稳定版本(从今天起为1.3.19)以来,已添加了clang的配置。通过构建解决了这个问题。您确定Qt组件没有链接到libstdc++
库吗?我不这么认为,我将-stdlib=libc++
传递给编译器和链接器(使用QMAKE_CXXFLAGS
和QMAKE_LFLAGS
),在构建输出中,我可以在传递给clang++的选项中看到它。奇怪的是,如果我不通过这个标志,它似乎可以工作(但我认为它也不能解决问题,而且我需要在我的项目中使用libc++)。
/*
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