Ошибка ссылки при добавлении библиотеки, созданной с помощью Clang, в приложение iOS, созданное с помощью GCC
Я пытаюсь добавить API синхронизации Dropbox (v1.1.2) в приложение для iOS, созданное с помощью Marmalade (v6.3). Я получаю следующую ссылку:
Undefined symbols for architecture armv7:
"___udivmodsi4", referenced from:
_sqlite3BitvecSet in libDropbox.a(sqlite3.o)
_sqlite3BitvecClear in libDropbox.a(sqlite3.o)
_sqlite3BitvecTest in libDropbox.a(sqlite3.o)
ld: symbol(s) not found for architecture armv7
Поиск соответствующих частей этого сообщения об ошибке обнаруживает, что у некоторых пользователей определенной библиотеки SQLCipher возникла та же проблема, и указывает на то, что проблема вызвана несогласованностью компиляторов, использованных для создания этой библиотеки, и различных проектов, использующих ее.
Поскольку система сборки для нашего проекта настраивается с помощью набора инструментов Marmalade, я думаю, что смена компилятора (в настоящее время версии GCC 4.4, поставляемой Marmalade) не является вариантом.
Может кто-нибудь сказать мне более точно, что происходит не так? Есть ли другие способы обойти эту проблему?
2 ответа
Другой ответ правильный. Однако для этой конкретной проблемы (если это единственные ошибки компоновщика, которые вы получаете) я вижу два обходных пути:
- Получите исходный код из sqlite3, который включает
sqlite3BitvecSet
и скомпилируйте эти функции в свой собственный проект, чтобы переопределить библиотеку. Они получат любую поддержку divmod, предлагаемую вашим собственным компилятором. - Реализуйте свой собственный
udivmodsi4
, Вам не нужно реализовывать побитовое деление (хотя вы можете получить эту базовую реализацию C из источника GCC). Вам просто нужно реализовать его в собственных операциях и позволить вашему компилятору вызывать любую внутреннюю поддержку, в которой он нуждается.
Это не проверено, но должно дать вам основную идею. Вам может понадобиться больше подчеркиваний в имени, чтобы соответствовать поведению / наименованию другой среды сборки:
unsigned long
udivmodsi4(unsigned long num, unsigned long den, int modwanted)
{
if (modwanted)
return num % den;
else
return num / den;
}
На таких процессорах, как ARM, с относительно простыми наборами команд, некоторые более сложные операции отображаются на вызовы функций, а не на последовательности инструкций. Когда вы ссылаетесь с помощью "правильного" компилятора, их реализация реализуется, и это работает! Вы обычно не видите этого.
Очевидным решением здесь было бы использовать мармелад для компиляции библиотеки dropbox, тогда он будет использовать совместимый компилятор.
Тогда возникает вопрос: есть ли причина, по которой вы этого не делаете? Текущие компиляторы Marmalade не поддерживают ARC. Я думаю, это было бы причиной не компилировать в ARC.