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