Ответ 1
Решение состоит в том, чтобы установить Symbols Hidden By Default
в "Да" во всех настройках сборки для всех целей проекта. Тем не менее, нет ничего мудрее в том, какова была настоящая проблема.
Перекомпиляция приложения iPhone С++ с Xcode 4 Я получаю эту неприятную ошибку компоновщика:
ld: bad codegen, pointer diff in __static_initialization_and_destruction_0(int, int)
to global weak symbol vmml::Vector2<float>::ZERO for architecture armv6
Кто-нибудь знает, что это значит? Как это сделать, тоже было бы здорово:)
Приложение скомпилировано и связано без ошибок в Xcode 3.
Изменить: решение заключается в том, чтобы установить символы "Скрытые по умолчанию" "Да" во всех настройках сборки для всех целей проекта. Тем не менее, нет ничего мудрее в том, какова была настоящая проблема.
Решение состоит в том, чтобы установить Symbols Hidden By Default
в "Да" во всех настройках сборки для всех целей проекта. Тем не менее, нет ничего мудрее в том, какова была настоящая проблема.
У меня была такая же проблема, а также в настройке параметров видимости. Тем не менее, я нервничал, просто возился с видимостью символа и не понимал проблему, поэтому я сделал немного больше исследований.
Если, как и я, вы используете Pete Goodliffe script/package для создания boost в качестве рамки, script устанавливает видимость по умолчанию для скрытого (== yes). Параметры видимости изменяют, как символы отмечены компилятором (по умолчанию, скрытые, внутренние). Эта информация используется компоновщиком при создании общих эльфов объектов (разделяемых библиотек). Он не должен применяться здесь, поэтому я подозреваю, что это ошибка компоновщика. Внутри библиотеки boost у вас есть слабый символ, помеченный как скрытый, а затем в вашем проекте/другой библиотеке тот же символ, помеченный как по умолчанию. Линкер запутан?
Что касается XCode 3 против 4, возможно, по умолчанию в 3 было скрыть символы?
В любом случае изменение видимости по умолчанию для скрытия должно действительно не иметь никакого эффекта, если задействовать только статические библиотеки, поэтому я чувствую себя намного безопаснее, используя этот маршрут.
Я разместил несколько дополнительных сведений в блоге для тех, кто заинтересован.
Я столкнулся с этой проблемой, пытаясь включить библиотеки boost в один из моих проектов. После обнаружения этого сообщения настройка Symbols Hidden By Default
на Yes
также решила эту проблему для меня. И мне также пришлось сделать одну и ту же настройку в каждом из зависимых проектов, чтобы полностью избавиться от ошибки.
Просто FYI. Это произошло только в моих целях, которые использовали стек clang++. Цели GCC и LLVM + GCC, похоже, не затронуты.
В принципе, любые символы в библиотеке, на которую вы ссылаетесь, и ваш собственный код, должны использовать один и тот же уровень видимости, то есть, если все символы в библиотеке, которые вы включаете, скрыты, вам нужно убедиться, что включенные файлы ссылаются на символы в вашем проекте не пытайтесь установить его на видимое. самый безопасный способ сделать это - иметь постоянный уровень видимости по умолчанию в вашем проекте, для меня это только стало проблемой с оптимизацией.
Возможно, вы используете библиотеку с скрытой информацией о символах. Если символ не был экспортирован из вашей библиотеки и вы пытаетесь использовать его извне, это приводит к аналогичной ошибке компоновщика. Правильное решение, похоже, должно было бы найти способ сделать этот символ "видимым" для внешнего мира с помощью макросов GCC и/или изменить сама библиотека, чтобы убедиться, что этот конкретный символ действительно "скрыт" от внешнего мира - -ie это не то, что когда-либо используется или отображается в файле заголовка.
Однако будьте осторожны: согласно документации Apple, вы не должны скрывать какую-либо информацию о символах по ряду причин; этот, приведенный ниже, кажется самым тревожным из группы:
Если ваш символ использует информацию об идентификаторе времени выполнения (RTTI), исключения или динамические кавычки для объекта, который определен в другой библиотеке, ваш символ должен быть видимым, если он ожидает обработки запросов, инициированных другой библиотекой. Например, если вы определяете обработчик catch для типа в стандартной библиотеке С++, и вы хотите поймать исключения этого типа, выписанные стандартной библиотекой С++, вы должны убедиться, что ваш объект typeinfo является видимым.
Таким образом, если вы хотите поймать исключение из библиотеки, с которой вы связываетесь, скрытие информации о символах представляется плохим выбором. Правильное решение будет состоять в том, чтобы отобразить символы любой библиотеки, на которую вы ссылаетесь. Это может быть сделано путем исключения следующих флагов компилятора GCC:
-fvisibility=hidden --fvisibility-inlines-hidden
(видимость по умолчанию должна быть достаточной), или есть также прагмы компилятора, которые позволяют вам это делать. См.: http://gcc.gnu.org/wiki/Visibility