2015-02-17 2 views
2

У меня есть библиотека C++, которая в значительной степени зависит от повышения, которое я пытаюсь скомпилировать для iOS8. Я использовал сценарий Даниэля россеровского для компиляции повысить-1.57.0 для прошивки: https://github.com/danoli3/ofxiOSBoostboost iOS linking error

Я изменил сценарий так, чтобы он также строит serialization библиотеки BOOST и все, кажется, хорошо.

Но, когда я скомпилировать свою библиотеку в XCode я получаю:

Undefined symbols for architecture x86_64: 
    "boost::archive::detail::shared_ptr_helper::shared_ptr_helper()", referenced from: 
     eos::portable_iarchive::portable_iarchive(std::__1::basic_istream<char, std::__1::char_traits<char> >&, unsigned int) in data_receiver.o 
     eos::portable_oarchive::portable_oarchive(std::__1::basic_streambuf<char, std::__1::char_traits<char> >&, unsigned int) in tcp_server.o 
    "boost::archive::detail::shared_ptr_helper::~shared_ptr_helper()", referenced from: 
     eos::portable_iarchive::portable_iarchive(std::__1::basic_istream<char, std::__1::char_traits<char> >&, unsigned int) in data_receiver.o 
     eos::portable_iarchive::~portable_iarchive() in data_receiver.o 
     eos::portable_oarchive::portable_oarchive(std::__1::basic_streambuf<char, std::__1::char_traits<char> >&, unsigned int) in tcp_server.o 
     eos::portable_oarchive::~portable_oarchive() in tcp_server.o 
ld: symbol(s) not found for architecture x86_64 
clang: error: linker command failed with exit code 1 (use -v to see invocation) 

Это, кажется, торчащие на функцию shared_ptr_helper() в буст :: архив библиотеки. Я немного смущен, потому что я думал, что эта часть boost не компилируется, что все заголовки, поэтому я не уверен, что вызывает ошибку «неправильной архитектуры». Есть ли другая библиотека boost, которая фактически определяет этот метод, который я не компилирую?

Позже ... вот ЭОС :: portable_iarchive код конструктора (который, кажется, что происходит ошибки --the oarchive код почти идентичен)

namespace eos { 

    // forward declaration 
    class portable_iarchive; 

    typedef boost::archive::basic_binary_iprimitive< 
      portable_iarchive 
    #if BOOST_VERSION < 103400 
      , std::istream 
    #else 
      , std::istream::char_type 
      , std::istream::traits_type 
    #endif 
    > portable_iprimitive; 

    /** 
    * \brief Portable binary input archive using little endian format. 
    * 
    * This archive addresses integer size, endianness and floating point types so 
    * that data can be transferred across different systems. There may still be 
    * constraints as to what systems are compatible and the user will have to take 
    * care that e.g. a very large int being saved on a 64 bit machine will result 
    * in a portable_archive_exception if loaded into an int on a 32 bit system. 
    * A possible workaround to this would be to use fixed types like 
    * boost::uint64_t in your serialization structures. 
    * 
    * \note The class is based on the portable binary example by Robert Ramey and 
    *   uses Beman Dawes endian library plus fp_utilities by Johan Rade. 
    */ 
    class portable_iarchive : public portable_iprimitive 

      // the example derives from common_oarchive but that lacks the 
      // load_override functions so we chose to stay one level higher 
      , public boost::archive::basic_binary_iarchive<portable_iarchive> 

    #if BOOST_VERSION >= 103500 
      // mix-in helper class for serializing shared_ptr 
      , public boost::archive::detail::shared_ptr_helper 
    #endif 
    { 
      // only needed for Robert's hack in basic_binary_iarchive::init 
      friend class boost::archive::basic_binary_iarchive<portable_iarchive>; 

      // workaround for gcc: use a dummy struct 
      // as additional argument type for overloading 
      template <int> struct dummy { dummy(int) {}}; 

      // loads directly from stream 
      inline signed char load_signed_char() 
      { 
        signed char c; 
        portable_iprimitive::load(c); 
        return c; 
      } 

      // archive initialization 
      void init(unsigned flags) 
      { 
        using namespace boost::archive; 
        archive_version_type input_library_version(3); 

        // it is vital to have version information! 
        // if we don't have any we assume boost 1.33 
        if (flags & no_header) 
          set_library_version(input_library_version); 

        // extract and check the magic eos byte 
        else if (load_signed_char() != magic_byte) 
          throw archive_exception(archive_exception::invalid_signature); 

        else 
        { 
          // extract version information 
          operator>>(input_library_version); 

          // throw if file version is newer than we are 
          if (input_library_version > archive_version) 
            throw archive_exception(archive_exception::unsupported_version); 

          // else set the library version accordingly 
          else set_library_version(input_library_version); 
        } 
      } 
public: 
     /** 
     * \brief Constructor on a stream using ios::binary mode! 
     * 
     * We cannot call basic_binary_iprimitive::init which tries to detect 
     * if the binary archive stems from a different platform by examining 
     * type sizes. 
     * 
     * We could have called basic_binary_iarchive::init which would create 
     * the boost::serialization standard archive header containing also the 
     * library version. Due to efficiency we stick with our own. 
     */ 
     portable_iarchive(std::istream& is, unsigned flags = 0) 
     #if BOOST_VERSION < 103400 
       : portable_iprimitive(is, flags & boost::archive::no_codecvt) 
     #else 
       : portable_iprimitive(*is.rdbuf(), flags & boost::archive::no_codecvt) 
     #endif 
       , boost::archive::basic_binary_iarchive<portable_iarchive>(flags) 
     { 
       init(flags); 
     } 

#if BOOST_VERSION >= 103400 
     portable_iarchive(std::streambuf& sb, unsigned flags = 0) 
       : portable_iprimitive(sb, flags & boost::archive::no_codecvt) 
       , boost::archive::basic_binary_iarchive<portable_iarchive>(flags) 
     { 
       init(flags); 
     } 
#endif 

     //! Load narrow strings. 
     void load(std::string& s) 
     { 
       portable_iprimitive::load(s); 
     } 

#ifndef BOOST_NO_STD_WSTRING 
     /** 
     * \brief Load wide strings. 
     * 
     * This is rather tricky to get right for true portability as there 
     * are so many different character encodings around. However, wide 
     * strings that are encoded in one of the Unicode schemes only need 
     * to be _transcoded_ which is a lot easier actually. 
     * 
     * We generate the output string to be encoded in the system's native 
     * format, ie. UTF-16 on Windows and UTF-32 on Linux machines. Don't 
     * know about Mac here so I can't really say about that. 
     */ 
     void load(std::wstring& s) 
     { 
       std::string utf8; 
       load(utf8); 
       s = boost::from_utf8(utf8); 
     } 

и т.д.

Эти строки особый интерес представляют:

#if BOOST_VERSION >= 103500 
     // mix-in helper class for serializing shared_ptr 
     , public boost::archive::detail::shared_ptr_helper 
#endif 

Комментируя их сделал мой билд успеха, но я до сих пор не рад не будучи в состоянии использовать shared_ptr_helper().

ответ

1

Во-первых, убедитесь, что:

  • Вы должны изменены параметры проекта или целевой сборки на C++ 11

Под компании Apple LLVM 6.0 - Язык - C++ сделать следующие изменения

C++ Language Dialect to C++ 11 [-std = C++ 11] Стандартная библиотека C++ для libC++ (стандартная библиотека LLVM C++ с поддержкой C++ 11)

Else Я считаю, что это может быть связано со следующей связанной EOS - Boost Bug (Boost> = 1.56.0)

Издание: https://epa.codeplex.com/workitem/2456

Я также сделал краткий обзор сценария сборки для убедитесь, что он определенно добавит в библиотеку Boost Serialization библиотеку повышения липоса для каждой архитектуры, и да, все это определенно существует.

+0

Спасибо за отличный ответ. Я верю, что ты прав. Я должен был упомянуть, что я строил с настройками проекта, как вы рекомендуете. Проблема EOS была определенно причиной, и в самом деле отчет об ошибке предлагает сделать именно то, что я сделал, - комментируя эти строки кода в файлах portable_iarchive.hpp и portable_oarchive.hpp. – dmedine