Создание статической библиотеки с кокоаподами

Я пытаюсь создать статическую библиотеку с разными зависимостями (например, AFNetworking), указанную в подфайле. Я не хочу, чтобы зависимости включались в финальную статическую библиотеку (вызов libMyProject.a), я просто хочу связать их, а затем создать файл MyProject.Podspec, где я могу установить те же зависимости.

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

Как я могу ссылаться на libPods.a lib, но не включать его в libMyProject.a? Он должен работать так же, как соединение с другими существующими структурами.

Спасибо!

Ответы

Ответ 1

Я решил это, удалив libPods.a lib из раздела "Link Binary With Libraries" на этапах сборки.

Ответ 2

Во время ручного удаления libPods.a из "Link Binary with Libraries" фаза сборки действительно работает, реальный ответ состоит в том, чтобы не допустить, чтобы она была добавлена ​​туда в первую очередь.

Причина, по которой она добавлена, заключается в том, что команда установки pod находит статическую библиотечную цель как одну из своих целей для связи. Это может быть связано с тем, что это первая цель в списке (реализация cocoapods заставляет ее выбирать первую, если вы явно не указали цели), или это может быть из-за того, что вы явно указали ее в разделе "link_with".

Ответ, который я нахожу, заключается в использовании раздела link_with в подфайле, чтобы явно указать ваши цели и опустить цель статической библиотеки.

Проект pods по-прежнему создается, и ваши зависимости включаются туда, как вы ожидали, но libPods.a не добавляется в фазу сборки вашей статической библиотеки.

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

Моя успешная стратегия до сих пор заключалась в создании цели статической библиотеки (да, отдельной из вашей основной статической библиотеки) и называть ее "Dummy". Задайте эту цель в разделе link_with вашего подфайла.

Это немного неприятно, дано, но оно действительно работает.

platform :ios, '5.1.1'

link_with ['Dummy']

pod 'AFNetworking', '= 1.3.1'

Ответ 3

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

Каждая созданная Cocoapods цель включает файл "Pods-target-dummy.m", который скомпилирован в продукт; если вы используете целевой объект Pods по умолчанию, он просто называется "Pods-dummy.m". Когда и библиотека, и клиент используют цель по умолчанию, идентичные символы, созданные при компиляции фиктивных файлов, вызовут ошибку связи.

Я попробовал вариант Craig answer сам и обнаружил, что оператор link_with также отвечает за подключение xcconfig, сгенерированного Cocoapods, который предоставляет компилятор флаги, которые контролируют путь поиска заголовка. Конечно, вы можете добавить xcconfig (или параметры проекта пути поиска заголовка) вручную, но я пошел искать повторяющееся решение для моей команды.

Мое решение - создать явную цель для библиотеки с именем, которое вряд ли вызовет конфликты с клиентским проектом (например, имя библиотеки):

target 'XYZLibrary' do
    pod 'AFNetworking', '2.5.2'
    ...
end

Вы можете включить оператор link_with в блок target, если имя цели статической библиотеки (в вашем проекте Xcode) отличается, но если есть только одна цель, я обычно предпочитаю использовать одно и то же имя в оба места, делая link_with ненужным.

Если у вас есть цель unit test, создайте две отдельные цели. (В настоящее время def набор общих контейнеров, которые используются в обеих целях, поскольку абстрактные цели в настоящее время не являются опцией, но они могут быть на один день.) Это выглядит так:

def common_pods
  pod 'AFNetworking', '2.5.2'
end

target 'XYZLibrary' do
  common_pods
end

target 'XYZLibraryTests' do
  common_pods
end

Ключ состоит в том, чтобы не иметь никаких элементов pod в корне Podfile, так что Cocoapods не будет создавать цель по умолчанию. Таким образом, каждый продукт получает уникальный "Pods-target-dummy.m", и нет конфликта, когда эти объектные файлы связаны друг с другом.