Как Xcode находит неявные целевые зависимости?

Xcode находит зависимости автоматически иногда. Я думаю, что это нормально, когда я тот, кто определяет отношения, и когда я ленюсь...

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

Какие правила Xcode использует, чтобы найти такие отношения? (Надеюсь, я смогу понять логику, поэтому запустите ее в своем уме и, возможно, сэкономите мне время в будущем) Или Что делает цель подходящей, чтобы быть неявно зависимой от другой?

Цель и продукт, который она создает, могут быть связаны с другой целью. Если цель требует вывода другой цели для построения, говорят, что первая цель зависит от второй. Если обе цели находятся в одной рабочей области, Xcode может обнаружить зависимость, и в этом случае он строит продукты в требуемом порядке. Такое отношение называется неявной зависимостью.

Источник: iOS Developer Library → Xcode Concepts → Xcode Target

1 ответ

Этот ответ относится к Xcode 8.x, а я думаю к Xcode 9.0.

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

Цель "A" может быть сделана "неявно" зависимой от цели "B" двумя способами:

  1. У цели A есть фаза сборки "Link Binary With Libraries", в списке которой есть библиотека с тем же именем, что и у продукта B. Этот продукт может находиться либо в том же проекте, либо в другом проекте в рабочей области. Обратите внимание, что я сказал "одно имя". Тот факт, что вы выбрали libA.a из цели A, не означает, что неявные зависимости будут создавать ее, если у вас есть другой продукт libA.a с другой целью. Смотрите ниже для деталей.
  2. У цели A есть "Фаза копирования файлов", которая копирует файл с базовым именем, совпадающим с продуктом B. Обычно фаза сборки "Копирование файлов" не может ссылаться на файл, который не находится в том же проекте, что и его цель, но Вы можете установить зависимость между проектами, если создаете фиктивный файл для фазы "копировать файл" для копирования, имя которого совпадает с именем продукта B. Например, если у вас есть рабочее пространство, содержащее два проекта ProjectA и ProjectB. ProjectA имеет TargetA, который создает libA.a, а ProjectB имеет TargetB, который создает libB.a. TargetA может заставить TargetB создать libB.a, имея "фальшивый" нулевой байт-файл как часть TargetA, который, как оказалось, называется libB.a, и этого будет достаточно для создания libB.a, даже если libB.a ссылается на этапе "Копирование файлов" файл полностью отличается от выходных данных продукта сборки TargetB. Если вы установите флажок "Копировать только при установке", XCode не будет выполнять копирование, но все равно разрешит зависимость. На самом деле вы можете удалить поддельный файл с вашего диска, который вы создали исключительно для того, чтобы что-то добавить в фазу "Копирование файлов" (но вы должны оставить это в своем проекте).

Так почему же кто-то захочет совершить ужас "2"? Я могу придумать пару причин.

  1. TargetA нужны некоторые файлы, скопированные / сгенерированные TargetB, но TargetB не создает библиотеку для ссылки. Возможно, вы могли бы обойти эту проблему, создав TargetB для создания небольшой фиктивной библиотеки, но это может быть болезненным по другим причинам.
  2. Допустим, у меня были projectA, targetA и libA.a (и эквиваленты для проектов B, C и D), и libA.a зависели от libB.a и libC.a, которые оба должны были сначала скачать libD.a (возможно, некоторые заголовки) и / или генерируемые источники). Вы можете сделать все это, используя фазу "Связать с библиотеками" (решение № 1), но в этом случае вы получите две копии файлов.o в libD в окончательной связанной версии libA. Если вы сделаете это достаточно глубоко (например, в рабочей области, в которой 40 проектов имеют различные уровни зависимости друг от друга), вы быстро получите огромные библиотечные файлы с несколькими одинаковыми файлами.o в них, и время компоновки станет ужасающим.

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

Что произойдет, если у вас окажется две цели в одной рабочей области, которые генерируют продукты с одинаковым именем и зависят от них от третьей цели? Неявные зависимости выберут одну. Похоже, что сопоставление основано на базовом названии продукта (поэтому foo / bar.a и baz / bar.a совпадают) и выберет первое, которое он найдет.

Xcode Dependency [О программе] - это зависимость, необходимая дляпостроения выбранной цели.

Implicit зависимость

  • исходный код иначеNon-compiled dependencies. Xcode позволяет добавить зависимость от всегоworkspace. Хорошим примером является проект от GitHub илиCocoaPods [О программе] с исходным кодом
  • закрытый код иначеPrecompiled dependencies он же External - внешний двоичный файл, CocoaPods, Carthage с закрытым кодом

Implicit dependency - это зависимость, необходимая для успешного построения цели, но не определенная явно.

  1. Нет зависимости в Build Phases -> Dependencies || Target Dependencies
  2. Указано в General -> Платформа, библиотеки и встроенный контент||Встроенные двоичные файлыorСвязанные платформы и библиотеки [Link vs Embed]

Чтобы включить эту функцию [Нет такого модуля]

Edit Scheme -> Build -> Find Implicit Dependencies

[Явная зависимость]

[Словарь]

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