Скомпилируйте несколько статических библиотек в одну платформу iOS

У меня есть большая статическая библиотека, которую я хотел бы упаковать в статическую платформу iOS для простоты использования. Библиотека на самом деле несколько .a файлы, по одному на логический модуль библиотеки.

У меня есть скомпилированный .a файлы, созданные для устройства (толстый файл с armv7, armv7s, arm64) и для симулятора (толстый файл с i386, x86_64).

Теперь, AFAIK, мне нужно объединить все эти файлы в один большой файл, чтобы создать правильную структуру.

Используя описанную здесь технику ( объединение статических библиотек), я мог бы сделать:

libtool -static -o new.a old1.a old2.a

Но, видимо, оба old1.a а также old2.a включать в себя те же символы. Таким образом, при связывании с моей структурой, я получаю ошибку компоновщика (по уважительной причине) duplicate symbols,

Более правильный способ сделать это (таким образом избегая повторяющихся символов), кажется, распаковывает .o файлы, и объединяя их в большой .a файл ( Как упаковать несколько библиотечных архивов (.a) в один архивный файл?)

ar x old1.a
ar x old2.a
ar rcs new.a *.o

Теперь запомни, old1.a а также old2.a толстые файлы, поэтому мне нужно отделить их для каждой архитектуры.

Итак, вот что я делаю:

lipo old1.a -thin armv7 -output armv7/old1.a
cd armv7; ar x old1.a; cd ..
...
lipo old1.a -thin x86_64 -output x86_64/old1.a
cd x86_64; ar x old1.a; cd ..

// Same goes for old2.a ...

// Then, 
libtool -static -o new.a armv7/*.o armv7s/*.o arm64/*.o // ... etc

Но по какой-то причине при связывании с созданным таким образом фреймворком компоновщик не может найти какой-либо символ (хотя nm раскрывает их всех).

Любая идея, как построить эту статическую структуру?

2 ответа

Вы можете предварительно связать ваши объекты статической библиотеки в один, также вы можете предварительно связать другие статические библиотеки в один. На самом деле он будет связывать объекты с компоновщиком (почти как в динамической библиотеке).

  1. В вашей единственной библиотеке (основной) перейдите в "Настройки сборки" и найдите "Выполнить предварительную ссылку на один объект" в разделах "Связывание". Переключите это на Да
  2. В Prelink библиотеки вы можете указать другие библиотеки, которые вы хотите включить. Там нужно указывать не только имена, но и полное имя файла. Если другие библиотеки также из вашего проекта, то вы можете использовать переменную $(CONFIGURATION_BUILD_DIR). Так что если у вас есть библиотека foo, то это будет $(CONFIGURATION_BUILD_DIR)/libfoo.a
  3. Вы можете добавить дополнительные флаги в флаги предварительной ссылки на один объект
  4. Если вы хотите удалить локальные символы, убедитесь, что для параметра Постобработка развертывания установлено значение Да, поскольку статические библиотеки по умолчанию не удаляются.

Если в ваших библиотеках есть повторяющиеся символы, значит, что-то не так в структуре ваших модулей.

  • Если они являются одинаковыми функциями, то разделите их в отдельной статической библиотеке и используйте повторно из других мест.
  • Если эти символы на самом деле отличаются и имеют одно и то же имя, рассмотрите возможность объявления их как статических (если это ANSI C). Вы также можете
  • Вы можете настроить некоторые локальные символы с помощью настройки видимости ( http://llvm.org/docs/LangRef.html, http://gcc.gnu.org/wiki/Visibility).

Действительно ли libtool создает толстую библиотеку? Мы делаем что-то похожее, но напрямую используем "lipo-create"

ar -r armv7.a a/armv7/*.o b/armv7/*.o c/armv7/*.o d/armv7/*.o e/armv7/*.o
ar -r armv7s.a a/armv7s/*.o b/armv7s/*.o c/armv7s/*.o d/armv7s/*.o e/armv7s/*.o
ar -r i386.a a/i386/*.o b/i386/*.o c/i386/*.o d/i386/*.o e/i386/*.o


$LIPO \
        -create \
        -arch armv7 "objs/armv7.a" \
        -arch i386  "objs/i386.a" \
        -o "$FRAMEWORK_INSTALL_NAME" \
    || abort "Lipo $1 failed"

Мы также столкнулись с проблемой, когда isv делал то же самое с нашими фреймворками, чтобы создать их фреймворк, так что, хотя a/foo.o и b/foo.a отлично подходили для нашего armv7.o. когда они извлекают "ar -x", ar не сохраняет пути, поэтому пишется только один файл foo.o.

Мы исправили это, просто переименовав каждый.o и присвоив ему префикс a_foo.o, перед созданием target.a.

Другие вопросы по тегам