Проблема связывания статических библиотек XCode 4.2 - PullRequest
2 голосов
/ 27 декабря 2011

У меня есть Core статическая библиотека, несколько Component статических библиотек, которые ретранслируют на Core одну, а затем есть App связывает библиотеки Core и Component . Мое приложение может связываться как с Core , так и Component , пока Component не использует классы Core ( Приложение использует классы из Core ).

Я получил следующую ошибку в версиях armv6 и armv7. Так что моя проблема - не очень популярная проблема с ссылками, которая есть у всех.

ld: symbol(s) not found for architecture armv6
clang: error: linker command failed with exit code 1 (use -v to see invocation)

Я добавил ссылку на Core в Компонент и даже добавил ее в "Link Binary With Libraries", которая не обязательна для статической библиотеки.

С тех пор, как у меня возникла эта проблема, я начинаю сомневаться в своем дизайне ... Вероятно, это имеет больше смысла в динамической компоновке среды, но все же это должно быть выполнимо в статической, тем более что это уже работает под Windows с компиляторами MSVC .

Edit: Я добился определенного прогресса! Хотя я до сих пор не знаю, куда идти с этим.

Вот мои настройки:

  • Ядро имеет класс cResourceManager с шаблонным методом GetResource (int id)

  • Core также имеет класс cResource

  • Компонент имеет класс cMesh, который наследует cResource

Вот несколько тестов:

  • Если я попытаюсь из App вызвать rm-> GetResource (...), я получу ошибку связывания

  • Если я попытаюсь из Приложения создать cMesh, я получу ссылку на ошибку соединения

  • Если я попытаюсь из App вызвать статический метод, который вернет новый экземпляр cMesh, я получу ошибку компоновки

  • Если я закомментирую конструкцию cMesh, но оставлю другой член, функция cMesh нормально вызывает ссылки приложения. Я могу даже вызвать delete mesh .

Я никогда не видел ничего подобного!

Ответы [ 3 ]

1 голос
/ 21 января 2012

Если вы удалите конструктор cMesh, тогда вы будете использовать конструктор по умолчанию (без аргумента, без тела) cMesh, который вам дан. Похоже, что в вашем конструкторе cMesh есть ошибка сборки или отсутствует код из-за некоторого кода, поэтому библиотека фактически не генерируется, и, возможно, Xcode не сообщает об ошибке. Xcode не умеет сообщать об ошибках компоновщика.

Я бы посоветовал посмотреть, какие символы, по словам компоновщика, отсутствуют, и еще раз проверить, действительно ли они определены в вашем коде. Я предполагаю, что вы используете один из этих символов в своем конструкторе cMesh. Часто с виртуальными базовыми классами вы можете забыть определить, и реализуют метод или два в дочернем классе. Это может быть связано с отсутствием метода, основанного на вашем шаблоне, или если ваш шаблон не #include d. Это может скомпилировать нормально, но привести к ошибкам компоновщика, как вы видите.

Если Xcode не отображает полную ошибку компоновщика, покажите Log Navigator ( Команда ⌘ + 7 ), дважды щелкните последнюю запись «Build», выберите Ошибка, а затем нажмите кнопку в крайнем правом углу строки, которая появляется при выборе. Символы должны быть перечислены там. Если нет, то пришло время для xcodebuild в Терминале.

Если это не в этом случае, мне было бы интересно посмотреть результаты того, будет ли библиотека создаваться для соответствующей архитектуры, или, возможно, это может стимулировать некоторый прогресс:

  1. В Xcode Organizer Shift ⇧ + Команда ⌘ + 2 , нажмите Projects и найдите путь к DerivedData для вашего проекта.
  2. В Терминале перейдите в этот каталог (cd ~/Library/Developer/Xcode/DerivedData/proj-<random value>/)
  3. Удалить (или отодвинуть) каталог сборки (rm -r Build)
  4. В Xcode попробуйте собрать с присутствующим конструктором cMesh.
  5. Найти файл продукта библиотеки (cd Build/Products/<scheme>-iphoneos)

Ваши скомпилированные статические библиотеки (<libname>.a) должны находиться в этом каталоге. Если их там нет, они не строят (если вы не разместите свои продукты в другом месте). Если ваши библиотеки есть, давайте подтвердим, что они действительно создаются для соответствующей архитектуры. Запустите otool -vh <library>.a. Вы должны увидеть что-то вроде:

$ otool -vh libtesting.a 
Archive : libtesting.a
libtesting.a(testing.o):
Mach header
      magic cputype cpusubtype  caps    filetype ncmds sizeofcmds      flags
   MH_MAGIC     ARM         V7  0x00      OBJECT     3       1928 SUBSECTIONS_VIA_SYMBOLS

Как видите, моя тестовая библиотека была построена для ARMv7.

1 голос
/ 27 декабря 2011

Убедитесь, что вы связываете их в правильном порядке.

Если Компонент зависит от символов в Core, то Компонент должен быть первым в порядке ссылки, чтобы компоновщик знал, какие символы искать в Core.

В MSVC порядок не имеет значения, но в большинстве других комплектов компиляторов он имеет значение.

0 голосов
/ 20 января 2012

Я не думаю, что Clang генерирует код для armv6, если вы ориентируетесь на старые устройства, вам все еще нужно использовать GCC.

...