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

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

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

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

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

Источник: Библиотека разработчиков iOS → Концепции Xcode → Цель Xcode

Ответ 1

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

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

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

  • В Target A есть фаза сборки Link Binary With Libraries, в которой есть библиотека в своем списке с тем же именем как продукт B. Этот продукт может быть либо в одном проекте, либо в другой проект в рабочей области. Обратите внимание, что я сказал "то же имя". Просто потому, что вы выбрали libA.a из цели A, это не означает, что неявные зависимости будут строить его, если у вас есть другой продукт libA.a в другой цели. Подробнее см. Ниже.
  • В Target A есть "Фаза копирования файлов", которая копирует файл с базовым именем, который соответствует продукту B. Обычно фаза сборки "Копировать файлы" не может ссылаться на файл, t в том же проекте, что и его цель, но вы можете настроить зависимость между проектами, если вы создадите фиктивный файл для фазы "копировать", чтобы скопировать то же имя, что и продукт 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"? Я могу придумать пару причин.

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

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

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

Ответ 2

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

Xcode поддерживает зависимости Implicit и Explicit[About].

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

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

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

  1. Нет зависимости в Build Phases -> Target Dependencies
  2. Указано в General -> Embedded Binaries и Linked Frameworks and Libraries[Link vs Embed]

Чтобы включить эту функцию[No such module]

Edit Scheme -> Build -> Find Implicit Dependencies

вокабулярный

Подробнее здесь, здесь