boost iOS链接错误 我有一个C++库,它依赖于我正在为IOS8编译的Boost。我使用Daniel Rosser的脚本为iOS编译boost-1.57.0:

boost iOS链接错误 我有一个C++库,它依赖于我正在为IOS8编译的Boost。我使用Daniel Rosser的脚本为iOS编译boost-1.57.0: ,c++,ios,xcode,boost,linker,C++,Ios,Xcode,Boost,Linker,我修改了脚本,这样它也可以构建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_

我修改了脚本,这样它也可以构建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()感到不高兴。

首先确保:

  • 您必须将项目或目标生成设置更改为c++11

苹果LLVM 6语言-C++下的更改

C++语言方言到C++ 11 [-STD= C++ 11 ] C++标准库到 LBV++(LVVM C++标准库,C++ 11支持)< /P> 否则我相信这可能与以下链接的EOS-Boost Bug有关(Boost>=1.56.0)

问题:


我还快速回顾了构建脚本,以确保它肯定会为每个体系结构将Boost序列化库添加到lipo Boost存档中,是的,所有这些都在那里。

感谢您给出的精彩答案。我相信你是完全正确的。我应该提到的是,我正在使用您推荐的项目设置进行构建。EOS问题无疑是原因,事实上,错误报告建议做的正是我所做的——在portable_iarchive.hpp和portable_oarchive.hpp中注释掉那些代码行。
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