Подтвердить что ты не робот

Предотвращение дублирования символов при создании статической библиотеки с помощью Cocoapods

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

В моем сценарии я создаю статическую библиотеку. Более конкретно, я взламываю MyLib.framework для использования пользователями. Я бы действительно хотел управлять зависимостями MyLib.framework с Cocoapods, но он создает много болевых точек, когда потребители моей библиотеки также используют Cocoapods.

Например, моя библиотека имеет зависимость AFNetworking, которой я управляю с Cocoapods. Когда я создаю свою библиотеку, она ссылается на libPods.a, которая включает в себя AFNetworking, а также некоторые "dummy" файлы/объекты. Если пользователи моей платформы также используют Cocoapods для создания своего приложения, они увидят что-то вроде этого:

duplicate symbol _OBJC_METACLASS_$_PodsDummy_Pods in:
    /Users/erikkerber/Dropbox/Projects/MillMain/MyLib.framework/BuddySDK(Pods-dummy.o)
    /Users/erikkerber/Library/Developer/Xcode/DerivedData/MillMain-fngfqhlslygksgcfuciznkpqfrbr/Build/Products/Debug-iphonesimulator/libPods.a(Pods-dummy.o)
duplicate symbol _OBJC_CLASS_$_PodsDummy_Pods in:
    /Users/erikkerber/Dropbox/Projects/MillMain/MyLib.framework/BuddySDK(Pods-dummy.o)
    /Users/erikkerber/Library/Developer/Xcode/DerivedData/MillMain-fngfqhlslygksgcfuciznkpqfrbr/Build/Products/Debug-iphonesimulator/libPods.a(Pods-dummy.o)
ld: 2 duplicate symbols for architecture i386

Я предполагаю, что если они будут добавлять зависимость AFNetworking, они также получат дубликаты символов, относящихся к AFNetworking.

Я планирую в конечном итоге также распространять MyLib вместе с Cocoapods, но я также хочу иметь возможность распространять сам MyLib.framework.

Есть ли способ использовать Cocoapods с моей библиотекой, делая Cocoapods безопасным для любого потенциального пользователя?

4b9b3361

Ответ 1

Короче говоря, единственный хороший способ распространения готовых библиотек - не, включая любую из зависимостей, но оставляя это до пользователя. То есть в вашем примере вы должны проинструктировать своих пользователей, как добавить AFNetworking в свой проект. То же самое относится и к файлам dummy.

Сказав это, вы могли бы, конечно, пойти на несколько заранее подготовленных вариантов:

  • Включить все зависимости.
  • Включите только источник libs, оставьте зависимости до пользователя.

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

В качестве обходного пути вы можете использовать свой Podfiles post_install hook, чтобы полностью удалить фиктивные файлы. (они необходимы только для не-исходных библиотек, таких как Testflight). что-то вроде следующего:

post_install do |installer|
  installer.project.targets.each do |target|
    source_files = target.source_build_phase.files
    dummy = source_files.find do |file|
      # TODO Fix this to the actual filename
      # puts "File: #{file.file_ref.name}"
      file.file_ref.name == 'TheDummyFile.m'
    end
    puts "Deleting source file #{dummy.inspect} from target #{target.inspect}."
    source_files.delete(dummy)
  end
end

Это непроверенный код.

Крючок post_install дает объект установки CocoaPods, из которого вы можете получить цели Pods.xcodeproj, для которых вы можете найти документацию здесь. Оттуда вы можете развернуться и сделать все, что вам нравится в проекте, которое сохраняется на диске после запуска этого крюка.

Ответ 2

У меня была такая же проблема. Я управлял зависимостями моей библиотеки с cocoapods, используя следующий формат podfile:

platform :ios, '6.0'
pod 'AFNetworking'

В результате появился файл Pods-dummy.o в моем .a файле. Если бы я включил эту библиотеку в другой проект, используя тот же формат podfile, они оба создали символ Pods-dummy.o и приводят к ошибке компоновщика. Решение состоит в том, чтобы использовать другой формат podfile, который приводит к символу подпункта с именами:

platform :ios, '6.0'
target "MyProject" do
    pod 'AFNetworking'
end

В результате получается файл Pods-MyProject-dummy.o, который не будет вызывать повторяющиеся символы.

Примечание. Если вы переключите свой проект на использование нового формата podfile, обязательно отмените libPods.a от своего проекта, так как он будет зависать как неработающая ссылка, потому что новая библиотека pods называется Pods-MyProject

Ответ 4

С ссылкой http://guides.cocoapods.org/syntax/podfile.html#post_install и http://pdx.esri.com/blog/2013/12/13/namespacing-dependencies/

Я использую метод "Вручную переименовать все символы". Я испытывал дублирующий символ _OBJC_METACLASS _ $_ PodsDummy_Pods, поэтому я добавил и отредактировал post_install в подфайле к чему-то подобному, чтобы избежать дублирования символа

post_install do |installer_representation|
    installer_representation.pods_project.targets.each do |target|
        target.build_configurations.each do |config|
            config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] = '$(inherited), PodsDummy_Pods=SomeOtherNamePodsDummy_Pods'
        end
    end
end

Ответ 5

Эта проблема возникла для меня, когда я вручную добавила какой-то внешний код в проект AFNetworking, например, а затем добавил несколько модулей, которые также включили его.

Просто удаление AFNetworking из моего собственного проекта (а не модуля) устранило проблему.