Ответ 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 совпадают) и выберет первый, который он найдет.