3

我一直在为我的 iOS 应用程序使用Google 的 LevelDB库,我对此非常满意。最近我将整个项目迁移到了最新的 Xcode 5,虽然部署目标仍然是 iOS 6.1,但基础 SDK 现在是 iOS 7。

一切都很好,直到它进入链接阶段,它无法找到所需架构的 leveldb 符号,即使 leveldb 的静态库是使用-isysroot正确指向 iOS 7 SDK 的选项构建的。它像这样失败:

Ld /Users/mathieudamours/Development/storm/iOS/Uptime/Build/Intermediates/Uptime.build/Release-iphoneos/Uptime.build/Objects-normal/armv7/Uptime normal armv7
    cd /Users/mathieudamours/Development/storm/iOS/Uptime/Uptime
    setenv IPHONEOS_DEPLOYMENT_TARGET 6.1
    setenv PATH "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin:/Applications/Xcode.app/Contents/Developer/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin"
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang -arch armv7 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.0.sdk -L/Users/mathieudamours/Development/storm/iOS/Uptime/Build/Products/Release-iphoneos -L/Users/mathieudamours/Development/storm/iOS/Uptime/Uptime/../Pods/Objective-LevelDB/leveldb-library -F/Users/mathieudamours/Development/storm/iOS/Uptime/Build/Products/Release-iphoneos -F/Users/mathieudamours/Development/storm/iOS/Common/HockeySDK.embeddedframework -filelist /Users/mathieudamours/Development/storm/iOS/Uptime/Build/Intermediates/Uptime.build/Release-iphoneos/Uptime.build/Objects-normal/armv7/Uptime.LinkFileList -dead_strip -ObjC -fobjc-arc -Wl,-no_compact_unwind -licucore -lleveldb -lstdc++ -framework Accelerate -framework CFNetwork -framework CoreGraphics -framework MessageUI -framework MobileCoreServices -framework QuartzCore -framework Security -framework SystemConfiguration -fobjc-arc -fobjc-link-runtime -miphoneos-version-min=6.1 -framework SystemConfiguration -framework QuartzCore -framework CoreText -framework EventKit -framework UIKit -framework HockeySDK -framework Foundation -framework CoreGraphics -lPods -Xlinker -dependency_info -Xlinker /Users/mathieudamours/Development/storm/iOS/Uptime/Build/Intermediates/Uptime.build/Release-iphoneos/Uptime.build/Objects-normal/armv7/Uptime_dependency_info.dat -o /Users/mathieudamours/Development/storm/iOS/Uptime/Build/Intermediates/Uptime.build/Release-iphoneos/Uptime.build/Objects-normal/armv7/Uptime

Undefined symbols for architecture armv7:
  "std::__1::__vector_base_common<true>::__throw_length_error() const", referenced from:
      void std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >::__push_back_slow_path<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) in libleveldb.a(env_posix.o)
  "std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::operator=(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)", referenced from:
      leveldb::(anonymous namespace)::PosixEnv::LockFile(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, leveldb::FileLock**) in libleveldb.a(env_posix.o)
  "std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::__init(char const*, unsigned long)", referenced from:
      leveldb::Status::ToString() const in libleveldb.a(status.o)
      leveldb::(anonymous namespace)::PosixEnv::GetChildren(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >*) in libleveldb.a(env_posix.o)
      leveldb::(anonymous namespace)::PosixEnv::UnlockFile(leveldb::FileLock*) in libleveldb.a(env_posix.o)
  "std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::append(char const*, unsigned long)", referenced from:
      leveldb::Status::ToString() const in libleveldb.a(status.o)
      leveldb::PutLengthPrefixedSlice(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >*, leveldb::Slice const&) in libleveldb.a(coding.o)
      leveldb::(anonymous namespace)::PosixEnv::LockFile(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, leveldb::FileLock**) in libleveldb.a(env_posix.o)
  "std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::push_back(char)", referenced from:
      leveldb::WriteBatch::Put(leveldb::Slice const&, leveldb::Slice const&) in libleveldb.a(write_batch.o)
      leveldb::WriteBatch::Delete(leveldb::Slice const&) in libleveldb.a(write_batch.o)
      leveldb::(anonymous namespace)::BloomFilterPolicy::CreateFilter(leveldb::Slice const*, int, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >*) const in libleveldb.a(bloom.o)
  "std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::assign(char const*)", referenced from:
      leveldb::(anonymous namespace)::PosixEnv::GetTestDirectory(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >*) in libleveldb.a(env_posix.o)
  "std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::~basic_string()", referenced from:
      leveldb::WriteBatch::WriteBatch() in libleveldb.a(write_batch.o)
      leveldb::WriteBatch::~WriteBatch() in libleveldb.a(write_batch.o)
      leveldb::Status::ToString() const in libleveldb.a(status.o)
      leveldb::(anonymous namespace)::PosixEnv::GetChildren(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >*) in libleveldb.a(env_posix.o)
      leveldb::(anonymous namespace)::PosixEnv::LockFile(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, leveldb::FileLock**) in libleveldb.a(env_posix.o)
      leveldb::(anonymous namespace)::PosixEnv::UnlockFile(leveldb::FileLock*) in libleveldb.a(env_posix.o)
      leveldb::(anonymous namespace)::PosixFileLock::~PosixFileLock() in libleveldb.a(env_posix.o)
      ...
  "std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::basic_string(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)", referenced from:
      leveldb::Status::ToString() const in libleveldb.a(status.o)
      leveldb::(anonymous namespace)::PosixEnv::NewSequentialFile(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, leveldb::SequentialFile**) in libleveldb.a(env_posix.o)
      leveldb::(anonymous namespace)::PosixEnv::NewRandomAccessFile(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, leveldb::RandomAccessFile**) in libleveldb.a(env_posix.o)
      leveldb::(anonymous namespace)::PosixEnv::NewWritableFile(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, leveldb::WritableFile**) in libleveldb.a(env_posix.o)
      leveldb::(anonymous namespace)::PosixEnv::GetChildren(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >*) in libleveldb.a(env_posix.o)
      std::__1::__tree<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::less<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >::__insert_unique(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) in libleveldb.a(env_posix.o)
      void std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >::__push_back_slow_path<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) in libleveldb.a(env_posix.o)
      ...
  "std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::resize(unsigned long, char)", referenced from:
      leveldb::WriteBatch::WriteBatch() in libleveldb.a(write_batch.o)
      leveldb::(anonymous namespace)::BloomFilterPolicy::CreateFilter(leveldb::Slice const*, int, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >*) const in libleveldb.a(bloom.o)
      leveldb::(anonymous namespace)::BytewiseComparatorImpl::FindShortestSeparator(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >*, leveldb::Slice const&) const in libleveldb.a(comparator.o)
      leveldb::(anonymous namespace)::BytewiseComparatorImpl::FindShortSuccessor(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >*) const in libleveldb.a(comparator.o)
  "std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::__init(char const*, unsigned long, unsigned long)", referenced from:
      leveldb::(anonymous namespace)::PosixEnv::LockFile(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, leveldb::FileLock**) in libleveldb.a(env_posix.o)
  "leveldb::DB::Open(leveldb::Options const&, std::string const&, leveldb::DB**)", referenced from:
      -[LevelDB initWithPath:name:andOptions:] in libPods.a(LevelDB.o)
ld: symbol(s) not found for architecture armv7
clang: error: linker command failed with exit code 1 (use -v to see invocation)

令人惊讶的是,如果我通过将 leveldb 的静态库指向旧的 iOS 6.1 SDK(为此我必须下载 Xcode 4.6、寻找 SDK 并将其存储在我的机器上的某个位置)来重建 leveldb 的静态库,链接工作正常。

所以,我的问题是,这是预期的行为吗?如果是这样,为什么?是否有可能/我必须改变什么才能不必保留旧版本的 iOS SDK 来构建这个库?

4

1 回答 1

7

您链接到的标准 C++ 库不匹配。Apple 的 LLVM 使用 libc++,而旧版本使用 libstdc++。您显示的符号是 libc++ 的。

如果库和应用程序之间的编译器、代码样式和标准库的构建设置相同,则应该没问题。

于 2013-09-16T01:22:52.920 回答